currency-rate 1.2.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +2 -1
  3. data/README.md +8 -0
  4. data/Rakefile +29 -0
  5. data/VERSION +1 -1
  6. data/api_keys.yml.sample +3 -0
  7. data/bin/rake +29 -0
  8. data/bin/rspec +29 -0
  9. data/currency-rate.gemspec +46 -35
  10. data/lib/adapter.rb +4 -3
  11. data/lib/adapters/crypto/binance_adapter.rb +42 -0
  12. data/lib/adapters/crypto/bitfinex_adapter.rb +29 -6
  13. data/lib/adapters/crypto/bitpay_adapter.rb +17 -2
  14. data/lib/adapters/crypto/bitstamp_adapter.rb +9 -8
  15. data/lib/adapters/crypto/coinbase_adapter.rb +20 -4
  16. data/lib/adapters/crypto/exmo_adapter.rb +27 -0
  17. data/lib/adapters/crypto/kraken_adapter.rb +22 -11
  18. data/lib/adapters/crypto/localbitcoins_adapter.rb +13 -2
  19. data/lib/adapters/fiat/currency_layer_adapter.rb +14 -12
  20. data/lib/adapters/fiat/fixer_adapter.rb +4 -2
  21. data/lib/adapters/fiat/forge_adapter.rb +5 -3
  22. data/lib/adapters/fiat/free_forex_adapter.rb +32 -0
  23. data/lib/configuration.rb +12 -8
  24. data/lib/currency_rate.rb +16 -7
  25. data/lib/fetcher.rb +28 -41
  26. data/lib/storage/file_storage.rb +2 -2
  27. data/lib/synchronizer.rb +31 -17
  28. data/spec/fixtures/adapters/binance_rates.yml +993 -0
  29. data/spec/fixtures/adapters/bitfinex_rates.yml +4050 -0
  30. data/spec/fixtures/adapters/{bitpay_adapter.yml → bitpay_rates.yml} +179 -175
  31. data/spec/fixtures/adapters/bitstamp_rates.yml +61 -0
  32. data/spec/fixtures/adapters/{btc_china_adapter.yml → btc_china_rates.yml} +0 -0
  33. data/spec/fixtures/adapters/{btce_adapter.yml → btce_rates.yml} +0 -0
  34. data/spec/fixtures/adapters/coinbase_rates.yml +181 -0
  35. data/spec/fixtures/adapters/{currency_layer_adapter.yml → currency_layer_rates.yml} +0 -0
  36. data/spec/fixtures/adapters/exmo_rates.yml +1251 -0
  37. data/spec/fixtures/adapters/fixer_rates.yml +174 -0
  38. data/spec/fixtures/adapters/{forge_adapter.yml → forge_rates.yml} +0 -0
  39. data/spec/fixtures/adapters/free_forex_rates.yml +59 -0
  40. data/spec/fixtures/adapters/{huobi_adapter.yml → huobi_rates.yml} +0 -0
  41. data/spec/fixtures/adapters/kraken_rates.yml +507 -0
  42. data/spec/fixtures/adapters/localbitcoins_rates.yml +493 -0
  43. data/spec/fixtures/adapters/normalized/binance_rates.yml +134 -0
  44. data/spec/fixtures/adapters/normalized/bitfinex_rates.yml +95 -0
  45. data/spec/fixtures/adapters/normalized/bitpay_rates.yml +164 -0
  46. data/spec/fixtures/adapters/normalized/bitstamp_rates.yml +9 -0
  47. data/spec/fixtures/adapters/normalized/{btc_china_adapter.yml → btc_china_rates.yml} +0 -0
  48. data/spec/fixtures/adapters/normalized/{btce_adapter.yml → btce_rates.yml} +0 -0
  49. data/spec/fixtures/adapters/normalized/coinbase_rates.yml +179 -0
  50. data/spec/fixtures/adapters/normalized/{currency_layer_adapter.yml → currency_layer_rates.yml} +0 -0
  51. data/spec/fixtures/adapters/normalized/exmo_rates.yml +42 -0
  52. data/spec/fixtures/adapters/normalized/fixer_rates.yml +170 -0
  53. data/spec/fixtures/adapters/normalized/{forge_adapter.yml → forge_rates.yml} +0 -0
  54. data/spec/fixtures/adapters/normalized/free_forex_rates.yml +16 -0
  55. data/spec/fixtures/adapters/normalized/{huobi_adapter.yml → huobi_rates.yml} +0 -0
  56. data/spec/fixtures/adapters/normalized/kraken_rates.yml +21 -0
  57. data/spec/fixtures/adapters/normalized/localbitcoins_rates.yml +73 -0
  58. data/spec/fixtures/adapters/normalized/{okcoin_adapter.yml → okcoin_rates.yml} +0 -0
  59. data/spec/fixtures/adapters/normalized/{yahoo_adapter.yml → yahoo_rates.yml} +0 -0
  60. data/spec/fixtures/adapters/{okcoin_adapter.yml → okcoin_rates.yml} +0 -0
  61. data/spec/fixtures/adapters/{yahoo_adapter.yml → yahoo_rates.yml} +0 -0
  62. data/spec/lib/adapters/crypto/binance_adapter_spec.rb +13 -0
  63. data/spec/lib/adapters/crypto/exmo_adapter_spec.rb +13 -0
  64. data/spec/lib/adapters/fiat/free_forex_adapter_spec.rb +13 -0
  65. data/spec/lib/fetcher_spec.rb +17 -49
  66. data/spec/lib/synchronizer_spec.rb +36 -2
  67. data/spec/spec_helper.rb +2 -2
  68. metadata +66 -35
  69. data/spec/fixtures/adapters/bitfinex_adapter.yml +0 -18
  70. data/spec/fixtures/adapters/bitstamp_adapter.yml +0 -30
  71. data/spec/fixtures/adapters/coinbase_adapter.yml +0 -680
  72. data/spec/fixtures/adapters/fixer_adapter.yml +0 -34
  73. data/spec/fixtures/adapters/kraken_adapter.yml +0 -124
  74. data/spec/fixtures/adapters/localbitcoins_adapter.yml +0 -381
  75. data/spec/fixtures/adapters/normalized/bitfinex_adapter.yml +0 -2
  76. data/spec/fixtures/adapters/normalized/bitpay_adapter.yml +0 -161
  77. data/spec/fixtures/adapters/normalized/bitstamp_adapter.yml +0 -3
  78. data/spec/fixtures/adapters/normalized/coinbase_adapter.yml +0 -680
  79. data/spec/fixtures/adapters/normalized/fixer_adapter.yml +0 -32
  80. data/spec/fixtures/adapters/normalized/kraken_adapter.yml +0 -4
  81. data/spec/fixtures/adapters/normalized/localbitcoins_adapter.yml +0 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4b0e8bee0c0bcace06ab89c9ec67491980d95bba
