cubits 0.1.0 → 0.2.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 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