cubits 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f407d28f07bf303f825ebc47aea0a17fe6e22b2c
4
- data.tar.gz: 7e2a552de743466e54b1cda08d01a2ae8d4e15df
3
+ metadata.gz: 3f20d1982b3ef43be0e3b9b8cbc9fea14c1cd44f
4
+ data.tar.gz: 193e702ea136342137d5c73f204e0135399051cc
5
5
  SHA512:
6
- metadata.gz: e4b801db8292d8a79a7c0ff07b785708d22b2aa49c88017bd0183797157e6f5020eb406554e4bc1791abe2fd22ddaaae67d4e4e7f3907777b1e3b81862dbd23e
7
- data.tar.gz: 9a830abbb493de37e1de68e142a37e8353b478d2fc6e57738a08acd05b521193f170d77d1b486291b20742768bdd4ddc82e7aa918668ce0b6569eadf8fa3dca4
6
+ metadata.gz: 21fc0a0189fa63b53c738a41252700a3a0075e2097706099ff6056614be1be2564f038281cd8a4e164897544b21b64dc6e7d17c614e54d0c1d8f9a53c53aa0f2
7
+ data.tar.gz: fce9506b0b8c7d36b367f44505031981679727b0a533f8cfd633d7eafcc6bc10b58392efcce75a9f786fd09684ca11e9188b14fb9a8d4b84d8e702aee26c8613
data/CHANGES.md ADDED
@@ -0,0 +1,21 @@
1
+ # 0.2.1
2
+
3
+ Minor fixes to README.
4
+
5
+ # 0.2.0
6
+
7
+ Implemented new API calls:
8
+
9
+ * Retrieving a list of accounts: `Cubits::Account.all`
10
+ * Get a quote for an operation: `Cubits::Quote.create(...)`
11
+ * Buy bitcoins using funds in a Cubits account: `Cubits.buy(...)`
12
+ * Sell bitcoins and credit funds to a Cubits account: `Cubits.sell(...)`
13
+
14
+ # 0.1.0
15
+
16
+ Initial release.
17
+
18
+ * Configuring connection
19
+ * Testing connection: `Cubits.available?`
20
+ * Creating, retrieving invoices: `Cubits::Invoice`
21
+ * Send bitcoins to a bitcoin address: `Cubits.send_money(...)`
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Ruby 1.9+ client for [Cubits](https://cubits.com) Merchant API v1.
4
4
 
5
- ## Installation
5
+ # Installation
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
@@ -18,11 +18,11 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install cubits
20
20
 
21
- ## Usage
21
+ # Usage
22
22
 
23
- ### Configuration
23
+ ## Configuration
24
24
 
25
- First thing you have to do is to get your API token (key+secret) from Cubits *...Merchant integration tab?..*
25
+ First thing you have to do is to generate your API token (key+secret) from your [Cubits Pay](https://cubits.com/merchant) account in the API integration section.
26
26
 
27
27
  Then, configure your Cubits client:
28
28
  ```ruby
@@ -40,26 +40,25 @@ Cubits.configure(key: '***', secret: '***')
40
40
  Cubits.available? # => true
41
41
  ```
42
42
 
43
- ### Invoices
43
+ ## Invoices
44
44
 
45
45
  Using the `cubits` Ruby client you can create and retrieve invoices.
46
46
 
47
- Invoices are represented by `Cubits::Invoice` class, which is a descendant of [Hashie::Mash](https://github.com/intridea/hashie#mash),
48
- so it's a Hash with a method-like access to its elements:
47
+ Invoices are represented by the `Cubits::Invoice` class, which is a descendant of [Hashie::Mash](https://github.com/intridea/hashie#mash), so it's a Hash with a method-like access to its elements:
49
48
 
50
49
  ```ruby
51
50
  invoice.id # => "686e4238970a92f04f1f5a30035bf024"
52
51
  invoice.status # => "pending"
53
52
  invoice.invoice_amount # => "0.00446216"
54
53
  invoice.invoice_currency # => "BTC"
55
- invoice.address # => "2MwFC54RmUyHtyNcNuxtU5zW4hCGTvYuXti"
54
+ invoice.address # => "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"
56
55
  ```
57
56
 
58
57
  #### .create
59
58
 
60
59
  Creates a new invoice.
61
60
 
62
- For a list of accepted and returned parameters, see `POST /api/v1/invoices` page in the [Cubits Help Center](https://cubits.com/help) Developer's section.
61
+ For a list of accepted and returned parameters, see the `POST /api/v1/invoices` page in the [Cubits Help Center](https://cubits.com/help) Developer's section.
63
62
 
64
63
 
65
64
  ```ruby
@@ -77,7 +76,7 @@ Retrieves an existing invoice.
77
76
  invoice = Cubits::Invoice.find("686e4238970a92f04f1f5a30035bf024")
78
77
  ```
79
78
 
80
- Returns `Cubits::Invoice` object or `nil` if invoice was not found.
79
+ Returns `Cubits::Invoice` object or `nil` if the specified invoice was not found.
81
80
 
82
81
 
83
82
  #### #reload
@@ -86,10 +85,104 @@ Reloads `Cubits::Invoice` object.
86
85
  ```ruby
87
86
  invoice = Cubits::Invoice.find("686e4238970a92f04f1f5a30035bf024")
88
87
  # do some stuff...
89
- invoice.reload # gets the up-to-date invoice data from Cubits API
88
+ invoice.reload # gets the up-to-date invoice data from the Cubits API
90
89
  ```
91
90
 
92
- ### Send money
91
+ ## Accounts
92
+
93
+ Your Cubits accounts are represented by the `Cubits::Account` class, which is a descendant of [Hashie::Mash](https://github.com/intridea/hashie#mash), so it's a Hash with a method-like access to its elements:
94
+ ```ruby
95
+ account = Cubits::Account.all.first
96
+
97
+ account.currency # => "EUR"
98
+ account.balance # => "125.00"
99
+ ```
100
+
101
+ #### .all
102
+
103
+ Retrieves a list of accounts.
104
+
105
+ Returns `Array` of `Cubits::Account` objects.
106
+
107
+ ```ruby
108
+ Cubits::Account.all # => [{ currency: 'EUR', balance: '125.00' }, ...]
109
+ ```
110
+
111
+ ## Quotes
112
+
113
+ Requests a quote for a *"buy"* or *"sell"* operation.
114
+
115
+ Quotes contain information about the current Cubits exchange rate for a certain operation type of a certain amount and can serve as an estimation for subsequent buy or sell requests.
116
+
117
+ #### .create
118
+ Creates a new quote.
119
+
120
+ For a list of accepted and returned parameters, see the `POST /api/v1/quotes` page in the [Cubits Help Center](https://cubits.com/help) Developer's section.
121
+
122
+
123
+ ```ruby
124
+ quote = Cubits::Quote.create(
125
+ operation: 'buy',
126
+ sender: {
127
+ currency: 'EUR'
128
+ },
129
+ receiver: {
130
+ currency: 'BTC',
131
+ amount: '1.0'
132
+ }
133
+ )
134
+
135
+ quote.sender # => {"currency"=>"EUR", "amount"=>"172.81"}
136
+ ```
137
+
138
+ Here a call to `POST /api/v1/quotes` is executed and the response is wrapped in a `Cubits::Quote` object.
139
+
140
+
141
+ ## Buy bitcoins
142
+
143
+ `Cubits.buy` helper method creates a transaction to buy bitcoins using funds from your Cubits account. Bought bitcoins will be credited to your Cubits wallet.
144
+
145
+ The exact exchange rate will be calculated at the transaction execution time.
146
+
147
+ #### Parameters
148
+ Attribute | Data type | Description
149
+ ------------|-------------|--------------
150
+ sender | Hash | Sender attributes define the spending part of the transaction
151
+ sender[:currency] | String | [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes) code of the currency that you want to spend (e.g. "EUR")
152
+ sender[:amount] | String | Amount in specified currency to be spent, decimal number as a string (e.g. "12.50")
153
+
154
+ ```ruby
155
+ Cubits.buy sender: { currency: 'EUR', amount: '150.00' }
156
+ # => {"tx_ref_code"=>"RNXH3"}
157
+ ```
158
+
159
+ On success, `.buy` creates a transaction and returns its reference code.
160
+
161
+
162
+ ## Sell bitcoins
163
+
164
+ `Cubits.sell` helper method creates a transaction to sell bitcoins from your Cubits wallet and receive the according amount in the specified fiat currency. Fiat funds will be credited to your Cubits cash account.
165
+
166
+ The exact exchange rate will be calculated at the transaction execution time.
167
+
168
+ #### Parameters
169
+ Attribute | Data type | Description
170
+ ------------|-------------|--------------
171
+ sender | Hash | Sender attributes define the spending part of the transaction
172
+ sender[:amount] | String | Amount in BTC to be spent, decimal number as a string (e.g. "0.01250000")
173
+ receiver | Hash | Receiver attributes define the receiving part of the transaction
174
+ receiver[:currency] | String | ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes) code of the currency that you want to receive (e.g. "EUR")
175
+
176
+
177
+ ```ruby
178
+ Cubits.sell sender: { amount: '0.45000000' }, receiver: { currency: 'EUR' }
179
+ # => {"tx_ref_code"=>"4XRX3"}
180
+ ```
181
+
182
+ On success, `.sell` creates a transaction and returns its reference code.
183
+
184
+
185
+ ## Send money
93
186
 
94
187
  `Cubits.send_money` helper method allows you to send Bitcoin from your Cubits Wallet to an external Bitcoin address.
95
188
 
data/cubits.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['alex.kukushkin@cubits.com']
11
11
  spec.summary = 'Ruby client for Cubits Merchant API'
12
12
  spec.description = 'Ruby client for Cubits Merchant API'
13
- spec.homepage = ''
13
+ spec.homepage = 'https://github.com/cubits/cubits-ruby'
14
14
  spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
@@ -0,0 +1,6 @@
1
+ module Cubits
2
+ class Account < Resource
3
+ path '/api/v1/accounts'
4
+ expose_methods :all
5
+ end # class Account
6
+ end
@@ -31,5 +31,66 @@ module Cubits
31
31
  amount: params[:amount], address: params[:address]
32
32
  )
33
33
  end
34
+
35
+ # Executes "Buy bitcoins" API call.
36
+ # Buy Bitcoins using funds in a Cubits account. Bought Bitcoins will be credited
37
+ # to your Cubits Wallet.
38
+ #
39
+ # @param params [Hash]
40
+ # @param params[:sender] [Hash] Sender attributes define spending part of transaction
41
+ # @param params[:sender][:currency] [String] ISO 4217 code of the currency, that you want
42
+ # to spend (e.g. "EUR")
43
+ # @param params[:sender][:amount] [String] Amount in specified currency to be spent,
44
+ # decimal number as a String (e.g. "12.50")
45
+ #
46
+ def buy(params)
47
+ fail ArgumentError, 'Hash is expected as params' unless params.is_a?(Hash)
48
+ fail ArgumentError, 'Hash is expected as :sender' unless params[:sender].is_a?(Hash)
49
+ sender = params[:sender]
50
+ fail ArgumentError, 'String is expected as sender[:currency]' unless sender[:currency].is_a?(String)
51
+ fail ArgumentError, 'String is expected as sender[:amount]' unless sender[:amount].is_a?(String)
52
+ fail ArgumentError, 'Invalid amount format' unless sender[:amount] =~ /^\d+\.\d+$/
53
+ Cubits.connection.post(
54
+ '/api/v1/buy',
55
+ sender: {
56
+ currency: sender[:currency],
57
+ amount: sender[:amount]
58
+ }
59
+ )
60
+ end
61
+
62
+
63
+ # Executes "Sell bitcoins" API call.
64
+ #
65
+ # Creates a transaction to sell bitcoins from your Cubits wallet and receive amount
66
+ # in specified fiat currency. Fiat funds will be credited to your Cubits account.
67
+ #
68
+ # @param params [Hash]
69
+ # @param params[:sender] [Hash] Sender attributes define spending part of transaction
70
+ # @param params[:sender][:amount] [String] Amount in bitcoins to be spent,
71
+ # decimal number as a String (e.g. "0.01250000")
72
+ # @param params[:receiver] [Hash] Receiver attributes define receiving part of transaction
73
+ # @param params[:receiver][:currency] [String] ISO 4217 code of the currency, that you want
74
+ # to receive (e.g. "EUR")
75
+ #
76
+ def sell(params)
77
+ fail ArgumentError, 'Hash is expected as params' unless params.is_a?(Hash)
78
+ fail ArgumentError, 'Hash is expected as :sender' unless params[:sender].is_a?(Hash)
79
+ sender = params[:sender]
80
+ fail ArgumentError, 'String is expected as sender[:amount]' unless sender[:amount].is_a?(String)
81
+ fail ArgumentError, 'Invalid amount format' unless sender[:amount] =~ /^\d+\.\d+$/
82
+ fail ArgumentError, 'Hash is expected as :receiver' unless params[:receiver].is_a?(Hash)
83
+ receiver = params[:receiver]
84
+ fail ArgumentError, 'String is expected as receiver[:currency]' unless receiver[:currency].is_a?(String)
85
+ Cubits.connection.post(
86
+ '/api/v1/sell',
87
+ sender: {
88
+ amount: sender[:amount]
89
+ },
90
+ receiver: {
91
+ currency: receiver[:currency]
92
+ }
93
+ )
94
+ end
34
95
  end # module Helpers
35
96
  end # module Cubits
@@ -1,6 +1,6 @@
1
1
  module Cubits
2
2
  class Invoice < Resource
3
3
  path '/api/v1/invoices'
4
-
4
+ expose_methods :create, :find, :reload
5
5
  end # class Invoice
6
6
  end
@@ -0,0 +1,7 @@
1
+ module Cubits
2
+ class Quote < Resource
3
+ path '/api/v1/quotes'
4
+
5
+ expose_methods :create
6
+ end # class Quote
7
+ end
@@ -9,6 +9,24 @@ module Cubits
9
9
  @path = p
10
10
  end
11
11
 
12
+ # By convention collection name for the resource is the last part of the path
13
+ #
14
+ def self.collection_name
15
+ @path.split('/').last
16
+ end
17
+
18
+ # Sets exposed methods for the resource
19
+ #
20
+ def self.expose_methods(*args)
21
+ @exposed_methods = args
22
+ end
23
+
24
+ # @return true if the method is exposed by this resource
25
+ #
26
+ def self.exposed_method?(method_name)
27
+ (@exposed_methods || []).include?(method_name)
28
+ end
29
+
12
30
  # Returns API path to resource
13
31
  #
14
32
  def self.path_to(resource_or_id = nil)
@@ -22,6 +40,17 @@ module Cubits
22
40
  end
23
41
  end
24
42
 
43
+ # Loads collection of resources
44
+ #
45
+ # @return [Array<Resource>]
46
+ #
47
+ def self.all
48
+ fail NoMethodError, "Resource #{name} does not expose .all" unless exposed_method?(:all)
49
+ Cubits.connection.get(path_to)[collection_name].map { |r| new r }
50
+ rescue NotFound
51
+ nil
52
+ end
53
+
25
54
  # Loads resource
26
55
  #
27
56
  # @param id [String]
@@ -29,7 +58,8 @@ module Cubits
29
58
  # @return nil if resource is not found
30
59
  #
31
60
  def self.find(id)
32
- self.new Cubits.connection.get(path_to(id))
61
+ fail NoMethodError, "Resource #{name} does not expose .find" unless exposed_method?(:find)
62
+ new Cubits.connection.get(path_to(id))
33
63
  rescue NotFound
34
64
  nil
35
65
  end
@@ -37,6 +67,9 @@ module Cubits
37
67
  # Reloads resource
38
68
  #
39
69
  def reload
70
+ unless self.class.exposed_method?(:reload)
71
+ fail NoMethodError, "Resource #{self.class.name} does not expose #reload"
72
+ end
40
73
  fail "Resource #{self.class.name} does not have an id" unless self.respond_to?(:id)
41
74
  replace(self.class.find(id))
42
75
  end
@@ -44,7 +77,8 @@ module Cubits
44
77
  # Creates a new resource
45
78
  #
46
79
  def self.create(params = {})
47
- self.new Cubits.connection.post(path_to, params)
80
+ fail NoMethodError, "Resource #{name} does not expose .create" unless exposed_method?(:create)
81
+ new Cubits.connection.post(path_to, params)
48
82
  end
49
83
  end # class Resource
50
84
  end # module Cubits
@@ -1,3 +1,3 @@
1
1
  module Cubits
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.1'
3
3
  end
data/lib/cubits.rb CHANGED
@@ -6,6 +6,8 @@ require 'cubits/errors'
6
6
  require 'cubits/helpers'
7
7
  require 'cubits/resource'
8
8
  require 'cubits/invoice'
9
+ require 'cubits/account'
10
+ require 'cubits/quote'
9
11
 
10
12
  module Cubits
11
13
  extend Cubits::Helpers
@@ -50,9 +52,10 @@ module Cubits
50
52
 
51
53
  # Sets new base API URL
52
54
  #
53
- # @param new_base_url [URI]
55
+ # @param new_base_url [URI,String]
54
56
  #
55
57
  def self.base_url=(new_base_url)
58
+ new_base_url = URI.parse(new_base_url) if new_base_url.is_a?(String)
56
59
  fail ArgumentError, 'URI is expected as new_base_url' unless new_base_url.is_a?(URI)
57
60
  @base_url = new_base_url
58
61
  end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cubits::Account do
4
+ context 'class methods,' do
5
+ subject { described_class }
6
+
7
+ it { is_expected.to respond_to(:all) }
8
+ end # class methods
9
+ end # describe Cubits::Account
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cubits do
4
+ context 'class methods,' do
5
+ subject { described_class }
6
+
7
+ it { is_expected.to respond_to(:available?) }
8
+ it { is_expected.to respond_to(:send_money) }
9
+ it { is_expected.to respond_to(:buy) }
10
+ it { is_expected.to respond_to(:sell) }
11
+ end # class methods
12
+ end # describe Cubits::Account
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cubits::Invoice do
4
+ context 'class methods,' do
5
+ subject { described_class }
6
+
7
+ it { is_expected.to respond_to(:create) }
8
+ it { is_expected.to respond_to(:find) }
9
+ end # class methods
10
+
11
+ it { is_expected.to respond_to(:reload) }
12
+ end # describe Cubits::Invoice
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cubits::Quote do
4
+ context 'class methods,' do
5
+ subject { described_class }
6
+
7
+ it { is_expected.to respond_to(:create) }
8
+ end # class methods
9
+ end # describe Cubits::Quote
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cubits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Kukushkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2015-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -102,22 +102,29 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - ".gitignore"
105
+ - CHANGES.md
105
106
  - Gemfile
106
107
  - LICENSE.txt
107
108
  - README.md
108
109
  - Rakefile
109
110
  - cubits.gemspec
110
111
  - lib/cubits.rb
112
+ - lib/cubits/account.rb
111
113
  - lib/cubits/connection.rb
112
114
  - lib/cubits/errors.rb
113
115
  - lib/cubits/helpers.rb
114
116
  - lib/cubits/invoice.rb
117
+ - lib/cubits/quote.rb
115
118
  - lib/cubits/resource.rb
116
119
  - lib/cubits/version.rb
120
+ - spec/lib/cubits/account_spec.rb
117
121
  - spec/lib/cubits/connection_spec.rb
122
+ - spec/lib/cubits/helpers_spec.rb
123
+ - spec/lib/cubits/invoice_spec.rb
124
+ - spec/lib/cubits/quote_spec.rb
118
125
  - spec/lib/cubits_spec.rb
119
126
  - spec/spec_helper.rb
120
- homepage: ''
127
+ homepage: https://github.com/cubits/cubits-ruby
121
128
  licenses:
122
129
  - MIT
123
130
  metadata: {}
@@ -142,6 +149,10 @@ signing_key:
142
149
  specification_version: 4
143
150
  summary: Ruby client for Cubits Merchant API
144
151
  test_files:
152
+ - spec/lib/cubits/account_spec.rb
145
153
  - spec/lib/cubits/connection_spec.rb
154
+ - spec/lib/cubits/helpers_spec.rb
155
+ - spec/lib/cubits/invoice_spec.rb
156
+ - spec/lib/cubits/quote_spec.rb
146
157
  - spec/lib/cubits_spec.rb
147
158
  - spec/spec_helper.rb