4
- data.tar.gz: fc7ec5d1b2423564e5cacb74b2355eb36b8f2e44
2
+ SHA256:
3
+ metadata.gz: 7ba5e25c02543d961b4806289dbe718957c31cf1350af31a0b19898fd409841c
4
+ data.tar.gz: 53f4d584d115d88bfb62ed75679a60e5aa2c46b20e48c6ebd5bfe168bda3c100
5
5
  SHA512:
6
- metadata.gz: f8a235cb9561e1f804a17e786a49a7c858702eaed7ee4a90334cf9c1840133984b4b2b21685c5c0d7d4960734cf90b1cb7f04512e339b2d7b4bd95b8f436202a
7
- data.tar.gz: 28988218d07dac5bfb30d9bd6a27be95ebbe4e477614304d475a707622ec8cbf884e75a6707c06c6bb468736b3a6f2fff108ea5c04a8318b529cecf1b5b57dc3
6
+ metadata.gz: 44fceddd1f172848b0c67506d061a24f3b80cdb494a752acbd40a72e82e66f5b7524debff9c96bcdef3153efe6601e12d1dc75f4b5db96d7c1414a50091061a9
7
+ data.tar.gz: 96a8c935a0dba5d299501898e052c098b4db93dcaa727ed4bb45ad167e88b3213372775eca21abcfe6b24005de65309d22bf37b7c2d6c1cd44a2e2c79f649925
data/Gemfile CHANGED
@@ -3,8 +3,9 @@ source "https://rubygems.org"
3
3
  gem "http"
4
4
 
5
5
  group :development do
6
+ gem "byebug"
6
7
  gem "jeweler", "~> 2.3.7", git: 'git@github.com:technicalpickles/jeweler.git'
8
+ gem "rake"
7
9
  gem "rspec"
8
10
  gem "webmock"
9
- gem "byebug"
10
11
  end
