Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
Added Money::Bank::Coinbase class to use Coinbase rates with the Mone…
Browse files Browse the repository at this point in the history
…y gem
  • Loading branch information
aianus committed Jun 8, 2014
1 parent d2a530f commit 24f4421
Show file tree
Hide file tree
Showing 6 changed files with 814 additions and 1 deletion.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
1 change: 1 addition & 0 deletions lib/coinbase.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
require "coinbase/version"
require "coinbase/client"
require "coinbase/oauth_client"
require "coinbase/rates"
6 changes: 5 additions & 1 deletion lib/coinbase/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
84 changes: 84 additions & 0 deletions lib/coinbase/rates.rb
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 24f4421

Please sign in to comment.