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: []
         |