data/README.md CHANGED
@@ -63,3 +63,11 @@ Details
63
63
  `CurrencyRate` contains two parts that can work independently: Synchronizer and Fetcher.
64
64
  `CurrencyRate::Synchronizer` loads data from selected exchanges using adapters and saves it into FileStorage in normalized format.
65
65
  `CurrencyRate::Fetch` reads data from FileStorage and returns rate for requested pair and exchange.
66
+
67
+ Development
68
+ -----------
69
+ When adapter's output format changes you can replace fixtures by running `bin/rake update_rates['ExchangeName']`.
70
+ For example `bin/rake update_rates['Fixer']` will update fixtures for the FixerAdapter.
71
+
72
+ Some of adapters require API keys so the task searches for 'api_keys.yml` file in project root.
73
+ You can copy it from `api_keys.yml.sample` and set up your values.
data/Rakefile CHANGED
@@ -22,3 +22,32 @@ Jeweler::Tasks.new do |gem|
22
22
  gem.email = "roman.snitko@gmail.com"
23
23
  gem.authors = ["Roman Snitko"]
24
24
  end
25
+
26
+ require 'byebug'
27
+ require 'yaml'
28
+ require_relative "lib/currency_rate"
29
+
30
+ desc "Update rates for specified adapter"
31
+ task :update_rates, [:exchange] do |t, args|
32
+ api_keys = YAML.load_file("api_keys.yml")
33
+
34
+ CurrencyRate.configure do |config|
35
+ api_keys.each { |name, key| config.api_keys[name] = key }
36
+ end
37
+
38
+ adapter = CurrencyRate::const_get("#{args.exchange}Adapter").instance
39
+
40
+ print "Loading data for #{args.exchange}... "
41
+ exchange_data = adapter.exchange_data
42
+ raw_storage = CurrencyRate::FileStorage.new(File.expand_path("spec/fixtures/adapters", __dir__))
43
+ raw_storage.write(args.exchange, exchange_data)
44
+ puts "Success!"
45
+
46
+ print "Normalizing data for #{args.exchange}..."
47
+ normalized_data = adapter.normalize exchange_data
48
+ normalized_storage = CurrencyRate::FileStorage.new(File.expand_path("spec/fixtures/adapters/normalized", __dir__))
49
+ normalized_storage.write(args.exchange, normalized_data)
50
+ puts "Success!"
51
+
52
+ puts "#{args.exchange} fixtures update finished!"
53
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.4.1
@@ -0,0 +1,3 @@
1
+ ForgeAdapter: "<your_key>"
2
+ CurrencyLayerAdapter: "<your_key>"
3
+ FixerAdapter: "<your_key>"
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/bin/rspec ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rspec-core", "rspec")
@@ -2,18 +2,19 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: currency-rate 1.2.0 ruby lib
5
+ # stub: currency-rate 1.4.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "currency-rate".freeze
9
- s.version = "1.2.0"
9
+ s.version = "1.4.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Roman Snitko".freeze]
14
- s.date = "2018-02-12"
14
+ s.date = "2018-12-12"
15
15
  s.description = "Fetches exchange rates from various sources and does the conversion".freeze
16
16
  s.email = "roman.snitko@gmail.com".freeze
