axentro-rb-util 0.0.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 +7 -0
- data/lib/axentro-rb-util.rb +17 -0
- data/lib/crypto/crypto.rb +2 -0
- data/lib/crypto/hashes.rb +13 -0
- data/lib/crypto/key_ring.rb +53 -0
- data/lib/crypto/keys/address.rb +66 -0
- data/lib/crypto/keys/key_utils.rb +61 -0
- data/lib/crypto/keys/private_key.rb +45 -0
- data/lib/crypto/keys/public_key.rb +35 -0
- data/lib/crypto/keys/wif.rb +49 -0
- data/lib/crypto/transaction.rb +57 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d00fc176356de2e02ba47caa16f5459c41c0d9a2ce022b7e22aa380f7fab9cde
|
4
|
+
data.tar.gz: 673c47711f9fbd2ff8d401c3c070f85c6421a4e4f8b3cdffe85553b7eed5857b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a81510252a00f751a1e242f50b1401e4acdc1204d511ac7265e6a92a54c162db3d790c19ef61b767452cfc171b73dac63d95b295fa1c96905fc0b2b288c821eb
|
7
|
+
data.tar.gz: 5c0ac4441f07ce2e59d72aa7bdc946a7f0dce57f1e5bd15149df05c638fefd9e2d8b20fb6c3c6cc82723066e1592bf5c06f7d900108db3583a24cb0f12fdff18
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "json"
|
2
|
+
require "securerandom"
|
3
|
+
require 'bigdecimal'
|
4
|
+
require "ed25519-hd"
|
5
|
+
require "faraday"
|
6
|
+
require "crypto/crypto"
|
7
|
+
require "crypto/hashes"
|
8
|
+
require "crypto/keys/address"
|
9
|
+
require "crypto/keys/key_utils"
|
10
|
+
require "crypto/keys/private_key"
|
11
|
+
require "crypto/keys/public_key"
|
12
|
+
require "crypto/keys/wif"
|
13
|
+
require "crypto/key_ring"
|
14
|
+
require "crypto/transaction"
|
15
|
+
|
16
|
+
include Crypto
|
17
|
+
include Keys
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Crypto::Keys
|
2
|
+
include Crypto::Hashes
|
3
|
+
|
4
|
+
MAINNET = { prefix: "M0", name: "mainnet" }
|
5
|
+
TESTNET = { prefix: "T0", name: "testnet" }
|
6
|
+
|
7
|
+
class KeyRing
|
8
|
+
attr_reader :private_key
|
9
|
+
attr_reader :public_key
|
10
|
+
attr_reader :wif
|
11
|
+
attr_reader :address
|
12
|
+
attr_reader :address
|
13
|
+
attr_reader :seed
|
14
|
+
|
15
|
+
def initialize(private_key, public_key, wif, address, seed = nil)
|
16
|
+
@private_key = private_key
|
17
|
+
@public_key = public_key
|
18
|
+
@wif = wif
|
19
|
+
@address = address
|
20
|
+
@seed = seed
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.generate(network = MAINNET)
|
24
|
+
key_pair = KeyUtils.create_new_keypair
|
25
|
+
private_key = PrivateKey.new(key_pair[:hex_private_key], network)
|
26
|
+
public_key = PublicKey.new(key_pair[:hex_public_key], network)
|
27
|
+
KeyRing.new(private_key, public_key, private_key.wif, public_key.address)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.generate_hd(seed = nil, derivation = nil, network = MAINNET)
|
31
|
+
_seed = seed.nil? ? SecureRandom.hex(64) : seed
|
32
|
+
keys = (derivation.nil? || derivation.nil? && derivation == "m") ?
|
33
|
+
HDKEY::KeyRing.get_master_key_from_seed(_seed) : HDKEY::KeyRing.derive_path(derivation, _seed, HDKEY::HARDENED_AXENTRO)
|
34
|
+
|
35
|
+
private_key = PrivateKey.new(keys.private_key, network)
|
36
|
+
_public_key = HDKEY::KeyRing.get_public_key(keys.private_key)[2..-1]
|
37
|
+
public_key = PublicKey.new(_public_key, network)
|
38
|
+
KeyRing.new(private_key, public_key, private_key.wif, public_key.address, _seed)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.is_valid?(public_key, wif, address)
|
42
|
+
address = Address.from(address)
|
43
|
+
wif = Wif.new(wif)
|
44
|
+
|
45
|
+
raise AxentroError, "network mismatch between address and wif" if address.network != wif.network
|
46
|
+
|
47
|
+
public_key = PublicKey.from_hex(public_key, address.network)
|
48
|
+
raise AxentroError, "public key mismatch between public key and wif" if public_key.as_hex != wif.public_key.as_hex
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "base64"
|
2
|
+
|
3
|
+
class AxentroError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
module Crypto::Keys
|
7
|
+
class Address
|
8
|
+
attr_reader :network
|
9
|
+
|
10
|
+
def initialize(hex_address, network = MAINNET, name = "generic")
|
11
|
+
@hex_address = hex_address
|
12
|
+
@network = network
|
13
|
+
@name = name
|
14
|
+
unless is_valid?
|
15
|
+
raise AxentroError, "invalid '#{@name}' address checksum for: '#{@hex_address}'"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_hex
|
20
|
+
@hex_address
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from(hex_address, name = "")
|
24
|
+
network = get_network_from_address(hex_address)
|
25
|
+
Address.new(hex_address, network, name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def is_valid?
|
29
|
+
Address.is_valid?(@hex_address)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.is_valid?(hex_address)
|
33
|
+
begin
|
34
|
+
decoded_address = Base64.strict_decode64(hex_address)
|
35
|
+
return false unless decoded_address.size == 48
|
36
|
+
version_address = decoded_address[0..-7]
|
37
|
+
hashed_address = Crypto::Hashes.sha256(Crypto::Hashes.sha256(version_address))
|
38
|
+
checksum = decoded_address[-6..-1]
|
39
|
+
checksum == hashed_address[0..5]
|
40
|
+
rescue AxentroError => e
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.get_network_from_address(hex_address)
|
46
|
+
begin
|
47
|
+
decoded_address = Base64.strict_decode64(hex_address)
|
48
|
+
rescue => e
|
49
|
+
raise AxentroError, "invalid address: #{e}"
|
50
|
+
end
|
51
|
+
|
52
|
+
case decoded_address[0..1]
|
53
|
+
when MAINNET[:prefix]
|
54
|
+
MAINNET
|
55
|
+
when TESTNET[:prefix]
|
56
|
+
TESTNET
|
57
|
+
else
|
58
|
+
raise AxentroError, "invalid network: #{decoded_address[0..1]} for address: #{hex_address}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s
|
63
|
+
as_hex
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Crypto::Keys
|
2
|
+
class KeyUtils
|
3
|
+
def self.verify_signature(message, signature_hex, hex_public_key)
|
4
|
+
begin
|
5
|
+
verify_key = Ed25519::VerifyKey.new([hex_public_key].pack("H*"))
|
6
|
+
verify_key.verify([signature_hex].pack("H*"), message)
|
7
|
+
rescue => e
|
8
|
+
raise AxentroError, "Verify fail: #{e.message}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.sign(hex_private_key, message)
|
13
|
+
signing_key = Ed25519::SigningKey.new([hex_private_key].pack("H*"))
|
14
|
+
signing_key.sign(message).unpack("H*").first
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.create_new_keypair
|
18
|
+
signing_key = Ed25519::SigningKey.generate
|
19
|
+
private_key = signing_key.keypair.unpack("H*").first[0..63]
|
20
|
+
public_key = signing_key.keypair.unpack("H*").first[64..-1]
|
21
|
+
{
|
22
|
+
hex_private_key: private_key,
|
23
|
+
hex_public_key: public_key
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.to_hex(bytes)
|
28
|
+
bytes.pack("c*").unpack("H*").first
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.to_bytes(hex)
|
32
|
+
[hex].pack('H*').bytes.to_a
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.get_address_from_public_key(public_key)
|
36
|
+
hashed_address = Crypto::Hashes.ripemd160(Crypto::Hashes.sha256(public_key.as_hex))
|
37
|
+
network_address = public_key.network[:prefix] + hashed_address
|
38
|
+
hashed_address_again = Crypto::Hashes.sha256(Crypto::Hashes.sha256(network_address))
|
39
|
+
checksum = hashed_address_again[0..5]
|
40
|
+
Base64.strict_encode64(network_address + checksum)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.to_wif(key, network)
|
44
|
+
private_key = key.as_hex
|
45
|
+
network_key = network[:prefix] + private_key
|
46
|
+
hashed_key = Crypto::Hashes.sha256(Crypto::Hashes.sha256(network_key))
|
47
|
+
checksum = hashed_key[0..5]
|
48
|
+
encoded_key = Base64.strict_encode64(network_key + checksum)
|
49
|
+
Wif.new(encoded_key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.from_wif(wif)
|
53
|
+
decoded_wif = Base64.strict_decode64(wif.as_hex)
|
54
|
+
network_prefix = decoded_wif[0..1]
|
55
|
+
network = network_prefix == "M0" ? MAINNET : TESTNET
|
56
|
+
private_key_hex = decoded_wif[2..-7]
|
57
|
+
private_key = PrivateKey.from_hex(private_key_hex)
|
58
|
+
{private_key: private_key, network: network}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Crypto::Keys
|
2
|
+
class PrivateKey
|
3
|
+
attr_reader :network
|
4
|
+
|
5
|
+
def initialize(private_key_hex, network = MAINNET)
|
6
|
+
@private_key_hex = private_key_hex
|
7
|
+
@network = network
|
8
|
+
raise AxentroError, "invalid private key: '#{@private_key_hex}'" unless is_valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_hex(hex, network = MAINNET)
|
12
|
+
PrivateKey.new(hex, network)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_bytes(bytes, network = MAINNET)
|
16
|
+
PrivateKey.new(KeyUtils.to_hex(bytes), network)
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_hex
|
20
|
+
@private_key_hex
|
21
|
+
end
|
22
|
+
|
23
|
+
def as_bytes
|
24
|
+
KeyUtils.to_bytes(@private_key_hex)
|
25
|
+
end
|
26
|
+
|
27
|
+
def wif
|
28
|
+
Wif.from(self, @network)
|
29
|
+
end
|
30
|
+
|
31
|
+
def public_key
|
32
|
+
signing_key = Ed25519::SigningKey.new([@private_key_hex].pack("H*"))
|
33
|
+
hex_public_key = signing_key.keypair.unpack("H*").first[64..-1]
|
34
|
+
PublicKey.new(hex_public_key, @network)
|
35
|
+
end
|
36
|
+
|
37
|
+
def address
|
38
|
+
Address.new(KeyUtils.get_address_from_public_key(self.public_key), @network)
|
39
|
+
end
|
40
|
+
|
41
|
+
def is_valid?
|
42
|
+
!@private_key_hex.nil? && @private_key_hex.size == 64
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Crypto::Keys
|
2
|
+
class PublicKey
|
3
|
+
attr_reader :network
|
4
|
+
|
5
|
+
def initialize(public_key_hex, network = MAINNET)
|
6
|
+
@public_key_hex = public_key_hex
|
7
|
+
@network = network
|
8
|
+
raise AxentroError, "invalid public key: #{@public_key_hex}" unless is_valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_hex(hex, network = MAINNET)
|
12
|
+
PublicKey.new(hex, network)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_bytes(bytes, network = MAINNET)
|
16
|
+
PublicKey.new(KeyUtils.to_hex(bytes), network)
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_hex
|
20
|
+
@public_key_hex
|
21
|
+
end
|
22
|
+
|
23
|
+
def as_bytes
|
24
|
+
KeyUtils.to_bytes(@public_key_hex)
|
25
|
+
end
|
26
|
+
|
27
|
+
def address
|
28
|
+
Address.new(KeyUtils.get_address_from_public_key(self), @network)
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_valid?
|
32
|
+
!@public_key_hex.nil? && @public_key_hex.size == 64
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Crypto::Keys
|
2
|
+
class Wif
|
3
|
+
def initialize(wif_hex)
|
4
|
+
@wif_hex = wif_hex
|
5
|
+
raise AxentroError, "invalid wif: #{@wif_hex}" unless is_valid?
|
6
|
+
end
|
7
|
+
|
8
|
+
def as_hex
|
9
|
+
@wif_hex
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from(private_key, network = MAINNET)
|
13
|
+
wif = KeyUtils.to_wif(private_key, network)
|
14
|
+
raise AxentroError, "invalid wif: #{wif.as_hex}" unless wif.is_valid?
|
15
|
+
wif
|
16
|
+
end
|
17
|
+
|
18
|
+
def private_key
|
19
|
+
KeyUtils.from_wif(self)[:private_key]
|
20
|
+
end
|
21
|
+
|
22
|
+
def public_key
|
23
|
+
KeyUtils.from_wif(self)[:private_key].public_key
|
24
|
+
end
|
25
|
+
|
26
|
+
def network
|
27
|
+
KeyUtils.from_wif(self)[:network]
|
28
|
+
end
|
29
|
+
|
30
|
+
def address
|
31
|
+
res = KeyUtils.from_wif(self)
|
32
|
+
public_key = res[:private_key].public_key
|
33
|
+
network = res[:network]
|
34
|
+
Address.new(KeyUtils.get_address_from_public_key(public_key), network)
|
35
|
+
end
|
36
|
+
|
37
|
+
def is_valid?
|
38
|
+
begin
|
39
|
+
decoded_wif = Base64.strict_decode64(@wif_hex)
|
40
|
+
network_key = decoded_wif[0..-7]
|
41
|
+
hashed_key = Crypto::Hashes.sha256(Crypto::Hashes.sha256(network_key))
|
42
|
+
checksum = hashed_key[0..5]
|
43
|
+
checksum == decoded_wif[-6..-1]
|
44
|
+
rescue
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Crypto::Transaction
|
2
|
+
extend self
|
3
|
+
SCALE_DECIMAL = 100000000
|
4
|
+
|
5
|
+
def create_signed_send_transaction(from_address, from_public_key, wif, to_address, amount, fee = "0.0001", speed = "FAST")
|
6
|
+
from_private_key = __get_private_key_from_wif(wif)
|
7
|
+
__create_signed_send_token_transaction(from_address, from_public_key, from_private_key, to_address, amount, fee, speed)
|
8
|
+
end
|
9
|
+
|
10
|
+
def post_transaction(transaction_json, url = "https://mainnet.axentro.io")
|
11
|
+
begin
|
12
|
+
response = Faraday.post("#{url}/api/v1/transaction", transaction_json, "Content-Type" => "application/json")
|
13
|
+
raise "status code was: #{response.status}" if response.status != 200
|
14
|
+
json_response = JSON.parse(response.body)
|
15
|
+
json_response["result"]["id"].to_s
|
16
|
+
rescue => e
|
17
|
+
puts "Error sending transaction: #{e}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def __create_signed_send_token_transaction(from_address, from_public_key, from_private_key, to_address, amount, fee = "0.0001", speed = "FAST")
|
22
|
+
transaction_id = __create_id
|
23
|
+
timestamp = __timestamp
|
24
|
+
scaled_amount = __scale_i64(amount)
|
25
|
+
scaled_fee = __scale_i64(fee)
|
26
|
+
|
27
|
+
unsigned_transaction = %Q{{"id":"#{transaction_id}","action":"send","senders":[{"address":"#{from_address}","public_key":"#{from_public_key}","amount":#{scaled_amount},"fee":#{scaled_fee},"signature":"0"}],"recipients":[{"address":"#{to_address}","amount":#{scaled_amount}}],"message":"","token":"AXNT","prev_hash":"0","timestamp":#{timestamp},"scaled":1,"kind":"#{speed}","version":"V1"}}
|
28
|
+
|
29
|
+
payload_hash = Hashes.sha256(unsigned_transaction)
|
30
|
+
signature = KeyUtils.sign(from_private_key, payload_hash)
|
31
|
+
signed_transaction = __to_signed(unsigned_transaction, signature)
|
32
|
+
|
33
|
+
%Q{{"transaction": #{signed_transaction}}}
|
34
|
+
end
|
35
|
+
|
36
|
+
def __create_id
|
37
|
+
tmp_id = SecureRandom.hex(32)
|
38
|
+
return __create_id if tmp_id[0] == "0"
|
39
|
+
tmp_id
|
40
|
+
end
|
41
|
+
|
42
|
+
def __timestamp
|
43
|
+
Time.now.to_i * 1000
|
44
|
+
end
|
45
|
+
|
46
|
+
def __to_signed(unsigned_transaction, signature)
|
47
|
+
unsigned_transaction.gsub(%Q{"signature":"0"}, %Q{"signature":"#{signature}"})
|
48
|
+
end
|
49
|
+
|
50
|
+
def __get_private_key_from_wif(wif)
|
51
|
+
Base64.strict_decode64(wif)[2..-7]
|
52
|
+
end
|
53
|
+
|
54
|
+
def __scale_i64(value)
|
55
|
+
(BigDecimal(value) * SCALE_DECIMAL).to_i
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: axentro-rb-util
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kingsley Hendrickse
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ed25519
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.2.4
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.2'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.2.4
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: ed25519-hd-rb
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.0.1
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.0.1
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.0.1
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.0.1
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: faraday
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.0'
|
60
|
+
type: :runtime
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '1.0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: bundler
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.3'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '1.3'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rake
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: rspec
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
description: Sending transactions
|
110
|
+
email: kingsley@axentro.io
|
111
|
+
executables: []
|
112
|
+
extensions: []
|
113
|
+
extra_rdoc_files: []
|
114
|
+
files:
|
115
|
+
- lib/axentro-rb-util.rb
|
116
|
+
- lib/crypto/crypto.rb
|
117
|
+
- lib/crypto/hashes.rb
|
118
|
+
- lib/crypto/key_ring.rb
|
119
|
+
- lib/crypto/keys/address.rb
|
120
|
+
- lib/crypto/keys/key_utils.rb
|
121
|
+
- lib/crypto/keys/private_key.rb
|
122
|
+
- lib/crypto/keys/public_key.rb
|
123
|
+
- lib/crypto/keys/wif.rb
|
124
|
+
- lib/crypto/transaction.rb
|
125
|
+
homepage: https://rubygems.org/gems/axentro-rb-util
|
126
|
+
licenses:
|
127
|
+
- MIT
|
128
|
+
metadata: {}
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubygems_version: 3.1.4
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Tools for Axentro blockchain crypto in Ruby
|
148
|
+
test_files: []
|