From 24f4421393dc69ea809f93a4cc2d82cb36f78755 Mon Sep 17 00:00:00 2001 From: Alex Ianus <aianus@coinbase.com> Date: Fri, 6 Jun 2014 14:04:04 +0700 Subject: [PATCH] Added Money::Bank::Coinbase class to use Coinbase rates with the Money gem --- README.md | 33 ++ lib/coinbase.rb | 1 + lib/coinbase/client.rb | 6 +- lib/coinbase/rates.rb | 84 ++++ spec/fixtures/rate_response.json | 634 +++++++++++++++++++++++++++++++ spec/rates_spec.rb | 57 +++ 6 files changed, 814 insertions(+), 1 deletion(-) create mode 100644 lib/coinbase/rates.rb create mode 100644 spec/fixtures/rate_response.json create mode 100644 spec/rates_spec.rb diff --git a/README.md b/README.md index 572d08b..dc38373 100644 --- a/README.md +++ b/README.md @@ -282,6 +282,39 @@ r.oauth.access_token => "93865b9cae83706ae59220c013bc0afd93865b9cae83706ae59220c013bc0afd" ``` +## Exchange rates + +This gem also extends Money::Bank::VariableExchange with Money::Bank::Coinbase to give you access to Coinbase exchange rates. + +### Usage + +``` ruby +cb_bank = Money::Bank::Coinbase.new + +# Call this before calculating exchange rates +# This will download the rates from CB +cb_bank.fetch_rates! + +# Exchange 100 USD to BTC +# API is the same as the money gem +cb_bank.exchange_with(Money.new(10000, :USD), :BTC) # '0.15210000'.to_money(:BTC) + +# Set as default bank to do arithmetic and comparisons on Money objects +Money.default_bank = cb_bank +money1 = Money.new(10) +money1.bank # cb_bank + +Money.us_dollar(10000).exchange_to(:BTC) # '0.15210000'.to_money(:BTC) +'1'.to_money(:BTC) > '1'.to_money(:USD) # true + +# Expire rates after some number of seconds (by default, rates are only updated when you call fetch_rates!) +cb_bank.ttl_in_seconds = 3600 # Cache rates for one hour + +# After an hour, different rates +cb_bank.exchange_with(Money.new(10000, :USD), :BTC) # '0.15310000'.to_money(:BTC) + +``` + ## Adding new methods You can see a [list of method calls here](https://github.com/coinbase/coinbase-ruby/blob/master/lib/coinbase/client.rb) and how they are implemented. They are a wrapper around the [Coinbase JSON API](https://coinbase.com/api/doc). diff --git a/lib/coinbase.rb b/lib/coinbase.rb index 7216d95..7a185e1 100644 --- a/lib/coinbase.rb +++ b/lib/coinbase.rb @@ -3,3 +3,4 @@ require "coinbase/version" require "coinbase/client" require "coinbase/oauth_client" +require "coinbase/rates" diff --git a/lib/coinbase/client.rb b/lib/coinbase/client.rb index 448fb07..3f03ab6 100644 --- a/lib/coinbase/client.rb +++ b/lib/coinbase/client.rb @@ -12,7 +12,7 @@ class Client BASE_URI = 'https://coinbase.com/api/v1' - def initialize(api_key, api_secret, options={}) + def initialize(api_key='', api_secret='', options={}) @api_key = api_key @api_secret = api_secret @@ -165,6 +165,10 @@ def spot_price currency='USD' r['amount'].to_money(r['currency']) end + def exchange_rates + get('/currencies/exchange_rates') + end + # Buys def buy! qty diff --git a/lib/coinbase/rates.rb b/lib/coinbase/rates.rb new file mode 100644 index 0000000..a3410b6 --- /dev/null +++ b/lib/coinbase/rates.rb @@ -0,0 +1,84 @@ +class Money + module Bank + class Coinbase < VariableExchange + + def initialize(coinbase=nil) + @coinbase = coinbase || ::Coinbase::Client.new + super() + end + + # @return [Integer] Returns the Time To Live (TTL) in seconds. + attr_reader :ttl_in_seconds + + # @return [Time] Returns the time when the rates expire. + attr_reader :rates_expiration + + ## + # Set the Time To Live (TTL) in seconds. + # + # @param [Integer] the seconds between an expiration and another. + def ttl_in_seconds=(value) + @ttl_in_seconds = value + refresh_rates_expiration! if ttl_in_seconds + end + + ## + # Fetch fresh rates from Coinbase + def fetch_rates!(opts={}) + fn = lambda do + @rates = @coinbase.exchange_rates + refresh_rates_expiration! + end + + if opts[:without_mutex] + fn.call + else + @mutex.synchronize { fn.call } + end + end + + # Refreshes all the rates if they are expired. + # + # @return [Boolean] + def expire_rates + if @ttl_in_seconds && @rates_expiration <= Time.now + fetch_rates! + true + else + false + end + end + + def get_rate(from, to, opts = {}) + expire_rates + super + end + + private + + ## + # Set the rates expiration TTL seconds from the current time. + # + # @return [Time] The next expiration. + def refresh_rates_expiration! + if @ttl_in_seconds + @rates_expiration = Time.now + @ttl_in_seconds + end + end + + # Return the rate hashkey for the given currencies. + # + # @param [Currency, String, Symbol] from The currency to exchange from. + # @param [Currency, String, Symbol] to The currency to exchange to. + # + # @return [String] + # + # @example + # rate_key_for("USD", "CAD") #=> "usd_to_cad" + def rate_key_for(from, to) + "#{::Money::Currency.wrap(from).iso_code}_to_#{::Money::Currency.wrap(to).iso_code}".downcase + end + + end + end +end diff --git a/spec/fixtures/rate_response.json b/spec/fixtures/rate_response.json new file mode 100644 index 0000000..f9867c7 --- /dev/null +++ b/spec/fixtures/rate_response.json @@ -0,0 +1,634 @@ +{ + "gbp_to_usd":"1.670983", + "usd_to_bwp":"8.86831", + "usd_to_azn":"0.7842", + "eur_to_usd":"1.361039", + "usd_to_czk":"20.18098", + "czk_to_btc":"7.6e-05", + "btc_to_mga":"1578731.7546", + "btc_to_djf":"116871.686671", + "idr_to_btc":"0.0", + "mnt_to_usd":"0.000551", + "usd_to_ngn":"162.381299", + "usd_to_gbp":"0.59845", + "irr_to_btc":"0.0", + "ils_to_usd":"0.287377", + "ars_to_usd":"0.123592", + "usd_to_uyu":"22.98199", + "uyu_to_btc":"6.7e-05", + "pyg_to_btc":"0.0", + "usd_to_yer":"214.992999", + "pgk_to_usd":"0.352952", + "xcd_to_btc":"0.000567", + "usd_to_fjd":"1.844267", + "dop_to_btc":"3.5e-05", + "mvr_to_usd":"0.064514", + "eek_to_usd":"0.085659", + "nzd_to_btc":"0.001289", + "gnf_to_btc":"0.0", + "usd_to_gtq":"7.781356", + "bmd_to_usd":"1.0", + "btc_to_lbp":"986372.4402", + "usd_to_omr":"0.385006", + "usd_to_sos":"944.4046", + "usd_to_thb":"32.67102", + "srd_to_btc":"0.000463", + "btc_to_all":"67109.732424", + "usd_to_vnd":"21205.233333", + "htg_to_usd":"0.022186", + "btc_to_bmd":"652.68", + "kpw_to_usd":"0.0", + "lyd_to_usd":"0.814776", + "tzs_to_btc":"1.0e-06", + "lak_to_usd":"0.000124", + "usd_to_idr":"11846.65", + "btc_to_bzd":"1303.81837", + "usd_to_gel":"1.77007", + "usd_to_kzt":"183.4134", + "uah_to_usd":"0.08389", + "usd_to_lkr":"130.345499", + "btc_to_zwl":"210394.665316", + "php_to_btc":"3.5e-05", + "ron_to_usd":"0.309147", + "btc_to_kyd":"539.569251", + "btc_to_cad":"713.207585", + "hkd_to_btc":"0.000198", + "usd_to_btc":"0.001532", + "nok_to_btc":"0.000255", + "top_to_usd":"0.539266", + "btc_to_xpf":"57257.807824", + "usd_to_kgs":"52.13045", + "usd_to_bnd":"1.256882", + "dzd_to_usd":"0.012628", + "vef_to_btc":"0.000244", + "usd_to_ars":"8.091152", + "syp_to_btc":"1.0e-05", + "ngn_to_btc":"9.0e-06", + "bgn_to_btc":"0.001066", + "lak_to_btc":"0.0", + "btc_to_cve":"52650.442454", + "mga_to_btc":"1.0e-06", + "idr_to_usd":"8.4e-05", + "btc_to_htg":"29418.369649", + "btc_to_ils":"2271.161925", + "mad_to_btc":"0.000186", + "usd_to_hnl":"20.67103", + "svc_to_btc":"0.000175", + "btc_to_ang":"1166.391374", + "hkd_to_usd":"0.128986", + "usd_to_nad":"10.73715", + "szl_to_btc":"0.000143", + "etb_to_usd":"0.051096", + "pkr_to_btc":"1.6e-05", + "usd_to_khr":"4049.893333", + "gnf_to_usd":"0.000142", + "btc_to_myr":"2109.683671", + "btc_to_top":"1210.310864", + "nad_to_btc":"0.000143", + "huf_to_usd":"0.004458", + "mkd_to_btc":"3.4e-05", + "lkr_to_btc":"1.2e-05", + "svc_to_usd":"0.114343", + "btc_to_lyd":"801.054397", + "usd_to_bam":"1.437821", + "usd_to_svc":"8.745614", + "usd_to_tzs":"1672.43", + "gbp_to_btc":"0.00256", + "btc_to_mop":"5210.920756", + "btc_to_jod":"462.302382", + "clp_to_usd":"0.001817", + "cad_to_usd":"0.915133", + "cny_to_btc":"0.000246", + "jod_to_btc":"0.002163", + "syp_to_usd":"0.006703", + "lvl_to_btc":"0.002969", + "btc_to_cny":"4070.100732", + "shp_to_btc":"0.00256", + "vef_to_usd":"0.158944", + "php_to_usd":"0.022789", + "mro_to_usd":"0.003403", + "tjs_to_btc":"0.000312", + "fkp_to_btc":"0.00256", + "bdt_to_usd":"0.012913", + "mkd_to_usd":"0.022094", + "lrd_to_usd":"0.011791", + "usd_to_kes":"87.49508", + "btc_to_ars":"5280.933087", + "usd_to_chf":"0.897733", + "usd_to_lak":"8060.718333", + "usd_to_bzd":"1.997638", + "usd_to_nzd":"1.188226", + "mvr_to_btc":"9.9e-05", + "usd_to_wst":"2.307868", + "nok_to_usd":"0.166534", + "tjs_to_usd":"0.203712", + "bob_to_usd":"0.144776", + "btc_to_cup":"652.582098", + "afn_to_btc":"2.7e-05", + "vnd_to_btc":"0.0", + "bnd_to_usd":"0.79562", + "byr_to_btc":"0.0", + "aed_to_btc":"0.000417", + "hnl_to_btc":"7.4e-05", + "mmk_to_usd":"0.001033", + "zmk_to_btc":"0.0", + "usd_to_myr":"3.23234", + "usd_to_ils":"3.479748", + "usd_to_mdl":"13.84405", + "djf_to_usd":"0.005585", + "mnt_to_btc":"1.0e-06", + "usd_to_sbd":"7.327961", + "lbp_to_usd":"0.000662", + "aoa_to_btc":"1.6e-05", + "btc_to_vnd":"13840231.691782", + "btc_to_lak":"5261069.641582", + "dkk_to_usd":"0.182357", + "inr_to_btc":"2.6e-05", + "lrd_to_btc":"1.8e-05", + "pab_to_btc":"0.001532", + "usd_to_mga":"2418.845", + "btc_to_awg":"1163.4021", + "usd_to_try":"2.119397", + "usd_to_qar":"3.640826", + "usd_to_lvl":"0.516075", + "bmd_to_btc":"0.001532", + "vuv_to_btc":"1.6e-05", + "usd_to_pen":"2.77272", + "usd_to_zmk":"5252.024745", + "usd_to_ttd":"6.430258", + "mwk_to_btc":"4.0e-06", + "btc_to_scr":"7956.35195", + "egp_to_btc":"0.000214", + "bam_to_btc":"0.001066", + "usd_to_kmf":"361.468839", + "btc_to_aed":"2397.253827", + "usd_to_shp":"0.59845", + "bbd_to_btc":"0.0", + "kes_to_usd":"0.011429", + "jpy_to_btc":"1.5e-05", + "wst_to_usd":"0.4333", + "gyd_to_usd":"0.004871", + "kgs_to_btc":"2.9e-05", + "btc_to_eek":"7619.500539", + "usd_to_php":"43.88156", + "sdg_to_usd":"0.175555", + "usd_to_isk":"113.362", + "scr_to_btc":"0.000126", + "cup_to_usd":"1.00015", + "std_to_btc":"0.0", + "usd_to_gip":"0.59845", + "usd_to_aud":"1.078471", + "usd_to_dzd":"79.18756", + "usd_to_xaf":"482.386502", + "usd_to_mro":"293.83072", + "clp_to_btc":"3.0e-06", + "bbd_to_usd":"0.0", + "mdl_to_btc":"0.000111", + "btc_to_pyg":"2883168.216969", + "xof_to_btc":"3.0e-06", + "kzt_to_btc":"8.0e-06", + "usd_to_irr":"25562", + "usd_to_vuv":"95.214999", + "bif_to_btc":"1.0e-06", + "btc_to_gtq":"5078.735434", + "usd_to_bif":"1555.111667", + "btc_to_xof":"314915.893289", + "btc_to_ghs":"1975.522034", + "btc_to_kes":"57106.288814", + "usd_to_bbd":"2", + "usd_to_afn":"57.1605", + "usd_to_sdg":"5.696225", + "uzs_to_usd":"0.000434", + "btc_to_dzd":"51684.136661", + "btc_to_uyu":"14999.885233", + "usd_to_mnt":"1813.833333", + "egp_to_usd":"0.139885", + "btc_to_nio":"16863.815304", + "usd_to_mur":"30.35299", + "usd_to_fkp":"0.59845", + "twd_to_usd":"0.033285", + "btc_to_bif":"1014990.282818", + "nio_to_btc":"5.9e-05", + "bhd_to_usd":"2.652471", + "aoa_to_usd":"0.010226", + "tmm_to_usd":"0.350865", + "btc_to_bhd":"246.064929", + "kyd_to_btc":"0.001853", + "usd_to_mzn":"31.53765", + "jmd_to_btc":"1.4e-05", + "lbp_to_btc":"1.0e-06", + "btc_to_ngn":"105983.026231", + "sek_to_btc":"0.000229", + "try_to_usd":"0.471832", + "btc_to_mkd":"29541.236659", + "btc_to_gbp":"390.596346", + "aud_to_btc":"0.001421", + "xpf_to_usd":"0.011399", + "bzd_to_btc":"0.000767", + "usd_to_cdf":"923.276333", + "btc_to_bdt":"50546.110759", + "cup_to_btc":"0.001532", + "usd_to_lsl":"10.73625", + "btc_to_tnd":"1067.324993", + "btc_to_pln":"1990.765375", + "usd_to_btn":"59.302038", + "zar_to_btc":"0.000142", + "bob_to_btc":"0.000222", + "usd_to_top":"1.854371", + "amd_to_btc":"4.0e-06", + "btc_to_syp":"97376.330223", + "szl_to_usd":"0.093148", + "gip_to_usd":"1.670983", + "usd_to_mvr":"15.50046", + "thb_to_usd":"0.030608", + "bgn_to_usd":"0.695934", + "btc_to_gnf":"4592247.777818", + "rwf_to_btc":"2.0e-06", + "cny_to_usd":"0.16036", + "btc_to_mzn":"20583.993402", + "btc_to_bob":"4508.220667", + "btc_to_etb":"12773.5807", + "ern_to_usd":"0.066878", + "mmk_to_btc":"2.0e-06", + "btc_to_uzs":"1505049.607023", + "usd_to_kwd":"0.282124", + "btc_to_twd":"19608.850321", + "usd_to_clp":"550.273902", + "ghs_to_usd":"0.330384", + "brl_to_btc":"0.000672", + "btc_to_try":"1383.288034", + "usd_to_dkk":"5.48374", + "myr_to_btc":"0.000474", + "btc_to_svc":"5708.087346", + "kmf_to_btc":"4.0e-06", + "mxn_to_btc":"0.000118", + "nio_to_usd":"0.038703", + "uah_to_btc":"0.000129", + "ttd_to_btc":"0.000238", + "usd_to_sgd":"1.257403", + "usd_to_hrk":"5.561099", + "btc_to_thb":"21323.721334", + "mwk_to_usd":"0.002535", + "btc_to_aud":"703.896452", + "btc_to_vuv":"62144.925547", + "btc_to_php":"28640.616581", + "pyg_to_usd":"0.000226", + "scr_to_usd":"0.082033", + "btc_to_kwd":"184.136692", + "ugx_to_usd":"0.000391", + "btc_to_gmd":"25848.26879", + "zwl_to_btc":"5.0e-06", + "btc_to_zar":"7021.701137", + "btc_to_hkd":"5060.077271", + "btc_to_afn":"37307.51514", + "btc_to_fkp":"390.596346", + "xaf_to_btc":"3.0e-06", + "usd_to_nok":"6.004781", + "btc_to_kzt":"119710.257912", + "btc_to_btn":"38705.254162", + "amd_to_usd":"0.002401", + "usd_to_syp":"149.194598", + "usd_to_jpy":"102.613", + "usd_to_sek":"6.67794", + "btc_to_clp":"359152.770357", + "sgd_to_usd":"0.79529", + "btc_to_qar":"2376.294314", + "czk_to_usd":"0.049552", + "usd_to_aoa":"97.787626", + "krw_to_usd":"0.000975", + "sar_to_usd":"0.266625", + "hnl_to_usd":"0.048377", + "bwp_to_usd":"0.112761", + "usd_to_brl":"2.278873", + "btc_to_bbd":"1305.36", + "ngn_to_usd":"0.006158", + "azn_to_usd":"1.275185", + "btc_to_mnt":"1183852.739782", + "usd_to_rub":"35.1272", + "btc_to_lvl":"336.831831", + "usd_to_ron":"3.234704", + "btc_to_azn":"511.831656", + "sll_to_usd":"0.0", + "usd_to_dop":"43.18491", + "pab_to_usd":"1.0", + "pkr_to_usd":"0.010143", + "usd_to_scr":"12.19028", + "usd_to_huf":"224.314201", + "bdt_to_btc":"2.0e-05", + "btc_to_crc":"360989.929453", + "std_to_usd":"5.6e-05", + "mzn_to_usd":"0.031708", + "mzn_to_btc":"4.9e-05", + "nzd_to_usd":"0.841591", + "btc_to_npr":"61959.813098", + "btc_to_bwp":"5788.168571", + "kwd_to_usd":"3.544541", + "omr_to_usd":"2.597362", + "btc_to_rwf":"443653.186183", + "kgs_to_usd":"0.019183", + "afn_to_usd":"0.017495", + "btc_to_egp":"4665.846803", + "aud_to_usd":"0.927239", + "usd_to_mwk":"394.478", + "usd_to_cny":"6.235982", + "rwf_to_usd":"0.001471", + "usd_to_zwl":"322.355006", + "btc_to_cdf":"602603.997022", + "usd_to_tjs":"4.9089", + "usd_to_all":"102.8218", + "bhd_to_btc":"0.004064", + "kpw_to_btc":"0.0", + "bam_to_usd":"0.695497", + "btc_to_szl":"7006.904881", + "usd_to_pyg":"4417.430007", + "gel_to_btc":"0.000866", + "xcd_to_usd":"0.370154", + "usd_to_lrd":"84.80715", + "sos_to_usd":"0.001059", + "usd_to_uzs":"2305.953311", + "btc_to_fjd":"1203.716186", + "btc_to_iqd":"768557.933073", + "usd_to_bsd":"1", + "cve_to_btc":"1.9e-05", + "rub_to_btc":"4.4e-05", + "usd_to_rsd":"84.94406", + "sar_to_btc":"0.000408", + "eek_to_btc":"0.000131", + "btc_to_ugx":"1667559.327218", + "awg_to_btc":"0.000859", + "btc_to_mwk":"257467.90104", + "huf_to_btc":"7.0e-06", + "ang_to_usd":"0.559572", + "usd_to_djf":"179.064299", + "usd_to_cad":"1.092737", + "btc_to_brl":"1487.37483", + "usd_to_ern":"14.952575", + "iqd_to_btc":"1.0e-06", + "btc_to_pgk":"1849.20561", + "usd_to_xcd":"2.70158", + "btn_to_btc":"2.6e-05", + "myr_to_usd":"0.309373", + "lsl_to_usd":"0.093142", + "crc_to_usd":"0.001808", + "usd_to_egp":"7.148751", + "btc_to_rsd":"55441.289081", + "gel_to_usd":"0.564949", + "jmd_to_usd":"0.009011", + "btc_to_ltl":"1655.651398", + "lyd_to_btc":"0.001248", + "nad_to_usd":"0.093135", + "usd_to_kyd":"0.826698", + "btc_to_bsd":"652.68", + "ltl_to_btc":"0.000604", + "usd_to_srd":"3.308533", + "usd_to_awg":"1.7825", + "usd_to_szl":"10.73559", + "chf_to_btc":"0.001707", + "zwl_to_usd":"0.003102", + "sll_to_btc":"0.0", + "usd_to_cop":"1898.56665", + "usd_to_tmm":"2.8501", + "btc_to_tjs":"3203.940852", + "sbd_to_btc":"0.000209", + "ern_to_btc":"0.000102", + "btc_to_bam":"938.43701", + "btc_to_gip":"390.596346", + "sbd_to_usd":"0.136464", + "mad_to_usd":"0.121316", + "btc_to_ern":"9759.246651", + "usd_to_ltl":"2.536697", + "qar_to_usd":"0.274663", + "usd_to_kpw":"900", + "usd_to_crc":"553.088695", + "usd_to_xpf":"87.727229", + "yer_to_btc":"7.0e-06", + "chf_to_usd":"1.113917", + "jpy_to_usd":"0.009745", + "ars_to_btc":"0.000189", + "usd_to_pgk":"2.83325", + "gyd_to_btc":"7.0e-06", + "aed_to_usd":"0.272262", + "usd_to_mop":"7.983883", + "usd_to_aed":"3.672939", + "qar_to_btc":"0.000421", + "btc_to_sll":"2822841.0", + "btc_to_dkk":"3579.127423", + "gtq_to_usd":"0.128512", + "sos_to_btc":"2.0e-06", + "dop_to_usd":"0.023156", + "awg_to_usd":"0.56101", + "btc_to_gel":"1155.289288", + "btc_to_lkr":"85073.900287", + "btc_to_lrd":"55351.930662", + "khr_to_usd":"0.000247", + "btc_to_hrk":"3629.618095", + "usd_to_etb":"19.57097", + "btc_to_sos":"616393.994328", + "btc_to_eur":"479.545534", + "usd_to_krw":"1025.500003", + "btc_to_dop":"28185.927059", + "usd_to_bob":"6.907245", + "btc_to_kgs":"34024.502106", + "cve_to_usd":"0.012396", + "fjd_to_usd":"0.542221", + "btc_to_jpy":"66973.45284", + "btc_to_omr":"251.285716", + "usd_to_gyd":"205.278749", + "pen_to_btc":"0.000553", + "btc_to_jmd":"72430.379131", + "npr_to_usd":"0.010534", + "usd_to_tnd":"1.635296", + "usd_to_twd":"30.04359", + "btc_to_nad":"7007.923062", + "azn_to_btc":"0.001954", + "btc_to_sgd":"820.68179", + "twd_to_btc":"5.1e-05", + "btc_to_sek":"4358.557879", + "inr_to_usd":"0.016881", + "crc_to_btc":"3.0e-06", + "usd_to_mxn":"12.94185", + "xaf_to_usd":"0.002073", + "btc_to_idr":"7732071.522", + "btc_to_hnl":"13491.56786", + "eur_to_btc":"0.002085", + "btc_to_sbd":"4782.813585", + "hrk_to_usd":"0.179821", + "pln_to_btc":"0.000502", + "gtq_to_btc":"0.000197", + "zmk_to_usd":"0.00019", + "thb_to_btc":"4.7e-05", + "btc_to_mvr":"10116.840233", + "ghs_to_btc":"0.000506", + "usd_to_gmd":"39.60328", + "usd_to_mkd":"45.26144", + "usd_to_eur":"0.734733", + "cop_to_btc":"1.0e-06", + "btc_to_xcd":"1763.267234", + "sdg_to_btc":"0.000269", + "btc_to_nzd":"775.531346", + "usd_to_uah":"11.92032", + "rsd_to_btc":"1.8e-05", + "cdf_to_btc":"2.0e-06", + "btn_to_usd":"0.016863", + "krw_to_btc":"1.0e-06", + "tzs_to_usd":"0.000598", + "pgk_to_btc":"0.000541", + "btc_to_byr":"6608689.584218", + "bsd_to_usd":"1.0", + "irr_to_usd":"0.0", + "uyu_to_usd":"0.043512", + "mop_to_btc":"0.000192", + "usd_to_ghs":"3.026785", + "btc_to_khr":"2643284.380582", + "kyd_to_usd":"1.209632", + "btc_to_zmk":"3427891.510567", + "cop_to_usd":"0.000527", + "btc_to_mad":"5379.989026", + "try_to_btc":"0.000723", + "xpf_to_btc":"1.7e-05", + "kzt_to_usd":"0.005452", + "usd_to_bhd":"0.377007", + "top_to_btc":"0.000826", + "ugx_to_btc":"1.0e-06", + "usd_to_mmk":"968.3123", + "usd_to_jod":"0.708314", + "btc_to_vef":"4106.358411", + "gip_to_btc":"0.00256", + "btc_to_mmk":"631998.071964", + "usd_to_xof":"482.496619", + "wst_to_btc":"0.000664", + "mdl_to_usd":"0.072233", + "ltl_to_usd":"0.394213", + "bnd_to_btc":"0.001219", + "usd_to_sll":"4325", + "usd_to_nio":"25.8378", + "btc_to_mro":"191777.43433", + "srd_to_usd":"0.302249", + "usd_to_lbp":"1511.265", + "btc_to_pkr":"64345.30041", + "rsd_to_usd":"0.011772", + "sgd_to_btc":"0.001218", + "yer_to_usd":"0.004651", + "lvl_to_usd":"1.937703", + "usd_to_ang":"1.78708", + "usd_to_sar":"3.750587", + "usd_to_iqd":"1177.541725", + "btc_to_kmf":"235923.481839", + "usd_to_bmd":"1", + "kes_to_btc":"1.8e-05", + "btc_to_irr":"16683806.16", + "btc_to_aoa":"63824.027738", + "btc_to_shp":"390.596346", + "btc_to_sdg":"3717.812133", + "kmf_to_usd":"0.002766", + "btc_to_krw":"669323.341958", + "btc_to_srd":"2159.413318", + "usd_to_bdt":"77.44394", + "usd_to_zar":"10.75826", + "bwp_to_btc":"0.000173", + "byr_to_usd":"9.9e-05", + "vnd_to_usd":"4.7e-05", + "usd_to_cve":"80.66808", + "btc_to_btc":"0.999906", + "btc_to_pen":"1809.69889", + "usd_to_hkd":"7.752769", + "isk_to_btc":"1.4e-05", + "pen_to_usd":"0.360657", + "btc_to_kpw":"587412.0", + "btc_to_tmm":"0.0", + "bzd_to_usd":"0.500591", + "npr_to_btc":"1.6e-05", + "btc_to_chf":"585.932374", + "btc_to_bgn":"937.846988", + "btc_to_uah":"7780.154458", + "pln_to_usd":"0.327854", + "btc_to_inr":"38664.038725", + "htg_to_btc":"3.4e-05", + "btc_to_wst":"1506.299286", + "btc_to_ron":"2111.226607", + "xof_to_usd":"0.002073", + "btc_to_mur":"19810.789513", + "usd_to_rwf":"679.74074", + "usd_to_pab":"1", + "btc_to_mxn":"8446.886658", + "all_to_btc":"1.5e-05", + "dkk_to_btc":"0.000279", + "usd_to_ugx":"2554.941667", + "tnd_to_usd":"0.61151", + "usd_to_lyd":"1.227331", + "usd_to_pkr":"98.586291", + "omr_to_btc":"0.003979", + "mga_to_usd":"0.000413", + "mur_to_btc":"5.0e-05", + "usd_to_amd":"416.522999", + "jod_to_usd":"1.411803", + "tnd_to_btc":"0.000937", + "shp_to_usd":"1.670983", + "vuv_to_usd":"0.010503", + "khr_to_btc":"0.0", + "usd_to_htg":"45.07319", + "iqd_to_usd":"0.000849", + "btc_to_sar":"2447.933123", + "mur_to_usd":"0.032946", + "lsl_to_btc":"0.000143", + "usd_to_jmd":"110.973799", + "ils_to_btc":"0.00044", + "zar_to_usd":"0.092952", + "usd_to_pln":"3.05014", + "bsd_to_btc":"0.001532", + "btc_to_rub":"22926.820896", + "usd_to_mad":"8.24292", + "usd_to_inr":"59.23889", + "btc_to_czk":"13171.722026", + "isk_to_usd":"0.008821", + "rub_to_usd":"0.028468", + "usd_to_usd":"1.0", + "fkp_to_usd":"1.670983", + "all_to_usd":"0.009726", + "mop_to_usd":"0.125252", + "usd_to_cup":"0.99985", + "mro_to_btc":"5.0e-06", + "tmm_to_btc":"0.0", + "fjd_to_btc":"0.000831", + "usd_to_gnf":"7035.986667", + "btc_to_huf":"146405.392709", + "usd_to_byr":"10125.466667", + "usd_to_bgn":"1.436917", + "ang_to_btc":"0.000857", + "gmd_to_usd":"0.02525", + "bif_to_usd":"0.000643", + "etb_to_btc":"7.8e-05", + "usd_to_std":"18006.983333", + "btc_to_std":"11752797.881782", + "btc_to_ttd":"4196.900791", + "ron_to_btc":"0.000474", + "gmd_to_btc":"3.9e-05", + "kwd_to_btc":"0.00543", + "btc_to_amd":"271856.230987", + "btc_to_gyd":"133981.333897", + "btc_to_nok":"3919.200463", + "btc_to_yer":"140321.630587", + "cdf_to_usd":"0.001083", + "btc_to_usd":"652.68", + "hrk_to_btc":"0.000275", + "btc_to_xaf":"314844.022125", + "btc_to_bnd":"820.341744", + "btc_to_lsl":"7007.33565", + "usd_to_eek":"11.674175", + "brl_to_usd":"0.438813", + "lkr_to_usd":"0.007672", + "btc_to_pab":"652.68", + "ttd_to_usd":"0.155515", + "btc_to_cop":"1239156.481122", + "btc_to_isk":"73989.11016", + "uzs_to_btc":"1.0e-06", + "mxn_to_usd":"0.077269", + "btc_to_mdl":"9035.734554", + "djf_to_btc":"9.0e-06", + "usd_to_npr":"94.93138", + "btc_to_tzs":"1091561.6124", + "usd_to_vef":"6.291534", + "cad_to_btc":"0.001402", + "dzd_to_btc":"1.9e-05", + "sek_to_usd":"0.149747" +} \ No newline at end of file diff --git a/spec/rates_spec.rb b/spec/rates_spec.rb new file mode 100644 index 0000000..d8d7a6f --- /dev/null +++ b/spec/rates_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' +require 'fakeweb' +require 'coinbase' + +describe Money::Bank::Coinbase do + BASE_URI = 'http://fake.com/api/v1' # switching to http (instead of https) seems to help FakeWeb + + before :all do + @coinbase = Coinbase::Client.new '', '', {base_uri: BASE_URI} + FakeWeb.allow_net_connect = false + @rates_response = JSON.parse(File.read(File.dirname(__FILE__) + '/fixtures/rate_response.json')) + fake :get, '/currencies/exchange_rates', @rates_response + @bank = Money::Bank::Coinbase.new @coinbase + @bank.fetch_rates! + Money.default_bank = @bank + end + + # Auth and Errors + + it "exposes rates directly" do + @bank.get_rate(:usd, :btc).should == '0.001532' + end + + it "lets you convert currencies" do + Money.us_dollar(100).exchange_to(:BTC).should == '0.001532'.to_money(:BTC) + end + + it "lets you convert currencies with tiny rates" do + '1000000'.to_money(:MRO).exchange_to(:BTC).should == '5'.to_money(:BTC) + end + + it "lets you compare currencies" do + '1'.to_money(:BTC).should > '1'.to_money(:USD) + end + + it "throws an exception for unknown currencies" do + expect{'1'.to_money(:BTC).exchange_to(:WTF)}.to raise_error(Money::Currency::UnknownCurrency) + end + + it "throws an exception for missing rates" do + expect{'1'.to_money(:EUR).exchange_to(:RON)}.to raise_error(Money::Bank::UnknownRate) + end + + it "automatically refreshes expired rates" do + '1'.to_money(:BTC).exchange_to(:RON).should == '2111.22'.to_money(:RON) + @rates_response['btc_to_ron'] = '2000' + fake :get, '/currencies/exchange_rates', @rates_response + @bank.ttl_in_seconds = 0.2 + sleep 0.3 + '1'.to_money(:BTC).exchange_to(:RON).should == '2000'.to_money(:RON) + end + + def fake method, path, body + FakeWeb.register_uri(method, "#{BASE_URI}#{path}", body: body.to_json) + end + +end