17
+ s.executables = ["rake".freeze, "rspec".freeze]
17
18
  s.extra_rdoc_files = [
18
19
  "LICENSE.txt",
19
20
  "README.md"
@@ -26,6 +27,9 @@ Gem::Specification.new do |s|
26
27
  "README.md",
27
28
  "Rakefile",
28
29
  "VERSION",
30
+ "api_keys.yml.sample",
31
+ "bin/rake",
32
+ "bin/rspec",
29
33
  "currency-rate.gemspec",
30
34
  "lib/adapter.rb",
31
35
  "lib/adapters/crypto/bitfinex_adapter.rb",
@@ -41,6 +45,7 @@ Gem::Specification.new do |s|
41
45
  "lib/adapters/fiat/currency_layer_adapter.rb",
42
46
  "lib/adapters/fiat/fixer_adapter.rb",
43
47
  "lib/adapters/fiat/forge_adapter.rb",
48
+ "lib/adapters/fiat/free_forex_adapter.rb",
44
49
  "lib/adapters/fiat/yahoo_adapter.rb",
45
50
  "lib/configuration.rb",
46
51
  "lib/currency_rate.rb",
@@ -48,34 +53,36 @@ Gem::Specification.new do |s|
48
53
  "lib/storage/file_storage.rb",
49
54
  "lib/storage/serializers/yaml_serializer.rb",
50
55
  "lib/synchronizer.rb",
51
- "spec/fixtures/adapters/bitfinex_adapter.yml",
52
- "spec/fixtures/adapters/bitpay_adapter.yml",
53
- "spec/fixtures/adapters/bitstamp_adapter.yml",
54
- "spec/fixtures/adapters/btc_china_adapter.yml",
55
- "spec/fixtures/adapters/btce_adapter.yml",
56
- "spec/fixtures/adapters/coinbase_adapter.yml",
57
- "spec/fixtures/adapters/currency_layer_adapter.yml",
58
- "spec/fixtures/adapters/fixer_adapter.yml",
59
- "spec/fixtures/adapters/forge_adapter.yml",
60
- "spec/fixtures/adapters/huobi_adapter.yml",
61
- "spec/fixtures/adapters/kraken_adapter.yml",
62
- "spec/fixtures/adapters/localbitcoins_adapter.yml",
63
- "spec/fixtures/adapters/normalized/bitfinex_adapter.yml",
64
- "spec/fixtures/adapters/normalized/bitpay_adapter.yml",
65
- "spec/fixtures/adapters/normalized/bitstamp_adapter.yml",
66
- "spec/fixtures/adapters/normalized/btc_china_adapter.yml",
67
- "spec/fixtures/adapters/normalized/btce_adapter.yml",
68
- "spec/fixtures/adapters/normalized/coinbase_adapter.yml",
69
- "spec/fixtures/adapters/normalized/currency_layer_adapter.yml",
70
- "spec/fixtures/adapters/normalized/fixer_adapter.yml",
71
- "spec/fixtures/adapters/normalized/forge_adapter.yml",
72
- "spec/fixtures/adapters/normalized/huobi_adapter.yml",
73
- "spec/fixtures/adapters/normalized/kraken_adapter.yml",
74
- "spec/fixtures/adapters/normalized/localbitcoins_adapter.yml",
75
- "spec/fixtures/adapters/normalized/okcoin_adapter.yml",
76
- "spec/fixtures/adapters/normalized/yahoo_adapter.yml",
77
- "spec/fixtures/adapters/okcoin_adapter.yml",
78
- "spec/fixtures/adapters/yahoo_adapter.yml",
56
+ "spec/fixtures/adapters/bitfinex_rates.yml",
57
+ "spec/fixtures/adapters/bitpay_rates.yml",
58
+ "spec/fixtures/adapters/bitstamp_rates.yml",
59
+ "spec/fixtures/adapters/btc_china_rates.yml",
60
+ "spec/fixtures/adapters/btce_rates.yml",
61
+ "spec/fixtures/adapters/coinbase_rates.yml",
62
+ "spec/fixtures/adapters/currency_layer_rates.yml",
63
+ "spec/fixtures/adapters/fixer_rates.yml",
64
+ "spec/fixtures/adapters/forge_rates.yml",
65
+ "spec/fixtures/adapters/free_forex_rates.yml",
66
+ "spec/fixtures/adapters/huobi_rates.yml",
67
+ "spec/fixtures/adapters/kraken_rates.yml",
68
+ "spec/fixtures/adapters/localbitcoins_rates.yml",
69
+ "spec/fixtures/adapters/normalized/bitfinex_rates.yml",
70
+ "spec/fixtures/adapters/normalized/bitpay_rates.yml",
71
+ "spec/fixtures/adapters/normalized/bitstamp_rates.yml",
72
+ "spec/fixtures/adapters/normalized/btc_china_rates.yml",
73
+ "spec/fixtures/adapters/normalized/btce_rates.yml",
74
+ "spec/fixtures/adapters/normalized/coinbase_rates.yml",
75
+ "spec/fixtures/adapters/normalized/currency_layer_rates.yml",
76
+ "spec/fixtures/adapters/normalized/fixer_rates.yml",
77
+ "spec/fixtures/adapters/normalized/forge_rates.yml",
78
+ "spec/fixtures/adapters/normalized/free_forex_rates.yml",
79
+ "spec/fixtures/adapters/normalized/huobi_rates.yml",
80
+ "spec/fixtures/adapters/normalized/kraken_rates.yml",
81
+ "spec/fixtures/adapters/normalized/localbitcoins_rates.yml",
82
+ "spec/fixtures/adapters/normalized/okcoin_rates.yml",
83
+ "spec/fixtures/adapters/normalized/yahoo_rates.yml",
84
+ "spec/fixtures/adapters/okcoin_rates.yml",
85
+ "spec/fixtures/adapters/yahoo_rates.yml",
79
86
  "spec/lib/adapter_spec.rb",
80
87
  "spec/lib/adapters/crypto/bitfinex_adapter_spec.rb",
81
88
  "spec/lib/adapters/crypto/bitpay_adapter_spec.rb",
@@ -90,6 +97,7 @@ Gem::Specification.new do |s|
90
97
  "spec/lib/adapters/fiat/currency_layer_adapter_spec.rb",
91
98
  "spec/lib/adapters/fiat/fixer_adapter_spec.rb",
92
99
  "spec/lib/adapters/fiat/forge_adapter_spec.rb",
100
+ "spec/lib/adapters/fiat/free_forex_adapter_spec.rb",
93
101
  "spec/lib/adapters/fiat/yahoo_adapter_spec.rb",
94
102
  "spec/lib/currency_rate_spec.rb",
95
103
  "spec/lib/fetcher_spec.rb",
@@ -100,7 +108,7 @@ Gem::Specification.new do |s|
100
108
  ]
