erc20 0.2.8 → 0.2.9
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 +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +1 -1
- data/bin/erc20 +139 -139
- data/erc20.gemspec +1 -1
- data/features/cli.feature +3 -15
- data/features/live.feature +17 -0
- data/features/step_definitions/steps.rb +0 -5
- data/lib/erc20/erc20.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bdb92899afb7e0f3ac74c59c07cdf1f48441d8b8bab6c96fadffe506c49dcedd
|
|
4
|
+
data.tar.gz: fd0faec13d2aafdd1cbd02afd0066c17b308b96637469f60eca0cbd1d5102629
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 509bdbaa8838f52ad6ea7d8a779001c1bfd87ba9c448ce4b808849967575069b8452e3a1f50b506c38f282b709e31e690a31b4247452b34d8cc097caa72e3b45
|
|
7
|
+
data.tar.gz: 8fa48303af7a75dd4019062bb9d3904c84f76f16dd994ee95d3d6cb0f952c9e207030be9063781c3224af6d0a3cde0f107667cdd4447c9fdc4108a05725b3bc3
|
data/Gemfile.lock
CHANGED
|
@@ -8,7 +8,7 @@ PATH
|
|
|
8
8
|
json (~> 2.10)
|
|
9
9
|
jsonrpc-client (~> 0.1)
|
|
10
10
|
loog (~> 0.4)
|
|
11
|
-
|
|
11
|
+
thor (~> 1.3)
|
|
12
12
|
|
|
13
13
|
GEM
|
|
14
14
|
remote: https://rubygems.org/
|
|
@@ -189,12 +189,12 @@ GEM
|
|
|
189
189
|
simplecov (~> 0.19)
|
|
190
190
|
simplecov-html (0.13.2)
|
|
191
191
|
simplecov_json_formatter (0.1.4)
|
|
192
|
-
slop (4.10.1)
|
|
193
192
|
stringio (3.2.0)
|
|
194
193
|
sys-uname (1.4.1)
|
|
195
194
|
ffi (~> 1.1)
|
|
196
195
|
memoist3 (~> 1.0.0)
|
|
197
|
-
tago (0.
|
|
196
|
+
tago (0.7.0)
|
|
197
|
+
thor (1.5.0)
|
|
198
198
|
threads (0.5.0)
|
|
199
199
|
backtrace (~> 0)
|
|
200
200
|
concurrent-ruby (~> 1.0)
|
data/README.md
CHANGED
data/bin/erc20
CHANGED
|
@@ -8,126 +8,140 @@ $stdout.sync = true
|
|
|
8
8
|
|
|
9
9
|
require 'backtrace'
|
|
10
10
|
require 'loog'
|
|
11
|
-
require '
|
|
11
|
+
require 'thor'
|
|
12
12
|
require_relative '../lib/erc20'
|
|
13
13
|
require_relative '../lib/erc20/erc20'
|
|
14
14
|
require_relative '../lib/erc20/wallet'
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
eth_balance: Get ETH balance
|
|
28
|
-
Options are:"
|
|
29
|
-
o.string(
|
|
30
|
-
'--contract',
|
|
31
|
-
'Public address of ERC20 contract',
|
|
32
|
-
default: ERC20::Wallet::USDT
|
|
33
|
-
)
|
|
34
|
-
o.integer(
|
|
35
|
-
'--chain',
|
|
36
|
-
'Ethereum chain ID',
|
|
37
|
-
default: 1
|
|
38
|
-
)
|
|
39
|
-
o.bool(
|
|
40
|
-
'--ssl',
|
|
41
|
-
'Use SSL for HTTP connections',
|
|
42
|
-
default: true
|
|
43
|
-
)
|
|
44
|
-
o.string(
|
|
45
|
-
'--host',
|
|
46
|
-
'Host name of the provider',
|
|
47
|
-
default: 'eth.llamarpc.com'
|
|
48
|
-
)
|
|
49
|
-
o.string(
|
|
50
|
-
'--port',
|
|
51
|
-
'TCP port of the provider',
|
|
52
|
-
default: 443
|
|
53
|
-
)
|
|
54
|
-
o.string(
|
|
55
|
-
'--http_path',
|
|
56
|
-
'URL path for the HTTP RPC entry point of the provider',
|
|
57
|
-
default: '/'
|
|
58
|
-
)
|
|
59
|
-
o.string(
|
|
60
|
-
'--ws_path',
|
|
61
|
-
'URL path for the Websockets entry point of the provider',
|
|
62
|
-
default: '/'
|
|
63
|
-
)
|
|
64
|
-
o.string(
|
|
65
|
-
'--proxy',
|
|
66
|
-
'HTTP/S proxy for all requests, e.g. "localhost:3128"'
|
|
67
|
-
)
|
|
68
|
-
o.integer(
|
|
69
|
-
'--attempts',
|
|
70
|
-
'How many times should we try before failing',
|
|
71
|
-
default: 1
|
|
72
|
-
)
|
|
73
|
-
o.bool(
|
|
74
|
-
'--dry',
|
|
75
|
-
'Don\'t send a real payment, run in a read-only mode'
|
|
76
|
-
)
|
|
77
|
-
o.bool('--help', 'Read this: https://github.com/yegor256/erc20') do
|
|
78
|
-
puts o
|
|
79
|
-
exit
|
|
80
|
-
end
|
|
81
|
-
o.bool('--verbose', 'Print all possible debug messages')
|
|
82
|
-
end
|
|
83
|
-
rescue Slop::Error => e
|
|
84
|
-
raise e.message
|
|
16
|
+
# Command line interface for ERC20 operations.
|
|
17
|
+
#
|
|
18
|
+
# This CLI provides commands for managing ERC20 tokens and ETH on Ethereum:
|
|
19
|
+
# generating keys, checking balances, and sending payments.
|
|
20
|
+
#
|
|
21
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
22
|
+
# Copyright:: Copyright (c) 2025 Yegor Bugayenko
|
|
23
|
+
# License:: MIT
|
|
24
|
+
class Bin < Thor
|
|
25
|
+
def self.exit_on_failure?
|
|
26
|
+
true
|
|
85
27
|
end
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
28
|
+
|
|
29
|
+
class_option :contract, type: :string, default: ERC20::Wallet::USDT,
|
|
30
|
+
desc: 'Public address of ERC20 contract'
|
|
31
|
+
class_option :chain, type: :numeric, default: 1,
|
|
32
|
+
desc: 'Ethereum chain ID'
|
|
33
|
+
class_option :ssl, type: :boolean, default: true,
|
|
34
|
+
desc: 'Use SSL for HTTP connections'
|
|
35
|
+
class_option :host, type: :string, default: 'eth.llamarpc.com',
|
|
36
|
+
desc: 'Host name of the provider'
|
|
37
|
+
class_option :port, type: :numeric, default: 443,
|
|
38
|
+
desc: 'TCP port of the provider'
|
|
39
|
+
class_option :http_path, type: :string, default: '/',
|
|
40
|
+
desc: 'URL path for the HTTP RPC entry point of the provider'
|
|
41
|
+
class_option :ws_path, type: :string, default: '/',
|
|
42
|
+
desc: 'URL path for the Websockets entry point of the provider'
|
|
43
|
+
class_option :proxy, type: :string,
|
|
44
|
+
desc: 'HTTP/S proxy for all requests, e.g. "localhost:3128"'
|
|
45
|
+
class_option :attempts, type: :numeric, default: 1,
|
|
46
|
+
desc: 'How many times should we try before failing'
|
|
47
|
+
class_option :dry, type: :boolean, default: false,
|
|
48
|
+
desc: "Don't send a real payment, run in a read-only mode"
|
|
49
|
+
class_option :verbose, type: :boolean, default: false,
|
|
50
|
+
desc: 'Print all possible debug messages'
|
|
51
|
+
|
|
52
|
+
desc 'version', 'Print version of the tool'
|
|
53
|
+
def version
|
|
54
|
+
log.info(ERC20::VERSION)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc 'key', 'Generate a new Ethereum private key (64 hex symbols)'
|
|
58
|
+
def key
|
|
59
|
+
log.info(Eth::Key.new.private_hex.downcase)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
desc 'address KEY', 'Turn private key into a public address (44 hex symbols)'
|
|
63
|
+
def address(pvt)
|
|
64
|
+
log.info(Eth::Key.new(priv: pvt).address.to_s.downcase)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
desc 'price', 'Get current price of one gas unit, in gwei'
|
|
68
|
+
def price
|
|
69
|
+
log.info(wallet.gas_price)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc 'balance ADDRESS', 'Get ERC20 balance'
|
|
73
|
+
def balance(address)
|
|
110
74
|
log.debug("Checking ERC20 balance of #{address}")
|
|
111
75
|
tokens = wallet.balance(address)
|
|
112
76
|
log.debug("The balance is #{tokens} ERC20 tokens (#{tokens.to_f / 1_000_000} USDT)")
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
77
|
+
log.info(tokens)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
desc 'eth_balance ADDRESS', 'Get ETH balance'
|
|
81
|
+
def eth_balance(address)
|
|
117
82
|
log.debug("Checking ETH balance of #{address}")
|
|
118
83
|
wei = wallet.eth_balance(address)
|
|
119
84
|
log.debug("The balance of #{address} is #{wei} wei (#{format('%0.4f', wei.to_f / 1_000_000_000_000_000_000)} ETH)")
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
85
|
+
log.info(wei)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
desc 'pay KEY ADDRESS AMOUNT', 'Send ERC20 payment'
|
|
89
|
+
def pay(pkey, address, amount)
|
|
124
90
|
priv = Eth::Key.new(priv: pkey)
|
|
125
|
-
log.debug("Sending ERC20 tokens from #{priv.address
|
|
126
|
-
address = opts.arguments[2]
|
|
127
|
-
raise 'Address is required' if address.nil?
|
|
91
|
+
log.debug("Sending ERC20 tokens from #{priv.address}")
|
|
128
92
|
log.debug("Sending ERC20 tokens to #{address}")
|
|
129
|
-
amount =
|
|
130
|
-
|
|
93
|
+
amount = tokens(amount)
|
|
94
|
+
log.debug("Sending #{amount} ERC20 tokens")
|
|
95
|
+
if wallet.eth_balance(priv.address.to_s).zero?
|
|
96
|
+
log.debug("ETH balance of #{priv.address} is zero, the txn most definitely will be rejected by the server!")
|
|
97
|
+
end
|
|
98
|
+
log.info(wallet.pay(priv.private_hex, address, amount))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
desc 'eth_pay KEY ADDRESS AMOUNT', 'Send ETH payment'
|
|
102
|
+
def eth_pay(pkey, address, amount)
|
|
103
|
+
priv = Eth::Key.new(priv: pkey)
|
|
104
|
+
log.debug("Sending ETH from #{priv.address}")
|
|
105
|
+
log.debug("Sending ETH to #{address}")
|
|
106
|
+
raise "Amount #{amount.inspect} is not valid" unless /^[0-9]+(\.[0-9]+)?(eth|wei|gwei)?$/.match?(amount)
|
|
107
|
+
amount = wei(amount)
|
|
108
|
+
log.debug("Sending #{amount} wei...")
|
|
109
|
+
log.info(wallet.eth_pay(priv.private_hex, address, amount))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.banner(task, namespace = false, subcommand = false)
|
|
113
|
+
"#{basename} #{task.usage}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.help(shell, subcommand = false)
|
|
117
|
+
shell.say "Usage (#{ERC20::VERSION}): erc20 [options] command [args]"
|
|
118
|
+
shell.say 'Commands are:'
|
|
119
|
+
super
|
|
120
|
+
shell.say "\nRead this: https://github.com/yegor256/erc20"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
private
|
|
124
|
+
|
|
125
|
+
def log
|
|
126
|
+
@log ||= options[:verbose] ? Loog::VERBOSE : Loog::REGULAR
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def wallet
|
|
130
|
+
@wallet ||=
|
|
131
|
+
if options[:dry]
|
|
132
|
+
ERC20::FakeWallet.new
|
|
133
|
+
else
|
|
134
|
+
ERC20::Wallet.new(
|
|
135
|
+
contract: options[:contract],
|
|
136
|
+
host: options[:host], port: options[:port].to_i,
|
|
137
|
+
http_path: options[:http_path], ws_path: options[:ws_path],
|
|
138
|
+
ssl: options[:ssl],
|
|
139
|
+
log: log
|
|
140
|
+
)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def tokens(amount)
|
|
131
145
|
if /^[0-9]+$/.match?(amount)
|
|
132
146
|
amount = amount.to_i
|
|
133
147
|
log.debug("The token amount equals to #{amount} ERC20 tokens (as provided)")
|
|
@@ -140,43 +154,29 @@ Options are:"
|
|
|
140
154
|
else
|
|
141
155
|
raise "Can't understand amount: #{amount.inspect}"
|
|
142
156
|
end
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
puts wallet.pay(priv.private_hex, address, amount)
|
|
148
|
-
when 'eth_pay'
|
|
149
|
-
pkey = opts.arguments[1]
|
|
150
|
-
raise 'Private key is required' if pkey.nil?
|
|
151
|
-
priv = Eth::Key.new(priv: pkey)
|
|
152
|
-
log.debug("Sending ETH from #{priv.address.to_s}")
|
|
153
|
-
address = opts.arguments[2]
|
|
154
|
-
raise 'Address is required' if address.nil?
|
|
155
|
-
log.debug("Sending ETH to #{address}")
|
|
156
|
-
amount = opts.arguments[3]
|
|
157
|
-
raise 'Amount argument is required' if amount.nil?
|
|
158
|
-
raise "Amount #{amount.inspect} is not valid" unless /^[0-9]+(\.[0-9]+)?(eth|wei|gwei)?$/.match?(amount)
|
|
157
|
+
amount
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def wei(amount)
|
|
159
161
|
if /^[0-9]+$/.match?(amount)
|
|
160
|
-
amount
|
|
161
|
-
elsif /[0-9]wei
|
|
162
|
-
amount
|
|
163
|
-
elsif /[0-9]gwei
|
|
164
|
-
|
|
165
|
-
elsif /[0-9]eth
|
|
166
|
-
|
|
162
|
+
amount.to_i
|
|
163
|
+
elsif /[0-9]wei$/.match?(amount)
|
|
164
|
+
amount.gsub(/wei$/, '').to_i
|
|
165
|
+
elsif /[0-9]gwei$/.match?(amount)
|
|
166
|
+
(amount.gsub(/gwei$/, '').to_f * 1_000_000_000).to_i
|
|
167
|
+
elsif /[0-9]eth$/.match?(amount)
|
|
168
|
+
(amount.gsub(/eth$/, '').to_f * 1_000_000_000_000_000_000).to_i
|
|
167
169
|
else
|
|
168
170
|
raise "Can't understand amount: #{amount.inspect}"
|
|
169
171
|
end
|
|
170
|
-
log.debug("Sending #{amount} wei...")
|
|
171
|
-
puts wallet.eth_pay(priv.private_hex, address, amount)
|
|
172
|
-
else
|
|
173
|
-
raise "Command #{opts.arguments[0]} is not supported"
|
|
174
172
|
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
begin
|
|
176
|
+
Bin.start(ARGV)
|
|
175
177
|
rescue StandardError => e
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
puts "ERROR: #{e.message}"
|
|
180
|
-
end
|
|
178
|
+
log = ARGV.include?('--verbose') ? Loog::VERBOSE : Loog::REGULAR
|
|
179
|
+
log.debug(Backtrace.new(e))
|
|
180
|
+
log.error(e.message)
|
|
181
181
|
exit(255)
|
|
182
182
|
end
|
data/erc20.gemspec
CHANGED
|
@@ -31,6 +31,6 @@ Gem::Specification.new do |s|
|
|
|
31
31
|
s.add_dependency 'json', '~>2.10'
|
|
32
32
|
s.add_dependency 'jsonrpc-client', '~>0.1'
|
|
33
33
|
s.add_dependency 'loog', '~>0.4'
|
|
34
|
-
s.add_dependency '
|
|
34
|
+
s.add_dependency 'thor', '~>1.3'
|
|
35
35
|
s.metadata['rubygems_mfa_required'] = 'true'
|
|
36
36
|
end
|
data/features/cli.feature
CHANGED
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
Feature: Command Line Processing
|
|
5
|
-
As a simple ETH/ERC20 user I want to
|
|
5
|
+
As a simple ETH/ERC20 user I want to use it
|
|
6
6
|
|
|
7
7
|
Scenario: Help can be printed
|
|
8
|
-
When I run bin/erc20 with "
|
|
9
|
-
Then Exit code is zero
|
|
10
|
-
And Stdout contains "--help"
|
|
11
|
-
|
|
12
|
-
Scenario: Gas price price can be retrieved
|
|
13
|
-
When I run bin/erc20 with "price --attempts=4"
|
|
8
|
+
When I run bin/erc20 with "help"
|
|
14
9
|
Then Exit code is zero
|
|
10
|
+
And Stdout contains "help"
|
|
15
11
|
|
|
16
12
|
Scenario: ETH private key can be generated
|
|
17
13
|
When I run bin/erc20 with "key"
|
|
@@ -20,11 +16,3 @@ Feature: Command Line Processing
|
|
|
20
16
|
Scenario: ETH address can be created
|
|
21
17
|
When I run bin/erc20 with "address 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1"
|
|
22
18
|
Then Exit code is zero
|
|
23
|
-
|
|
24
|
-
Scenario: ERC20 balance can be checked
|
|
25
|
-
When I run bin/erc20 with "balance 0x7232148927F8a580053792f44D4d59d40Fd00ABD --verbose"
|
|
26
|
-
Then Exit code is zero
|
|
27
|
-
|
|
28
|
-
Scenario: ETH balance can be checked
|
|
29
|
-
When I run bin/erc20 with "eth_balance 0x7232148927F8a580053792f44D4d59d40Fd00ABD --verbose"
|
|
30
|
-
Then Exit code is zero
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
Feature: Command Line Processing
|
|
5
|
+
As a simple ETH/ERC20 user I want to use it live
|
|
6
|
+
|
|
7
|
+
Scenario: Gas price price can be retrieved
|
|
8
|
+
When I run bin/erc20 with "price --attempts=4"
|
|
9
|
+
Then Exit code is zero
|
|
10
|
+
|
|
11
|
+
Scenario: ERC20 balance can be checked
|
|
12
|
+
When I run bin/erc20 with "balance 0x7232148927F8a580053792f44D4d59d40Fd00ABD --verbose --attempts=4"
|
|
13
|
+
Then Exit code is zero
|
|
14
|
+
|
|
15
|
+
Scenario: ETH balance can be checked
|
|
16
|
+
When I run bin/erc20 with "eth_balance 0x7232148927F8a580053792f44D4d59d40Fd00ABD --verbose --attempts=4"
|
|
17
|
+
Then Exit code is zero
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'tmpdir'
|
|
7
|
-
require 'slop'
|
|
8
7
|
require 'English'
|
|
9
8
|
require_relative '../../lib/erc20'
|
|
10
9
|
|
|
@@ -13,10 +12,6 @@ Before do
|
|
|
13
12
|
@dir = Dir.mktmpdir('test')
|
|
14
13
|
FileUtils.mkdir_p(@dir)
|
|
15
14
|
Dir.chdir(@dir)
|
|
16
|
-
@opts =
|
|
17
|
-
Slop.parse ['-v'] do |o|
|
|
18
|
-
o.bool '-v', '--verbose'
|
|
19
|
-
end
|
|
20
15
|
end
|
|
21
16
|
|
|
22
17
|
After do
|
data/lib/erc20/erc20.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: erc20
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yegor Bugayenko
|
|
@@ -94,19 +94,19 @@ dependencies:
|
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
95
|
version: '0.4'
|
|
96
96
|
- !ruby/object:Gem::Dependency
|
|
97
|
-
name:
|
|
97
|
+
name: thor
|
|
98
98
|
requirement: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
|
100
100
|
- - "~>"
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: '
|
|
102
|
+
version: '1.3'
|
|
103
103
|
type: :runtime
|
|
104
104
|
prerelease: false
|
|
105
105
|
version_requirements: !ruby/object:Gem::Requirement
|
|
106
106
|
requirements:
|
|
107
107
|
- - "~>"
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: '
|
|
109
|
+
version: '1.3'
|
|
110
110
|
description: 'A simple library for making ERC20 manipulations as easy as they can
|
|
111
111
|
be for cryptocurrency newbies: checking balance, sending payments, and monitoring
|
|
112
112
|
addresses for incoming payments. The library expects Ethereum node to provide JSON
|
|
@@ -131,6 +131,7 @@ files:
|
|
|
131
131
|
- features/cli.feature
|
|
132
132
|
- features/dry.feature
|
|
133
133
|
- features/gem_package.feature
|
|
134
|
+
- features/live.feature
|
|
134
135
|
- features/step_definitions/steps.rb
|
|
135
136
|
- features/support/env.rb
|
|
136
137
|
- hardhat/.gitignore
|