straight 0.2.3 → 1.0.0
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 +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"])
|