101
109
  s.homepage = "http://github.com/snitko/currency-rate".freeze
102
110
  s.licenses = ["MIT".freeze]
103
- s.rubygems_version = "2.6.14".freeze
111
+ s.rubygems_version = "2.7.6".freeze
104
112
  s.summary = "Converter for fiat and crypto currencies".freeze
105
113
 
106
114
  if s.respond_to? :specification_version then
@@ -108,23 +116,26 @@ Gem::Specification.new do |s|
108
116
 
109
117
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
110
118
  s.add_runtime_dependency(%q<http>.freeze, [">= 0"])
119
+ s.add_development_dependency(%q<byebug>.freeze, [">= 0"])
111
120
  s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.7"])
121
+ s.add_development_dependency(%q<rake>.freeze, [">= 0"])
112
122
  s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
113
123
  s.add_development_dependency(%q<webmock>.freeze, [">= 0"])
114
- s.add_development_dependency(%q<byebug>.freeze, [">= 0"])
115
124
  else
116
125
  s.add_dependency(%q<http>.freeze, [">= 0"])
126
+ s.add_dependency(%q<byebug>.freeze, [">= 0"])
117
127
  s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.7"])
128
+ s.add_dependency(%q<rake>.freeze, [">= 0"])
118
129
  s.add_dependency(%q<rspec>.freeze, [">= 0"])
119
130
  s.add_dependency(%q<webmock>.freeze, [">= 0"])
120
- s.add_dependency(%q<byebug>.freeze, [">= 0"])
121
131
  end
122
132
  else
123
133
  s.add_dependency(%q<http>.freeze, [">= 0"])
134
+ s.add_dependency(%q<byebug>.freeze, [">= 0"])
124
135
  s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.7"])
136
+ s.add_dependency(%q<rake>.freeze, [">= 0"])
125
137
  s.add_dependency(%q<rspec>.freeze, [">= 0"])
126
138
  s.add_dependency(%q<webmock>.freeze, [">= 0"])
127
- s.add_dependency(%q<byebug>.freeze, [">= 0"])
128
139
  end
129
140
  end
130
141
 
data/lib/adapter.rb CHANGED
@@ -1,7 +1,9 @@
1
+
1
2
  module CurrencyRate
2
3
  class Adapter
3
4
  include Singleton
4
5
 
6
+ SUPPORTED_CURRENCIES = []
5
7
  FETCH_URL = nil
6
8
  API_KEY_PARAM = nil
7
9
 
@@ -32,9 +34,8 @@ module CurrencyRate
32
34
 
33
35
  begin
34
36
  if self.class::FETCH_URL.kind_of?(Hash)
35
- self.class::FETCH_URL.reduce({}) do |result, (name, url)|
37
+ self.class::FETCH_URL.each_with_object({}) do |(name, url), result|
36
38
  result[name] = request url
37
- result
38
39
  end
39
40
  else
40
41
  request self.class::FETCH_URL
@@ -57,7 +58,7 @@ module CurrencyRate
57
58
  param_symbol = fetch_url.split("/").last.include?("?") ? "&" : "?"
