Module: OpenReceive::Server::Swap
- Defined in:
- lib/openreceive/server/swap.rb,
lib/openreceive/server/swap/assets.rb,
lib/openreceive/server/swap/fixedfloat.rb,
lib/openreceive/server/swap/rates_feed.rb,
lib/openreceive/server/swap/weight_budget.rb,
lib/openreceive/server/swap/transient_cache.rb
Overview
Automated swaps: the FixedFloat(-compatible) provider, the asset catalog, rates/limits caching, and the LSC connection factories. Ruby port of packages/js/node/src/swap/ plus the LSC provider factory from packages/js/node/src/lsc-uri.ts.
Defined Under Namespace
Modules: Assets, FixedFloatRates Classes: FixedFloatApiError, FixedFloatProvider, SwapProviderWeightBudget, TransientSwapCache, WeightBudgetError
Class Method Summary collapse
- .amount_too_large_message?(message) ⇒ Boolean
- .amount_too_small_message?(message) ⇒ Boolean
-
.availability_message(reason) ⇒ Object
Payer-facing copy per availability reason (mirrors fixedFloatAvailabilityMessage).
-
.classify_fixedfloat_quote_error(error) ⇒ Object
Map a quote-path failure to a SwapAvailabilityReason.
-
.default_http_request(method:, url:, headers:, body: nil, timeout_ms: nil) ⇒ Object
Default HTTP transport on stdlib Net::HTTP.
- .fixedfloat_provider(**options) ⇒ Object
-
.providers_from_connections(connections, http: nil, now: nil) ⇒ Object
Build one provider per parsed LSC connection (the hashes produced by OpenReceive::Server::LscUri.parse / read_environment).
-
.providers_from_environment(env = ENV, http: nil, now: nil) ⇒ Object
Mirror of createLscSwapProvidersFromEnvironment: LSC_URI_PRIMARY first, LSC_URI_BACKUP second — the order the service fails over in.
-
.timeout_error?(error) ⇒ Boolean
Timeout classification shared by the API client and the rates feed (the Ruby analogue of the JS AbortError check).
- .weight_budget_error?(error) ⇒ Boolean
Class Method Details
.amount_too_large_message?(message) ⇒ Boolean
136 137 138 |
# File 'lib/openreceive/server/swap.rb', line 136 def () .include?("max") || .include?("large") || .include?("limit_max") end |
.amount_too_small_message?(message) ⇒ Boolean
131 132 133 134 |
# File 'lib/openreceive/server/swap.rb', line 131 def () .include?("min") || .include?("small") || .include?("out of limits") || .include?("limit_min") end |
.availability_message(reason) ⇒ Object
Payer-facing copy per availability reason (mirrors fixedFloatAvailabilityMessage).
89 90 91 92 93 94 95 96 |
# File 'lib/openreceive/server/swap.rb', line 89 def (reason) return "This invoice is below the provider minimum." if reason == "amount_too_small" return "This invoice is above the provider maximum." if reason == "amount_too_large" return "The swap provider is rate limited." if reason == "provider_rate_limited" return "The swap provider is temporarily unreachable." if reason == "provider_unreachable" "This payment route is temporarily unavailable." end |
.classify_fixedfloat_quote_error(error) ⇒ Object
Map a quote-path failure to a SwapAvailabilityReason. The Ruby quote math reads its limits with fetch, so unlike the JS twin (whose pair math returns an unavailable quote instead of raising) this path is reachable and keeps its classifier.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/openreceive/server/swap.rb', line 102 def classify_fixedfloat_quote_error(error) return "provider_rate_limited" if weight_budget_error?(error) if error.is_a?(FixedFloatApiError) return "provider_rate_limited" if error.kind == "rate_limited" || error.http_status == 429 if %w[timeout network invalid_json].include?(error.kind) || (!error.http_status.nil? && error.http_status >= 500) return "provider_unreachable" end = (error. || error.).downcase return "amount_too_small" if () return "amount_too_large" if () return "pair_temporarily_unavailable" end = (error.is_a?(StandardError) ? error. : error.to_s).downcase if .include?("rate") || .include?("429") || .include?("weight budget") return "provider_rate_limited" end if .include?("fetch") || .include?("network") || .include?("timeout") return "provider_unreachable" end return "amount_too_small" if () return "amount_too_large" if () "pair_temporarily_unavailable" end |
.default_http_request(method:, url:, headers:, body: nil, timeout_ms: nil) ⇒ Object
Default HTTP transport on stdlib Net::HTTP. Injectable replacements must be callable as call(method:, url:, headers:, body:, timeout_ms:) and return a Hash with :status (Integer) and :body (String).
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/openreceive/server/swap.rb', line 51 def default_http_request(method:, url:, headers:, body: nil, timeout_ms: nil) uri = URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == "https" unless timeout_ms.nil? seconds = timeout_ms / 1000.0 http.open_timeout = seconds http.read_timeout = seconds http.write_timeout = seconds if http.respond_to?(:write_timeout=) end request = if method.to_s.upcase == "POST" Net::HTTP::Post.new(uri.request_uri) else Net::HTTP::Get.new(uri.request_uri) end headers.each { |key, value| request[key] = value } request.body = body unless body.nil? response = http.start { |connection| connection.request(request) } { status: Integer(response.code), body: response.body.to_s } end |
.fixedfloat_provider(**options) ⇒ Object
23 24 25 |
# File 'lib/openreceive/server/swap.rb', line 23 def fixedfloat_provider(**) FixedFloatProvider.new(**) end |
.providers_from_connections(connections, http: nil, now: nil) ⇒ Object
Build one provider per parsed LSC connection (the hashes produced by OpenReceive::Server::LscUri.parse / read_environment).
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/openreceive/server/swap.rb', line 29 def providers_from_connections(connections, http: nil, now: nil) Array(connections).map do |connection| FixedFloatProvider.new( id: connection.fetch("provider_id"), base_url: connection.fetch("base_url"), key: connection.fetch("key"), secret: connection.fetch("secret"), http: http, now: now ) end end |
.providers_from_environment(env = ENV, http: nil, now: nil) ⇒ Object
Mirror of createLscSwapProvidersFromEnvironment: LSC_URI_PRIMARY first, LSC_URI_BACKUP second — the order the service fails over in.
44 45 46 |
# File 'lib/openreceive/server/swap.rb', line 44 def providers_from_environment(env = ENV, http: nil, now: nil) providers_from_connections(LscUri.read_environment(env), http: http, now: now) end |
.timeout_error?(error) ⇒ Boolean
Timeout classification shared by the API client and the rates feed (the Ruby analogue of the JS AbortError check).
75 76 77 78 79 80 81 |
# File 'lib/openreceive/server/swap.rb', line 75 def timeout_error?(error) return true if defined?(Net::OpenTimeout) && error.is_a?(Net::OpenTimeout) return true if defined?(Net::ReadTimeout) && error.is_a?(Net::ReadTimeout) return true if error.is_a?(Timeout::Error) error.is_a?(StandardError) && error..to_s.downcase.include?("abort") end |
.weight_budget_error?(error) ⇒ Boolean
83 84 85 |
# File 'lib/openreceive/server/swap.rb', line 83 def weight_budget_error?(error) error.respond_to?(:weight_budget?) && error.weight_budget? == true end |