Skip to content
This repository has been archived by the owner on Apr 25, 2019. It is now read-only.

Handle address provider unsupported currencies when creating a new order #18

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/straight/address_providers/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ def new_address(keychain_id:, **args)
def takes_fees?
false
end

# Address provider is expected to define SUPPORTED_CURRENCIES as an
# Enumerable with valid currency codes. e.g. 'EUR', 'USD'
def currency_supported?(currency)
SUPPORTED_CURRENCIES.include?(currency)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ class FixerAdapter < FiatAdapter
FETCH_URL = "http://api.fixer.io/latest?base=#{CROSS_RATE_CURRENCY}"

def rate_for(currency_code)
super
rate = get_rate_value_from_hash(@rates, 'rates', currency_code)
rate = super
rate ||= get_rate_value_from_hash(@rates, 'rates', currency_code)
rate_to_f(rate)
end
end
Expand Down
21 changes: 21 additions & 0 deletions lib/straight/gateway.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ def new_order(args)
raise OrderAmountInvalid, "amount cannot be nil and should be more than 0"
end
# Setting default values

if address_provider.takes_fees? &&
!address_provider.currency_supported?(args[:currency])
supported_currency = select_supported_currency_by_address_provider
args[:amount] = convert_amount_to_supported_currency(args[:amount],
args[:currency], supported_currency)
args[:currency] = supported_currency
end

args[:currency] ||= default_currency
args[:btc_denomination] ||= :satoshi

Expand Down Expand Up @@ -197,6 +206,18 @@ def address_provider_type

private

def select_supported_currency_by_address_provider
address_provider.class::SUPPORTED_CURRENCIES.first
end

def convert_amount_to_supported_currency(amount, currency, supported_currency)
adapter = ExchangeRate::FixerAdapter.instance
rate_for_supported_currency = adapter.rate_for(supported_currency)
rate_for_currency = adapter.rate_for(currency)

(amount * rate_for_supported_currency) / rate_for_currency
end

# Calls the block with each adapter until one of them does not fail.
# Fails with the:
# - priority_exception, if it is set and was raised at least once
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@
expect( -> { @exchange_adapter.rate_for('KZT') }).to raise_error(Straight::ExchangeRate::Adapter::CurrencyNotSupported)
end

it "returns 1.0 when the currency is the FiatAdapter::CROSS_RATE_CURRENCY" do
expect(@exchange_adapter.
rate_for(Straight::ExchangeRate::FiatAdapter::CROSS_RATE_CURRENCY)).to eq(1.0)
end
end
22 changes: 22 additions & 0 deletions spec/lib/gateway_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@
@gateway.order_status_changed(order)
end

describe "when the address provider doesn't support the selected currency" do
it "converts the currency to one the address provider supports" do
@gateway.address_provider = AddressProvider.new(provider: :cashila)
allow(@gateway.address_provider).to receive(:new_address_and_amount)
allow(@gateway).to receive(:select_supported_currency_by_address_provider).
and_return("EUR")
expect(@gateway).to receive(:amount_from_exchange_rate).
with(0.91996, currency: "EUR", btc_denomination: :satoshi)
@gateway.new_order(amount: 1, keychain_id: 1, currency: "USD")
end
end

describe "exchange rate calculation" do

it "sets order amount in satoshis calculated from another currency" do
Expand Down Expand Up @@ -153,3 +165,13 @@
end

end

AddressProvider = Struct.new(:provider) do
def takes_fees?
true
end

def currency_supported?(currency)
currency == "EUR"
end
end