bitbond 0.0.5
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 +5 -0
- data/Gemfile +5 -0
- data/LICENSE +22 -0
- data/README.md +11 -0
- data/USAGES.md +21 -0
- data/bin/pry +16 -0
- data/bin/rspec +16 -0
- data/bitbond.gemspec +28 -0
- data/example/Gemfile +4 -0
- data/example/README.md +12 -0
- data/example/bid_on_a_rated_loans.rb +84 -0
- data/lib/bitbond.rb +7 -0
- data/lib/bitbond/client.rb +120 -0
- data/lib/bitbond/configuration.rb +21 -0
- data/lib/bitbond/version.rb +3 -0
- data/spec/bitbond/client_spec.rb +203 -0
- data/spec/bitbond/configuration_spec.rb +46 -0
- data/spec/spec_helper.rb +65 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a14cb6c29f65f520edb136b7899c5ffb924b04a2b2cf63ee8b666ac31b3f0db8
|
4
|
+
data.tar.gz: 8ba3fb970ac94818b4b9827ac57f9f22194ba68324f331948fa8eb52d73db752
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7e2ab266cc5e41c08e840ab5459fdda96acab7dede89f08c25cca55fe321a8626899e55319f1bf44a0c9ef4dee274fd3c3afc0ac0a187fb3111c0b2c6a0f6259
|
7
|
+
data.tar.gz: dffddc348b8f7e37fac6a8e2bb16eec0d53559bd9b33a270430a8a9fc5e5daadddba0801ed1bebe40a1662db6655ec9cb3941da09e5b211975ee12784dd0c1a9
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Bitbond
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
data/USAGES.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Bitbond Ruby
|
2
|
+
|
3
|
+
## Usages
|
4
|
+
|
5
|
+
### Configure
|
6
|
+
|
7
|
+
Once you have your API keys then you can configure the client as
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
Bitbond.configure do |config|
|
11
|
+
config.app_id = "YOUR_APP_ID"
|
12
|
+
config.secret_key = "SECRET_KEY"
|
13
|
+
end
|
14
|
+
```
|
15
|
+
|
16
|
+
Or
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
Bitbond.configuration.app_id = "YOUR_APP_ID"
|
20
|
+
Bitbond.configuration.secret_key = "SECRET_KEY"
|
21
|
+
```
|
data/bin/pry
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'pry' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('pry', 'pry')
|
data/bin/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/bitbond.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bitbond/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "bitbond"
|
8
|
+
gem.version = Bitbond::VERSION
|
9
|
+
gem.authors = ["Michal"]
|
10
|
+
gem.email = ["api@bitbond.com"]
|
11
|
+
gem.description = "Client library for Bitbond API"
|
12
|
+
gem.summary = "Discontiued"
|
13
|
+
gem.licenses = ['MIT']
|
14
|
+
gem.homepage = "https://github.com/bitbond/bitbond-ruby"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
# gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|gem|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_runtime_dependency 'oauth2', '~> 1.0'
|
22
|
+
|
23
|
+
|
24
|
+
gem.add_development_dependency "rake", '~> 10.0'
|
25
|
+
gem.add_development_dependency "rspec", '~> 3.4'
|
26
|
+
gem.add_development_dependency "webmock", '~> 1.0'
|
27
|
+
gem.add_development_dependency "timecop", '~> 0.8'
|
28
|
+
end
|
data/example/Gemfile
ADDED
data/example/README.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
This is an example bitbond api client.
|
2
|
+
|
3
|
+
To run it, execute the following command from the `example` folder:
|
4
|
+
|
5
|
+
`bundle install`
|
6
|
+
|
7
|
+
then
|
8
|
+
|
9
|
+
`bundle exec ruby bid_on_a_rated_loans.rb`
|
10
|
+
|
11
|
+
Follow the instructions to generate an access_token and query the loans
|
12
|
+
endpoint.
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "pstore"
|
2
|
+
require 'bitbond'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
db = PStore.new('db.pstore')
|
6
|
+
|
7
|
+
Bitbond.configure do |config|
|
8
|
+
config.api_host = 'http://www.bitbond.dev/api/v1'
|
9
|
+
config.app_id = 'eb19c240663942b10075e837c408620e3b5743247d8f8e67a5516f3f3bfee58e'
|
10
|
+
config.secret_key = '567e81e6b48d59f865f555a117df0a701080347ed549a4500ca8a636fd5f2b05'
|
11
|
+
end
|
12
|
+
|
13
|
+
callback = "urn:ietf:wg:oauth:2.0:oob"
|
14
|
+
scope = 'api'
|
15
|
+
|
16
|
+
token = nil
|
17
|
+
token_hash = nil
|
18
|
+
|
19
|
+
db.transaction(true) do
|
20
|
+
token_hash = db[:token]
|
21
|
+
end
|
22
|
+
|
23
|
+
create_client = ->(token_options = {}) {
|
24
|
+
opts = Hash[token_options.map { |k,v| [k.to_sym, v] } ]
|
25
|
+
opts = opts.select {|k,v| [:access_token, :refresh_token, :expires_at].include?(k) }
|
26
|
+
Bitbond::Client.new(**opts)
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
if token_hash
|
31
|
+
# We have a token already, refresh it and use
|
32
|
+
puts token_hash
|
33
|
+
client = create_client.call(token_hash)
|
34
|
+
db.transaction do
|
35
|
+
token = client.refresh
|
36
|
+
db[:token] = token.to_hash
|
37
|
+
end
|
38
|
+
else
|
39
|
+
# We need to generate a new token
|
40
|
+
client = create_client.call(access_token: nil)
|
41
|
+
|
42
|
+
puts "Authorize url: \n"
|
43
|
+
puts client.oauth_client.auth_code.authorize_url(redirect_uri: callback, scope: scope)
|
44
|
+
|
45
|
+
puts "Input token: \n"
|
46
|
+
authorization_token = gets
|
47
|
+
authorization_token = authorization_token.delete("\n")
|
48
|
+
puts "Authorization token: '#{authorization_token}'"
|
49
|
+
|
50
|
+
token = client.oauth_client.auth_code.get_token(authorization_token, redirect_uri: callback)
|
51
|
+
db.transaction do
|
52
|
+
db[:token] = token.to_hash
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
prog = ->(c) {
|
57
|
+
puts JSON.pretty_generate(c.account(account_type: 'primary'))
|
58
|
+
loans = c.loans(status: 'in_funding', base_currency: 'usd', rating: 'A', term: 'term_6_weeks')['loans']
|
59
|
+
puts JSON.pretty_generate(loans)
|
60
|
+
puts "Matching loan size: #{loans.size}."
|
61
|
+
puts "Press y to bid on the loans, any other key to cancel"
|
62
|
+
answer = gets.strip
|
63
|
+
if answer == 'y'
|
64
|
+
loans.each do |l|
|
65
|
+
puts "Bidding on loan: #{l['code']}, amount is 0.1 BTC"
|
66
|
+
# c.bid(loan_id: l['code'], amount: 0.1)
|
67
|
+
end
|
68
|
+
else
|
69
|
+
puts "Not doing anything.."
|
70
|
+
end
|
71
|
+
}
|
72
|
+
|
73
|
+
client = create_client.call(token.to_hash)
|
74
|
+
puts "*****************"
|
75
|
+
begin
|
76
|
+
prog.call(client)
|
77
|
+
rescue => e
|
78
|
+
puts "Got error when getting loans: #{e}"
|
79
|
+
end
|
80
|
+
puts "*****************"
|
81
|
+
puts "\n\n"
|
82
|
+
puts "The token is: #{token.to_hash}\n"
|
83
|
+
|
84
|
+
|
data/lib/bitbond.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
require "bitbond/configuration"
|
3
|
+
|
4
|
+
module Bitbond
|
5
|
+
class Client
|
6
|
+
|
7
|
+
attr_accessor :token, :refresh_token, :expires_at
|
8
|
+
|
9
|
+
def initialize(access_token:, refresh_token: nil, expires_at: nil)
|
10
|
+
self.token = access_token
|
11
|
+
self.refresh_token = refresh_token
|
12
|
+
self.expires_at = expires_at
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def investments(base_currency: [], rating: [], term: [], status: [])
|
17
|
+
get "investments", {
|
18
|
+
status: Array(status),
|
19
|
+
base_currency: Array(base_currency),
|
20
|
+
rating: Array(rating),
|
21
|
+
term: Array(term)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def investment(investment_id: )
|
26
|
+
require_param :investment_id, investment_id
|
27
|
+
get "investments/#{investment_id}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def profile(profile_id:)
|
31
|
+
require_param :profile_id, profile_id
|
32
|
+
get "profiles/#{profile_id}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def account(account_type: 'primary')
|
36
|
+
require_param :account_type, account_type
|
37
|
+
get "accounts/#{account_type}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def loans(status: [], base_currency: [], rating: [], term: [], page: 0)
|
41
|
+
get "loans", {
|
42
|
+
status: Array(status),
|
43
|
+
base_currency: Array(base_currency),
|
44
|
+
rating: Array(rating),
|
45
|
+
term: Array(term),
|
46
|
+
page: page
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def loan(loan_id: )
|
51
|
+
require_param :loan_id, loan_id
|
52
|
+
get "loans/#{loan_id}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def bid(loan_id:, amount:)
|
56
|
+
require_param :loan_id, loan_id
|
57
|
+
require_param :amount, amount
|
58
|
+
post "loans/#{loan_id}/bids", { bid: { amount: amount } }
|
59
|
+
end
|
60
|
+
|
61
|
+
def webhooks
|
62
|
+
get 'webhooks'
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_webhook(callback_url: )
|
66
|
+
require_param :callback_url, callback_url
|
67
|
+
post 'webhooks', { webhook: { callback_url: callback_url }}
|
68
|
+
end
|
69
|
+
|
70
|
+
def delete_webhook(webhook_id:)
|
71
|
+
require_param :webhook_id, webhook_id
|
72
|
+
delete "webhooks/#{webhook_id}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def get( endpoint, params = {})
|
76
|
+
result = access_token.get( url(endpoint), { params: params } )
|
77
|
+
result.parsed
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def post( endpoint, params = {})
|
82
|
+
result = access_token.post( url(endpoint), { body: params.to_json, headers: {'Content-Type' => 'application/json'}})
|
83
|
+
result.parsed
|
84
|
+
end
|
85
|
+
|
86
|
+
def delete(endpoint)
|
87
|
+
access_token.delete(url(endpoint))
|
88
|
+
end
|
89
|
+
|
90
|
+
def url(endpoint)
|
91
|
+
[Bitbond.configuration.api_host, endpoint].join("/")
|
92
|
+
end
|
93
|
+
|
94
|
+
def oauth_client
|
95
|
+
@oauth_client ||= OAuth2::Client.new(
|
96
|
+
Bitbond.configuration.app_id,
|
97
|
+
Bitbond.configuration.secret_key,
|
98
|
+
site: Bitbond.configuration.api_host
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
def access_token
|
103
|
+
@access_token ||= OAuth2::AccessToken.new(oauth_client, token, refresh_token: refresh_token, expires_at: expires_at)
|
104
|
+
end
|
105
|
+
|
106
|
+
def refresh
|
107
|
+
access_token.refresh!
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def require_param(symbol, val)
|
113
|
+
# this is taken from the implementation of rails: blank?
|
114
|
+
if val.respond_to?(:empty?) ? !!val.empty? : !val
|
115
|
+
raise ArgumentError, "Expected #{symbol} to be present, got: '#{val}'"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bitbond
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :app_id, :secret_key, :api_host
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@api_host ||= "https://www.bitbond.com/api/v1"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configure
|
11
|
+
yield configuration
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.configuration
|
15
|
+
@configuration ||= Configuration.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configuration=(config)
|
19
|
+
@configuration = config
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bitbond::Client do
|
4
|
+
|
5
|
+
subject(:client) {
|
6
|
+
bitbond_client
|
7
|
+
}
|
8
|
+
|
9
|
+
it 'exists' do
|
10
|
+
expect(client).to be
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'Investments' do
|
14
|
+
it 'can display investments' do
|
15
|
+
url = api_url "investments"
|
16
|
+
|
17
|
+
stub_request(:get, url).to_return(mock_json_collection)
|
18
|
+
|
19
|
+
expect( client.investments() ).to eq(mock_collection)
|
20
|
+
|
21
|
+
expect(a_request(:get, url)).to have_been_made
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can filter by base currency' do
|
25
|
+
url = api_url "investments"
|
26
|
+
|
27
|
+
stub_request(:get, url).with(query: {base_currency: ['usd']}).to_return(mock_json_collection)
|
28
|
+
|
29
|
+
expect( client.investments(base_currency: ['usd']) ).to eq(mock_collection)
|
30
|
+
|
31
|
+
expect(a_request(:get, url).with(query: {base_currency: ['usd']} )).to have_been_made
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'can filter by rating' do
|
35
|
+
url = api_url "investments"
|
36
|
+
|
37
|
+
stub_request(:get, url).with(query: {rating: ['A']}).to_return(mock_json_collection)
|
38
|
+
|
39
|
+
expect( client.investments(rating: ['A']) ).to eq(mock_collection)
|
40
|
+
|
41
|
+
expect(a_request(:get, url).with(query: {rating: ['A']} )).to have_been_made
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'can display investment details' do
|
45
|
+
url = api_url "investments/INVESTMENT_ID"
|
46
|
+
|
47
|
+
stub_request(:get, url).to_return(mock_json_item)
|
48
|
+
|
49
|
+
expect(client.investment(investment_id: 'INVESTMENT_ID')).to eq(mock_item)
|
50
|
+
|
51
|
+
expect(a_request(:get, url)).to have_been_made
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'will raise an error if no id is provided' do
|
55
|
+
expect { client.investment(investment_id: nil) }.to raise_error ArgumentError
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
describe 'Profiles' do
|
61
|
+
it 'can display profile information' do
|
62
|
+
url = api_url "profiles/PROFILE_ID"
|
63
|
+
|
64
|
+
stub_request(:get, url).to_return(mock_json_item)
|
65
|
+
|
66
|
+
expect(client.profile(profile_id: 'PROFILE_ID')).to eq(mock_item)
|
67
|
+
expect(a_request(:get, url)).to have_been_made
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
describe 'Accounts' do
|
73
|
+
|
74
|
+
it 'can display information for primary account' do
|
75
|
+
url = api_url "accounts/primary"
|
76
|
+
|
77
|
+
stub_request(:get, url).to_return(mock_json_item)
|
78
|
+
|
79
|
+
expect(client.account).to eq(mock_item)
|
80
|
+
expect(a_request(:get, url)).to have_been_made
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'can display information for auto-invest account' do
|
85
|
+
url = api_url "accounts/auto_invest"
|
86
|
+
|
87
|
+
stub_request(:get, url).to_return(mock_json_item)
|
88
|
+
|
89
|
+
expect(client.account(account_type: 'auto_invest')).to eq(mock_item)
|
90
|
+
expect(a_request(:get, url)).to have_been_made
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'Loans' do
|
96
|
+
|
97
|
+
it 'can display information about loans' do
|
98
|
+
url = api_url "loans?page=0"
|
99
|
+
|
100
|
+
stub_request(:get, url).to_return(mock_json_collection)
|
101
|
+
|
102
|
+
expect(client.loans).to eq(mock_collection)
|
103
|
+
expect(a_request(:get, url)).to have_been_made
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'can filter loans by status' do
|
107
|
+
url = api_url "loans"
|
108
|
+
|
109
|
+
stub_request(:get, url).with(query: { status: ['funded'], page: 0 } ).to_return(mock_json_collection)
|
110
|
+
|
111
|
+
expect(client.loans(status: ['funded'])).to eq(mock_collection)
|
112
|
+
expect(a_request(:get, url).with(query: { status: ['funded'], page: 0})).to have_been_made
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'can search loans' do
|
116
|
+
stub_request(
|
117
|
+
:get, api_url("loans?base_currency%5B%5D=usd&page=0&rating%5B%5D=A")
|
118
|
+
).to_return(mock_json_collection)
|
119
|
+
|
120
|
+
client.loans(base_currency: ['usd'], rating: ['A'])
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'can search for term and accepts page arguments' do
|
124
|
+
stub_request(
|
125
|
+
:get,
|
126
|
+
api_url("loans?base_currency%5B%5D=btc&base_currency%5B%5D=usd&page=2&term%5B%5D=term_6_weeks")
|
127
|
+
).to_return(mock_json_collection)
|
128
|
+
|
129
|
+
client.loans(base_currency: ['usd', 'btc'], page: 2, term: ['term_6_weeks'])
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'can show loan detais' do
|
133
|
+
url = api_url "loans/LOAN_ID"
|
134
|
+
|
135
|
+
stub_request(:get, url).to_return(mock_json_item)
|
136
|
+
|
137
|
+
expect(client.loan(loan_id: 'LOAN_ID')).to eq(mock_item)
|
138
|
+
expect(a_request(:get, url)).to have_been_made
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'can bid on a loan' do
|
142
|
+
url = api_url("loans/LOAN_ID/bids")
|
143
|
+
stub_request(:post, url).with(body: { bid: { amount: 0.1 }})
|
144
|
+
|
145
|
+
client.bid(loan_id: "LOAN_ID", amount: 0.1)
|
146
|
+
|
147
|
+
expect(a_request(:post, url)).to have_been_made
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'Webhooks' do
|
153
|
+
it 'it can list the webhooks' do
|
154
|
+
url = api_url "webhooks"
|
155
|
+
|
156
|
+
stub_request(:get, url).to_return(mock_json_collection)
|
157
|
+
|
158
|
+
expect(client.webhooks).to eq(mock_collection)
|
159
|
+
expect(a_request(:get, url)).to have_been_made
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'can create a new webhook' do
|
163
|
+
url = api_url "webhooks"
|
164
|
+
stub_request(:post, url).with(body: { webhook: { callback_url: 'https://www.test.com/callback?secret=xyz' }})
|
165
|
+
|
166
|
+
client.create_webhook(callback_url: 'https://www.test.com/callback?secret=xyz')
|
167
|
+
|
168
|
+
expect(a_request(:post, url)).to have_been_made
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'can delete a webhook' do
|
172
|
+
url = api_url "webhooks/WEBHOOK_ID"
|
173
|
+
stub_request(:delete, url)
|
174
|
+
|
175
|
+
client.delete_webhook(webhook_id: 'WEBHOOK_ID')
|
176
|
+
|
177
|
+
expect(a_request(:delete, url)).to have_been_made
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
describe 'Refresh token' do
|
184
|
+
subject(:client) {
|
185
|
+
Bitbond::Client.new(
|
186
|
+
access_token: access_token, **{ refresh_token: 'REFRESH' }
|
187
|
+
)
|
188
|
+
}
|
189
|
+
|
190
|
+
it 'will be able to refresh the oauth token' do
|
191
|
+
stub_request(:post, "https://www.bitbond.com/oauth/token").
|
192
|
+
with(:body => {"client_id"=>"APP_ID", "client_secret"=>"SECRET", "grant_type"=>"refresh_token", "refresh_token"=>"REFRESH"}).
|
193
|
+
to_return(:status => 200, :body => '{"access_token": "NEW_TOKEN", "refresh_token": "NEW_REFRESH_TOKEN"}', headers: {'Content-Type'=>'application/json'})
|
194
|
+
|
195
|
+
new_token = client.refresh
|
196
|
+
|
197
|
+
expect(new_token.token).to eq("NEW_TOKEN")
|
198
|
+
expect(new_token.refresh_token).to eq("NEW_REFRESH_TOKEN")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Bitbond::Configuration do
|
4
|
+
after { restore_default_config }
|
5
|
+
|
6
|
+
describe "#app_id" do
|
7
|
+
context "when app id configured" do
|
8
|
+
it "is used as app id" do
|
9
|
+
app_id = "app_id_123"
|
10
|
+
Bitbond.configure { |config| config.app_id = app_id }
|
11
|
+
|
12
|
+
expect(Bitbond.configuration.app_id).to eq(app_id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#secret_key" do
|
18
|
+
context "when secret_key configured" do
|
19
|
+
it "is used" do
|
20
|
+
secret_key = "bitbond-secret-key"
|
21
|
+
Bitbond.configure { |config| config.secret_key = secret_key }
|
22
|
+
|
23
|
+
expect(Bitbond.configuration.secret_key).to eq(secret_key)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#api_host" do
|
29
|
+
context "when no api host specified" do
|
30
|
+
it "usages the deafult host" do
|
31
|
+
expect(
|
32
|
+
Bitbond.configuration.api_host
|
33
|
+
).to eq("https://www.bitbond.com/api/v1")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when custom api host specified" do
|
38
|
+
it "use the custom host" do
|
39
|
+
custom_api_host = "http://custom-api-host.example.com"
|
40
|
+
Bitbond.configure {|config| config.api_host = custom_api_host }
|
41
|
+
|
42
|
+
expect(Bitbond.configuration.api_host).to eq(custom_api_host)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
require 'bitbond'
|
6
|
+
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.before :suite do
|
10
|
+
Bitbond.configuration.app_id = "APP_ID"
|
11
|
+
Bitbond.configuration.secret_key = "SECRET"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def access_token
|
16
|
+
'ACCESS_TOKEN'
|
17
|
+
end
|
18
|
+
|
19
|
+
def bitbond_client
|
20
|
+
Bitbond::Client.new(access_token: access_token)
|
21
|
+
end
|
22
|
+
|
23
|
+
def mock_item
|
24
|
+
{ 'key1' => 'val1', 'key2' => 'val2' }
|
25
|
+
end
|
26
|
+
|
27
|
+
def mock_collection
|
28
|
+
[ mock_item, mock_item ]
|
29
|
+
end
|
30
|
+
|
31
|
+
def api_url(endpoint)
|
32
|
+
[Bitbond.configuration.api_host, endpoint].join("/")
|
33
|
+
end
|
34
|
+
|
35
|
+
def mock_json_collection
|
36
|
+
{ body: mock_collection.to_json, headers: {'Content-Type'=>'application/json'} }
|
37
|
+
end
|
38
|
+
|
39
|
+
def mock_json_item
|
40
|
+
{ body: mock_item.to_json, headers: {'Content-Type'=>'application/json'} }
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def test_get_item(client, endpoint, method, id)
|
45
|
+
url = api_url(endpoint + "/#{id}")
|
46
|
+
stub_request(:get, url)
|
47
|
+
.to_return(body: mock_item.to_json, headers: {'Content-Type' => 'application/json'})
|
48
|
+
|
49
|
+
expect(client.public_send(method.to_sym, id)).to eq mock_item
|
50
|
+
expect(a_request(:get, url)).to have_been_made
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_get_collection(client, endpoint, method = endpoint)
|
54
|
+
url = api_url(endpoint)
|
55
|
+
stub_request(:get, url)
|
56
|
+
.to_return(body: mock_collection.to_json, headers: {'Content-Type' => 'application/json'})
|
57
|
+
|
58
|
+
expect(client.public_send(method)).to eq mock_collection
|
59
|
+
expect(a_request(:get, url)).to have_been_made
|
60
|
+
end
|
61
|
+
|
62
|
+
def restore_default_config
|
63
|
+
Bitbond.configuration = nil
|
64
|
+
Bitbond.configure {}
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitbond
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michal
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oauth2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: timecop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.8'
|
83
|
+
description: Client library for Bitbond API
|
84
|
+
email:
|
85
|
+
- api@bitbond.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE
|
93
|
+
- README.md
|
94
|
+
- USAGES.md
|
95
|
+
- bin/pry
|
96
|
+
- bin/rspec
|
97
|
+
- bitbond.gemspec
|
98
|
+
- example/Gemfile
|
99
|
+
- example/README.md
|
100
|
+
- example/bid_on_a_rated_loans.rb
|
101
|
+
- lib/bitbond.rb
|
102
|
+
- lib/bitbond/client.rb
|
103
|
+
- lib/bitbond/configuration.rb
|
104
|
+
- lib/bitbond/version.rb
|
105
|
+
- spec/bitbond/client_spec.rb
|
106
|
+
- spec/bitbond/configuration_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
homepage: https://github.com/bitbond/bitbond-ruby
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.7.7
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: Discontiued
|
132
|
+
test_files: []
|