exocrypto 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +27 -0
- data/lib/exocrypto/bip44_wallet_provider.rb +317 -0
- data/lib/exocrypto/crypto_calc.rb +97 -0
- data/lib/exocrypto/network.rb +19 -0
- data/lib/exocrypto/version.rb +3 -0
- data/lib/exocrypto.rb +3 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 675e5aafa265e33dec84cb3427d8c71afcd3fec9ab3118210be650e96c5b3101
|
4
|
+
data.tar.gz: eff4eeb5a746b56925a0860e6c867ced98f4bb480477c48f14cabdb777487297
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 20e268da580a84adfcc9563fa2004037b41e05ef288523925d4c5fc070aa9d0f454dbcda19ae8b65a0e5abab82d144faa4e3e1dee5a5f83e25cf838f236ddb6a
|
7
|
+
data.tar.gz: bfff000fe68bbb3affd5360fdcc94e63b4d714812cc0402dc0c05ecab307d2782e8ec9694e5a028f851788d5db4d0b2882e0155abcaf0275935282829da224a5
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# ExoCrypto
|
2
|
+
|
3
|
+
CryptoHelpers: This gem provides helpers for crypto calculus.
|
4
|
+
|
5
|
+
- Addresses
|
6
|
+
- HD Wallets
|
7
|
+
|
8
|
+
[reference for gem creation: [newgem-template](https://github.com/wycats/newgem-template)]
|
9
|
+
|
10
|
+
[reference for git init: [github init](https://gist.github.com/seankross/8830032)]
|
11
|
+
|
12
|
+
|
13
|
+
## Getting started
|
14
|
+
|
15
|
+
`bundle`
|
16
|
+
|
17
|
+
`rake build`
|
18
|
+
|
19
|
+
`gem push [GEM.gem]`
|
20
|
+
|
21
|
+
|
22
|
+
### Requirements
|
23
|
+
|
24
|
+
- Ruby 2.5+
|
25
|
+
- Bitcoin-ruby 0.0.20
|
26
|
+
- BIP44 0.2.18
|
27
|
+
- ExoBasic 0.1.0
|
@@ -0,0 +1,317 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'openssl'
|
3
|
+
require 'ecdsa'
|
4
|
+
require 'digest'
|
5
|
+
require 'digest/sha3'
|
6
|
+
require 'rlp'
|
7
|
+
require 'money-tree'
|
8
|
+
require 'bip_mnemonic'
|
9
|
+
require 'eth'
|
10
|
+
require "bip44/version"
|
11
|
+
require 'bip44/utils'
|
12
|
+
require 'bip44/bitcoin'
|
13
|
+
require 'bip44/ethereum'
|
14
|
+
require 'bip44/wallet'
|
15
|
+
|
16
|
+
module ExoCrypto
|
17
|
+
# see: https://github.com/wuminzhe/bip44
|
18
|
+
class Bip44WalletProvider
|
19
|
+
TESTNET_TICKER = 'TESTNET'
|
20
|
+
|
21
|
+
# see: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
22
|
+
def self.ticker_map
|
23
|
+
{
|
24
|
+
'TESTNET' => {
|
25
|
+
:slip => 1,
|
26
|
+
:precision => 8
|
27
|
+
},
|
28
|
+
'BTC' => {
|
29
|
+
:slip => 0,
|
30
|
+
:precision => 8
|
31
|
+
},
|
32
|
+
'ETH' => {
|
33
|
+
:slip => 60,
|
34
|
+
:precision => 18
|
35
|
+
},
|
36
|
+
'DASH' => {
|
37
|
+
:slip => 5,
|
38
|
+
:precision => 8
|
39
|
+
},
|
40
|
+
'DOGE' => {
|
41
|
+
:slip => 3,
|
42
|
+
:precision => 8
|
43
|
+
},
|
44
|
+
'LTC' => {
|
45
|
+
:slip => 2,
|
46
|
+
:precision => 8
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.coins
|
52
|
+
Bip44WalletProvider.ticker_map.keys.to_set.delete(Bip44WalletProvider::TESTNET_TICKER)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.precision_of(ticker)
|
56
|
+
Bip44WalletProvider.ticker_map[ticker][:precision]
|
57
|
+
end
|
58
|
+
|
59
|
+
# see: https://github.com/citizen010/bitcoin-prefixes-address-list
|
60
|
+
def self.address_details(sub_wallet, is_testnet, include_private)
|
61
|
+
if include_private
|
62
|
+
{
|
63
|
+
:bitcoin_address => sub_wallet.bitcoin_address(testnet: is_testnet),
|
64
|
+
:ethereum_address => sub_wallet.ethereum_address,
|
65
|
+
:public_hex => sub_wallet.public_key,
|
66
|
+
:private_hex => sub_wallet.private_key,
|
67
|
+
:private_wif => sub_wallet.wif(testnet: is_testnet)
|
68
|
+
}
|
69
|
+
else
|
70
|
+
{
|
71
|
+
:bitcoin_address => sub_wallet.bitcoin_address(testnet: is_testnet),
|
72
|
+
:ethereum_address => sub_wallet.ethereum_address,
|
73
|
+
:public_hex => sub_wallet.public_key
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.master_details(mnemonic, wallet, is_testnet)
|
79
|
+
{
|
80
|
+
:mnemonic => mnemonic,
|
81
|
+
:seed_hex => BipMnemonic.to_seed(mnemonic: mnemonic),
|
82
|
+
:xpub => wallet.xpub(testnet: is_testnet),
|
83
|
+
:xprv => wallet.xprv(testnet: is_testnet),
|
84
|
+
:details => Bip44WalletProvider.address_details(wallet, is_testnet, true)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.create_wallet(coin_ticker='BTC')
|
89
|
+
words = BipMnemonic.to_mnemonic(bits: 128)
|
90
|
+
seed = BipMnemonic.to_seed(mnemonic: words)
|
91
|
+
|
92
|
+
coin = ticker_map[coin_ticker][:slip]
|
93
|
+
path = "m/44'/#{coin}'/0'"
|
94
|
+
wallet = Bip44::Wallet.from_seed(seed, path)
|
95
|
+
testnet = coin_ticker == Bip44WalletProvider::TESTNET_TICKER
|
96
|
+
|
97
|
+
{
|
98
|
+
:obj => wallet,
|
99
|
+
:seed_hex => seed,
|
100
|
+
:path => path,
|
101
|
+
:details => Bip44WalletProvider.master_details(words, wallet, testnet)
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.create_subwallet(xpub, sub_path, is_testnet=false)
|
106
|
+
wallet = Bip44::Wallet.from_xpub(xpub)
|
107
|
+
sub_wallet = wallet.sub_wallet(sub_path)
|
108
|
+
|
109
|
+
{
|
110
|
+
:obj => sub_wallet,
|
111
|
+
:path => sub_path,
|
112
|
+
:details => Bip44WalletProvider.address_details(sub_wallet, is_testnet, false)
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.seed_of(mnemonic, password=nil)
|
117
|
+
#BipMnemonic.to_seed(mnemonic: mnemonic)
|
118
|
+
OpenSSL::PKCS5.pbkdf2_hmac(mnemonic,
|
119
|
+
"mnemonic#{password}",
|
120
|
+
2048,
|
121
|
+
64,
|
122
|
+
OpenSSL::Digest::SHA512.new)
|
123
|
+
.unpack('H*').first
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.btc_address_details_of(seed, path, is_testnet=false)
|
127
|
+
wallet = Bip44::Wallet.from_seed(seed, path)
|
128
|
+
details = Bip44WalletProvider.address_details(wallet, is_testnet, true)
|
129
|
+
details[:address] = details[:bitcoin_address]
|
130
|
+
details.delete(:bitcoin_address)
|
131
|
+
details.delete(:ethereum_address)
|
132
|
+
details
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.from_absolute_path(path)
|
136
|
+
elements = path.split('/')
|
137
|
+
derivation = "m/#{elements.take(4).drop(1).join('/')}"
|
138
|
+
relative = "m/#{elements.drop(4).join('/')}"
|
139
|
+
|
140
|
+
{
|
141
|
+
:absolute_path => path,
|
142
|
+
:derivation => derivation,
|
143
|
+
:relative_path => relative
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# see: https://gobittest.appspot.com/PrivateKey
|
149
|
+
# https://github.com/dougal/base58/blob/master/lib/base58.rb
|
150
|
+
# http://royalforkblog.github.io/2014/07/31/address-gen
|
151
|
+
#
|
152
|
+
def self.sha256(hex)
|
153
|
+
Digest::SHA256.hexdigest([hex].pack('H*'))
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.ripemd160(hex)
|
157
|
+
Digest::RMD160.hexdigest([hex].pack('H*'))
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.checksum(hex)
|
161
|
+
Bip44WalletProvider.sha256(Bip44WalletProvider.sha256(hex))[0...8]
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.int_to_hex(int)
|
165
|
+
hex = int.to_s(16)
|
166
|
+
#
|
167
|
+
# The hex string must always consist of an even number of characters,
|
168
|
+
# otherwise the pack() parsing will be misaligned.
|
169
|
+
#
|
170
|
+
(hex.length % 2 == 0) ? hex : ('0' + hex)
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.btc_int_to_base58(int_val, leading_zero_bytes=0)
|
174
|
+
alpha = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
175
|
+
base58_val, base = '', alpha.size
|
176
|
+
while int_val > 0
|
177
|
+
int_val, remainder = int_val.divmod(base)
|
178
|
+
base58_val = alpha[remainder] + base58_val
|
179
|
+
end
|
180
|
+
|
181
|
+
base58_val
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.btc_encode_base58(hex)
|
185
|
+
leading_zero_bytes = (hex.match(/^([0]+)/) ? $1 : '').size / 2
|
186
|
+
('1' * leading_zero_bytes) + Bip44WalletProvider.btc_int_to_base58(hex.to_i(16))
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.btc_base58_to_int(base58_val)
|
190
|
+
alpha = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
191
|
+
int_val, base = 0, alpha.size
|
192
|
+
base58_val.reverse.split(//).each_with_index do |char, index|
|
193
|
+
char_index = alpha.index(char)
|
194
|
+
int_val += char_index * base**index
|
195
|
+
end
|
196
|
+
|
197
|
+
int_val
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.btc_decode_base58(base58_val)
|
201
|
+
nzeroes = base58_val.chars.find_index { |c| c != '1' } || base58_val.length - 1
|
202
|
+
prefix = nzeroes < 0 ? '' : '00' * nzeroes
|
203
|
+
decoded = Bip44WalletProvider.int_to_hex(Bip44WalletProvider.btc_base58_to_int(base58_val))
|
204
|
+
|
205
|
+
[prefix + decoded].pack('H*')
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.btc_wif_of_privkey(hex, is_compressed=false, is_testnet=false)
|
209
|
+
priv_key_version = is_testnet ? 'ef' : '80'
|
210
|
+
data = priv_key_version + hex
|
211
|
+
if is_compressed
|
212
|
+
data += '01'
|
213
|
+
end
|
214
|
+
|
215
|
+
Bip44WalletProvider.btc_encode_base58(data + Bip44WalletProvider.checksum(data))
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.btc_privkey_of_wif(wif, is_compressed=false)
|
219
|
+
result = Bip44WalletProvider.btc_decode_base58(wif)[1..-5].unpack('H*').first
|
220
|
+
if is_compressed
|
221
|
+
result = result[0...-2]
|
222
|
+
end
|
223
|
+
result
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.btc_pubkey_of_wif(wif, is_compressed=false, is_testnet=false)
|
227
|
+
priv_key = Bip44WalletProvider.btc_privkey_of_wif(wif, is_compressed)
|
228
|
+
group = OpenSSL::PKey::EC::Group.new('secp256k1')
|
229
|
+
public_key = group.generator.mul(OpenSSL::BN.new(priv_key, 16))
|
230
|
+
decompressed_public_key_hex = public_key.to_bn.to_s(16)
|
231
|
+
|
232
|
+
# NOTE: for compression
|
233
|
+
public_key_hex = decompressed_public_key_hex
|
234
|
+
if is_compressed
|
235
|
+
x = decompressed_public_key_hex[2..-1][0..63]
|
236
|
+
y = decompressed_public_key_hex[2..-1][64..-1]
|
237
|
+
leader = y.to_i(16) % 2 == 0 ? '02' : '03'
|
238
|
+
public_key_hex = leader + x
|
239
|
+
end
|
240
|
+
|
241
|
+
public_key_hash = Bip44WalletProvider.ripemd160(Bip44WalletProvider.sha256(public_key_hex))
|
242
|
+
network = is_testnet ? '6f' : '00'
|
243
|
+
data = network + public_key_hash
|
244
|
+
|
245
|
+
public_address =
|
246
|
+
Bip44WalletProvider.btc_encode_base58(data + Bip44WalletProvider.checksum(data))
|
247
|
+
|
248
|
+
{
|
249
|
+
:decompressed_public_key => decompressed_public_key_hex,
|
250
|
+
:public_key => public_key_hex,
|
251
|
+
:bitcoin_address => public_address
|
252
|
+
}
|
253
|
+
end
|
254
|
+
def self.btc_pubkey_of_wif_ecdsa(wif, is_compressed=false, is_testnet=false)
|
255
|
+
priv_key = Bip44WalletProvider.btc_privkey_of_wif(wif, is_compressed)
|
256
|
+
|
257
|
+
# kpub = kpriv * G
|
258
|
+
curve = ECDSA::Group::Secp256k1
|
259
|
+
pub_key_point = curve.generator.multiply_by_scalar(priv_key.to_i(16))
|
260
|
+
|
261
|
+
#
|
262
|
+
# uncompressed, pub key is in form 0x04 + x + y
|
263
|
+
# compressed, pub key is in form
|
264
|
+
# 0x02 + x if y is even
|
265
|
+
# 0x03 + x if y is odd
|
266
|
+
# Getting encodings right is difficult...pub.x is a Bignum. Bignum + Bignum is
|
267
|
+
# a biggernum, which isn't really what we want. We want string concatenation. To do that,
|
268
|
+
# we translate to hex, concatenate the hex, and pack it back into a string to
|
269
|
+
# concatenate with our leading byte
|
270
|
+
#
|
271
|
+
# pub.x is a Bignum,
|
272
|
+
# so we must concatenate our compression byte with the hex representation of pub_key.x
|
273
|
+
#
|
274
|
+
decompressed_pub_key = "\x04" +
|
275
|
+
[pub_key_point.x.to_s(16)].pack('H*') +
|
276
|
+
[pub_key_point.y.to_s(16)].pack('H*')
|
277
|
+
pub_key = decompressed_pub_key
|
278
|
+
if is_compressed
|
279
|
+
leader = pub_key_point.y % 2 == 0 ? "\x02" : "\x03"
|
280
|
+
pub_key = leader + [pub_key_point.x.to_s(16)].pack('H*')
|
281
|
+
end
|
282
|
+
|
283
|
+
# ripe160(sha256(pub_key))
|
284
|
+
pub_key_hash = Digest::RMD160.digest(Digest::SHA256.digest(pub_key))
|
285
|
+
|
286
|
+
#
|
287
|
+
# prepend version to our double hashed pub key, append checksum
|
288
|
+
# Bitcoin: 0x00
|
289
|
+
# Testnet: 0x6f
|
290
|
+
#
|
291
|
+
network = is_testnet ? "\x6f" : "\x00"
|
292
|
+
pub_key_hash_and_version = network + pub_key_hash
|
293
|
+
|
294
|
+
# add checksum
|
295
|
+
pub_key_hash_and_version_str = pub_key_hash_and_version.unpack('H*').first
|
296
|
+
pub_key_hash_and_version_and_checksum = pub_key_hash_and_version_str +
|
297
|
+
Bip44WalletProvider.checksum(
|
298
|
+
pub_key_hash_and_version_str)
|
299
|
+
|
300
|
+
# base58 encode version, hash, checksum
|
301
|
+
pub_addr = Bip44WalletProvider.btc_encode_base58(pub_key_hash_and_version_and_checksum)
|
302
|
+
|
303
|
+
{
|
304
|
+
:decompressed_public_key => decompressed_pub_key.unpack("H*").first,
|
305
|
+
:public_key => pub_key.unpack("H*").first,
|
306
|
+
:bitcoin_address => pub_addr
|
307
|
+
}
|
308
|
+
end
|
309
|
+
|
310
|
+
def self.btc_pubkey_of_privkey(hex, is_compressed=false, is_testnet=false)
|
311
|
+
priv = Bip44WalletProvider.btc_wif_of_privkey(hex, is_compressed, is_testnet)
|
312
|
+
|
313
|
+
Bip44WalletProvider.btc_pubkey_of_wif(priv, is_compressed, is_testnet)
|
314
|
+
end
|
315
|
+
|
316
|
+
end
|
317
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module ExoCrypto
|
2
|
+
class CryptoCalc
|
3
|
+
def self.mul(a, b)
|
4
|
+
BigDecimal(a) * BigDecimal(b)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.s_to_satoshis(amount, precision)
|
8
|
+
(BigDecimal(amount) * BigDecimal(10 ** precision)).to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.s_from_satoshis(amount, precision)
|
12
|
+
(amount / BigDecimal(10 ** precision)).to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.fixed_length_to_s(amount, precision)
|
16
|
+
"%.#{precision}f" % amount
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.to_fixed_length(amount, currency)
|
20
|
+
precision = Bip44WalletProvider.precision_of(currency)
|
21
|
+
CryptoCalc.fixed_length_to_s(CryptoCalc.s_from_satoshis(amount, precision), precision)
|
22
|
+
end
|
23
|
+
|
24
|
+
# see: https://reinteractive.com/posts/373-diving-into-the-ruby-source-code-bigdecimal-rounding-options
|
25
|
+
def self.get_satoshis(currency, exchange_rate, remaining)
|
26
|
+
precision = Bip44WalletProvider.precision_of(currency)
|
27
|
+
amount_to_be_paid = 0
|
28
|
+
rate = BigDecimal(exchange_rate)
|
29
|
+
if !rate.zero?
|
30
|
+
amount_to_be_paid = BigDecimal(remaining) / rate
|
31
|
+
amount_to_be_paid = (amount_to_be_paid.round(precision) * BigDecimal(10 ** precision)).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
amount_to_be_paid
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.do_partial_payments(request, payments)
|
38
|
+
epoch = ExoBasic::Timer::EPOCH.to_datetime
|
39
|
+
xs = payments.map do |payment|
|
40
|
+
if payment[:paid]
|
41
|
+
precision = Bip44WalletProvider.precision_of(payment[:currency])
|
42
|
+
satoshis = BigDecimal(payment[:amount_paid]) * BigDecimal(payment[:exchange_rate])
|
43
|
+
|
44
|
+
[satoshis / BigDecimal(10 ** precision), payment[:date]]
|
45
|
+
else
|
46
|
+
[BigDecimal(0), epoch]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
total_paid = xs.map { |x| x[0] }.sum
|
50
|
+
paid_date = xs.map { |x| x[1] }.max
|
51
|
+
if paid_date == epoch
|
52
|
+
paid_date = nil
|
53
|
+
end
|
54
|
+
request_amount = request[:amount]
|
55
|
+
request_precision = request[:precision]
|
56
|
+
total_paid_rounded_s = CryptoCalc.fixed_length_to_s(total_paid.round(request_precision),
|
57
|
+
request_precision)
|
58
|
+
remaining = BigDecimal(request[:amount]) - BigDecimal(total_paid_rounded_s)
|
59
|
+
remaining_rounded_s = CryptoCalc.fixed_length_to_s(remaining.round(request_precision),
|
60
|
+
request_precision)
|
61
|
+
n_paid = payments.select { |payment| payment[:paid] == true }.length
|
62
|
+
n_unpaid = payments.length - n_paid
|
63
|
+
remaining_rounded = BigDecimal(remaining_rounded_s)
|
64
|
+
needs_change = remaining_rounded < BigDecimal(0)
|
65
|
+
is_fully_paid = remaining_rounded.zero? || needs_change
|
66
|
+
is_partially_paid = !is_fully_paid && remaining_rounded < BigDecimal(request_amount)
|
67
|
+
|
68
|
+
{
|
69
|
+
:n_paid => n_paid,
|
70
|
+
:n_unpaid => n_unpaid,
|
71
|
+
:paid_date => paid_date,
|
72
|
+
:amount_paid => total_paid_rounded_s,
|
73
|
+
:amount_remaining => remaining_rounded_s,
|
74
|
+
:overpaid => needs_change,
|
75
|
+
:is_fully_paid => is_fully_paid,
|
76
|
+
:is_partially_paid => is_partially_paid
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.apply_fun(f, args)
|
81
|
+
args_prime = args.map { |i| BigDecimal(i) }
|
82
|
+
|
83
|
+
lambdas = {
|
84
|
+
'fst' => lambda { |args| args[0] },
|
85
|
+
'1/fst' => lambda { |args| 1.0 / args[0] },
|
86
|
+
'fst,snd' => lambda { |args| [args[0], args[1]] },
|
87
|
+
'fst*snd' => lambda { |args| args[0] * args[1] },
|
88
|
+
'fst/snd' => lambda { |args| args[0] / args[1] },
|
89
|
+
'snd/fst' => lambda { |args| args[1] / args[0] },
|
90
|
+
'1/(fst*snd)' => lambda { |args| 1.0 / (args[0] * args[1]) },
|
91
|
+
}
|
92
|
+
|
93
|
+
lambdas[f].call(args_prime)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ExoCrypto
|
2
|
+
class Network
|
3
|
+
SETTINGS_SECTION = 'crypto_network'
|
4
|
+
|
5
|
+
@@conf = ExoBasic::Settings.loaded
|
6
|
+
ExoBasic::Settings.add_on_load_observer(Network)
|
7
|
+
|
8
|
+
def self.is_testnet?
|
9
|
+
ExoBasic::Settings.try_get_nested_key(@@conf,
|
10
|
+
false,
|
11
|
+
[Network::SETTINGS_SECTION, 'testnet'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.settings_reloaded
|
15
|
+
@@conf = ExoBasic::Settings.loaded
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/exocrypto.rb
ADDED
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: exocrypto
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dionysios Kakolyris
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-01-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bitcoin-ruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.20
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.20
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bip44
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.18
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.2.18
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: exobasic
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.1.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.1.0
|
55
|
+
description: Exotic Crypto Helpers
|
56
|
+
email:
|
57
|
+
- contact@exotic.industries
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- README.md
|
63
|
+
- lib/exocrypto.rb
|
64
|
+
- lib/exocrypto/bip44_wallet_provider.rb
|
65
|
+
- lib/exocrypto/crypto_calc.rb
|
66
|
+
- lib/exocrypto/network.rb
|
67
|
+
- lib/exocrypto/version.rb
|
68
|
+
homepage: https://bitbucket.org/vertigoindustries/exotic-crypto
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.3.6
|
86
|
+
requirements: []
|
87
|
+
rubygems_version: 3.0.6
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: CryptoHelpers
|
91
|
+
test_files: []
|