58
59
  fetch_url << "#{param_symbol}#{self.class::API_KEY_PARAM}=#{api_key}" if api_key
59
60
  end
60
- http_client = HTTP.timeout(connect: 4, read: 4)
61
+ http_client = HTTP.timeout(connect: CurrencyRate.configuration.connect_timeout, read: CurrencyRate.configuration.read_timeout)
61
62
  JSON.parse(http_client.get(fetch_url).to_s)
62
63
  end
63
64
 
@@ -0,0 +1,42 @@
1
+ module CurrencyRate
2
+ class BinanceAdapter < Adapter
3
+ # No need to use it for fetching, just additional information about supported currencies
4
+ SUPPORTED_CURRENCIES = %w(
5
+ ADA ADX AGI AMB ARK ARN AST BAT BCC BCD BCN BLZ BNB BNT BQX
6
+ BRD BTG BTS CDT CMT CND CVC DCR DGD DLT DNT EDO ELF ENG ENJ
7
+ EOS ETC ETH EVX FUN GAS GNT GRS GTO GVT GXS HOT HSR ICN ICX
8
+ INS KEY KMD KNC LRC LSK LTC LUN MCO MDA MFT MOD MTH MTL NAS
9
+ NAV NEO NXS OAX OMG ONT OST PAX PHX POA POE PPT QKC QLC QSP
10
+ RCN RDN REN REP REQ RLC RPX RVN SKY SNM SNT SUB SYS TNB TNT
11
+ TRX USDC USDT VEN VET VIA VIB WAN WPR WTC XEM XLM XMR XRP
12
+ XVG XZC ZEC ZEN ZIL ZRX
13
+ )
14
+
15
+ ANCHOR_CURRENCY = "BTC"
16
+
17
+ FETCH_URL = {
18
+ "Binance" => "https://api.binance.com/api/v3/ticker/price",
19
+ "Blockchain" => "https://blockchain.info/ticker"
20
+ }
21
+
22
+ def normalize(data)
23
+ return nil unless super
24
+ binance_result = data["Binance"].reduce({ "anchor" => ANCHOR_CURRENCY }) do |result, hash|
25
+ if hash["symbol"].index(ANCHOR_CURRENCY) == 0
26
+ result[hash["symbol"].sub(ANCHOR_CURRENCY, "")] = BigDecimal.new(hash["price"].to_s)
27
+ elsif hash["symbol"].index(ANCHOR_CURRENCY) == 3
28
+ result[hash["symbol"].sub(ANCHOR_CURRENCY, "")] = 1 / BigDecimal.new(hash["price"].to_s)
29
+ end
30
+ result
31
+ end
32
+
33
+ blockchain_result = data["Blockchain"].reduce({}) do |result, (key, value)|
34
+ result[key] = BigDecimal.new(value["last"].to_s)
35
+ result
36
+ end
37
+
38
+ binance_result.merge(blockchain_result)
39
+ end
40
+
41
+ end
42
+ end
@@ -1,14 +1,37 @@
1
1
  module CurrencyRate
2
2
  class BitfinexAdapter < Adapter
3
- FETCH_URL = {
4
- "BTC_USD" => "https://api.bitfinex.com/v1/pubticker/btcusd",
5
- "LTC_USD" => "https://api.bitfinex.com/v1/pubticker/ltcusd",
6
- }
3
+ # No need to use it for fetching, just additional information about supported currencies
4
+ SUPPORTED_CURRENCIES = %w(
5
+ AGI AID AIO ANT ATM AUC AVT BAB BAT BCI BFT BNT BSV BTG CBT CFI CND CTX
6
+ DAD DAI DAT DGB DASH DTA DTH EDO ELF EOS ESS ETC ETH ETP EUR FSN FUN GBP
7
+ GNT HOT IOS IOT IQX JPY KNC LRC LTC LYM MIT MKR MNA MTN NCA NEO ODE OMG
8
+ OMNI ORS PAI POA POY QSH QTM RBT RCN RDN REP REQ RLC RRT SAN SEE SEN SNG
9
+ SNT SPK STJ TNB TRX USD UTK VEE VET WAX WPR XLM XMR XRP XTZ XVG YYW ZCN
10
+ ZEC ZIL ZRX
11
+ )
12
+
13
+ ASSET_MAP = {
14
+ "DSH" => "DASH",
15
+ "OMN" => "OMNI",
16
+ }
17
+
18
+ ANCHOR_CURRENCY = "BTC"
19
+
20
+ FETCH_URL = "https://api.bitfinex.com/v2/tickers?symbols=ALL"
7
21
 
