package discovery import "strings" const ( RailCrypto = "CRYPTO" RailProviderSettlement = "PROVIDER_SETTLEMENT" RailLedger = "LEDGER" RailCardPayout = "CARD_PAYOUT" RailFiatOnRamp = "FIAT_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 { return strings.ToUpper(strings.TrimSpace(value)) } // 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 strings.HasPrefix(clean, "RAIL_OPERATION_") { clean = strings.TrimPrefix(clean, "RAIL_OPERATION_") } 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 "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": return []string{RailOperationFee} case "observe.confirm", "observe_confirm": return []string{RailOperationObserveConfirm} 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{ RailOperationSend, RailOperationExternalDebit, RailOperationExternalCredit, RailOperationFee, RailOperationObserveConfirm, } } // CardPayoutRailGatewayOperations returns canonical operations for card payout gateways. func CardPayoutRailGatewayOperations() []string { return []string{ RailOperationSend, RailOperationExternalCredit, RailOperationObserveConfirm, } }