axentro-rb-util 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|