trx 0.2.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dfcdbe41de11ca908dfaf1b12e58262dba9966cc7b319d57fc48c9e455d36360
4
+ data.tar.gz: f048ec52470a044ae883262dbfe51ee706bd2a8339a2298c014c642ac4e92e53
5
+ SHA512:
6
+ metadata.gz: 870645d6c67d40a2ca3eb7f6d70186408cfd622534eb89040008683298e68ae4c84a9137f6144771afe9003844b6fb3d7339fbb0eb1085f8c9c3835464ed54cc
7
+ data.tar.gz: 134d7401cfd15c6192f6f8974dd3fb13bf829e7e707632dba50166ecc26a422fe081a94b2cfccc78d37c749cc90293bc08abc50d3b07c9ce51a8fa2a8dc83408
@@ -0,0 +1,25 @@
1
+ module Trx
2
+ module Abi
3
+ class ContractEvent
4
+
5
+ attr_accessor :name, :signature, :input_types, :inputs, :event_string, :address, :client
6
+
7
+ def initialize(data)
8
+ @name = data["name"]
9
+ @input_types = data.fetch("inputs", []).map {|x| x["type"]}
10
+ @inputs = data.fetch("inputs", []).map {|x| x["name"]}
11
+ @event_string = "#{@name}(#{@input_types.join(",")})"
12
+ @signature = Digest::Keccak.hexdigest(@event_string, 256)
13
+ end
14
+
15
+ def set_address(address)
16
+ @address = address
17
+ end
18
+
19
+ def set_client(client)
20
+ @client = client
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,101 @@
1
+ module Trx
2
+ module Abi
3
+ class Decoder
4
+
5
+ def decode(type, value, start = 0)
6
+ is_array, arity, array_subtype = Abi::parse_array_type(type)
7
+ if is_array && arity
8
+ decode_static_array(arity, array_subtype, value, start)
9
+ elsif is_array
10
+ decode_dynamic_array(array_subtype, value, start)
11
+ else
12
+ value = value.gsub(/^0x/,'')
13
+ core, subtype = Abi::parse_type(type)
14
+ method_name = "decode_#{core}".to_sym
15
+ self.send(method_name, value, subtype, start)
16
+ end
17
+ end
18
+
19
+ def decode_static_array(arity, array_subtype, value, start)
20
+ (0..arity-1).map { |i| decode(array_subtype, value, start + i * 64) }
21
+ end
22
+
23
+ def decode_dynamic_array(array_subtype, value, start)
24
+ location = decode_uint(value[start..(start+63)]) * 2
25
+ size = decode_uint(value[location..location+63])
26
+ (0..size-1).map { |i| decode(array_subtype, value, location + (i+1) * 64) }
27
+ end
28
+
29
+ def decode_fixed(value, subtype = "128x128", start = 0)
30
+ decode_int(trim(value, start, fixed_bitsize(subtype))).to_f / 2**exponent(subtype)
31
+ end
32
+
33
+ def decode_uint(value, subtype = "256", start = 0)
34
+ trim(value, start, bitsize(subtype)).hex
35
+ end
36
+
37
+ def decode_int(value, subtype = "256", start = 0)
38
+ raise ArgumentError if value.nil?
39
+ size = bitsize(subtype)
40
+ value = trim(value, start, size)
41
+ (value[0..1] == "ff") ? (value.hex - (2 ** size)) : value.hex
42
+ end
43
+
44
+ def decode_bool(value, _, start)
45
+ value = trim(value, start, 4)
46
+ return true if value == "1"
47
+ return false if value == "0"
48
+ raise ArgumentError
49
+ end
50
+
51
+ def decode_address(value, _ = nil, start)
52
+ raise ArgumentError if value.size-start < 64
53
+ value[start+24..start+63]
54
+ end
55
+
56
+ def decode_bytes(value, subtype, start)
57
+ subtype.present? ? decode_static_bytes(value, subtype, start) : decode_dynamic_bytes(value, start)
58
+ end
59
+
60
+ def decode_static_bytes(value, subtype = nil, start = 0)
61
+ trim(value, start, subtype.to_i*8).scan(/.{2}/).map {|x| x.hex}.pack('C*').strip
62
+ end
63
+
64
+ def decode_dynamic_bytes(value, start = 0)
65
+ location = decode_uint(value[start..(start+63)]) * 2
66
+ size = decode_uint(value[location..location+63]) * 2
67
+ value[location+64..location+63+size].scan(/.{2}/).map {|x| x.hex}.pack('C*')
68
+ end
69
+
70
+ def decode_string(value, _ = nil, start = 0)
71
+ decode_dynamic_bytes(value, start).force_encoding('utf-8')
72
+ end
73
+
74
+ def decode_arguments(arguments, data)
75
+ data = data.gsub(/^0x/,'')
76
+ types = arguments.map { |o| o.type }
77
+ types.each.with_index.map { |t , i| decode(t, data, i*64) }
78
+ end
79
+
80
+ private
81
+ def trim(value, start, bitsize = 256)
82
+ value[start+63-(bitsize/4-1)..start+63]
83
+ end
84
+
85
+ def bitsize(subtype, default = 256)
86
+ subtype.present? ? subtype.to_i : default
87
+ end
88
+
89
+ def fixed_bitsize(subtype = nil)
90
+ subtype ||= "128x128"
91
+ _, x, n = /(\d+)x(\d+)/.match(subtype).to_a
92
+ x.to_i + n.to_i
93
+ end
94
+
95
+ def exponent(subtype, default = 128)
96
+ subtype.nil? ? default : /(\d+)x(\d+)/.match(subtype)[2].to_i
97
+ end
98
+
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,119 @@
1
+ module Trx
2
+
3
+ module Abi
4
+ class Encoder
5
+
6
+ def encode(type, value)
7
+ is_array, arity, array_subtype = Abi::parse_array_type(type)
8
+ if is_array && arity
9
+ encode_static_array(arity, array_subtype, value)
10
+ elsif is_array
11
+ encode_dynamic_array(array_subtype, value)
12
+ else
13
+ core, subtype = Abi::parse_type(type)
14
+ method_name = "encode_#{core}".to_sym
15
+ self.send(method_name, value, subtype)
16
+ end
17
+ end
18
+
19
+ def encode_static_array(arity, array_subtype, array)
20
+ raise "Wrong number of arguments" if arity != array.size
21
+ array.inject("") { |a, e| a << encode(array_subtype, e) }
22
+ end
23
+
24
+ def encode_dynamic_array(array_subtype, array)
25
+ location = encode_uint(@inputs ? size_of_inputs(@inputs) + @tail.size/2 : 32)
26
+ size = encode_uint(array.size)
27
+ data = array.inject("") { |a, e| a << encode(array_subtype, e) }
28
+ [location, size + data]
29
+ end
30
+
31
+ def encode_int(value, _ = nil)
32
+ to_twos_complement(value).to_s(16).rjust(64, '0')
33
+ end
34
+
35
+ def encode_uint(value, _ = nil)
36
+ raise ArgumentError if value < 0
37
+ encode_int(value)
38
+ end
39
+
40
+ def encode_bool(value, _)
41
+ (value ? "1" : "0").rjust(64, '0')
42
+ end
43
+
44
+ def encode_fixed(value, subtype)
45
+ n = subtype.nil? ? 128 : /(\d+)x(\d+)/.match(subtype)[2].to_i
46
+ do_encode_fixed(value, n)
47
+ end
48
+
49
+ def do_encode_fixed(value, n)
50
+ encode_uint((value * 2**n).to_i)
51
+ end
52
+
53
+ def encode_ufixed(_value, _)
54
+ raise NotImplementedError
55
+ end
56
+
57
+ def encode_bytes(value, subtype)
58
+ subtype.nil? ? encode_dynamic_bytes(value) : encode_static_bytes(value)
59
+ end
60
+
61
+ def encode_static_bytes(value)
62
+ value.bytes.map {|x| x.to_s(16).rjust(2, '0')}.join("").ljust(64, '0')
63
+ end
64
+
65
+ def encode_dynamic_bytes(value)
66
+ location = encode_uint(@inputs ? size_of_inputs(@inputs) + @tail.size/2 : 32)
67
+ size = encode_uint(value.size)
68
+ content = encode_static_bytes(value)
69
+ [location, size + content]
70
+ end
71
+
72
+ def encode_string(value, _)
73
+ location = encode_uint(@inputs ? size_of_inputs(@inputs) + @tail.size/2 : 32)
74
+ size = encode_uint(value.bytes.size)
75
+ content = value.bytes.map {|x| x.to_s(16).rjust(2, '0')}.join("").ljust(64, '0')
76
+ [location, size + content]
77
+ end
78
+
79
+ def encode_address(value, _)
80
+ value = "0" * 24 + value.gsub(/^0x/,'')
81
+ raise ArgumentError if value.size != 64
82
+ value
83
+ end
84
+
85
+ def ensure_prefix(value)
86
+ value.start_with?("0x") ? value : ("0x" + value)
87
+ end
88
+
89
+ def encode_arguments(inputs, args)
90
+ raise "Wrong number of arguments" if inputs.length != args.length
91
+ @head = ""
92
+ @tail = ""
93
+ @inputs = inputs
94
+ inputs.each.with_index do |input, index|
95
+ encoded = encode(input.type, args[index])
96
+ if encoded.is_a? Array
97
+ @head << encoded[0]
98
+ @tail << encoded[1]
99
+ else
100
+ @head << encoded
101
+ end
102
+ end
103
+ @head + @tail
104
+ end
105
+
106
+ private
107
+ def to_twos_complement(number)
108
+ (number & ((1 << 256) - 1))
109
+ end
110
+
111
+ def size_of_inputs(inputs)
112
+ inputs.map do |input|
113
+ _, arity, _ = Abi::parse_array_type(input.type)
114
+ arity.nil? ? 32 : arity * 32
115
+ end.inject(:+)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,37 @@
1
+ module Trx
2
+ module Abi
3
+ class Function
4
+
5
+ attr_accessor :name, :inputs, :outputs, :signature, :constant, :function_string
6
+
7
+ def initialize(data)
8
+ @name = data["name"]
9
+ @constant = data["constant"]
10
+ @inputs = data.fetch("inputs", []).map do |input|
11
+ FunctionInput.new(input)
12
+ end
13
+ @outputs = data.fetch("outputs", []).map do |output|
14
+ FunctionOutput.new(output)
15
+ end
16
+ @function_string = self.class.calc_signature(@name, @inputs)
17
+ @signature = self.class.calc_id(@function_string)
18
+ end
19
+
20
+ def self.to_canonical_type(type)
21
+ type
22
+ .gsub(/(int)(\z|\D)/, '\1256\2')
23
+ .gsub(/(uint)(\z|\D)/, '\1256\2')
24
+ .gsub(/(fixed)(\z|\D)/, '\1128x128\2')
25
+ .gsub(/(ufixed)(\z|\D)/, '\1128x128\2')
26
+ end
27
+
28
+ def self.calc_signature(name, inputs)
29
+ "#{name}(#{inputs.map {|x| self.to_canonical_type(x.type) }.join(",")})"
30
+ end
31
+
32
+ def self.calc_id(signature)
33
+ Digest::Keccak.hexdigest(signature, 256)[0..7]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ module Trx
2
+
3
+ module Abi
4
+ class FunctionInput
5
+
6
+ attr_accessor :type, :name
7
+
8
+ def initialize(data)
9
+ @type = data["type"]
10
+ @name = data["name"]
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Trx
2
+
3
+ module Abi
4
+ class FunctionOutput
5
+
6
+ attr_accessor :type, :name
7
+
8
+ def initialize(data)
9
+ @type = data["type"]
10
+ @name = data["name"]
11
+ end
12
+
13
+ end
14
+ end
15
+ end
data/lib/trx/abi.rb ADDED
@@ -0,0 +1,33 @@
1
+ module Trx
2
+ module Abi
3
+ extend self
4
+
5
+ def parse_abi(abi)
6
+ constructor = abi.detect {|x| x["type"].downcase == "constructor"}
7
+ if constructor.present?
8
+ constructor_inputs = constructor["inputs"].map { |input| FunctionInput.new(input) }
9
+ else
10
+ constructor_inputs = []
11
+ end
12
+ functions = abi.select {|x| x["type"].downcase == "function" }.map { |fun| Function.new(fun) }
13
+ events = abi.select {|x| x["type"].downcase == "event" }.map { |evt| ContractEvent.new(evt) }
14
+ [constructor_inputs, functions, events]
15
+ end
16
+
17
+ def parse_type(type)
18
+ raise NotImplementedError if type.ends_with?("]")
19
+ match = /(\D+)(\d.*)?/.match(type)
20
+ [match[1], match[2]]
21
+ end
22
+
23
+ def parse_array_type(type)
24
+ match = /(.+)\[(\d*)\]\z/.match(type)
25
+ if match
26
+ [true, match[2].present? ? match[2].to_i : nil, match[1]]
27
+ else
28
+ [false, nil, nil]
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trx
4
+ class Address
5
+ ADDRESS_PREFIX = "41"
6
+
7
+ def self.from_public_hex(public_hex)
8
+ raise ArgumentError, "Expected String, got #{public_hex.class}" unless public_hex.is_a?(String)
9
+
10
+ bytes = Utils.hex_to_bin(public_hex)
11
+ address_bytes = Utils.keccak256(bytes[1..-1])[-20..-1]
12
+ prefixed_address_hex = ADDRESS_PREFIX + RLP::Utils.encode_hex(address_bytes)
13
+ prefixed_address_bytes = Utils.hex_to_bin(prefixed_address_hex)
14
+ checksum = Utils.base58check(prefixed_address_bytes).hexdigest[0..7]
15
+ base58check_adress = Base58.encode_hex(prefixed_address_hex + checksum)
16
+
17
+ Address.new(base58check_adress)
18
+ end
19
+
20
+ attr_reader :address
21
+
22
+ def initialize(address)
23
+ raise ArgumentError, "Expected String, got #{address.class}" unless address.is_a?(String)
24
+
25
+ @address = Utils.prefix_hex(address)
26
+ end
27
+
28
+ def checksum_matches?
29
+ computed_checksum = Utils.sha256(
30
+ Utils.sha256(to_bytes).digest
31
+ ).hexdigest[0..7]
32
+
33
+ checksum_hex == computed_checksum
34
+ end
35
+ alias_method :valid?, :checksum_matches?
36
+
37
+ def to_bytes
38
+ Utils.hex_to_bin(to_base58_decode_hex)[0..-5]
39
+ end
40
+
41
+ def to_base58_decode_hex
42
+ Utils.base58_decode_hex(address)
43
+ end
44
+
45
+ def to_hex
46
+ Utils.base58_decode_hex(address)[0..-9]
47
+ end
48
+
49
+ def to_s
50
+ Utils.remove_hex_prefix(address)
51
+ end
52
+
53
+ private
54
+
55
+ def checksum_bytes
56
+ bytes[0..3]
57
+ end
58
+
59
+ def checksum_hex
60
+ to_base58_decode_hex[-8..-1]
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,34 @@
1
+ module Trx
2
+ class HttpClient
3
+ attr_reader :host, :timeout, :trongrig_token, :headers, :raise_error
4
+
5
+ MAINNET_HOST = "https://api.trongrid.io"
6
+ SHASTA_HOST = "https://api.shasta.trongrid.io"
7
+ NILE_HOST = "https://nile.trongrid.io"
8
+
9
+ def initialize(host = nil, timeout: 10, trongrig_token: nil, headers: {}, raise_error: true)
10
+ @host = host
11
+ @timeout = timeout
12
+ @trongrig_token = trongrig_token
13
+ @headers = headers
14
+ @raise_error = raise_error
15
+ end
16
+
17
+ def perform_command(command, params, method: :post)
18
+ connection.public_send(method, command, params).body
19
+ end
20
+
21
+ private
22
+
23
+ def connection
24
+ @_connection ||= Faraday.new(host) do |builder|
25
+ builder.options.timeout = timeout
26
+ builder.use Faraday::Response::RaiseError if raise_error
27
+ builder.request :url_encoded
28
+ builder.response :json
29
+ builder.adapter Faraday.default_adapter
30
+ builder.headers['TRON-PRO-API-KEY'] = trongrig_token unless trongrig_token.nil?
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/trx/key.rb ADDED
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trx
4
+ class Key
5
+ attr_reader :private_key, :public_key
6
+
7
+ def initialize(priv: nil)
8
+
9
+ # Creates a new, randomized libsecp256k1 context.
10
+ ctx = Secp256k1::Context.new context_randomization_bytes: SecureRandom.random_bytes(32)
11
+
12
+ key = if priv.nil?
13
+ # Creates a new random key pair (public, private).
14
+ ctx.generate_key_pair
15
+ else
16
+
17
+ # Converts hex private keys to binary strings.
18
+ priv = Utils.hex_to_bin priv if Utils.is_hex? priv
19
+
20
+ # Creates a keypair from existing private key data.
21
+ ctx.key_pair_from_private_key priv
22
+ end
23
+
24
+ # Sets the attributes.
25
+ @private_key = key.private_key
26
+ @public_key = key.public_key
27
+ end
28
+
29
+ def private_hex
30
+ Utils.bin_to_hex @private_key.data
31
+ end
32
+
33
+ def private_bytes
34
+ @private_key.data
35
+ end
36
+
37
+ def public_hex
38
+ Utils.bin_to_hex @public_key.uncompressed
39
+ end
40
+
41
+ def public_hex_compressed
42
+ Utils.bin_to_hex @public_key.compressed
43
+ end
44
+
45
+ def public_bytes
46
+ @public_key.uncompressed
47
+ end
48
+
49
+ def public_bytes_compressed
50
+ @public_key.compressed
51
+ end
52
+
53
+ def address
54
+ Address.from_public_hex public_hex
55
+ end
56
+
57
+ def sign(blob)
58
+ context = Secp256k1::Context.new
59
+ compact, recovery_id = context.sign_recoverable(@private_key, blob).compact
60
+ signature = compact.bytes
61
+ is_leading_zero = true
62
+ signature.append recovery_id
63
+
64
+ # TODO: WTF? It is necessary?
65
+
66
+ # [recovery_id].pack("N").unpack("C*").each do |byte|
67
+ # is_leading_zero = false if byte > 0 and is_leading_zero
68
+ # unless is_leading_zero and byte === 0
69
+ # signature.append recovery_id
70
+ # end
71
+ # end
72
+
73
+ Utils.bin_to_hex signature.pack "c*"
74
+ end
75
+
76
+ def personal_sign(message)
77
+ prefixed_message = Signature.prefix_message message
78
+ hashed_message = Utils.keccak256 prefixed_message
79
+ sign hashed_message
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trx
4
+ module Signature
5
+ class SignatureError < StandardError; end
6
+ extend self
7
+
8
+ PREFIX_BYTE = "\x19".freeze
9
+
10
+ def prefix_message(message)
11
+ "#{PREFIX_BYTE}Tron Signed Message:\n#{message.size}#{message}"
12
+ end
13
+ end
14
+ end
data/lib/trx/utils.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trx
4
+ module Utils
5
+ extend self
6
+
7
+ def hex_to_bin(string)
8
+ RLP::Utils.decode_hex remove_hex_prefix(string)
9
+ end
10
+
11
+ def bin_to_hex(bytes)
12
+ RLP::Utils.encode_hex bytes
13
+ end
14
+
15
+ def remove_hex_prefix(string)
16
+ string[0, 2] == "0x" ? string[2..-1] : string
17
+ end
18
+
19
+ def prefix_hex(hex)
20
+ hex.match(/\A0x/) ? hex : "0x#{hex}"
21
+ end
22
+
23
+ def keccak256(value)
24
+ Digest::Keccak.new(256).digest(value)
25
+ end
26
+
27
+ def base58check(value)
28
+ sha256(sha256(value).digest)
29
+ end
30
+
31
+ def base58_decode_hex(hex)
32
+ Base58.decode_hex(remove_hex_prefix(hex))
33
+ end
34
+
35
+ def sha256(value)
36
+ hash = OpenSSL::Digest.new("SHA256")
37
+ hash.update(value)
38
+
39
+ hash
40
+ end
41
+
42
+ def is_hex?(str)
43
+ return false unless str.is_a? String
44
+ str = remove_hex_prefix str
45
+ str.match /\A[0-9a-fA-F]*\z/
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trx
4
+ VERSION = "0.2.2"
5
+ end
data/lib/trx.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/keccak"
4
+ require "rlp"
5
+ require "openssl"
6
+ require "base58-alphabets"
7
+ require "rbsecp256k1"
8
+ require "securerandom"
9
+ require "faraday"
10
+ require "active_support"
11
+ require "active_support/core_ext"
12
+
13
+ require_relative "trx/utils"
14
+ require_relative "trx/signature"
15
+ require_relative "trx/key"
16
+ require_relative "trx/address"
17
+ require_relative "trx/version"
18
+ require_relative "trx/http_client"
19
+ require_relative "trx/abi"
20
+ require_relative "trx/abi/encoder"
21
+ require_relative "trx/abi/decoder"
22
+ require_relative "trx/abi/function"
23
+ require_relative "trx/abi/function_input"
24
+ require_relative "trx/abi/function_output"
25
+ require_relative "trx/abi/contract_event"
26
+
27
+ module Trx
28
+ class Error < StandardError; end
29
+ end
metadata ADDED
@@ -0,0 +1,201 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Anton Kostyuk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-02-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ecdsa
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.2.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.2.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: keccak
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rlp
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.3
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.7.3
97
+ - !ruby/object:Gem::Dependency
98
+ name: rbsecp256k1
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.1'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: securerandom
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: base58-alphabets
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: activesupport
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '4.2'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '4.2'
153
+ description: ''
154
+ email:
155
+ - anton.kostuk.2012@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - lib/trx.rb
161
+ - lib/trx/abi.rb
162
+ - lib/trx/abi/contract_event.rb
163
+ - lib/trx/abi/decoder.rb
164
+ - lib/trx/abi/encoder.rb
165
+ - lib/trx/abi/function.rb
166
+ - lib/trx/abi/function_input.rb
167
+ - lib/trx/abi/function_output.rb
168
+ - lib/trx/address.rb
169
+ - lib/trx/http_client.rb
170
+ - lib/trx/key.rb
171
+ - lib/trx/signature.rb
172
+ - lib/trx/utils.rb
173
+ - lib/trx/version.rb
174
+ homepage: https://github.com/RainbowPonny/trx-rb
175
+ licenses:
176
+ - MIT
177
+ metadata:
178
+ homepage_uri: https://github.com/RainbowPonny/trx-rb
179
+ source_code_uri: https://github.com/RainbowPonny/trx-rb
180
+ changelog_uri: https://github.com/RainbowPonny/trx-rb
181
+ rubygems_mfa_required: 'true'
182
+ post_install_message:
183
+ rdoc_options: []
184
+ require_paths:
185
+ - lib
186
+ required_ruby_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: 2.5.0
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ requirements: []
197
+ rubygems_version: 3.3.7
198
+ signing_key:
199
+ specification_version: 4
200
+ summary: TRON HTTP API client
201
+ test_files: []