8
22
  def normalize(data)
9
23
  return nil unless super
10
- data.reduce({}) do |result, (pair, value)|
11
- result[pair] = BigDecimal.new(value["last_price"].to_s)
24
+ data.reduce({ "anchor" => ANCHOR_CURRENCY }) do |result, pair_info|
25
+ pair_name = pair_info[0].sub("t", "")
26
+ key = pair_name.sub(ANCHOR_CURRENCY, "")
27
+ key = ASSET_MAP[key] || key
28
+
29
+ if pair_name.index(ANCHOR_CURRENCY) == 0
30
+ result[key] = BigDecimal.new(pair_info[7].to_s)
31
+ elsif pair_name.index(ANCHOR_CURRENCY) == 3
32
+ result[key] = 1 / BigDecimal.new(pair_info[7].to_s)
33
+ end
34
+
12
35
  result
13
36
  end
14
37
  end
@@ -1,11 +1,26 @@
1
1
  module CurrencyRate
2
2
  class BitpayAdapter < Adapter
3
+ # No need to use it for fetching, just additional information about supported currencies
4
+ SUPPORTED_CURRENCIES = %w(
5
+ AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BCH BDT BGN BHD BIF BMD
6
+ BND BOB BRL BSD BTN BWP BZD CAD CDF CHF CLF CLP CNY COP CRC CUP CVE CZK
7
+ DJF DKK DOP DZD EGP ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GUSD GYD
8
+ HKD HNL HRK HTG HUF IDR ILS INR IQD IRR ISK JEP JMD JOD JPY KES KGS KHR
9
+ KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT
10
+ MOP MRU MUR MVR MWK MXN MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PAX PEN
11
+ PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLL
12
+ SOS SRD STN SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD
13
+ USDC UYU UZS VEF VES VND VUV WST XAF XAG XAU XCD XOF XPF YER ZAR ZMW ZWL
14
+ )
15
+
16
+ ANCHOR_CURRENCY = "BTC"
17
+
3
18
  FETCH_URL = "https://bitpay.com/api/rates"
4
19
 
5
20
  def normalize(data)
6
21
  return nil unless super
7
- data.reject { |rate| rate["code"] == "BTC" }.reduce({}) do |result, rate|
8
- result["BTC_#{rate['code'].upcase}"] = BigDecimal.new(rate["rate"].to_s)
22
+ data.reject { |rate| rate["code"] == ANCHOR_CURRENCY }.reduce({ "anchor" => ANCHOR_CURRENCY }) do |result, rate|
23
+ result["#{rate['code'].upcase}"] = BigDecimal.new(rate["rate"].to_s)
9
24
  result
10
25
  end
11
26
  end
@@ -1,16 +1,17 @@
1
1
  module CurrencyRate
2
2
  class BitstampAdapter < Adapter
3
- FETCH_URL = {
4
- 'BTC_USD' => 'https://www.bitstamp.net/api/v2/ticker/btcusd/',
5
- 'BTC_EUR' => 'https://www.bitstamp.net/api/v2/ticker/btceur/',
6
- 'LTC_USD' => 'https://www.bitstamp.net/api/v2/ticker/ltcusd/',
7
- 'LTC_EUR' => 'https://www.bitstamp.net/api/v2/ticker/ltceur/',
8
- }
3
+ SUPPORTED_CURRENCIES = %w(
4
+ BCH BTC ETH EUR LTC XRP
5
+ )
6
+
7
+ ANCHOR_CURRENCY = "USD"
8
+
9
+ FETCH_URL = Hash[SUPPORTED_CURRENCIES.collect { |currency| [ currency, "https://www.bitstamp.net/api/v2/ticker/#{currency}usd/".downcase ] }]
9
10
 
10
11
  def normalize(data)
11
12
  return nil unless super
12
- data.reduce({}) do |result, (pair, value)|
13
- result[pair] = BigDecimal.new(value["last"].to_s)
13
+ data.reduce({ "anchor" => ANCHOR_CURRENCY, ANCHOR_CURRENCY => BigDecimal.new("1") }) do |result, (key, value)|
14
+ result[key] = 1 / BigDecimal.new(value["last"].to_s)
14
15
  result
15
16
  end
16
17
  end