straight 0.2.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/Gemfile +7 -5
- data/Gemfile.lock +17 -7
- data/README.md +3 -0
- data/Rakefile +9 -0
- data/VERSION +1 -1
- data/lib/straight.rb +9 -1
- data/lib/straight/address_providers/base.rb +28 -0
- data/lib/straight/address_providers/bip32.rb +22 -0
- data/lib/straight/blockchain_adapter.rb +17 -1
- data/lib/straight/blockchain_adapters/biteasy_adapter.rb +14 -13
- data/lib/straight/blockchain_adapters/blockchain_info_adapter.rb +15 -14
- data/lib/straight/blockchain_adapters/insight_adapter.rb +76 -0
- data/lib/straight/blockchain_adapters/mycelium_adapter.rb +74 -49
- data/lib/straight/exchange_rate_adapter.rb +2 -2
- data/lib/straight/exchange_rate_adapters/average_rate_adapter.rb +1 -1
- data/lib/straight/exchange_rate_adapters/okcoin_adapter.rb +1 -1
- data/lib/straight/faraday_monkeypatch.rb +22 -0
- data/lib/straight/gateway.rb +71 -34
- data/lib/straight/order.rb +43 -32
- data/straight.gemspec +20 -27
- metadata +30 -26
- data/spec/lib/blockchain_adapters/biteasy_adapter_spec.rb +0 -48
- data/spec/lib/blockchain_adapters/blockchain_info_adapter_spec.rb +0 -57
- data/spec/lib/blockchain_adapters/mycelium_adapter_spec.rb +0 -58
- data/spec/lib/exchange_rate_adapter_spec.rb +0 -55
- data/spec/lib/exchange_rate_adapters/average_rate_adapter_spec.rb +0 -43
- data/spec/lib/exchange_rate_adapters/bitpay_adapter_spec.rb +0 -27
- data/spec/lib/exchange_rate_adapters/bitstamp_adapter_spec.rb +0 -27
- data/spec/lib/exchange_rate_adapters/btce_adapter_spec.rb +0 -27
- data/spec/lib/exchange_rate_adapters/coinbase_adapter_spec.rb +0 -27
- data/spec/lib/exchange_rate_adapters/kraken_adapter_spec.rb +0 -27
- data/spec/lib/exchange_rate_adapters/localbitcoins_adapter_spec.rb +0 -27
- data/spec/lib/exchange_rate_adapters/okcoin_adapter_spec.rb +0 -27
- data/spec/lib/gateway_spec.rb +0 -98
- data/spec/lib/order_spec.rb +0 -128
- data/spec/spec_helper.rb +0 -1
@@ -5,8 +5,8 @@ module Straight
|
|
5
5
|
|
6
6
|
include Singleton
|
7
7
|
|
8
|
-
class FetchingFailed <
|
9
|
-
class CurrencyNotSupported <
|
8
|
+
class FetchingFailed < StraightError; end
|
9
|
+
class CurrencyNotSupported < StraightError; end
|
10
10
|
|
11
11
|
def initialize(rates_expire_in: 1800)
|
12
12
|
@rates_expire_in = rates_expire_in # in seconds
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Faraday::SSLOptions = Faraday::Options.new(*(Faraday::SSLOptions.members | [:verify_callback])) do
|
2
|
+
|
3
|
+
def verify?
|
4
|
+
verify != false
|
5
|
+
end
|
6
|
+
|
7
|
+
def disable?
|
8
|
+
!verify?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Faraday::ConnectionOptions.options(ssl: Faraday::SSLOptions)
|
13
|
+
|
14
|
+
Faraday::Adapter::NetHttp.class_exec do
|
15
|
+
|
16
|
+
alias_method :orig_configure_ssl, :configure_ssl
|
17
|
+
|
18
|
+
def configure_ssl(http, ssl)
|
19
|
+
http.verify_callback = ssl[:verify_callback] if ssl[:verify_callback]
|
20
|
+
orig_configure_ssl(http, ssl)
|
21
|
+
end
|
22
|
+
end
|
data/lib/straight/gateway.rb
CHANGED
@@ -18,7 +18,8 @@ module Straight
|
|
18
18
|
module GatewayModule
|
19
19
|
|
20
20
|
# Raised when adapter's list (either Exchange or Blockchain adapters) is empty
|
21
|
-
class NoAdaptersAvailable <
|
21
|
+
class NoAdaptersAvailable < StraightError;end
|
22
|
+
class OrderAmountInvalid < StraightError;end
|
22
23
|
|
23
24
|
# Only add getters and setters for those properties in the extended class
|
24
25
|
# that don't already have them. This is very useful with ActiveRecord for example
|
@@ -27,6 +28,7 @@ module Straight
|
|
27
28
|
base.class_eval do
|
28
29
|
[
|
29
30
|
:pubkey,
|
31
|
+
:test_pubkey,
|
30
32
|
:confirmations_required,
|
31
33
|
:status_check_schedule,
|
32
34
|
:blockchain_adapters,
|
@@ -34,7 +36,11 @@ module Straight
|
|
34
36
|
:order_callbacks,
|
35
37
|
:order_class,
|
36
38
|
:default_currency,
|
37
|
-
:name
|
39
|
+
:name,
|
40
|
+
:address_provider,
|
41
|
+
:address_provider_type,
|
42
|
+
:address_derivation_scheme,
|
43
|
+
:test_mode
|
38
44
|
].each do |field|
|
39
45
|
attr_reader field unless base.method_defined?(field)
|
40
46
|
attr_writer field unless base.method_defined?("#{field}=")
|
@@ -64,52 +70,67 @@ module Straight
|
|
64
70
|
|
65
71
|
module Includable
|
66
72
|
|
67
|
-
|
68
|
-
|
69
|
-
|
73
|
+
def blockchain_adapters
|
74
|
+
return test_blockchain_adapters if test_mode
|
75
|
+
@blockchain_adapters
|
76
|
+
end
|
70
77
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
78
|
+
def test_blockchain_adapters
|
79
|
+
@blockchain_adapters.map{ |el| el.class.testnet_adapter rescue next }.compact
|
80
|
+
end
|
81
|
+
|
82
|
+
# Creates a new order for the address derived from the pubkey and the keychain_id argument provided.
|
83
|
+
# See explanation of this keychain_id argument is in the description for the AddressProvider::Base#new_address method.
|
84
|
+
def new_order(args)
|
85
|
+
|
86
|
+
# Args: amount:, keychain_id: nil, currency: nil, btc_denomination: :satoshi
|
87
|
+
#
|
88
|
+
# The reason these arguments are supplied as a hash and not as named arguments
|
89
|
+
# is because we don't know in advance which arguments are required for a particular
|
90
|
+
# AddressAdapter. So we accpet all, check manually for required ones like :amount,
|
91
|
+
# set default values where needed and then hand them all to address_adapter.
|
92
|
+
if args[:amount].nil? || !args[:amount].kind_of?(Numeric) || args[:amount] <= 0
|
93
|
+
raise OrderAmountInvalid, "amount cannot be nil and should be more than 0"
|
94
|
+
end
|
95
|
+
# Setting default values
|
96
|
+
args[:currency] ||= default_currency
|
97
|
+
args[:btc_denomination] ||= :satoshi
|
98
|
+
|
99
|
+
amount = args[:amount_from_exchange_rate] = amount_from_exchange_rate(
|
100
|
+
args[:amount],
|
101
|
+
currency: args[:currency],
|
102
|
+
btc_denomination: args[:btc_denomination]
|
75
103
|
)
|
76
104
|
|
105
|
+
if address_provider.takes_fees?
|
106
|
+
address, amount = address_provider.new_address_and_amount(**args)
|
107
|
+
else
|
108
|
+
address = address_provider.new_address(**args)
|
109
|
+
end
|
110
|
+
|
77
111
|
order = Kernel.const_get(order_class).new
|
78
|
-
order.amount = amount
|
79
112
|
order.gateway = self
|
80
|
-
order.
|
81
|
-
order.
|
113
|
+
order.keychain_id = args[:keychain_id]
|
114
|
+
order.address = address
|
115
|
+
order.amount = amount
|
82
116
|
order
|
83
117
|
end
|
84
118
|
|
85
|
-
# Returns a Base58-encoded Bitcoin address to which the payment transaction
|
86
|
-
# is expected to arrive. id is an an integer > 0 (hopefully not too large and hopefully
|
87
|
-
# the one a user of this class is going to properly increment) that is used to generate a
|
88
|
-
# an BIP32 bitcoin address deterministically.
|
89
|
-
def address_for_keychain_id(id)
|
90
|
-
# First check the depth. If the depth is 4 use '/i' notation (Mycelium iOS wallet)
|
91
|
-
# TODO deal with other depths later. Currently only supports 0 and 4
|
92
|
-
if keychain.depth > 0
|
93
|
-
keychain.node_for_path(id.to_s).to_address
|
94
|
-
else # Otherwise, use 'm/0/n' - both Electrum and Mycelium on Android
|
95
|
-
keychain.node_for_path("m/0/#{id.to_s}").to_address
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
119
|
def fetch_transaction(tid, address: nil)
|
100
|
-
try_adapters(
|
120
|
+
try_adapters(blockchain_adapters, type: "blockchain") { |b| b.fetch_transaction(tid, address: address) }
|
101
121
|
end
|
102
122
|
|
103
123
|
def fetch_transactions_for(address)
|
104
|
-
try_adapters(
|
124
|
+
try_adapters(blockchain_adapters, type: "blockchain", raise_exceptions: [Blockchain::Adapter::BitcoinAddressInvalid]) { |b| b.fetch_transactions_for(address) }
|
105
125
|
end
|
106
126
|
|
107
127
|
def fetch_balance_for(address)
|
108
|
-
try_adapters(
|
128
|
+
try_adapters(blockchain_adapters, type: "blockchain") { |b| b.fetch_balance_for(address) }
|
109
129
|
end
|
110
130
|
|
111
131
|
def keychain
|
112
|
-
|
132
|
+
key = self.test_mode ? self.test_pubkey : self.pubkey
|
133
|
+
@keychain ||= BTC::Keychain.new(xpub: key)
|
113
134
|
end
|
114
135
|
|
115
136
|
# This is a callback method called from each order
|
@@ -145,11 +166,23 @@ module Straight
|
|
145
166
|
end
|
146
167
|
end
|
147
168
|
|
169
|
+
def test_pubkey_missing?
|
170
|
+
address_provider_type == :Bip32 && test_mode && test_pubkey.to_s.empty?
|
171
|
+
end
|
172
|
+
|
173
|
+
def pubkey_missing?
|
174
|
+
address_provider_type == :Bip32 && !test_mode && pubkey.to_s.empty?
|
175
|
+
end
|
176
|
+
|
177
|
+
def address_provider_type
|
178
|
+
@address_provider ? @address_provider.class.name.split('::')[-1].to_sym : :Bip32
|
179
|
+
end
|
180
|
+
|
148
181
|
private
|
149
|
-
|
182
|
+
|
150
183
|
# Calls the block with each adapter until one of them does not fail.
|
151
184
|
# Fails with the last exception.
|
152
|
-
def try_adapters(adapters, type: nil, &block)
|
185
|
+
def try_adapters(adapters, type: nil, raise_exceptions: [], &block)
|
153
186
|
|
154
187
|
# TODO: specify which adapters are unavailable (blockchain or exchange rate)
|
155
188
|
raise NoAdaptersAvailable, "the list of #{type} adapters is empty or nil" if adapters.nil? || adapters.empty?
|
@@ -160,7 +193,8 @@ module Straight
|
|
160
193
|
result = yield(adapter)
|
161
194
|
last_exception = nil
|
162
195
|
return result
|
163
|
-
rescue
|
196
|
+
rescue => e
|
197
|
+
raise e if raise_exceptions.include?(e)
|
164
198
|
last_exception = e
|
165
199
|
# If an Exception is raised, it passes on
|
166
200
|
# to the next adapter and attempts to call a method on it.
|
@@ -182,7 +216,8 @@ module Straight
|
|
182
216
|
@default_currency = 'BTC'
|
183
217
|
@blockchain_adapters = [
|
184
218
|
Blockchain::BlockchainInfoAdapter.mainnet_adapter,
|
185
|
-
Blockchain::MyceliumAdapter.mainnet_adapter
|
219
|
+
Blockchain::MyceliumAdapter.mainnet_adapter,
|
220
|
+
Blockchain::InsightAdapter.mainnet_adapter(main_url: "https://insight.mycelium.com/api")
|
186
221
|
]
|
187
222
|
@exchange_rate_adapters = [
|
188
223
|
ExchangeRate::BitpayAdapter.instance,
|
@@ -194,6 +229,8 @@ module Straight
|
|
194
229
|
ExchangeRate::OkcoinAdapter.instance
|
195
230
|
]
|
196
231
|
@status_check_schedule = DEFAULT_STATUS_CHECK_SCHEDULE
|
232
|
+
@address_provider = AddressProvider::Bip32.new(self)
|
233
|
+
@test_mode = false
|
197
234
|
end
|
198
235
|
|
199
236
|
def order_class
|
data/lib/straight/order.rb
CHANGED
@@ -22,7 +22,7 @@ module Straight
|
|
22
22
|
# where we don't want to override AR getters and setters that set attribtues.
|
23
23
|
def self.included(base)
|
24
24
|
base.class_eval do
|
25
|
-
[:amount, :address, :gateway, :keychain_id, :status, :tid].each do |field|
|
25
|
+
[:amount, :amount_paid, :address, :gateway, :keychain_id, :status, :tid, :title, :callback_url, :test_mode].each do |field|
|
26
26
|
attr_reader field unless base.method_defined?(field)
|
27
27
|
attr_writer field unless base.method_defined?("#{field}=")
|
28
28
|
end
|
@@ -41,12 +41,13 @@ module Straight
|
|
41
41
|
paid: 2, # transaction received with enough confirmations and the correct amount
|
42
42
|
underpaid: 3, # amount that was received in a transaction was not enough
|
43
43
|
overpaid: 4, # amount that was received in a transaction was too large
|
44
|
-
expired: 5
|
44
|
+
expired: 5, # too much time passed since creating an order
|
45
|
+
canceled: 6, # user decides to economize
|
45
46
|
}
|
46
47
|
|
47
48
|
attr_reader :old_status
|
48
49
|
|
49
|
-
class IncorrectAmount <
|
50
|
+
class IncorrectAmount < StraightError; end
|
50
51
|
|
51
52
|
# If you are defining methods in this module, it means you most likely want to
|
52
53
|
# call super() somehwere inside those methods. An example would be the #status=
|
@@ -65,7 +66,7 @@ module Straight
|
|
65
66
|
def status(as_sym: false, reload: false)
|
66
67
|
|
67
68
|
if defined?(super)
|
68
|
-
begin
|
69
|
+
begin
|
69
70
|
@status = super
|
70
71
|
# if no method with arguments found in the class
|
71
72
|
# we're prepending to, then let's use a standard getter
|
@@ -78,43 +79,25 @@ module Straight
|
|
78
79
|
# Prohibit status update if the order was paid in some way.
|
79
80
|
# This is just a caching workaround so we don't query
|
80
81
|
# the blockchain needlessly. The actual safety switch is in the setter.
|
81
|
-
|
82
|
-
|
83
|
-
return @status if @status && @status > 1
|
84
|
-
|
85
|
-
if reload || !@status
|
86
|
-
t = transaction(reload: reload)
|
87
|
-
self.status = if t.nil?
|
88
|
-
STATUSES[:new]
|
89
|
-
else
|
90
|
-
if t[:confirmations] >= gateway.confirmations_required
|
91
|
-
if t[:total_amount] == amount
|
92
|
-
STATUSES[:paid]
|
93
|
-
elsif t[:total_amount] < amount
|
94
|
-
STATUSES[:underpaid]
|
95
|
-
else
|
96
|
-
STATUSES[:overpaid]
|
97
|
-
end
|
98
|
-
else
|
99
|
-
STATUSES[:unconfirmed]
|
100
|
-
end
|
101
|
-
end
|
82
|
+
if (reload || @status.nil?) && !status_locked?
|
83
|
+
self.status = get_transaction_status(reload: reload)
|
102
84
|
end
|
103
|
-
|
85
|
+
|
86
|
+
as_sym ? STATUSES.invert[@status] : @status
|
104
87
|
end
|
105
88
|
|
106
89
|
def status=(new_status)
|
107
90
|
# Prohibit status update if the order was paid in some way,
|
108
91
|
# so statuses above 1 are in fact immutable.
|
109
|
-
return false if
|
92
|
+
return false if status_locked?
|
110
93
|
|
111
94
|
self.tid = transaction[:tid] if transaction
|
112
|
-
|
95
|
+
|
113
96
|
# Pay special attention to the order of these statements. If you place
|
114
97
|
# the assignment @status = new_status below the callback call,
|
115
98
|
# you may get a "Stack level too deep" error if the callback checks
|
116
99
|
# for the status and it's nil (therefore, force reload and the cycle continues).
|
117
|
-
#
|
100
|
+
#
|
118
101
|
# The order in which these statements currently are prevents that error, because
|
119
102
|
# by the time a callback checks the status it's already set.
|
120
103
|
@status_changed = (@status != new_status)
|
@@ -124,6 +107,34 @@ module Straight
|
|
124
107
|
super if defined?(super)
|
125
108
|
end
|
126
109
|
|
110
|
+
def set_amount_paid(transaction)
|
111
|
+
self.amount_paid = transaction[:total_amount]
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_transaction_status(reload: false)
|
115
|
+
t = transaction(reload: reload)
|
116
|
+
|
117
|
+
return STATUSES[:new] if t.nil?
|
118
|
+
return STATUSES[:unconfirmed] if status_unconfirmed?(t[:confirmations])
|
119
|
+
|
120
|
+
set_amount_paid(t)
|
121
|
+
if t[:total_amount] == amount
|
122
|
+
STATUSES[:paid]
|
123
|
+
elsif t[:total_amount] < amount
|
124
|
+
STATUSES[:underpaid]
|
125
|
+
else
|
126
|
+
STATUSES[:overpaid]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def status_unconfirmed?(confirmations)
|
131
|
+
confirmations < gateway.confirmations_required
|
132
|
+
end
|
133
|
+
|
134
|
+
def status_locked?
|
135
|
+
@status && @status > 1
|
136
|
+
end
|
137
|
+
|
127
138
|
def status_changed?
|
128
139
|
@status_changed
|
129
140
|
end
|
@@ -170,7 +181,7 @@ module Straight
|
|
170
181
|
def start_periodic_status_check(duration: 600)
|
171
182
|
check_status_on_schedule(duration: duration)
|
172
183
|
end
|
173
|
-
|
184
|
+
|
174
185
|
# Recursion here! Keeps calling itself according to the schedule until
|
175
186
|
# either the status changes or the schedule tells it to stop.
|
176
187
|
def check_status_on_schedule(period: 10, iteration_index: 0, duration: 600, time_passed: 0)
|
@@ -200,8 +211,8 @@ module Straight
|
|
200
211
|
{ status: status, amount: amount, address: address, tid: tid }
|
201
212
|
end
|
202
213
|
|
203
|
-
def amount_in_btc(as: :number)
|
204
|
-
a = Satoshi.new(
|
214
|
+
def amount_in_btc(field: amount, as: :number)
|
215
|
+
a = Satoshi.new(field, from_unit: :satoshi, to_unit: :btc)
|
205
216
|
as == :string ? a.to_unit(as: :string) : a.to_unit
|
206
217
|
end
|
207
218
|
|
data/straight.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: straight 0.
|
5
|
+
# stub: straight 1.0.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "straight"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "1.0.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Roman Snitko"]
|
14
|
-
s.date = "2015-
|
14
|
+
s.date = "2015-07-31"
|
15
15
|
s.description = "An engine for the Straight payment gateway software. Requires no state to be saved (that is, no storage or DB). Its responsibilities only include processing data coming from an actual gateway."
|
16
16
|
s.email = "roman.snitko@gmail.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
23
|
".rspec",
|
24
|
+
".travis.yml",
|
24
25
|
"Gemfile",
|
25
26
|
"Gemfile.lock",
|
26
27
|
"LICENSE.txt",
|
@@ -28,9 +29,12 @@ Gem::Specification.new do |s|
|
|
28
29
|
"Rakefile",
|
29
30
|
"VERSION",
|
30
31
|
"lib/straight.rb",
|
32
|
+
"lib/straight/address_providers/base.rb",
|
33
|
+
"lib/straight/address_providers/bip32.rb",
|
31
34
|
"lib/straight/blockchain_adapter.rb",
|
32
35
|
"lib/straight/blockchain_adapters/biteasy_adapter.rb",
|
33
36
|
"lib/straight/blockchain_adapters/blockchain_info_adapter.rb",
|
37
|
+
"lib/straight/blockchain_adapters/insight_adapter.rb",
|
34
38
|
"lib/straight/blockchain_adapters/mycelium_adapter.rb",
|
35
39
|
"lib/straight/exchange_rate_adapter.rb",
|
36
40
|
"lib/straight/exchange_rate_adapters/average_rate_adapter.rb",
|
@@ -41,23 +45,9 @@ Gem::Specification.new do |s|
|
|
41
45
|
"lib/straight/exchange_rate_adapters/kraken_adapter.rb",
|
42
46
|
"lib/straight/exchange_rate_adapters/localbitcoins_adapter.rb",
|
43
47
|
"lib/straight/exchange_rate_adapters/okcoin_adapter.rb",
|
48
|
+
"lib/straight/faraday_monkeypatch.rb",
|
44
49
|
"lib/straight/gateway.rb",
|
45
50
|
"lib/straight/order.rb",
|
46
|
-
"spec/lib/blockchain_adapters/biteasy_adapter_spec.rb",
|
47
|
-
"spec/lib/blockchain_adapters/blockchain_info_adapter_spec.rb",
|
48
|
-
"spec/lib/blockchain_adapters/mycelium_adapter_spec.rb",
|
49
|
-
"spec/lib/exchange_rate_adapter_spec.rb",
|
50
|
-
"spec/lib/exchange_rate_adapters/average_rate_adapter_spec.rb",
|
51
|
-
"spec/lib/exchange_rate_adapters/bitpay_adapter_spec.rb",
|
52
|
-
"spec/lib/exchange_rate_adapters/bitstamp_adapter_spec.rb",
|
53
|
-
"spec/lib/exchange_rate_adapters/btce_adapter_spec.rb",
|
54
|
-
"spec/lib/exchange_rate_adapters/coinbase_adapter_spec.rb",
|
55
|
-
"spec/lib/exchange_rate_adapters/kraken_adapter_spec.rb",
|
56
|
-
"spec/lib/exchange_rate_adapters/localbitcoins_adapter_spec.rb",
|
57
|
-
"spec/lib/exchange_rate_adapters/okcoin_adapter_spec.rb",
|
58
|
-
"spec/lib/gateway_spec.rb",
|
59
|
-
"spec/lib/order_spec.rb",
|
60
|
-
"spec/spec_helper.rb",
|
61
51
|
"straight.gemspec"
|
62
52
|
]
|
63
53
|
s.homepage = "http://github.com/snitko/straight"
|
@@ -69,24 +59,27 @@ Gem::Specification.new do |s|
|
|
69
59
|
s.specification_version = 4
|
70
60
|
|
71
61
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
72
|
-
s.add_runtime_dependency(%q<
|
73
|
-
s.add_runtime_dependency(%q<satoshi-unit>, ["
|
74
|
-
s.add_runtime_dependency(%q<httparty>, ["
|
62
|
+
s.add_runtime_dependency(%q<btcruby>, ["~> 1.0"])
|
63
|
+
s.add_runtime_dependency(%q<satoshi-unit>, ["~> 0.1"])
|
64
|
+
s.add_runtime_dependency(%q<httparty>, ["~> 0.13.5"])
|
65
|
+
s.add_runtime_dependency(%q<faraday>, [">= 0"])
|
75
66
|
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
76
67
|
s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
|
77
68
|
s.add_development_dependency(%q<github_api>, ["= 0.11.3"])
|
78
69
|
else
|
79
|
-
s.add_dependency(%q<
|
80
|
-
s.add_dependency(%q<satoshi-unit>, ["
|
81
|
-
s.add_dependency(%q<httparty>, ["
|
70
|
+
s.add_dependency(%q<btcruby>, ["~> 1.0"])
|
71
|
+
s.add_dependency(%q<satoshi-unit>, ["~> 0.1"])
|
72
|
+
s.add_dependency(%q<httparty>, ["~> 0.13.5"])
|
73
|
+
s.add_dependency(%q<faraday>, [">= 0"])
|
82
74
|
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
83
75
|
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
84
76
|
s.add_dependency(%q<github_api>, ["= 0.11.3"])
|
85
77
|
end
|
86
78
|
else
|
87
|
-
s.add_dependency(%q<
|
88
|
-
s.add_dependency(%q<satoshi-unit>, ["
|
89
|
-
s.add_dependency(%q<httparty>, ["
|
79
|
+
s.add_dependency(%q<btcruby>, ["~> 1.0"])
|
80
|
+
s.add_dependency(%q<satoshi-unit>, ["~> 0.1"])
|
81
|
+
s.add_dependency(%q<httparty>, ["~> 0.13.5"])
|
82
|
+
s.add_dependency(%q<faraday>, [">= 0"])
|
90
83
|
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
91
84
|
s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
|
92
85
|
s.add_dependency(%q<github_api>, ["= 0.11.3"])
|