better-coinbase 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +336 -0
- data/Rakefile +6 -0
- data/better-coinbase.gemspec +33 -0
- data/lib/better-coinbase.rb +5 -0
- data/lib/better-coinbase/ca-coinbase.crt +629 -0
- data/lib/better-coinbase/client.rb +315 -0
- data/lib/better-coinbase/oauth_client.rb +77 -0
- data/lib/better-coinbase/version.rb +3 -0
- data/spec/client_spec.rb +429 -0
- data/spec/oauth_client_spec.rb +81 -0
- data/supported_currencies.json +163 -0
- metadata +185 -0
@@ -0,0 +1,315 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'hashie'
|
4
|
+
require 'money'
|
5
|
+
require 'monetize'
|
6
|
+
require 'time'
|
7
|
+
require 'securerandom'
|
8
|
+
|
9
|
+
module BetterCoinbase
|
10
|
+
class Client
|
11
|
+
include HTTParty
|
12
|
+
|
13
|
+
BASE_URI = 'https://coinbase.com/api/v1'
|
14
|
+
|
15
|
+
def initialize(api_key, api_secret, options={})
|
16
|
+
@api_key = api_key
|
17
|
+
@api_secret = api_secret
|
18
|
+
|
19
|
+
# defaults
|
20
|
+
options[:base_uri] ||= BASE_URI
|
21
|
+
@base_uri = options[:base_uri]
|
22
|
+
options[:format] ||= :json
|
23
|
+
options.each do |k,v|
|
24
|
+
self.class.send k, v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Account
|
29
|
+
|
30
|
+
def balance options={}
|
31
|
+
h = get '/account/balance', options
|
32
|
+
h['amount'].to_money(h['currency'])
|
33
|
+
end
|
34
|
+
|
35
|
+
def accounts options={}
|
36
|
+
accts = get '/accounts', options
|
37
|
+
accts = convert_money_objects(accts)
|
38
|
+
accts
|
39
|
+
end
|
40
|
+
|
41
|
+
def receive_address options={}
|
42
|
+
get '/account/receive_address', options
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_receive_address options={}
|
46
|
+
post '/account/generate_receive_address', options
|
47
|
+
end
|
48
|
+
|
49
|
+
# Buttons
|
50
|
+
|
51
|
+
def create_button name, price, description=nil, custom=nil, options={}
|
52
|
+
options[:button] ||= {}
|
53
|
+
options[:button][:name] ||= name
|
54
|
+
price = price.to_money("BTC") unless price.is_a?(Money)
|
55
|
+
options[:button][:price_string] ||= price.to_s
|
56
|
+
options[:button][:price_currency_iso] ||= price.currency.iso_code
|
57
|
+
options[:button][:description] ||= description
|
58
|
+
options[:button][:custom] ||= custom
|
59
|
+
r = post '/buttons', options
|
60
|
+
if r.success?
|
61
|
+
r.embed_html = case options[:button_mode]
|
62
|
+
when 'page'
|
63
|
+
%[<a href="https://coinbase.com/checkouts/#{r.button.code}" target="_blank"><img alt="#{r.button.text}" src="https://coinbase.com/assets/buttons/#{r.button.style}.png"></a>]
|
64
|
+
when 'iframe'
|
65
|
+
%[<iframe src="https://coinbase.com/inline_payments/#{r.button.code}" style="width:500px;height:160px;border:none;box-shadow:0 1px 3px rgba(0,0,0,0.25);overflow:hidden;" scrolling="no" allowtransparency="true" frameborder="0"></iframe>]
|
66
|
+
else
|
67
|
+
%[<div class="coinbase-button" data-code="#{r.button.code}"></div><script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
r
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_order_for_button button_id
|
74
|
+
post "/buttons/#{button_id}/create_order"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Addresses
|
78
|
+
|
79
|
+
def addresses page=1, options={}
|
80
|
+
get '/addresses', {page: page}.merge(options)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Currencies
|
84
|
+
|
85
|
+
def exchange_rates
|
86
|
+
get('/currencies/exchange_rates')
|
87
|
+
end
|
88
|
+
|
89
|
+
def currencies_short
|
90
|
+
currencies.collect { |c| c[1] }
|
91
|
+
end
|
92
|
+
|
93
|
+
def currencies_long
|
94
|
+
currencies.collect { |c| c[0] }
|
95
|
+
end
|
96
|
+
|
97
|
+
def currencies
|
98
|
+
eval(self.class.send(:get, '/currencies'))
|
99
|
+
end
|
100
|
+
private :currencies
|
101
|
+
|
102
|
+
# Transactions
|
103
|
+
|
104
|
+
def transactions page=1, options ={}
|
105
|
+
r = get '/transactions', {page: page}.merge(options)
|
106
|
+
r.transactions ||= []
|
107
|
+
convert_money_objects(r.transactions)
|
108
|
+
r
|
109
|
+
end
|
110
|
+
|
111
|
+
def transaction transaction_id
|
112
|
+
r = get "/transactions/#{transaction_id}"
|
113
|
+
convert_money_objects(r.transaction)
|
114
|
+
r
|
115
|
+
end
|
116
|
+
|
117
|
+
def send_money to, amount, notes=nil, options={}
|
118
|
+
options[:transaction] ||= {}
|
119
|
+
options[:transaction][:to] ||= to
|
120
|
+
amount = amount.to_money("BTC") unless amount.is_a?(Money)
|
121
|
+
options[:transaction][:amount_string] ||= amount.to_s
|
122
|
+
options[:transaction][:amount_currency_iso] ||= amount.currency.iso_code
|
123
|
+
options[:transaction][:notes] ||= notes
|
124
|
+
r = post '/transactions/send_money', options
|
125
|
+
if amt = r.transaction.amount
|
126
|
+
r.transaction.amount = amt.amount.to_money(amt.currency)
|
127
|
+
end
|
128
|
+
r
|
129
|
+
end
|
130
|
+
|
131
|
+
def request_money from, amount, notes=nil, options={}
|
132
|
+
options[:transaction] ||= {}
|
133
|
+
options[:transaction][:from] ||= from
|
134
|
+
amount = amount.to_money("BTC") unless amount.is_a?(Money)
|
135
|
+
options[:transaction][:amount_string] ||= amount.to_s
|
136
|
+
options[:transaction][:amount_currency_iso] ||= amount.currency.iso_code
|
137
|
+
options[:transaction][:notes] ||= notes
|
138
|
+
r = post '/transactions/request_money', options
|
139
|
+
if amt = r.transaction.amount
|
140
|
+
r.transaction.amount = amt.amount.to_money(amt.currency)
|
141
|
+
end
|
142
|
+
r
|
143
|
+
end
|
144
|
+
|
145
|
+
def resend_request transaction_id
|
146
|
+
put "/transactions/#{transaction_id}/resend_request"
|
147
|
+
end
|
148
|
+
|
149
|
+
def cancel_request transaction_id
|
150
|
+
delete "/transactions/#{transaction_id}/cancel_request"
|
151
|
+
end
|
152
|
+
|
153
|
+
def complete_request transaction_id
|
154
|
+
put "/transactions/#{transaction_id}/complete_request"
|
155
|
+
end
|
156
|
+
|
157
|
+
# Users
|
158
|
+
|
159
|
+
def create_user email, password=nil, client_id=nil, scopes=nil
|
160
|
+
password ||= SecureRandom.urlsafe_base64(12)
|
161
|
+
options = {user: {email: email, password: password}}
|
162
|
+
if client_id
|
163
|
+
options[:client_id] = client_id
|
164
|
+
raise Error.new("Invalid scopes parameter; must be an array") if !scopes.is_a?(Array)
|
165
|
+
options[:scopes] = scopes.join(' ')
|
166
|
+
end
|
167
|
+
post '/users', options
|
168
|
+
end
|
169
|
+
|
170
|
+
# Prices
|
171
|
+
|
172
|
+
def buy_price qty=1
|
173
|
+
r = get '/prices/buy', {qty: qty}
|
174
|
+
r['amount'].to_money(r['currency'])
|
175
|
+
end
|
176
|
+
|
177
|
+
def sell_price qty=1
|
178
|
+
r = get '/prices/sell', {qty: qty}
|
179
|
+
r['amount'].to_money(r['currency'])
|
180
|
+
end
|
181
|
+
|
182
|
+
def spot_price currency='USD'
|
183
|
+
r = get '/prices/spot_rate', {currency: currency}
|
184
|
+
r['amount'].to_money(r['currency'])
|
185
|
+
end
|
186
|
+
|
187
|
+
# Buys
|
188
|
+
|
189
|
+
def buy! qty
|
190
|
+
r = post '/buys', {qty: qty}
|
191
|
+
r = convert_money_objects(r)
|
192
|
+
r.transfer.payout_date = Time.parse(r.transfer.payout_date) rescue nil
|
193
|
+
r
|
194
|
+
end
|
195
|
+
|
196
|
+
# Sells
|
197
|
+
|
198
|
+
def sell! qty
|
199
|
+
r = post '/sells', {qty: qty}
|
200
|
+
r = convert_money_objects(r)
|
201
|
+
r.transfer.payout_date = Time.parse(r.transfer.payout_date) rescue nil
|
202
|
+
r
|
203
|
+
end
|
204
|
+
|
205
|
+
# Transfers
|
206
|
+
|
207
|
+
def transfers options={}
|
208
|
+
r = get '/transfers', options
|
209
|
+
r = convert_money_objects(r)
|
210
|
+
r.transfers.each do |t|
|
211
|
+
t.transfer.payout_date = Time.parse(t.transfer.payout_date) rescue nil
|
212
|
+
end
|
213
|
+
r
|
214
|
+
end
|
215
|
+
|
216
|
+
# Wrappers for the main HTTP verbs
|
217
|
+
|
218
|
+
def get(path, options={})
|
219
|
+
http_verb :get, path, options
|
220
|
+
end
|
221
|
+
|
222
|
+
def post(path, options={})
|
223
|
+
http_verb :post, path, options
|
224
|
+
end
|
225
|
+
|
226
|
+
def put(path, options={})
|
227
|
+
http_verb :put, path, options
|
228
|
+
end
|
229
|
+
|
230
|
+
def delete(path, options={})
|
231
|
+
http_verb :delete, path, options
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.whitelisted_cert_store
|
235
|
+
@@cert_store ||= build_whitelisted_cert_store
|
236
|
+
end
|
237
|
+
|
238
|
+
def self.build_whitelisted_cert_store
|
239
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), 'ca-coinbase.crt'))
|
240
|
+
|
241
|
+
certs = [ [] ]
|
242
|
+
File.readlines(path).each{|line|
|
243
|
+
next if ["\n","#"].include?(line[0])
|
244
|
+
certs.last << line
|
245
|
+
certs << [] if line == "-----END CERTIFICATE-----\n"
|
246
|
+
}
|
247
|
+
|
248
|
+
result = OpenSSL::X509::Store.new
|
249
|
+
|
250
|
+
certs.each{|lines|
|
251
|
+
next if lines.empty?
|
252
|
+
cert = OpenSSL::X509::Certificate.new(lines.join)
|
253
|
+
result.add_cert(cert)
|
254
|
+
}
|
255
|
+
|
256
|
+
result
|
257
|
+
end
|
258
|
+
|
259
|
+
def ssl_options
|
260
|
+
{ verify: true, cert_store: self.class.whitelisted_cert_store }
|
261
|
+
end
|
262
|
+
|
263
|
+
def http_verb(verb, path, options={})
|
264
|
+
|
265
|
+
nonce = options[:nonce] || (Time.now.to_f * 1e6).to_i
|
266
|
+
|
267
|
+
if [:get, :delete].include? verb
|
268
|
+
request_options = {}
|
269
|
+
path = "#{path}?#{URI.encode_www_form(options)}" if !options.empty?
|
270
|
+
hmac_message = nonce.to_s + @base_uri + path
|
271
|
+
else
|
272
|
+
request_options = {body: options.to_json}
|
273
|
+
hmac_message = nonce.to_s + @base_uri + path + options.to_json
|
274
|
+
end
|
275
|
+
|
276
|
+
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @api_secret, hmac_message)
|
277
|
+
|
278
|
+
headers = {
|
279
|
+
'ACCESS_KEY' => @api_key,
|
280
|
+
'ACCESS_SIGNATURE' => signature,
|
281
|
+
'ACCESS_NONCE' => nonce.to_s,
|
282
|
+
"Content-Type" => "application/json",
|
283
|
+
}
|
284
|
+
|
285
|
+
request_options[:headers] = headers
|
286
|
+
|
287
|
+
r = self.class.send(verb, path, request_options.merge(ssl_options))
|
288
|
+
hash = Hashie::Mash.new(JSON.parse(r.body))
|
289
|
+
raise Error.new(hash.error) if hash.error
|
290
|
+
raise Error.new(hash.errors.join(", ")) if hash.errors
|
291
|
+
hash
|
292
|
+
end
|
293
|
+
|
294
|
+
class Error < StandardError; end
|
295
|
+
|
296
|
+
private
|
297
|
+
|
298
|
+
def convert_money_objects obj
|
299
|
+
if obj.is_a?(Array)
|
300
|
+
obj.each_with_index do |o, i|
|
301
|
+
obj[i] = convert_money_objects(o)
|
302
|
+
end
|
303
|
+
elsif obj.is_a?(Hash)
|
304
|
+
if obj[:amount] && (obj[:currency] || obj[:currency_iso])
|
305
|
+
obj = obj[:amount].to_money((obj[:currency] || obj[:currency_iso]))
|
306
|
+
else
|
307
|
+
obj.each do |k,v|
|
308
|
+
obj[k] = convert_money_objects(v)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
obj
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
module BetterCoinbase
|
4
|
+
class OAuthClient < Client
|
5
|
+
|
6
|
+
AUTHORIZE_URL = 'https://coinbase.com/oauth/authorize'
|
7
|
+
TOKEN_URL = 'https://coinbase.com/oauth/token'
|
8
|
+
|
9
|
+
# Initializes a Coinbase Client using OAuth 2.0 credentials
|
10
|
+
#
|
11
|
+
# @param [String] client_id this application's Coinbase OAuth2 CLIENT_ID
|
12
|
+
# @param [String] client_secret this application's Coinbase OAuth2 CLIENT_SECRET
|
13
|
+
# @param [Hash] user_credentials OAuth 2.0 credentials to use
|
14
|
+
# @option user_credentials [String] access_token Must pass either this or token
|
15
|
+
# @option user_credentials [String] token Must pass either this or access_token
|
16
|
+
# @option user_credentials [String] refresh_token Optional
|
17
|
+
# @option user_credentials [Integer] expires_at Optional
|
18
|
+
# @option user_credentials [Integer] expires_in Optional
|
19
|
+
#
|
20
|
+
# Please note access tokens will be automatically refreshed when expired
|
21
|
+
# Use the credentials method when finished with the client to retrieve up-to-date credentials
|
22
|
+
def initialize(client_id, client_secret, user_credentials, options={})
|
23
|
+
client_opts = {
|
24
|
+
:site => options[:base_uri] || BASE_URI,
|
25
|
+
:authorize_url => options[:authorize_url] || AUTHORIZE_URL,
|
26
|
+
:token_url => options[:token_url] || TOKEN_URL,
|
27
|
+
:ssl => {
|
28
|
+
:verify => true,
|
29
|
+
:cert_store => ::BetterCoinbase::Client.whitelisted_cert_store
|
30
|
+
}
|
31
|
+
}
|
32
|
+
@oauth_client = OAuth2::Client.new(client_id, client_secret, client_opts)
|
33
|
+
token_hash = user_credentials.dup
|
34
|
+
token_hash[:access_token] ||= token_hash[:token]
|
35
|
+
token_hash.delete :expires
|
36
|
+
raise "No access token provided" unless token_hash[:access_token]
|
37
|
+
@oauth_token = OAuth2::AccessToken.from_hash(@oauth_client, token_hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def http_verb(verb, path, options={})
|
41
|
+
path = remove_leading_slash(path)
|
42
|
+
|
43
|
+
if [:get, :delete].include? verb
|
44
|
+
request_options = {params: options}
|
45
|
+
else
|
46
|
+
request_options = {headers: {"Content-Type" => "application/json"}, body: options.to_json}
|
47
|
+
end
|
48
|
+
response = oauth_token.request(verb, path, request_options)
|
49
|
+
|
50
|
+
hash = Hashie::Mash.new(JSON.parse(response.body))
|
51
|
+
raise Error.new(hash.error) if hash.error
|
52
|
+
raise Error.new(hash.errors.join(", ")) if hash.errors
|
53
|
+
hash
|
54
|
+
end
|
55
|
+
|
56
|
+
def refresh!
|
57
|
+
raise "Access token not initialized." unless @oauth_token
|
58
|
+
@oauth_token = @oauth_token.refresh!
|
59
|
+
end
|
60
|
+
|
61
|
+
def oauth_token
|
62
|
+
raise "Access token not initialized." unless @oauth_token
|
63
|
+
refresh! if @oauth_token.expired?
|
64
|
+
@oauth_token
|
65
|
+
end
|
66
|
+
|
67
|
+
def credentials
|
68
|
+
@oauth_token.to_hash
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def remove_leading_slash(path)
|
74
|
+
path.sub(/^\//, '')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,429 @@
|
|
1
|
+
require 'fakeweb'
|
2
|
+
require 'better-coinbase'
|
3
|
+
|
4
|
+
describe BetterCoinbase::Client do
|
5
|
+
BASE_URI = 'http://fake.com/api/v1' # switching to http (instead of https) seems to help FakeWeb
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@c = BetterCoinbase::Client.new 'api key', 'api secret', {base_uri: BASE_URI}
|
9
|
+
FakeWeb.allow_net_connect = false
|
10
|
+
end
|
11
|
+
|
12
|
+
# Auth and Errors
|
13
|
+
|
14
|
+
it "raise errors" do
|
15
|
+
fake :get, '/account/balance', {error: "some error"}
|
16
|
+
expect{ @c.balance }.to raise_error(BetterCoinbase::Client::Error, 'some error')
|
17
|
+
fake :get, '/account/balance', {errors: ["some", "error"]}
|
18
|
+
expect{ @c.balance }.to raise_error(BetterCoinbase::Client::Error, 'some, error')
|
19
|
+
end
|
20
|
+
|
21
|
+
# Account
|
22
|
+
|
23
|
+
it "should get balance" do
|
24
|
+
fake :get, '/account/balance', {amount: "50.00000000", currency: 'BTC'}
|
25
|
+
@c.balance.should == 50.to_money('BTC')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should get a receive address" do
|
29
|
+
fake :get, '/account/receive_address', {address: "muVu2JZo8PbewBHRp6bpqFvVD87qvqEHWA", callback_url: nil}
|
30
|
+
a = @c.receive_address
|
31
|
+
a.address.should == "muVu2JZo8PbewBHRp6bpqFvVD87qvqEHWA"
|
32
|
+
a.callback_url.should == nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should generate new receive addresses" do
|
36
|
+
fake :post, '/account/generate_receive_address', {address: "mmxJyTdxHUJUDoptwLHAGxLEd1rAxDJ7EV", callback_url: "http://example.com/callback"}
|
37
|
+
a = @c.generate_receive_address
|
38
|
+
a.address.should == "mmxJyTdxHUJUDoptwLHAGxLEd1rAxDJ7EV"
|
39
|
+
a.callback_url.should == "http://example.com/callback"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should list accounts" do
|
43
|
+
accounts_response = <<-eos
|
44
|
+
{
|
45
|
+
"accounts": [
|
46
|
+
{
|
47
|
+
"id": "536a541fa9393bb3c7000023",
|
48
|
+
"name": "My Wallet",
|
49
|
+
"balance": {
|
50
|
+
"amount": "50.00000000",
|
51
|
+
"currency": "BTC"
|
52
|
+
},
|
53
|
+
"native_balance": {
|
54
|
+
"amount": "500.12",
|
55
|
+
"currency": "USD"
|
56
|
+
},
|
57
|
+
"created_at": "2014-05-07T08:41:19-07:00",
|
58
|
+
"primary": true,
|
59
|
+
"active": true
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"id": "536a541fa9393bb3c7000034",
|
63
|
+
"name": "Savings",
|
64
|
+
"balance": {
|
65
|
+
"amount": "0.00000000",
|
66
|
+
"currency": "BTC"
|
67
|
+
},
|
68
|
+
"native_balance": {
|
69
|
+
"amount": "0.00",
|
70
|
+
"currency": "USD"
|
71
|
+
},
|
72
|
+
"created_at": "2014-05-07T08:50:10-07:00",
|
73
|
+
"primary": false,
|
74
|
+
"active": true
|
75
|
+
}
|
76
|
+
],
|
77
|
+
"total_count": 2,
|
78
|
+
"num_pages": 1,
|
79
|
+
"current_page": 1
|
80
|
+
}
|
81
|
+
eos
|
82
|
+
|
83
|
+
fake :get, '/accounts', JSON.parse(accounts_response)
|
84
|
+
r = @c.accounts
|
85
|
+
r.total_count.should == 2
|
86
|
+
primary_account = r.accounts.select { |acct| acct.primary }.first
|
87
|
+
primary_account.id.should == "536a541fa9393bb3c7000023"
|
88
|
+
primary_account.balance.should == 50.to_money("BTC")
|
89
|
+
|
90
|
+
# Make sure paging works
|
91
|
+
fake :get, '/accounts?page=2', JSON.parse(accounts_response)
|
92
|
+
r = @c.accounts :page => 2
|
93
|
+
FakeWeb.last_request.path.should include("page=2")
|
94
|
+
end
|
95
|
+
|
96
|
+
# Buttons
|
97
|
+
|
98
|
+
it "should create a new button" do
|
99
|
+
response = {:success=>true, :button=>{:code=>"93865b9cae83706ae59220c013bc0afd", :type=>"buy_now", :style=>"custom_large", :text=>"Pay With Bitcoin", :name=>"Order 123", :description=>"Sample description", :custom=>"Order123", :price=>{:cents=>123, :currency_iso=>"BTC"}}}
|
100
|
+
fake :post, '/buttons', response
|
101
|
+
r = @c.create_button "Order 123", 1.23, "Sample description"
|
102
|
+
|
103
|
+
# Ensure BTC is assumed to be the default currency
|
104
|
+
post_params = JSON.parse(FakeWeb.last_request.body)
|
105
|
+
post_params['button']['price_currency_iso'].should == "BTC"
|
106
|
+
post_params['button']['price_string'].should == "1.23000000"
|
107
|
+
|
108
|
+
r.success?.should == true
|
109
|
+
r.button.name.should == "Order 123"
|
110
|
+
r.embed_html.should == %[<div class="coinbase-button" data-code="93865b9cae83706ae59220c013bc0afd"></div><script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>]
|
111
|
+
|
112
|
+
r = @c.create_button "Order 123", 1.23, "Sample description", nil, button_mode: 'page'
|
113
|
+
r.success?.should == true
|
114
|
+
r.button.name.should == "Order 123"
|
115
|
+
r.embed_html.should == %[<a href="https://coinbase.com/checkouts/93865b9cae83706ae59220c013bc0afd" target="_blank"><img alt="Pay With Bitcoin" src="https://coinbase.com/assets/buttons/custom_large.png"></a>]
|
116
|
+
|
117
|
+
r = @c.create_button "Order 123", 1.23, "Sample description", nil, button_mode: 'iframe'
|
118
|
+
r.success?.should == true
|
119
|
+
r.button.name.should == "Order 123"
|
120
|
+
r.embed_html.should == %[<iframe src="https://coinbase.com/inline_payments/93865b9cae83706ae59220c013bc0afd" style="width:500px;height:160px;border:none;box-shadow:0 1px 3px rgba(0,0,0,0.25);overflow:hidden;" scrolling="no" allowtransparency="true" frameborder="0"></iframe>]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should create a new button with price in USD" do
|
124
|
+
response = {:success=>true, :button=>{:code=>"93865b9cae83706ae59220c013bc0afd", :type=>"buy_now", :style=>"custom_large", :text=>"Pay With Bitcoin", :name=>"Order 123", :description=>"Sample description", :custom=>"Order123", :price=>{:cents=>123, :currency_iso=>"USD"}}}
|
125
|
+
fake :post, '/buttons', response
|
126
|
+
r = @c.create_button "Order 123", 1.23.to_money("USD"), "Sample description"
|
127
|
+
|
128
|
+
post_params = JSON.parse(FakeWeb.last_request.body)
|
129
|
+
post_params['button']['price_currency_iso'].should == "USD"
|
130
|
+
post_params['button']['price_string'].should == "1.23"
|
131
|
+
|
132
|
+
r.success?.should == true
|
133
|
+
r.button.name.should == "Order 123"
|
134
|
+
r.embed_html.should == %[<div class="coinbase-button" data-code="93865b9cae83706ae59220c013bc0afd"></div><script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>]
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should create order for the button" do
|
138
|
+
response = {"success"=>true, "order"=>{"id"=>"UAHXEK24", "created_at"=>"2013-12-13T01:15:56-08:00", "status"=>"new", "total_btc"=>{"cents"=>123, "currency_iso"=>"BTC"}, "total_native"=>{"cents"=>123, "currency_iso"=>"BTC"}, "custom"=>"Order123", "receive_address"=>"1EWxf61QGAkQDNUDq6XynH2PdFRyZUm111", "button"=>{"type"=>"buy_now", "name"=>"Order 123", "description"=>"Sample description", "id"=>"93865b9cae83706ae59220c013bc0afd"}, "transaction"=>nil}}
|
139
|
+
fake :post, '/buttons/93865b9cae83706ae59220c013bc0afd/create_order', response
|
140
|
+
r = @c.create_order_for_button "93865b9cae83706ae59220c013bc0afd"
|
141
|
+
r.order.button.id.should == "93865b9cae83706ae59220c013bc0afd"
|
142
|
+
r.order.status.should == "new"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Transactions
|
146
|
+
|
147
|
+
it "should get transaction list" do
|
148
|
+
response = {"current_user"=>{"id"=>"5011f33df8182b142400000e", "email"=>"user2@example.com", "name"=>"user2@example.com"}, "balance"=>{"amount"=>"50.00000000", "currency"=>"BTC"}, "total_count"=>2, "num_pages"=>1, "current_page"=>1, "transactions"=>[{"transaction"=>{"id"=>"5018f833f8182b129c00002f", "created_at"=>"2012-08-01T02:34:43-07:00", "amount"=>{"amount"=>"-1.10000000", "currency"=>"BTC"}, "request"=>true, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}}}, {"transaction"=>{"id"=>"5018f833f8182b129c00002e", "created_at"=>"2012-08-01T02:36:43-07:00", "hsh" => "9d6a7d1112c3db9de5315b421a5153d71413f5f752aff75bf504b77df4e646a3", "amount"=>{"amount"=>"-1.00000000", "currency"=>"BTC"}, "request"=>false, "status"=>"complete", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient_address"=>"37muSN5ZrukVTvyVh3mT5Zc5ew9L9CBare"}}]}
|
149
|
+
fake :get, '/transactions?page=1', response
|
150
|
+
r = @c.transactions
|
151
|
+
r.transactions.first.transaction.id.should == '5018f833f8182b129c00002f'
|
152
|
+
r.transactions.last.transaction.hsh.should == '9d6a7d1112c3db9de5315b421a5153d71413f5f752aff75bf504b77df4e646a3'
|
153
|
+
r.transactions.first.transaction.amount.should == "-1.1".to_money("BTC")
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should get transaction detail" do
|
157
|
+
response = {"transaction"=>{"id"=>"5011f33df8182b142400000e", "created_at"=>"2013-12-19T05:20:15-08:00", "hsh"=>"ff11a892bc6f7c345a5d74d52b0878f6a7e5011f33df8182b142400000e", "amount"=>{"amount"=>"-0.01000000", "currency"=>"BTC"}, "request"=>false, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "email"=>"tuser2@example.com", "name"=>"User Two"}, "recipient_address"=>"1EWxf61QGAkQDNUDq6XynH2PdFRyZUm111", "notes"=>""}}
|
158
|
+
fake :get, "/transactions/5011f33df8182b142400000e", response
|
159
|
+
r = @c.transaction "5011f33df8182b142400000e"
|
160
|
+
r.transaction.id.should == "5011f33df8182b142400000e"
|
161
|
+
r.transaction.status.should == "pending"
|
162
|
+
r.transaction.amount.should == "-0.01".to_money("BTC")
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should not fail if there are no transactions" do
|
166
|
+
response = {"current_user"=>{"id"=>"5011f33df8182b142400000e", "email"=>"user2@example.com", "name"=>"user2@example.com"}, "balance"=>{"amount"=>"0.00000000", "currency"=>"BTC"}, "total_count"=>0, "num_pages"=>0, "current_page"=>1}
|
167
|
+
fake :get, '/transactions?page=1', response
|
168
|
+
r = @c.transactions
|
169
|
+
r.transactions.should_not be_nil
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should send money in BTC" do
|
173
|
+
response = {"success"=>true, "transaction"=>{"id"=>"501a1791f8182b2071000087", "created_at"=>"2012-08-01T23:00:49-07:00", "notes"=>"Sample transaction for you!", "amount"=>{"amount"=>"-1.23400000", "currency"=>"BTC"}, "request"=>false, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}}}
|
174
|
+
fake :post, '/transactions/send_money', response
|
175
|
+
r = @c.send_money "user1@example.com", 1.2345, "Sample transaction for you"
|
176
|
+
|
177
|
+
# Ensure BTC is assumed to be the default currency
|
178
|
+
post_params = JSON.parse(FakeWeb.last_request.body)
|
179
|
+
post_params['transaction']['amount_currency_iso'].should == "BTC"
|
180
|
+
post_params['transaction']['amount_string'].should == "1.23450000"
|
181
|
+
|
182
|
+
r.success.should == true
|
183
|
+
r.transaction.id.should == '501a1791f8182b2071000087'
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should send money in USD" do
|
187
|
+
response = {"success"=>true, "transaction"=>{"id"=>"501a1791f8182b2071000087", "created_at"=>"2012-08-01T23:00:49-07:00", "notes"=>"Sample transaction for you!", "amount"=>{"amount"=>"-1.23400000", "currency"=>"BTC"}, "request"=>false, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}}}
|
188
|
+
fake :post, '/transactions/send_money', response
|
189
|
+
r = @c.send_money "user1@example.com", 500.to_money("USD"), "Sample transaction for you"
|
190
|
+
|
191
|
+
post_params = JSON.parse(FakeWeb.last_request.body)
|
192
|
+
post_params['transaction']['amount_currency_iso'].should == "USD"
|
193
|
+
post_params['transaction']['amount_string'].should == "500.00"
|
194
|
+
|
195
|
+
r.success.should == true
|
196
|
+
r.transaction.id.should == '501a1791f8182b2071000087'
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should request money" do
|
200
|
+
response = {"success"=>true, "transaction"=>{"id"=>"501a3554f8182b2754000003", "created_at"=>"2012-08-02T01:07:48-07:00", "notes"=>"Sample request for you!", "amount"=>{"amount"=>"1.23400000", "currency"=>"BTC"}, "request"=>true, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}}}
|
201
|
+
fake :post, '/transactions/request_money', response
|
202
|
+
r = @c.request_money "user1@example.com", 1.2345, "Sample transaction for you"
|
203
|
+
|
204
|
+
# Ensure BTC is assumed to be the default currency
|
205
|
+
post_params = JSON.parse(FakeWeb.last_request.body)
|
206
|
+
post_params['transaction']['amount_currency_iso'].should == "BTC"
|
207
|
+
post_params['transaction']['amount_string'].should == "1.23450000"
|
208
|
+
|
209
|
+
r.success.should == true
|
210
|
+
r.transaction.id.should == '501a3554f8182b2754000003'
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should request money in USD" do
|
214
|
+
response = {"success"=>true, "transaction"=>{"id"=>"501a3554f8182b2754000003", "created_at"=>"2012-08-02T01:07:48-07:00", "notes"=>"Sample request for you!", "amount"=>{"amount"=>"1.23400000", "currency"=>"BTC"}, "request"=>true, "status"=>"pending", "sender"=>{"id"=>"5011f33df8182b142400000a", "name"=>"User One", "email"=>"user1@example.com"}, "recipient"=>{"id"=>"5011f33df8182b142400000e", "name"=>"User Two", "email"=>"user2@example.com"}}}
|
215
|
+
fake :post, '/transactions/request_money', response
|
216
|
+
r = @c.request_money "user1@example.com", 500.to_money("USD"), "Sample transaction for you"
|
217
|
+
|
218
|
+
# Ensure BTC is assumed to be the default currency
|
219
|
+
post_params = JSON.parse(FakeWeb.last_request.body)
|
220
|
+
post_params['transaction']['amount_currency_iso'].should == "USD"
|
221
|
+
post_params['transaction']['amount_string'].should == "500.00"
|
222
|
+
|
223
|
+
r.success.should == true
|
224
|
+
r.transaction.id.should == '501a3554f8182b2754000003'
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should resend requests" do
|
228
|
+
response = {"success"=>true}
|
229
|
+
fake :put, "/transactions/501a3554f8182b2754000003/resend_request", response
|
230
|
+
r = @c.resend_request '501a3554f8182b2754000003'
|
231
|
+
r.success.should == true
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should cancel requests" do
|
235
|
+
response = {"success"=>true}
|
236
|
+
fake :delete, "/transactions/501a3554f8182b2754000003/cancel_request", response
|
237
|
+
r = @c.cancel_request '501a3554f8182b2754000003'
|
238
|
+
r.success.should == true
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should resend requests" do
|
242
|
+
response = {"success"=>true}
|
243
|
+
fake :put, "/transactions/501a3554f8182b2754000003/complete_request", response
|
244
|
+
r = @c.complete_request '501a3554f8182b2754000003'
|
245
|
+
r.success.should == true
|
246
|
+
end
|
247
|
+
|
248
|
+
# Users
|
249
|
+
|
250
|
+
it "should let you create users" do
|
251
|
+
response = {"success"=>true, "user"=>{"id"=>"501a3d22f8182b2754000011", "name"=>"New User", "email"=>"newuser@example.com", "receive_address"=>"mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"}}
|
252
|
+
fake :post, "/users", response
|
253
|
+
r = @c.create_user "newuser@example.com"
|
254
|
+
r.success.should == true
|
255
|
+
r.user.email.should == "newuser@example.com"
|
256
|
+
r.user.receive_address.should == "mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should let you create users with OAuth" do
|
260
|
+
response = {
|
261
|
+
"success"=>true,
|
262
|
+
"oauth" => {
|
263
|
+
"access_token" => "the_access_token",
|
264
|
+
"refresh_token" => "the_refresh_token",
|
265
|
+
"scope" => "transactions buy sell",
|
266
|
+
"token_type" => "bearer"
|
267
|
+
},
|
268
|
+
"user" => {
|
269
|
+
"id"=>"501a3d22f8182b2754000011",
|
270
|
+
"name"=>"New User",
|
271
|
+
"email"=>"newuser@example.com",
|
272
|
+
"receive_address"=>"mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"
|
273
|
+
}
|
274
|
+
}
|
275
|
+
fake :post, "/users", response
|
276
|
+
r = @c.create_user "newuser@example.com", "newpassword", "the_client_id", ['transactions', 'buy', 'sell']
|
277
|
+
r.success.should == true
|
278
|
+
r.oauth.access_token.should == "the_access_token"
|
279
|
+
r.user.email.should == "newuser@example.com"
|
280
|
+
r.user.receive_address.should == "mpJKwdmJKYjiyfNo26eRp4j6qGwuUUnw9x"
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should not let you specify client_id without scopes" do
|
284
|
+
expect{ @c.create_user "newuser@example.com", "newpassword", "the_client_id" }.to raise_error(BetterCoinbase::Client::Error)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Prices
|
288
|
+
|
289
|
+
it "should let you get buy, sell, and spot prices" do
|
290
|
+
fake :get, "/prices/buy?qty=1", {"amount"=>"13.85", "currency"=>"USD"}
|
291
|
+
r = @c.buy_price 1
|
292
|
+
r.to_f.should == 13.85
|
293
|
+
|
294
|
+
fake :get, "/prices/sell?qty=1", {"amount"=>"13.83", "currency"=>"USD"}
|
295
|
+
r = @c.sell_price 1
|
296
|
+
r.to_f.should == 13.83
|
297
|
+
|
298
|
+
fake :get, "/prices/spot_rate?currency=USD", {"amount"=>"13.84", "currency"=>"USD"}
|
299
|
+
r = @c.spot_price
|
300
|
+
r.to_f.should == 13.84
|
301
|
+
end
|
302
|
+
|
303
|
+
# Buys
|
304
|
+
|
305
|
+
it "should let you buy bitcoin" do
|
306
|
+
response = {"success"=>true, "transfer"=>{"_type"=>"AchDebit", "code"=>"6H7GYLXZ", "created_at"=>"2013-01-28T16:08:58-08:00", "fees"=>{"coinbase"=>{"cents"=>14, "currency_iso"=>"USD"}, "bank"=>{"cents"=>15, "currency_iso"=>"USD"}}, "status"=>"created", "payout_date"=>"2013-02-01T18:00:00-08:00", "btc"=>{"amount"=>"1.00000000", "currency"=>"BTC"}, "subtotal"=>{"amount"=>"13.55", "currency"=>"USD"}, "total"=>{"amount"=>"13.84", "currency"=>"USD"}}}
|
307
|
+
fake :post, "/buys", response
|
308
|
+
r = @c.buy! 1
|
309
|
+
r.success?.should == true
|
310
|
+
r.transfer.code.should == '6H7GYLXZ'
|
311
|
+
r.transfer.status.should == 'created'
|
312
|
+
r.transfer.btc.should == 1.to_money("BTC")
|
313
|
+
end
|
314
|
+
|
315
|
+
# Sells
|
316
|
+
|
317
|
+
it "should let you sell bitcoin" do
|
318
|
+
response = {"success"=>true, "transfer"=>{"_type"=>"AchCredit", "code"=>"RD2OC8AL", "created_at"=>"2013-01-28T16:32:35-08:00", "fees"=>{"coinbase"=>{"cents"=>14, "currency_iso"=>"USD"}, "bank"=>{"cents"=>15, "currency_iso"=>"USD"}}, "status"=>"created", "payout_date"=>"2013-02-01T18:00:00-08:00", "btc"=>{"amount"=>"1.00000000", "currency"=>"BTC"}, "subtotal"=>{"amount"=>"13.50", "currency"=>"USD"}, "total"=>{"amount"=>"13.21", "currency"=>"USD"}}}
|
319
|
+
fake :post, "/sells", response
|
320
|
+
r = @c.sell! 1
|
321
|
+
r.success?.should == true
|
322
|
+
r.transfer.code.should == 'RD2OC8AL'
|
323
|
+
r.transfer.status.should == 'created'
|
324
|
+
r.transfer.btc.should == 1.to_money("BTC")
|
325
|
+
end
|
326
|
+
|
327
|
+
# Transfers
|
328
|
+
|
329
|
+
it "should get recent transfers" do
|
330
|
+
response = {"transfers" => [{"transfer" => {"type" => "Buy", "code" => "QPCUCZHR", "created_at" => "2013-02-27T23:28:18-08:00", "fees" => {"coinbase" => {"cents" => 14, "currency_iso" => "USD"}, "bank" => {"cents" => 15, "currency_iso" => "USD"} }, "payout_date" => "2013-03-05T18:00:00-08:00", "transaction_id" => "5011f33df8182b142400000e", "status" => "Pending", "btc" => {"amount" => "1.00000000", "currency" => "BTC"}, "subtotal" => {"amount" => "13.55", "currency" => "USD"}, "total" => {"amount" => "13.84", "currency" => "USD"}, "description" => "Paid for with $13.84 from Test xxxxx3111."} } ], "total_count" => 1, "num_pages" => 1, "current_page" => 1 }
|
331
|
+
fake :get, "/transfers", response
|
332
|
+
r = @c.transfers
|
333
|
+
t = r.transfers.first.transfer
|
334
|
+
t.type.should == "Buy"
|
335
|
+
t.code.should == "QPCUCZHR"
|
336
|
+
t.status.should == "Pending"
|
337
|
+
t.btc.should == 1.to_money("BTC")
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should support pagination" do
|
341
|
+
response = {"transfers" => [{"transfer" => {"type" => "Buy", "code" => "QPCUCZHZ", "created_at" => "2013-02-27T23:28:18-08:00", "fees" => {"coinbase" => {"cents" => 14, "currency_iso" => "USD"}, "bank" => {"cents" => 15, "currency_iso" => "USD"} }, "payout_date" => "2013-03-05T18:00:00-08:00", "transaction_id" => "5011f33df8182b142400000e", "status" => "Pending", "btc" => {"amount" => "1.00000000", "currency" => "BTC"}, "subtotal" => {"amount" => "13.55", "currency" => "USD"}, "total" => {"amount" => "13.84", "currency" => "USD"}, "description" => "Paid for with $13.84 from Test xxxxx3111."} } ], "total_count" => 1, "num_pages" => 1, "current_page" => 1 }
|
342
|
+
fake :get, "/transfers?page=2", response
|
343
|
+
r = @c.transfers :page => 2
|
344
|
+
t = r.transfers.first.transfer
|
345
|
+
t.type.should == "Buy"
|
346
|
+
t.code.should == "QPCUCZHZ"
|
347
|
+
t.status.should == "Pending"
|
348
|
+
t.btc.should == 1.to_money("BTC")
|
349
|
+
FakeWeb.last_request.path.should include("page=2")
|
350
|
+
end
|
351
|
+
|
352
|
+
# Addresses
|
353
|
+
|
354
|
+
it 'should read addresses json' do
|
355
|
+
raw_addresses = <<-eos
|
356
|
+
{
|
357
|
+
"addresses": [
|
358
|
+
{
|
359
|
+
"address": {
|
360
|
+
"address": "moLxGrqWNcnGq4A8Caq8EGP4n9GUGWanj4",
|
361
|
+
"callback_url": null,
|
362
|
+
"label": "My Label",
|
363
|
+
"created_at": "2013-05-09T23:07:08-07:00"
|
364
|
+
}
|
365
|
+
},
|
366
|
+
{
|
367
|
+
"address": {
|
368
|
+
"address": "mwigfecvyG4MZjb6R5jMbmNcs7TkzhUaCj",
|
369
|
+
"callback_url": null,
|
370
|
+
"label": null,
|
371
|
+
"created_at": "2013-05-09T17:50:37-07:00"
|
372
|
+
}
|
373
|
+
}
|
374
|
+
],
|
375
|
+
"total_count": 2,
|
376
|
+
"num_pages": 1,
|
377
|
+
"current_page": 1
|
378
|
+
}
|
379
|
+
eos
|
380
|
+
|
381
|
+
fake :get, '/addresses?page=1', JSON.parse(raw_addresses)
|
382
|
+
|
383
|
+
r = @c.addresses
|
384
|
+
r.total_count.should == 2
|
385
|
+
r.num_pages.should == 1
|
386
|
+
r.current_page.should == 1
|
387
|
+
r.addresses.size.should == 2
|
388
|
+
r.addresses.first.address.address.should == 'moLxGrqWNcnGq4A8Caq8EGP4n9GUGWanj4'
|
389
|
+
r.addresses.first.address.callback_url.should == nil
|
390
|
+
r.addresses.first.address.label.should == 'My Label'
|
391
|
+
r.addresses.first.addresscreated_at == '2013-05-09T23:07:08-07:00'
|
392
|
+
r.addresses[1].address.address.should == 'mwigfecvyG4MZjb6R5jMbmNcs7TkzhUaCj'
|
393
|
+
r.addresses[1].address.callback_url.should == nil
|
394
|
+
r.addresses[1].address.label.should == nil
|
395
|
+
r.addresses[1].address.created_at.should == '2013-05-09T17:50:37-07:00'
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'should get a list of currency exchanges' do
|
399
|
+
response = {'gbp_to_usd'=>'1.633667', 'usd_to_bwp'=>'8.62852', 'usd_to_azn'=>'0.784167', 'eur_to_usd'=>'1.35924', 'usd_to_czk'=>'20.11621', 'czk_to_btc'=>'5.6e-05', 'btc_to_mga'=>'1999686.885067', 'btc_to_djf'=>'158147.411834', 'idr_to_btc'=>'0.0', 'mnt_to_usd'=>'0.00058', 'usd_to_ngn'=>'158.682199', 'usd_to_gbp'=>'0.61212', 'irr_to_btc'=>'0.0', 'ils_to_usd'=>'0.282751', 'ars_to_usd'=>'0.163763', 'usd_to_uyu'=>'21.16168', 'uyu_to_btc'=>'5.3e-05', 'pyg_to_btc'=>'0.0', 'usd_to_yer'=>'215.006099', 'pgk_to_usd'=>'0.387254', 'xcd_to_btc'=>'0.000416', 'usd_to_fjd'=>'1.870015', 'dop_to_btc'=>'2.7e-05', 'mvr_to_usd'=>'0.06503', 'eek_to_usd'=>'0.085636', 'nzd_to_btc'=>'0.000918', 'gnf_to_btc'=>'0.0', 'usd_to_gtq'=>'7.88508', 'bmd_to_usd'=>'1.0', 'btc_to_lbp'=>'1338220.674541', 'usd_to_omr'=>'0.385012', 'usd_to_sos'=>'1207.4067', 'usd_to_thb'=>'32.11708', 'srd_to_btc'=>'0.000343', 'btc_to_all'=>'91888.63729', 'usd_to_vnd'=>'21106.95', 'htg_to_usd'=>'0.025083', 'btc_to_bmd'=>'888.93805', 'kpw_to_usd'=>'0.0', 'lyd_to_usd'=>'0.804161', 'tzs_to_btc'=>'1.0e-06', 'lak_to_usd'=>'0.000125', 'usd_to_idr'=>'11907.583333', 'btc_to_bzd'=>'1770.195675', 'usd_to_gel'=>'1.6904', 'usd_to_kzt'=>'153.658001', 'uah_to_usd'=>'0.121707', 'usd_to_lkr'=>'131.201499', 'btc_to_zwl'=>'286553.630441', 'php_to_btc'=>'2.6e-05', 'ron_to_usd'=>'0.306263', 'btc_to_kyd'=>'734.803304', 'btc_to_cad'=>'940.246665', 'hkd_to_btc'=>'0.000145', 'usd_to_btc'=>'0.001125', 'nok_to_btc'=>'0.000185', 'top_to_usd'=>'0.548145', 'btc_to_xpf'=>'78126.987338', 'usd_to_kgs'=>'48.862875', 'usd_to_bnd'=>'1.25468', 'dzd_to_usd'=>'0.012516', 'vef_to_btc'=>'0.000179', 'usd_to_ars'=>'6.106376', 'syp_to_btc'=>'8.0e-06', 'ngn_to_btc'=>'7.0e-06', 'bgn_to_btc'=>'0.000782', 'lak_to_btc'=>'0.0', 'btc_to_cve'=>'71977.305019', 'mga_to_btc'=>'1.0e-06', 'idr_to_usd'=>'8.4e-05', 'btc_to_htg'=>'35439.725263', 'btc_to_ils'=>'3143.884978', 'mad_to_btc'=>'0.000136', 'usd_to_hnl'=>'20.52386', 'svc_to_btc'=>'0.000129', 'btc_to_ang'=>'1590.274614', 'hkd_to_usd'=>'0.12899', 'usd_to_nad'=>'10.20123', 'szl_to_btc'=>'0.00011', 'etb_to_usd'=>'0.052406', 'pkr_to_btc'=>'1.0e-05', 'usd_to_khr'=>'4003.966833', 'gnf_to_usd'=>'0.000144', 'btc_to_myr'=>'2870.615643', 'btc_to_top'=>'1621.720797', 'nad_to_btc'=>'0.00011', 'huf_to_usd'=>'0.004546', 'mkd_to_btc'=>'2.5e-05', 'lkr_to_btc'=>'9.0e-06', 'svc_to_usd'=>'0.114311', 'btc_to_lyd'=>'1105.422911', 'usd_to_bam'=>'1.440026', 'usd_to_svc'=>'8.74805', 'usd_to_tzs'=>'1609.666667', 'gbp_to_btc'=>'0.001838', 'btc_to_mop'=>'7097.761418', 'btc_to_jod'=>'629.416142', 'clp_to_usd'=>'0.001896', 'cad_to_usd'=>'0.945431', 'cny_to_btc'=>'0.000184', 'jod_to_btc'=>'0.001589', 'syp_to_usd'=>'0.007141', 'lvl_to_btc'=>'0.002175', 'btc_to_cny'=>'5422.419877', 'shp_to_btc'=>'0.001838', 'vef_to_usd'=>'0.158944', 'php_to_usd'=>'0.022869', 'mro_to_usd'=>'0.003427', 'tjs_to_btc'=>'0.000236', 'fkp_to_btc'=>'0.001838', 'bdt_to_usd'=>'0.012869', 'mkd_to_usd'=>'0.021979', 'lrd_to_usd'=>'0.012418', 'usd_to_kes'=>'87.034389', 'btc_to_ars'=>'5428.189974', 'usd_to_chf'=>'0.906341', 'usd_to_lak'=>'7987.781667', 'usd_to_bzd'=>'1.99136', 'usd_to_nzd'=>'1.225977', 'mvr_to_btc'=>'7.3e-05', 'usd_to_wst'=>'2.344837', 'nok_to_usd'=>'0.164135', 'tjs_to_usd'=>'0.209516', 'bob_to_usd'=>'0.144729', 'btc_to_cup'=>'20163.676005', 'afn_to_btc'=>'2.0e-05', 'vnd_to_btc'=>'0.0', 'bnd_to_usd'=>'0.797016', 'byr_to_btc'=>'0.0', 'aed_to_btc'=>'0.000306', 'hnl_to_btc'=>'5.5e-05', 'mmk_to_usd'=>'0.001018', 'zmk_to_btc'=>'0.0', 'usd_to_myr'=>'3.229264', 'usd_to_ils'=>'3.536675', 'usd_to_mdl'=>'13.1323', 'djf_to_usd'=>'0.005621', 'mnt_to_btc'=>'1.0e-06', 'usd_to_sbd'=>'7.143096', 'lbp_to_usd'=>'0.000664', 'aoa_to_btc'=>'1.2e-05', 'btc_to_vnd'=>'18762770.974447', 'btc_to_lak'=>'7100643.058889', 'dkk_to_usd'=>'0.182213', 'inr_to_btc'=>'1.8e-05', 'lrd_to_btc'=>'1.4e-05', 'pab_to_btc'=>'0.001125', 'usd_to_mga'=>'2249.523333', 'btc_to_awg'=>'1591.065769', 'usd_to_try'=>'2.015658', 'usd_to_qar'=>'3.641038', 'usd_to_lvl'=>'0.517161', 'bmd_to_btc'=>'0.001125', 'vuv_to_btc'=>'1.2e-05', 'usd_to_pen'=>'2.80238', 'usd_to_zmk'=>'5253.075255', 'usd_to_ttd'=>'6.41373', 'mwk_to_btc'=>'3.0e-06', 'btc_to_scr'=>'10736.55821', 'egp_to_btc'=>'0.000163', 'bam_to_btc'=>'0.000781', 'usd_to_kmf'=>'362.286958', 'btc_to_aed'=>'3264.928117', 'usd_to_shp'=>'0.61212', 'bbd_to_btc'=>'0.0', 'kes_to_usd'=>'0.01149', 'jpy_to_btc'=>'1.1e-05', 'wst_to_usd'=>'0.426469', 'gyd_to_usd'=>'0.004843', 'kgs_to_btc'=>'2.3e-05', 'btc_to_eek'=>'10380.418515', 'usd_to_php'=>'43.72676', 'sdg_to_usd'=>'0.225802', 'usd_to_isk'=>'120.165', 'scr_to_btc'=>'9.3e-05', 'cup_to_usd'=>'0.044086', 'std_to_btc'=>'0.0', 'usd_to_gip'=>'0.61212', 'usd_to_aud'=>'1.0963', 'usd_to_dzd'=>'79.89655', 'usd_to_xaf'=>'483.051199', 'usd_to_mro'=>'291.7967', 'clp_to_btc'=>'2.0e-06', 'bbd_to_usd'=>'0.0', 'mdl_to_btc'=>'8.6e-05', 'btc_to_pyg'=>'3929049.928111', 'xof_to_btc'=>'2.0e-06', 'kzt_to_btc'=>'7.0e-06', 'usd_to_irr'=>'24785.667967', 'usd_to_vuv'=>'96.5375', 'bif_to_btc'=>'1.0e-06', 'btc_to_gtq'=>'7009.347639', 'usd_to_bif'=>'1551.3184', 'btc_to_xof'=>'429968.666639', 'btc_to_ghs'=>'2020.911763', 'btc_to_kes'=>'77368.180041', 'usd_to_bbd'=>'2', 'usd_to_afn'=>'57.430025', 'usd_to_sdg'=>'4.428657', 'uzs_to_usd'=>'0.00046', 'btc_to_dzd'=>'71023.083359', 'btc_to_uyu'=>'18811.422554', 'usd_to_mnt'=>'1725.083333', 'egp_to_usd'=>'0.145211', 'btc_to_nio'=>'22379.602108', 'usd_to_mur'=>'30.35621', 'usd_to_fkp'=>'0.61212', 'twd_to_usd'=>'0.033739', 'btc_to_bif'=>'1379025.953425', 'nio_to_btc'=>'4.5e-05', 'bhd_to_usd'=>'2.652604', 'aoa_to_usd'=>'0.010273', 'tmm_to_usd'=>'0.350652', 'btc_to_bhd'=>'335.118978', 'kyd_to_btc'=>'0.001361', 'usd_to_mzn'=>'29.89945', 'jmd_to_btc'=>'1.1e-05', 'lbp_to_btc'=>'1.0e-06', 'btc_to_ngn'=>'141058.644549', 'sek_to_btc'=>'0.000171', 'try_to_usd'=>'0.496116', 'btc_to_mkd'=>'40444.556713', 'btc_to_gbp'=>'544.136759', 'aud_to_btc'=>'0.001026', 'xpf_to_usd'=>'0.011378', 'bzd_to_btc'=>'0.000565', 'usd_to_cdf'=>'921.303003', 'btc_to_bdt'=>'69075.748998', 'cup_to_btc'=>'5.0e-05', 'usd_to_lsl'=>'10.19269', 'btc_to_tnd'=>'1481.973513', 'btc_to_pln'=>'2744.550005', 'usd_to_btn'=>'62.405663', 'zar_to_btc'=>'0.00011', 'bob_to_btc'=>'0.000163', 'usd_to_top'=>'1.824335', 'amd_to_btc'=>'3.0e-06', 'btc_to_syp'=>'124475.771907', 'szl_to_usd'=>'0.098101', 'gip_to_usd'=>'1.633667', 'usd_to_mvr'=>'15.37749', 'thb_to_usd'=>'0.031136', 'bgn_to_usd'=>'0.694751', 'btc_to_gnf'=>'6165712.835153', 'rwf_to_btc'=>'2.0e-06', 'cny_to_usd'=>'0.163938', 'btc_to_mzn'=>'26578.758779', 'btc_to_bob'=>'6142.090788', 'btc_to_etb'=>'16962.395852', 'ern_to_usd'=>'0.066235', 'mmk_to_btc'=>'1.0e-06', 'btc_to_uzs'=>'1931941.125176', 'usd_to_kwd'=>'0.282781', 'btc_to_twd'=>'26347.794895', 'usd_to_clp'=>'527.4221', 'ghs_to_usd'=>'0.43987', 'brl_to_btc'=>'0.000485', 'btc_to_try'=>'1791.795092', 'usd_to_dkk'=>'5.488097', 'myr_to_btc'=>'0.000348', 'btc_to_svc'=>'7776.474508', 'kmf_to_btc'=>'3.0e-06', 'mxn_to_btc'=>'8.6e-05', 'nio_to_usd'=>'0.039721', 'uah_to_btc'=>'0.000137', 'ttd_to_btc'=>'0.000175', 'usd_to_sgd'=>'1.254902', 'usd_to_hrk'=>'5.615268', 'btc_to_thb'=>'28550.094467', 'mwk_to_usd'=>'0.002446', 'btc_to_aud'=>'974.542784', 'btc_to_vuv'=>'85815.857002', 'btc_to_php'=>'38870.380767', 'pyg_to_usd'=>'0.000226', 'scr_to_usd'=>'0.082795', 'btc_to_kwd'=>'251.374791', 'ugx_to_usd'=>'0.000396', 'btc_to_gmd'=>'33591.155476', 'zwl_to_btc'=>'3.0e-06', 'btc_to_zar'=>'9069.212668', 'btc_to_hkd'=>'6891.55268', 'btc_to_afn'=>'51051.734435', 'btc_to_fkp'=>'544.136759', 'xaf_to_btc'=>'2.0e-06', 'usd_to_nok'=>'6.092554', 'btc_to_kzt'=>'136592.443776', 'btc_to_btn'=>'55474.768376', 'amd_to_usd'=>'0.002449', 'usd_to_syp'=>'140.027499', 'usd_to_jpy'=>'102.181201', 'usd_to_sek'=>'6.570703', 'btc_to_clp'=>'468845.573101', 'sgd_to_usd'=>'0.796875', 'btc_to_qar'=>'3236.65722', 'czk_to_usd'=>'0.049711', 'usd_to_aoa'=>'97.343626', 'krw_to_usd'=>'0.000942', 'sar_to_usd'=>'0.266627', 'hnl_to_usd'=>'0.048724', 'bwp_to_usd'=>'0.115895', 'usd_to_brl'=>'2.319796', 'btc_to_bbd'=>'1777.8761', 'ngn_to_usd'=>'0.006302', 'azn_to_usd'=>'1.275239', 'btc_to_mnt'=>'1533492.214125', 'usd_to_rub'=>'33.12431', 'btc_to_lvl'=>'459.724091', 'usd_to_ron'=>'3.265171', 'btc_to_azn'=>'697.075884', 'sll_to_usd'=>'0.000232', 'usd_to_dop'=>'42.3681', 'pab_to_usd'=>'1.0', 'pkr_to_usd'=>'0.009223', 'usd_to_scr'=>'12.07796', 'usd_to_huf'=>'219.952799', 'bdt_to_btc'=>'1.4e-05', 'btc_to_crc'=>'439769.207752', 'std_to_usd'=>'5.5e-05', 'mzn_to_usd'=>'0.033445', 'mzn_to_btc'=>'3.8e-05', 'nzd_to_usd'=>'0.815676', 'btc_to_npr'=>'88656.014961', 'btc_to_bwp'=>'7670.219743', 'kwd_to_usd'=>'3.536305', 'omr_to_usd'=>'2.597322', 'btc_to_rwf'=>'600360.508519', 'kgs_to_usd'=>'0.020465', 'afn_to_usd'=>'0.017412', 'btc_to_egp'=>'6121.693216', 'aud_to_usd'=>'0.912159', 'usd_to_mwk'=>'408.8331', 'usd_to_cny'=>'6.099885', 'rwf_to_usd'=>'0.001481', 'usd_to_zwl'=>'322.355006', 'btc_to_cdf'=>'818981.294946', 'usd_to_tjs'=>'4.7729', 'usd_to_all'=>'103.369', 'bhd_to_btc'=>'0.002984', 'kpw_to_btc'=>'0.0', 'bam_to_usd'=>'0.694432', 'btc_to_szl'=>'9061.452238', 'usd_to_pyg'=>'4419.936719', 'gel_to_btc'=>'0.000666', 'xcd_to_usd'=>'0.370165', 'usd_to_lrd'=>'80.528251', 'sos_to_usd'=>'0.000828', 'usd_to_uzs'=>'2173.313568', 'btc_to_fjd'=>'1662.327488', 'btc_to_iqd'=>'1034670.598364', 'usd_to_bsd'=>'1', 'cve_to_btc'=>'1.4e-05', 'rub_to_btc'=>'3.4e-05', 'usd_to_rsd'=>'83.906211', 'sar_to_btc'=>'0.0003', 'eek_to_btc'=>'9.6e-05', 'btc_to_ugx'=>'2244746.378083', 'awg_to_btc'=>'0.000629', 'btc_to_mwk'=>'363427.298689', 'huf_to_btc'=>'5.0e-06', 'ang_to_usd'=>'0.558984', 'usd_to_djf'=>'177.905999', 'usd_to_cad'=>'1.057719', 'btc_to_brl'=>'2062.154933', 'usd_to_ern'=>'15.097825', 'iqd_to_btc'=>'1.0e-06', 'btc_to_pgk'=>'2295.489615', 'usd_to_xcd'=>'2.7015', 'btn_to_btc'=>'1.8e-05', 'myr_to_usd'=>'0.309668', 'lsl_to_usd'=>'0.09811', 'crc_to_usd'=>'0.002021', 'usd_to_egp'=>'6.886524', 'btc_to_rsd'=>'74587.423589', 'gel_to_usd'=>'0.591576', 'jmd_to_usd'=>'0.009719', 'btc_to_ltl'=>'2258.393341', 'lyd_to_btc'=>'0.000905', 'nad_to_usd'=>'0.098027', 'usd_to_kyd'=>'0.826608', 'btc_to_bsd'=>'888.93805', 'ltl_to_btc'=>'0.000443', 'usd_to_srd'=>'3.283333', 'usd_to_awg'=>'1.78985', 'usd_to_szl'=>'10.19357', 'chf_to_btc'=>'0.001241', 'zwl_to_usd'=>'0.003102', 'sll_to_btc'=>'0.0', 'usd_to_cop'=>'1927.433333', 'usd_to_tmm'=>'2.851833', 'btc_to_tjs'=>'4242.812419', 'sbd_to_btc'=>'0.000157', 'ern_to_btc'=>'7.5e-05', 'btc_to_bam'=>'1280.093904', 'btc_to_gip'=>'544.136759', 'sbd_to_usd'=>'0.139995', 'mad_to_usd'=>'0.121088', 'btc_to_ern'=>'13421.031115', 'usd_to_ltl'=>'2.540552', 'qar_to_usd'=>'0.274647', 'usd_to_kpw'=>'900', 'usd_to_crc'=>'494.712998', 'usd_to_xpf'=>'87.888', 'yer_to_btc'=>'5.0e-06', 'chf_to_usd'=>'1.103337', 'jpy_to_usd'=>'0.009787', 'ars_to_btc'=>'0.000184', 'usd_to_pgk'=>'2.582283', 'gyd_to_btc'=>'5.0e-06', 'aed_to_usd'=>'0.272269', 'usd_to_mop'=>'7.98454', 'usd_to_aed'=>'3.672841', 'qar_to_btc'=>'0.000309', 'btc_to_sll'=>'3837842.02269', 'btc_to_dkk'=>'4878.578245', 'gtq_to_usd'=>'0.126822', 'sos_to_btc'=>'1.0e-06', 'dop_to_usd'=>'0.023603', 'awg_to_usd'=>'0.558706', 'btc_to_gel'=>'1502.66088', 'btc_to_lkr'=>'116630.004678', 'btc_to_lrd'=>'71584.626414', 'khr_to_usd'=>'0.00025', 'btc_to_hrk'=>'4991.625386', 'usd_to_etb'=>'19.08164', 'btc_to_sos'=>'1073309.757455', 'btc_to_eur'=>'653.996168', 'usd_to_krw'=>'1061.26498', 'btc_to_dop'=>'37662.616196', 'usd_to_bob'=>'6.90947', 'btc_to_kgs'=>'43436.06882', 'cve_to_usd'=>'0.01235', 'fjd_to_usd'=>'0.534755', 'btc_to_jpy'=>'90832.757564', 'btc_to_omr'=>'342.251817', 'usd_to_gyd'=>'206.501249', 'pen_to_btc'=>'0.000401', 'btc_to_jmd'=>'91465.502779', 'npr_to_usd'=>'0.010027', 'usd_to_tnd'=>'1.667128', 'usd_to_twd'=>'29.63963', 'btc_to_nad'=>'9068.261504', 'azn_to_btc'=>'0.001435', 'btc_to_sgd'=>'1115.530137', 'twd_to_btc'=>'3.8e-05', 'btc_to_sek'=>'5840.947912', 'inr_to_usd'=>'0.016031', 'crc_to_btc'=>'2.0e-06', 'usd_to_mxn'=>'13.10359', 'xaf_to_usd'=>'0.00207', 'btc_to_idr'=>'10585103.90825', 'btc_to_hnl'=>'18244.440087', 'eur_to_btc'=>'0.001529', 'btc_to_sbd'=>'6349.769829', 'hrk_to_usd'=>'0.178086', 'pln_to_btc'=>'0.000364', 'gtq_to_btc'=>'0.000143', 'zmk_to_usd'=>'0.00019', 'thb_to_btc'=>'3.5e-05', 'btc_to_mvr'=>'13669.635974', 'ghs_to_btc'=>'0.000495', 'usd_to_gmd'=>'37.78796', 'usd_to_mkd'=>'45.49761', 'usd_to_eur'=>'0.735705', 'cop_to_btc'=>'1.0e-06', 'btc_to_xcd'=>'2401.466142', 'sdg_to_btc'=>'0.000254', 'btc_to_nzd'=>'1089.817604', 'usd_to_uah'=>'8.21647', 'rsd_to_btc'=>'1.3e-05', 'cdf_to_btc'=>'1.0e-06', 'btn_to_usd'=>'0.016024', 'krw_to_btc'=>'1.0e-06', 'tzs_to_usd'=>'0.000621', 'pgk_to_btc'=>'0.000436', 'btc_to_byr'=>'8303422.168412', 'bsd_to_usd'=>'1.0', 'irr_to_usd'=>'4.0e-05', 'uyu_to_usd'=>'0.047255', 'mop_to_btc'=>'0.000141', 'usd_to_ghs'=>'2.2734', 'btc_to_khr'=>'3559278.468792', 'kyd_to_usd'=>'1.209763', 'btc_to_zmk'=>'4669658.473683', 'cop_to_usd'=>'0.000519', 'btc_to_mad'=>'7341.276218', 'try_to_btc'=>'0.000558', 'xpf_to_btc'=>'1.3e-05', 'kzt_to_usd'=>'0.006508', 'usd_to_bhd'=>'0.376988', 'top_to_btc'=>'0.000617', 'ugx_to_btc'=>'0.0', 'usd_to_mmk'=>'982.69002', 'usd_to_jod'=>'0.708054', 'btc_to_vef'=>'5592.762631', 'gip_to_btc'=>'0.001838', 'btc_to_mmk'=>'873550.550133', 'usd_to_xof'=>'483.687999', 'wst_to_btc'=>'0.00048', 'mdl_to_usd'=>'0.076148', 'ltl_to_usd'=>'0.393615', 'bnd_to_btc'=>'0.000897', 'usd_to_sll'=>'4317.3335', 'usd_to_nio'=>'25.17566', 'btc_to_mro'=>'259389.189494', 'srd_to_usd'=>'0.304569', 'usd_to_lbp'=>'1505.415', 'btc_to_pkr'=>'96380.691049', 'rsd_to_usd'=>'0.011918', 'sgd_to_btc'=>'0.000896', 'yer_to_usd'=>'0.004651', 'lvl_to_usd'=>'1.933634', 'usd_to_ang'=>'1.78896', 'usd_to_sar'=>'3.750561', 'usd_to_iqd'=>'1163.94005', 'btc_to_kmf'=>'322050.661985', 'usd_to_bmd'=>'1', 'kes_to_btc'=>'1.3e-05', 'btc_to_irr'=>'22032923.350532', 'btc_to_aoa'=>'86532.453076', 'btc_to_shp'=>'544.136759', 'btc_to_sdg'=>'3936.801718', 'kmf_to_usd'=>'0.00276', 'btc_to_krw'=>'943398.821854', 'btc_to_srd'=>'2918.679635', 'usd_to_bdt'=>'77.70592', 'usd_to_zar'=>'10.2023', 'bwp_to_btc'=>'0.00013', 'byr_to_usd'=>'0.000107', 'vnd_to_usd'=>'4.7e-05', 'usd_to_cve'=>'80.96999', 'btc_to_btc'=>'1.000055', 'btc_to_pen'=>'2491.142213', 'usd_to_hkd'=>'7.752568', 'isk_to_btc'=>'9.0e-06', 'pen_to_usd'=>'0.35684', 'btc_to_kpw'=>'800044.245', 'btc_to_tmm'=>'0.0', 'bzd_to_usd'=>'0.502169', 'npr_to_btc'=>'1.1e-05', 'btc_to_chf'=>'805.681001', 'btc_to_bgn'=>'1279.506316', 'btc_to_uah'=>'7303.93282', 'pln_to_usd'=>'0.323892', 'btc_to_inr'=>'55450.142125', 'htg_to_btc'=>'2.8e-05', 'btc_to_wst'=>'2084.41483', 'btc_to_ron'=>'2902.534742', 'xof_to_usd'=>'0.002067', 'btc_to_mur'=>'26984.790123', 'usd_to_rwf'=>'675.36822', 'usd_to_pab'=>'1', 'btc_to_mxn'=>'11648.279743', 'all_to_btc'=>'1.1e-05', 'dkk_to_btc'=>'0.000205', 'usd_to_ugx'=>'2525.200016', 'tnd_to_usd'=>'0.599834', 'usd_to_lyd'=>'1.243532', 'usd_to_pkr'=>'108.422281', 'omr_to_btc'=>'0.002922', 'mga_to_usd'=>'0.000445', 'mur_to_btc'=>'3.7e-05', 'usd_to_amd'=>'408.364003', 'jod_to_usd'=>'1.412322', 'tnd_to_btc'=>'0.000675', 'shp_to_usd'=>'1.633667', 'vuv_to_usd'=>'0.010359', 'khr_to_btc'=>'0.0', 'usd_to_htg'=>'39.867486', 'iqd_to_usd'=>'0.000859', 'btc_to_sar'=>'3334.016382', 'mur_to_usd'=>'0.032942', 'lsl_to_btc'=>'0.00011', 'usd_to_jmd'=>'102.893', 'ils_to_btc'=>'0.000318', 'zar_to_usd'=>'0.098017', 'usd_to_pln'=>'3.087448', 'bsd_to_btc'=>'0.001125', 'btc_to_rub'=>'29445.459539', 'usd_to_mad'=>'8.258479', 'usd_to_inr'=>'62.37796', 'btc_to_czk'=>'17882.064491', 'isk_to_usd'=>'0.008322', 'rub_to_usd'=>'0.030189', 'usd_to_usd'=>'1.0', 'fkp_to_usd'=>'1.633667', 'all_to_usd'=>'0.009674', 'mop_to_usd'=>'0.125242', 'usd_to_cup'=>'22.682881', 'mro_to_btc'=>'4.0e-06', 'tmm_to_btc'=>'0.0', 'fjd_to_btc'=>'0.000602', 'usd_to_gnf'=>'6936.043333', 'btc_to_huf'=>'195524.412235', 'usd_to_byr'=>'9340.833333', 'usd_to_bgn'=>'1.439365', 'ang_to_btc'=>'0.000629', 'gmd_to_usd'=>'0.026463', 'bif_to_usd'=>'0.000645', 'etb_to_btc'=>'5.9e-05', 'usd_to_std'=>'18145.400667', 'btc_to_std'=>'16130137.085392', 'btc_to_ttd'=>'5701.408639', 'ron_to_btc'=>'0.000345', 'gmd_to_btc'=>'3.0e-05', 'kwd_to_btc'=>'0.003978', 'btc_to_amd'=>'363010.300517', 'btc_to_gyd'=>'183566.817609', 'btc_to_nok'=>'5415.903072', 'btc_to_yer'=>'191127.102383', 'cdf_to_usd'=>'0.001085', 'btc_to_usd'=>'888.9380499999999', 'hrk_to_btc'=>'0.0002', 'btc_to_xaf'=>'429402.590889', 'btc_to_bnd'=>'1115.332793', 'btc_to_lsl'=>'9060.669973', 'usd_to_eek'=>'11.677325', 'brl_to_usd'=>'0.431072', 'lkr_to_usd'=>'0.007622', 'btc_to_pab'=>'888.93805', 'ttd_to_usd'=>'0.155916', 'btc_to_cop'=>'1713368.828542', 'btc_to_isk'=>'106819.240778', 'uzs_to_btc'=>'1.0e-06', 'mxn_to_usd'=>'0.076315', 'btc_to_mdl'=>'11673.801154', 'djf_to_btc'=>'6.0e-06', 'usd_to_npr'=>'99.732501', 'btc_to_tzs'=>'1430893.948113', 'usd_to_vef'=>'6.29151', 'cad_to_btc'=>'0.001064', 'dzd_to_btc'=>'1.4e-05', 'sek_to_usd'=>'0.152191'}
|
400
|
+
fake :get, '/currencies/exchange_rates', response
|
401
|
+
r = @c.exchange_rates
|
402
|
+
r.usd_to_btc.should == '0.001125'
|
403
|
+
r.btc_to_usd.should == '888.9380499999999'
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'should let you get short list of accepted currencies' do
|
407
|
+
response = "[['Afghan Afghani (AFN)','AFN'],['Albanian Lek (ALL)','ALL'],['Algerian Dinar (DZD)','DZD'],['Angolan Kwanza (AOA)','AOA'],['Argentine Peso (ARS)','ARS'],['Armenian Dram (AMD)','AMD'],['Aruban Florin (AWG)','AWG'],['Australian Dollar (AUD)','AUD'],['Azerbaijani Manat (AZN)','AZN'],['Bahamian Dollar (BSD)','BSD'],['Bahraini Dinar (BHD)','BHD'],['Bangladeshi Taka (BDT)','BDT'],['Barbadian Dollar (BBD)','BBD'],['Belarusian Ruble (BYR)','BYR'],['Belize Dollar (BZD)','BZD'],['Bermudian Dollar (BMD)','BMD'],['Bhutanese Ngultrum (BTN)','BTN'],['Bolivian Boliviano (BOB)','BOB'],['Bosnia and Herzegovina Convertible Mark (BAM)','BAM'],['Botswana Pula (BWP)','BWP'],['Brazilian Real (BRL)','BRL'],['British Pound (GBP)','GBP'],['Brunei Dollar (BND)','BND'],['Bulgarian Lev (BGN)','BGN'],['Burundian Franc (BIF)','BIF'],['Cambodian Riel (KHR)','KHR'],['Canadian Dollar (CAD)','CAD'],['Cape Verdean Escudo (CVE)','CVE'],['Cayman Islands Dollar (KYD)','KYD'],['Central African Cfa Franc (XAF)','XAF'],['Cfp Franc (XPF)','XPF'],['Chilean Peso (CLP)','CLP'],['Chinese Renminbi Yuan (CNY)','CNY'],['Colombian Peso (COP)','COP'],['Comorian Franc (KMF)','KMF'],['Congolese Franc (CDF)','CDF'],['Costa Rican Col\u00f3n (CRC)','CRC'],['Croatian Kuna (HRK)','HRK'],['Cuban Peso (CUP)','CUP'],['Czech Koruna (CZK)','CZK'],['Danish Krone (DKK)','DKK'],['Djiboutian Franc (DJF)','DJF'],['Dominican Peso (DOP)','DOP'],['East Caribbean Dollar (XCD)','XCD'],['Egyptian Pound (EGP)','EGP'],['Eritrean Nakfa (ERN)','ERN'],['Estonian Kroon (EEK)','EEK'],['Ethiopian Birr (ETB)','ETB'],['Euro (EUR)','EUR'],['Falkland Pound (FKP)','FKP'],['Fijian Dollar (FJD)','FJD'],['Gambian Dalasi (GMD)','GMD'],['Georgian Lari (GEL)','GEL'],['Ghanaian Cedi (GHS)','GHS'],['Ghanaian Cedi (GHS)','GHS'],['Gibraltar Pound (GIP)','GIP'],['Guatemalan Quetzal (GTQ)','GTQ'],['Guinean Franc (GNF)','GNF'],['Guyanese Dollar (GYD)','GYD'],['Haitian Gourde (HTG)','HTG'],['Honduran Lempira (HNL)','HNL'],['Hong Kong Dollar (HKD)','HKD'],['Hungarian Forint (HUF)','HUF'],['Icelandic Kr\u00f3na (ISK)','ISK'],['Indian Rupee (INR)','INR'],['Indonesian Rupiah (IDR)','IDR'],['Iranian Rial (IRR)','IRR'],['Iraqi Dinar (IQD)','IQD'],['Israeli New Sheqel (ILS)','ILS'],['Jamaican Dollar (JMD)','JMD'],['Japanese Yen (JPY)','JPY'],['Japanese Yen (JPY)','JPY'],['Jordanian Dinar (JOD)','JOD'],['Kazakhstani Tenge (KZT)','KZT'],['Kenyan Shilling (KES)','KES'],['Kuwaiti Dinar (KWD)','KWD'],['Kyrgyzstani Som (KGS)','KGS'],['Lao Kip (LAK)','LAK'],['Latvian Lats (LVL)','LVL'],['Lebanese Pound (LBP)','LBP'],['Lesotho Loti (LSL)','LSL'],['Liberian Dollar (LRD)','LRD'],['Libyan Dinar (LYD)','LYD'],['Lithuanian Litas (LTL)','LTL'],['Macanese Pataca (MOP)','MOP'],['Macedonian Denar (MKD)','MKD'],['Malagasy Ariary (MGA)','MGA'],['Malawian Kwacha (MWK)','MWK'],['Malaysian Ringgit (MYR)','MYR'],['Maldivian Rufiyaa (MVR)','MVR'],['Mauritanian Ouguiya (MRO)','MRO'],['Mauritian Rupee (MUR)','MUR'],['Mexican Peso (MXN)','MXN'],['Moldovan Leu (MDL)','MDL'],['Mongolian T\u00f6gr\u00f6g (MNT)','MNT'],['Moroccan Dirham (MAD)','MAD'],['Mozambican Metical (MZN)','MZN'],['Myanmar Kyat (MMK)','MMK'],['Namibian Dollar (NAD)','NAD'],['Nepalese Rupee (NPR)','NPR'],['Netherlands Antillean Gulden (ANG)','ANG'],['New Taiwan Dollar (TWD)','TWD'],['New Zealand Dollar (NZD)','NZD'],['Nicaraguan C\u00f3rdoba (NIO)','NIO'],['Nigerian Naira (NGN)','NGN'],['North Korean Won (KPW)','KPW'],['Norwegian Krone (NOK)','NOK'],['Omani Rial (OMR)','OMR'],['Pakistani Rupee (PKR)','PKR'],['Panamanian Balboa (PAB)','PAB'],['Papua New Guinean Kina (PGK)','PGK'],['Paraguayan Guaran\u00ed (PYG)','PYG'],['Peruvian Nuevo Sol (PEN)','PEN'],['Philippine Peso (PHP)','PHP'],['Polish Z\u0142oty (PLN)','PLN'],['Qatari Riyal (QAR)','QAR'],['Romanian Leu (RON)','RON'],['Russian Ruble (RUB)','RUB'],['Rwandan Franc (RWF)','RWF'],['Saint Helenian Pound (SHP)','SHP'],['Salvadoran Col\u00f3n (SVC)','SVC'],['Samoan Tala (WST)','WST'],['Saudi Riyal (SAR)','SAR'],['Serbian Dinar (RSD)','RSD'],['Seychellois Rupee (SCR)','SCR'],['Sierra Leonean Leone (SLL)','SLL'],['Singapore Dollar (SGD)','SGD'],['Solomon Islands Dollar (SBD)','SBD'],['Somali Shilling (SOS)','SOS'],['South African Rand (ZAR)','ZAR'],['South Korean Won (KRW)','KRW'],['Sri Lankan Rupee (LKR)','LKR'],['Sudanese Pound (SDG)','SDG'],['Surinamese Dollar (SRD)','SRD'],['Swazi Lilangeni (SZL)','SZL'],['Swedish Krona (SEK)','SEK'],['Swiss Franc (CHF)','CHF'],['Syrian Pound (SYP)','SYP'],['S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra (STD)','STD'],['Tajikistani Somoni (TJS)','TJS'],['Tanzanian Shilling (TZS)','TZS'],['Thai Baht (THB)','THB'],['Tongan Pa\u02bbanga (TOP)','TOP'],['Trinidad and Tobago Dollar (TTD)','TTD'],['Tunisian Dinar (TND)','TND'],['Turkish Lira (TRY)','TRY'],['Turkmenistani Manat (TMM)','TMM'],['Turkmenistani Manat (TMM)','TMM'],['Ugandan Shilling (UGX)','UGX'],['Ukrainian Hryvnia (UAH)','UAH'],['United Arab Emirates Dirham (AED)','AED'],['United States Dollar (USD)','USD'],['Uruguayan Peso (UYU)','UYU'],['Uzbekistani Som (UZS)','UZS'],['Vanuatu Vatu (VUV)','VUV'],['Venezuelan Bol\u00edvar (VEF)','VEF'],['Vietnamese \u0110\u1ed3ng (VND)','VND'],['West African Cfa Franc (XOF)','XOF'],['Yemeni Rial (YER)','YER'],['Zambian Kwacha (ZMK)','ZMK'],['Zimbabwean Dollar (ZWL)','ZWL']]"
|
408
|
+
fake :get, '/currencies', response
|
409
|
+
r = @c.currencies_short
|
410
|
+
r.first.should == 'AFN'
|
411
|
+
r[1].should == 'ALL'
|
412
|
+
r.last.should == 'ZWL'
|
413
|
+
end
|
414
|
+
|
415
|
+
it 'should let you get long list of accepted currencies' do
|
416
|
+
response = '[["Afghan Afghani (AFN)","AFN"],["Albanian Lek (ALL)","ALL"],["Algerian Dinar (DZD)","DZD"],["Angolan Kwanza (AOA)","AOA"],["Argentine Peso (ARS)","ARS"],["Armenian Dram (AMD)","AMD"],["Aruban Florin (AWG)","AWG"],["Australian Dollar (AUD)","AUD"],["Azerbaijani Manat (AZN)","AZN"],["Bahamian Dollar (BSD)","BSD"],["Bahraini Dinar (BHD)","BHD"],["Bangladeshi Taka (BDT)","BDT"],["Barbadian Dollar (BBD)","BBD"],["Belarusian Ruble (BYR)","BYR"],["Belize Dollar (BZD)","BZD"],["Bermudian Dollar (BMD)","BMD"],["Bhutanese Ngultrum (BTN)","BTN"],["Bolivian Boliviano (BOB)","BOB"],["Bosnia and Herzegovina Convertible Mark (BAM)","BAM"],["Botswana Pula (BWP)","BWP"],["Brazilian Real (BRL)","BRL"],["British Pound (GBP)","GBP"],["Brunei Dollar (BND)","BND"],["Bulgarian Lev (BGN)","BGN"],["Burundian Franc (BIF)","BIF"],["Cambodian Riel (KHR)","KHR"],["Canadian Dollar (CAD)","CAD"],["Cape Verdean Escudo (CVE)","CVE"],["Cayman Islands Dollar (KYD)","KYD"],["Central African Cfa Franc (XAF)","XAF"],["Cfp Franc (XPF)","XPF"],["Chilean Peso (CLP)","CLP"],["Chinese Renminbi Yuan (CNY)","CNY"],["Colombian Peso (COP)","COP"],["Comorian Franc (KMF)","KMF"],["Congolese Franc (CDF)","CDF"],["Costa Rican Col\u00f3n (CRC)","CRC"],["Croatian Kuna (HRK)","HRK"],["Cuban Peso (CUP)","CUP"],["Czech Koruna (CZK)","CZK"],["Danish Krone (DKK)","DKK"],["Djiboutian Franc (DJF)","DJF"],["Dominican Peso (DOP)","DOP"],["East Caribbean Dollar (XCD)","XCD"],["Egyptian Pound (EGP)","EGP"],["Eritrean Nakfa (ERN)","ERN"],["Estonian Kroon (EEK)","EEK"],["Ethiopian Birr (ETB)","ETB"],["Euro (EUR)","EUR"],["Falkland Pound (FKP)","FKP"],["Fijian Dollar (FJD)","FJD"],["Gambian Dalasi (GMD)","GMD"],["Georgian Lari (GEL)","GEL"],["Ghanaian Cedi (GHS)","GHS"],["Ghanaian Cedi (GHS)","GHS"],["Gibraltar Pound (GIP)","GIP"],["Guatemalan Quetzal (GTQ)","GTQ"],["Guinean Franc (GNF)","GNF"],["Guyanese Dollar (GYD)","GYD"],["Haitian Gourde (HTG)","HTG"],["Honduran Lempira (HNL)","HNL"],["Hong Kong Dollar (HKD)","HKD"],["Hungarian Forint (HUF)","HUF"],["Icelandic Kr\u00f3na (ISK)","ISK"],["Indian Rupee (INR)","INR"],["Indonesian Rupiah (IDR)","IDR"],["Iranian Rial (IRR)","IRR"],["Iraqi Dinar (IQD)","IQD"],["Israeli New Sheqel (ILS)","ILS"],["Jamaican Dollar (JMD)","JMD"],["Japanese Yen (JPY)","JPY"],["Japanese Yen (JPY)","JPY"],["Jordanian Dinar (JOD)","JOD"],["Kazakhstani Tenge (KZT)","KZT"],["Kenyan Shilling (KES)","KES"],["Kuwaiti Dinar (KWD)","KWD"],["Kyrgyzstani Som (KGS)","KGS"],["Lao Kip (LAK)","LAK"],["Latvian Lats (LVL)","LVL"],["Lebanese Pound (LBP)","LBP"],["Lesotho Loti (LSL)","LSL"],["Liberian Dollar (LRD)","LRD"],["Libyan Dinar (LYD)","LYD"],["Lithuanian Litas (LTL)","LTL"],["Macanese Pataca (MOP)","MOP"],["Macedonian Denar (MKD)","MKD"],["Malagasy Ariary (MGA)","MGA"],["Malawian Kwacha (MWK)","MWK"],["Malaysian Ringgit (MYR)","MYR"],["Maldivian Rufiyaa (MVR)","MVR"],["Mauritanian Ouguiya (MRO)","MRO"],["Mauritian Rupee (MUR)","MUR"],["Mexican Peso (MXN)","MXN"],["Moldovan Leu (MDL)","MDL"],["Mongolian T\u00f6gr\u00f6g (MNT)","MNT"],["Moroccan Dirham (MAD)","MAD"],["Mozambican Metical (MZN)","MZN"],["Myanmar Kyat (MMK)","MMK"],["Namibian Dollar (NAD)","NAD"],["Nepalese Rupee (NPR)","NPR"],["Netherlands Antillean Gulden (ANG)","ANG"],["New Taiwan Dollar (TWD)","TWD"],["New Zealand Dollar (NZD)","NZD"],["Nicaraguan C\u00f3rdoba (NIO)","NIO"],["Nigerian Naira (NGN)","NGN"],["North Korean Won (KPW)","KPW"],["Norwegian Krone (NOK)","NOK"],["Omani Rial (OMR)","OMR"],["Pakistani Rupee (PKR)","PKR"],["Panamanian Balboa (PAB)","PAB"],["Papua New Guinean Kina (PGK)","PGK"],["Paraguayan Guaran\u00ed (PYG)","PYG"],["Peruvian Nuevo Sol (PEN)","PEN"],["Philippine Peso (PHP)","PHP"],["Polish Z\u0142oty (PLN)","PLN"],["Qatari Riyal (QAR)","QAR"],["Romanian Leu (RON)","RON"],["Russian Ruble (RUB)","RUB"],["Rwandan Franc (RWF)","RWF"],["Saint Helenian Pound (SHP)","SHP"],["Salvadoran Col\u00f3n (SVC)","SVC"],["Samoan Tala (WST)","WST"],["Saudi Riyal (SAR)","SAR"],["Serbian Dinar (RSD)","RSD"],["Seychellois Rupee (SCR)","SCR"],["Sierra Leonean Leone (SLL)","SLL"],["Singapore Dollar (SGD)","SGD"],["Solomon Islands Dollar (SBD)","SBD"],["Somali Shilling (SOS)","SOS"],["South African Rand (ZAR)","ZAR"],["South Korean Won (KRW)","KRW"],["Sri Lankan Rupee (LKR)","LKR"],["Sudanese Pound (SDG)","SDG"],["Surinamese Dollar (SRD)","SRD"],["Swazi Lilangeni (SZL)","SZL"],["Swedish Krona (SEK)","SEK"],["Swiss Franc (CHF)","CHF"],["Syrian Pound (SYP)","SYP"],["S\u00e3o Tom\u00e9 and Pr\u00edncipe Dobra (STD)","STD"],["Tajikistani Somoni (TJS)","TJS"],["Tanzanian Shilling (TZS)","TZS"],["Thai Baht (THB)","THB"],["Tongan Pa\u02bbanga (TOP)","TOP"],["Trinidad and Tobago Dollar (TTD)","TTD"],["Tunisian Dinar (TND)","TND"],["Turkish Lira (TRY)","TRY"],["Turkmenistani Manat (TMM)","TMM"],["Turkmenistani Manat (TMM)","TMM"],["Ugandan Shilling (UGX)","UGX"],["Ukrainian Hryvnia (UAH)","UAH"],["United Arab Emirates Dirham (AED)","AED"],["United States Dollar (USD)","USD"],["Uruguayan Peso (UYU)","UYU"],["Uzbekistani Som (UZS)","UZS"],["Vanuatu Vatu (VUV)","VUV"],["Venezuelan Bol\u00edvar (VEF)","VEF"],["Vietnamese \u0110\u1ed3ng (VND)","VND"],["West African Cfa Franc (XOF)","XOF"],["Yemeni Rial (YER)","YER"],["Zambian Kwacha (ZMK)","ZMK"],["Zimbabwean Dollar (ZWL)","ZWL"]]'
|
417
|
+
fake :get, '/currencies', response
|
418
|
+
r = @c.currencies_long
|
419
|
+
r.first.should == 'Afghan Afghani (AFN)'
|
420
|
+
r[1].should == 'Albanian Lek (ALL)'
|
421
|
+
r.last.should == 'Zimbabwean Dollar (ZWL)'
|
422
|
+
end
|
423
|
+
|
424
|
+
private
|
425
|
+
def fake method, path, body
|
426
|
+
FakeWeb.register_uri(method, "#{BASE_URI}#{path}", body: body.to_json)
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|