package discovery import "strings" const ( RailCrypto = "CRYPTO" RailProviderSettlement = "SETTLEMENT" RailLedger = "LEDGER" RailCardPayout = "CARD" RailFiatOnRamp = "ONRAMP" ) const ( RailOperationDebit = "DEBIT" RailOperationCredit = "CREDIT" RailOperationExternalDebit = "EXTERNAL_DEBIT" RailOperationExternalCredit = "EXTERNAL_CREDIT" RailOperationMove = "MOVE" RailOperationSend = "SEND" RailOperationFee = "FEE" RailOperationObserveConfirm = "OBSERVE_CONFIRM" RailOperationFXConvert = "FX_CONVERT" RailOperationBlock = "BLOCK" RailOperationRelease = "RELEASE" ) var knownRails = map[string]struct{}{ RailCrypto: {}, RailProviderSettlement: {}, RailLedger: {}, RailCardPayout: {}, RailFiatOnRamp: {}, } var knownRailOperations = map[string]struct{}{ RailOperationDebit: {}, RailOperationCredit: {}, RailOperationExternalDebit: {}, RailOperationExternalCredit: {}, RailOperationMove: {}, RailOperationSend: {}, RailOperationFee: {}, RailOperationObserveConfirm: {}, RailOperationFXConvert: {}, RailOperationBlock: {}, RailOperationRelease: {}, } // NormalizeRail canonicalizes a rail token. func NormalizeRail(value string) string { clean := strings.ToUpper(strings.TrimSpace(value)) if clean == "" { return "" } clean = strings.ReplaceAll(clean, "-", "_") clean = strings.ReplaceAll(clean, " ", "_") for strings.Contains(clean, "__") { clean = strings.ReplaceAll(clean, "__", "_") } switch clean { case RailCrypto, "RAIL_CRYPTO": return RailCrypto case RailProviderSettlement, "PROVIDER_SETTLEMENT", "RAIL_SETTLEMENT", "RAIL_PROVIDER_SETTLEMENT": return RailProviderSettlement case RailLedger, "RAIL_LEDGER": return RailLedger case RailCardPayout, "CARD_PAYOUT", "RAIL_CARD", "RAIL_CARD_PAYOUT": return RailCardPayout case RailFiatOnRamp, "FIAT_ONRAMP", "RAIL_ONRAMP", "RAIL_FIAT_ONRAMP": return RailFiatOnRamp default: return clean } } // IsKnownRail reports whether the value is a recognized payment rail. func IsKnownRail(value string) bool { _, ok := knownRails[NormalizeRail(value)] return ok } // NormalizeRailOperation canonicalizes a rail operation token. func NormalizeRailOperation(value string) string { clean := strings.ToUpper(strings.TrimSpace(value)) if after, ok := strings.CutPrefix(clean, "RAIL_OPERATION_"); ok { clean = after } return clean } // IsKnownRailOperation reports whether the value is a recognized rail operation. func IsKnownRailOperation(value string) bool { _, ok := knownRailOperations[NormalizeRailOperation(value)] return ok } // ExpandRailOperation maps canonical and legacy names to normalized rail operations. func ExpandRailOperation(value string) []string { if op := NormalizeRailOperation(value); op != "" { if IsKnownRailOperation(op) { return []string{op} } } switch strings.ToLower(strings.TrimSpace(value)) { case OperationExternalDebit, "external_debit": return []string{RailOperationExternalDebit} case OperationExternalCredit, "external_credit": return []string{RailOperationExternalCredit} case "payin", "payin.crypto", "payin.fiat", "payin.card": return []string{RailOperationExternalDebit} case "payout", "payout.crypto", "payout.fiat", "payout.card": return []string{RailOperationExternalCredit, RailOperationSend} case "fee.send", "fees.send", OperationFee: return []string{RailOperationFee} case OperationObserveConfirm, "observe_confirm": return []string{RailOperationObserveConfirm} case OperationFXConvert, "fx_convert": return []string{RailOperationFXConvert} case "funds.block", "hold.balance", "block": return []string{RailOperationBlock} case "funds.release", "release", "unblock": return []string{RailOperationRelease} default: return nil } } // NormalizeRailOperations canonicalizes and deduplicates rail operation values. func NormalizeRailOperations(values []string) []string { if len(values) == 0 { return nil } result := make([]string, 0, len(values)) seen := map[string]bool{} for _, value := range values { for _, op := range ExpandRailOperation(value) { if op == "" || seen[op] { continue } seen[op] = true result = append(result, op) } } if len(result) == 0 { return nil } return result } // CryptoRailGatewayOperations returns canonical operations for crypto rail gateways. func CryptoRailGatewayOperations() []string { return []string{ OperationBalanceRead, OperationSend, OperationExternalDebit, OperationExternalCredit, OperationFee, OperationObserveConfirm, // Legacy rail tokens retained for backward compatibility. RailOperationSend, RailOperationExternalDebit, RailOperationExternalCredit, RailOperationFee, RailOperationObserveConfirm, } } // CardPayoutRailGatewayOperations returns canonical operations for card payout gateways. func CardPayoutRailGatewayOperations() []string { return []string{ OperationSend, OperationExternalCredit, OperationObserveConfirm, // Legacy rail tokens retained for backward compatibility. RailOperationSend, RailOperationExternalCredit, RailOperationObserveConfirm, } } // ProviderSettlementRailGatewayOperations returns canonical operations for settlement gateways. func ProviderSettlementRailGatewayOperations() []string { return []string{ OperationFXConvert, OperationObserveConfirm, // Legacy rail tokens retained for backward compatibility. RailOperationFXConvert, RailOperationObserveConfirm, } }