erc20 0.0.21 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b64594a5ded4f8f34912d468efbf8fd2a47b716098853df38857a3a0b973cd1e
4
- data.tar.gz: bb0285b23d6624f633b92c45ab29bb0975e377a4ea971d0a9772c660c622b4ea
3
+ metadata.gz: c869348131d5d5bcb38966bc1eaac3d3e9655b11d6846f7ca9bc54893fb68458
4
+ data.tar.gz: 625b971154f40e09a8fd66091d154df5657efc4dee202bf3a5db3cc62c7e2a54
5
5
  SHA512:
6
- metadata.gz: de7f6cb6ff26a078860cc9530146f49b7d5df6f462a51120fd48bd3ab9dde07bfe781c03952eb5625350c2e69dad10f2222b9edb05a0902ed4fb4fc564a055ea
7
- data.tar.gz: 9ecd61346360053c15d3cdfdd838c3cfdb1d5eff1d789260a04e42662fa16d9183646d14a7fba19d1862d4f6a294ab7cfa19763c48ca4cf5586a4edf1c4e8ecd
6
+ metadata.gz: 30abb7a895214f536f1c91ad6758b023ded4d28be61265c1db9576a60e71e3b3737b7c86157ba314d649b4096dd86b93936920d8c8a0d76ded554c86da69d931
7
+ data.tar.gz: 39083d6adc8e2eed75a7d548c2ae4a8311fc226199f2f6c679f23012945a31b2458a766278cb028fd7754d5c95975b2bbde7afbeb1342591cc1f3bf5d8b4f69e
@@ -1,5 +1,3 @@
1
- # (The MIT License)
2
- #
3
1
  # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
4
2
  # SPDX-License-Identifier: MIT
5
3
  ---
data/.gitignore CHANGED
@@ -7,3 +7,4 @@ rdoc/
7
7
  doc/
8
8
  .yardoc/
9
9
  node_modules/
10
+ vendor/
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ source 'https://rubygems.org'
7
7
  gemspec
8
8
 
9
9
  gem 'backtrace', '>0', require: false
10
+ gem 'cucumber', '9.1.2', require: false
10
11
  gem 'donce', '>0', require: false
11
12
  gem 'faraday', '>0', require: false
12
13
  gem 'loog', '>0', require: false
data/Gemfile.lock CHANGED
@@ -7,6 +7,7 @@ PATH
7
7
  json (>= 2.10.1)
8
8
  jsonrpc-client (>= 0.1.4)
9
9
  loog (> 0)
10
+ slop (> 4)
10
11
 
11
12
  GEM
12
13
  remote: https://rubygems.org/
@@ -50,6 +51,31 @@ GEM
50
51
  concurrent-ruby (1.3.5)
51
52
  connection_pool (2.5.0)
52
53
  crass (1.0.6)
54
+ cucumber (9.1.2)
55
+ builder (~> 3.2, >= 3.2.4)
56
+ cucumber-ci-environment (~> 9.2, >= 9.2.0)
57
+ cucumber-core (~> 12.0)
58
+ cucumber-cucumber-expressions (~> 17.0)
59
+ cucumber-gherkin (> 24, < 27)
60
+ cucumber-html-formatter (> 20.3, < 22)
61
+ cucumber-messages (> 19, < 25)
62
+ diff-lcs (~> 1.5)
63
+ mini_mime (~> 1.1, >= 1.1.5)
64
+ multi_test (~> 1.1, >= 1.1.0)
65
+ sys-uname (~> 1.2, >= 1.2.3)
66
+ cucumber-ci-environment (9.2.0)
67
+ cucumber-core (12.0.0)
68
+ cucumber-gherkin (>= 25, < 27)
69
+ cucumber-messages (>= 20, < 23)
70
+ cucumber-tag-expressions (~> 5.0, >= 5.0.4)
71
+ cucumber-cucumber-expressions (17.1.0)
72
+ bigdecimal
73
+ cucumber-gherkin (26.2.0)
74
+ cucumber-messages (>= 19.1.4, < 22.1)
75
+ cucumber-html-formatter (21.9.0)
76
+ cucumber-messages (> 19, < 28)
77
+ cucumber-messages (22.0.0)
78
+ cucumber-tag-expressions (5.0.6)
53
79
  date (3.4.1)
54
80
  diff-lcs (1.6.0)
55
81
  docile (1.4.1)
@@ -109,6 +135,7 @@ GEM
109
135
  crass (~> 1.0.2)
110
136
  nokogiri (>= 1.12.0)
111
137
  loog (0.6.0)
138
+ mini_mime (1.1.5)
112
139
  mini_portile2 (2.8.8)
113
140
  minitest (5.25.4)
114
141
  minitest-reporters (1.7.1)
@@ -119,6 +146,7 @@ GEM
119
146
  minitest-retry (0.2.5)
120
147
  minitest (>= 5.0)
121
148
  multi_json (1.15.0)
149
+ multi_test (1.1.0)
122
150
  net-http (0.6.0)
123
151
  uri
124
152
  nokogiri (1.18.3-arm64-darwin)
@@ -244,7 +272,10 @@ GEM
244
272
  simplecov (~> 0.19)
245
273
  simplecov-html (0.13.1)
246
274
  simplecov_json_formatter (0.1.4)
247
- stringio (3.1.3)
275
+ slop (4.10.1)
276
+ stringio (3.1.5)
277
+ sys-uname (1.3.1)
278
+ ffi (~> 1.1)
248
279
  tago (0.0.2)
249
280
  thor (1.3.2)
250
281
  threads (0.4.1)
@@ -277,6 +308,7 @@ PLATFORMS
277
308
 
278
309
  DEPENDENCIES
279
310
  backtrace (> 0)
311
+ cucumber (= 9.1.2)
280
312
  donce (> 0)
281
313
  erc20!
282
314
  faraday (> 0)
data/README.md CHANGED
@@ -93,6 +93,25 @@ You can use [squid-proxy] [Docker] image to set up your own [HTTP proxy] server.
93
93
  Of course, this library works with [Polygon], [Optimism],
94
94
  and other forks of [Etherium].
95
95
 
96
+ ## How to use in command line
97
+
98
+ This gem also provides a command line tool for sending ETH and ERC20 payments
99
+ and checking balances.
100
+
101
+ First, you install it, via [gem]:
102
+
103
+ ```bash
104
+ gem install erc20
105
+ ```
106
+
107
+ Then, run it:
108
+
109
+ ```bash
110
+ erc20 --help
111
+ ```
112
+
113
+ It should be obvious how to use it. If not, please, submit an issue.
114
+
96
115
  ## How to use in tests
97
116
 
98
117
  You can use `ERC20::FakeWallet` class that behaves exactly like
@@ -122,6 +141,7 @@ bundle exec rake
122
141
 
123
142
  If it's clean and you don't see any error messages, submit your pull request.
124
143
 
144
+ [gem]: https://github.com/rubygems/rubygems
125
145
  [Etherium]: https://en.wikipedia.org/wiki/Ethereum
126
146
  [ERC20]: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
127
147
  [JSON-RPC]: https://ethereum.org/en/developers/docs/apis/json-rpc/
data/REUSE.toml CHANGED
@@ -4,15 +4,27 @@
4
4
  version = 1
5
5
  [[annotations]]
6
6
  path = [
7
+ "**/*.csv",
8
+ "**/*.jpg",
9
+ "**/*.json",
10
+ "**/*.md",
11
+ "**/*.pdf",
12
+ "**/*.png",
13
+ "**/*.svg",
14
+ "**/*.txt",
15
+ "**/*.vm",
16
+ "**/.gitignore",
17
+ "**/CNAME",
7
18
  ".gitattributes",
8
19
  ".gitignore",
9
20
  ".gitleaksignore",
10
21
  ".pdd",
22
+ ".xcop",
11
23
  "Gemfile.lock",
12
24
  "README.md",
13
25
  "hardhat/.gitignore",
14
26
  "hardhat/package.json",
15
- "renovate.json"
27
+ "renovate.json",
16
28
  ]
17
29
  precedence = "override"
18
30
  SPDX-FileCopyrightText = "Copyright (c) 2025 Yegor Bugayenko"
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ def version
17
17
  Gem::Specification.load(Dir['*.gemspec'].first).version
18
18
  end
19
19
 
20
- task default: %i[clean test rubocop yard]
20
+ task default: %i[clean test features rubocop yard]
21
21
 
22
22
  require 'rake/testtask'
23
23
  desc 'Run all unit tests'
@@ -42,6 +42,14 @@ RuboCop::RakeTask.new(:rubocop) do |task|
42
42
  task.requires << 'rubocop-rspec'
43
43
  end
44
44
 
45
+ require 'cucumber/rake/task'
46
+ Cucumber::Rake::Task.new(:features) do
47
+ Rake::Cleaner.cleanup_files(['coverage'])
48
+ end
49
+ Cucumber::Rake::Task.new(:'features:html') do |t|
50
+ t.profile = 'html_report'
51
+ end
52
+
45
53
  desc 'Run benchmark script'
46
54
  task :benchmark do
47
55
  ruby 'benchmarks/simple.rb'
data/bin/erc20 ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
5
+ # SPDX-License-Identifier: MIT
6
+
7
+ $stdout.sync = true
8
+
9
+ require 'backtrace'
10
+ require 'loog'
11
+ require 'slop'
12
+ require_relative '../lib/erc20'
13
+ require_relative '../lib/erc20/erc20'
14
+ require_relative '../lib/erc20/wallet'
15
+
16
+ begin
17
+ begin
18
+ opts = Slop.parse(ARGV, strict: true, help: true) do |o|
19
+ o.banner = "Usage (#{ERC20::VERSION}): erc20 [options] command [args]
20
+ Commands are:
21
+ key: Generate a new Etherium private key (64 symbols)
22
+ address: Turn private key into a public address (44 symbols)
23
+ price: Get current price of one gas unit, in gwei
24
+ pay: Send ERC20 payment
25
+ eth_pay: Send ETH payment
26
+ balance: Get ERC20 balance
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
+ 'Etherium chain ID',
37
+ default: 1
38
+ )
39
+ o.string(
40
+ '--host',
41
+ 'Host name of the provider',
42
+ default: 'eth.llamarpc.com'
43
+ )
44
+ o.string(
45
+ '--port',
46
+ 'TCP port of the provider',
47
+ default: 443
48
+ )
49
+ o.string(
50
+ '--http_path',
51
+ 'URL path for the HTTP RPC entry point of the provider',
52
+ default: '/'
53
+ )
54
+ o.string(
55
+ '--ws_path',
56
+ 'URL path for the Websockets entry point of the provider',
57
+ default: '/'
58
+ )
59
+ o.string(
60
+ '--proxy',
61
+ 'HTTP/S proxy for all requests, e.g. "localhost:3128"'
62
+ )
63
+ o.integer(
64
+ '--attempts',
65
+ 'How many times should we try before failing',
66
+ default: 1
67
+ )
68
+ o.bool(
69
+ '--dry',
70
+ 'Don\'t send a real payment, run in a read-only mode'
71
+ )
72
+ o.bool('--help', 'Read this: https://github.com/yegor256/erc20') do
73
+ puts o
74
+ exit
75
+ end
76
+ o.bool('--verbose', 'Print all possible debug messages')
77
+ end
78
+ rescue Slop::Error => e
79
+ raise e.message
80
+ end
81
+ raise 'Try --help' if opts.arguments.empty?
82
+ log = opts[:verbose] ? Loog::VERBOSE : Loog::REGULAR
83
+ wallet = ERC20::Wallet.new(
84
+ contract: opts[:contract],
85
+ host: opts[:host], port: opts[:port],
86
+ http_path: opts[:http_path], ws_path: opts[:ws_path],
87
+ log:
88
+ )
89
+ case opts.arguments[0]
90
+ when 'key'
91
+ puts Eth::Key.new.private_hex
92
+ when 'address'
93
+ puts Eth::Key.new(priv: opts.arguments[1]).address.to_s
94
+ when 'price'
95
+ puts wallet.gas_price
96
+ when 'balance'
97
+ address = opts.arguments[1]
98
+ raise 'Address is required' if address.nil?
99
+ log.debug("Checking ERC20 balance of #{address}")
100
+ tokens = wallet.balance(address)
101
+ log.debug("The balance is #{tokens} ERC20 tokens (#{tokens.to_f / 1_000_000} USDT)")
102
+ puts tokens
103
+ when 'eth_balance'
104
+ address = opts.arguments[1]
105
+ raise 'Address is required' if address.nil?
106
+ log.debug("Checking ETH balance of #{address}")
107
+ wei = wallet.eth_balance(address)
108
+ log.debug("The balance of #{address} is #{wei} wei (#{format('%0.4f', wei.to_f / 1_000_000_000_000_000_000)} ETH)")
109
+ puts wei
110
+ when 'pay'
111
+ pkey = opts.arguments[1]
112
+ raise 'Private key is required' if pkey.nil?
113
+ priv = Eth::Key.new(priv: pkey)
114
+ log.debug("Sending ERC20 tokens from #{priv.address.to_s}")
115
+ address = opts.arguments[2]
116
+ raise 'Address is required' if address.nil?
117
+ log.debug("Sending ERC20 tokens to #{address}")
118
+ amount = opts.arguments[3]
119
+ raise 'Amount argument is required' if amount.nil?
120
+ raise 'Amount is not valid' unless /^[0-9]+(usdt)?$/.match?(amount)
121
+ amount = amount.to_i if /^[0-9]+$/.match?(amount)
122
+ amount = (amount.gsub(/usdt^/, '').to_f * 1_000_000).to_i if /^[0-9]usdt+$/.match?(amount)
123
+ log.debug("Sending #{amount} ERC20 tokens")
124
+ puts wallet.pay(priv.private_hex, address, amount)
125
+ when 'eth_pay'
126
+ pkey = opts.arguments[1]
127
+ raise 'Private key is required' if pkey.nil?
128
+ priv = Eth::Key.new(priv: pkey)
129
+ log.debug("Sending ETH from #{priv.address.to_s}")
130
+ address = opts.arguments[2]
131
+ raise 'Address is required' if address.nil?
132
+ log.debug("Sending ETH to #{address}")
133
+ amount = opts.arguments[3]
134
+ raise 'Amount argument is required' if amount.nil?
135
+ raise "Amount #{amount.inspect} is not valid" unless /^[0-9]+(\.[0-9]+)?(eth|wei|gwei)?$/.match?(amount)
136
+ amount = amount.to_i if /^[0-9]+$/.match?(amount)
137
+ amount = amount.gsub(/wei^/, '').to_i if /[0-9]wei+$/.match?(amount)
138
+ amount = (amount.gsub(/gwei^/, '').to_f * 1_000_000_000).to_i if /[0-9]gwei+$/.match?(amount)
139
+ amount = (amount.gsub(/eth^/, '').to_f * 1_000_000_000_000_000_000).to_i if /[0-9]eth+$/.match?(amount)
140
+ log.debug("Sending #{amount} wei...")
141
+ puts wallet.eth_pay(priv.private_hex, address, amount)
142
+ else
143
+ raise "Command #{opts.arguments[0]} is not supported"
144
+ end
145
+ rescue StandardError => e
146
+ if opts[:verbose]
147
+ puts Backtrace.new(e)
148
+ else
149
+ puts "ERROR: #{e.message}"
150
+ end
151
+ exit(255)
152
+ end
data/erc20.gemspec CHANGED
@@ -23,11 +23,13 @@ Gem::Specification.new do |s|
23
23
  s.homepage = 'http://github.com/yegor256/erc20.rb'
24
24
  s.files = `git ls-files`.split($RS)
25
25
  s.rdoc_options = ['--charset=UTF-8']
26
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
27
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
27
28
  s.add_dependency 'eth', '>=0.5.13'
28
29
  s.add_dependency 'faye-websocket', '>=0.11.3'
29
30
  s.add_dependency 'json', '>=2.10.1'
30
31
  s.add_dependency 'jsonrpc-client', '>=0.1.4'
31
32
  s.add_dependency 'loog', '>0'
33
+ s.add_dependency 'slop', '>4'
32
34
  s.metadata['rubygems_mfa_required'] = 'true'
33
35
  end
@@ -0,0 +1,30 @@
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 send payments
6
+
7
+ Scenario: Help can be printed
8
+ When I run bin/erc20 with "--help"
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"
14
+ Then Exit code is zero
15
+
16
+ Scenario: ETH private key can be generated
17
+ When I run bin/erc20 with "key"
18
+ Then Exit code is zero
19
+
20
+ Scenario: ETH address can be created
21
+ When I run bin/erc20 with "address 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1"
22
+ 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,27 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ Feature: Gem Package
5
+ As a source code writer I want to be able to
6
+ package the Gem into .gem file
7
+
8
+ Scenario: Gem can be packaged
9
+ Given It is Unix
10
+ Given I have a "execs.rb" file with content:
11
+ """
12
+ #!/usr/bin/env ruby
13
+ require 'rubygems'
14
+ spec = Gem::Specification::load('./spec.rb')
15
+ if spec.executables.empty?
16
+ fail 'no executables: ' + File.read('./spec.rb')
17
+ end
18
+ """
19
+ When I run bash with:
20
+ """
21
+ cd erc20
22
+ gem build erc20.gemspec
23
+ gem specification --ruby erc20-*.gem > ../spec.rb
24
+ cd ..
25
+ ruby execs.rb
26
+ """
27
+ Then Exit code is zero
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ require 'tmpdir'
7
+ require 'slop'
8
+ require 'English'
9
+ require_relative '../../lib/erc20'
10
+
11
+ Before do
12
+ @cwd = Dir.pwd
13
+ @dir = Dir.mktmpdir('test')
14
+ FileUtils.mkdir_p(@dir)
15
+ Dir.chdir(@dir)
16
+ @opts =
17
+ Slop.parse ['-v'] do |o|
18
+ o.bool '-v', '--verbose'
19
+ end
20
+ end
21
+
22
+ After do
23
+ Dir.chdir(@cwd)
24
+ FileUtils.rm_rf(@dir)
25
+ end
26
+
27
+ Given(/^I have a "([^"]*)" file with content:$/) do |file, text|
28
+ FileUtils.mkdir_p(File.dirname(file)) unless File.exist?(file)
29
+ File.write(file, text.gsub('\\xFF', 0xFF.chr))
30
+ end
31
+
32
+ When(%r{^I run bin/erc20 with "([^"]*)"$}) do |arg|
33
+ home = File.join(File.dirname(__FILE__), '../..')
34
+ @stdout = `ruby -I#{home}/lib #{home}/bin/erc20 #{arg}`
35
+ @exitstatus = $CHILD_STATUS.exitstatus
36
+ end
37
+
38
+ Then(/^Stdout contains "([^"]*)"$/) do |txt|
39
+ raise "STDOUT doesn't contain '#{txt}':\n#{@stdout}" unless @stdout.include?(txt)
40
+ end
41
+
42
+ Then(/^Stdout is empty$/) do
43
+ raise "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
44
+ end
45
+
46
+ Then(/^Exit code is zero$/) do
47
+ raise "Non-zero exit #{@exitstatus}:\n#{@stdout}" unless @exitstatus.zero?
48
+ end
49
+
50
+ Then(/^Exit code is not zero$/) do
51
+ raise 'Zero exit code' if @exitstatus.zero?
52
+ end
53
+
54
+ When(/^I run bash with "([^"]*)"$/) do |text|
55
+ FileUtils.copy_entry(@cwd, File.join(@dir, 'erc20'))
56
+ @stdout = `#{text}`
57
+ @exitstatus = $CHILD_STATUS.exitstatus
58
+ end
59
+
60
+ When(/^I run bash with:$/) do |text|
61
+ FileUtils.copy_entry(@cwd, File.join(@dir, 'erc20'))
62
+ @stdout = `#{text}`
63
+ @exitstatus = $CHILD_STATUS.exitstatus
64
+ end
65
+
66
+ Given(/^It is Unix$/) do
67
+ pending if Gem.win_platform?
68
+ end
69
+
70
+ Given(/^It is Windows$/) do
71
+ pending unless Gem.win_platform?
72
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ require 'simplecov'
7
+ require 'cucumber'
8
+ require_relative '../../lib/erc20'
data/lib/erc20/erc20.rb CHANGED
@@ -25,5 +25,5 @@
25
25
  # License:: MIT
26
26
  module ERC20
27
27
  # Current version of the gem (changed by the +.rultor.yml+ on every release)
28
- VERSION = '0.0.21'
28
+ VERSION = '0.1.0'
29
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erc20
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-19 00:00:00.000000000 Z
11
+ date: 2025-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eth
@@ -80,12 +80,27 @@ dependencies:
80
80
  - - ">"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: slop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">"
88
+ - !ruby/object:Gem::Version
89
+ version: '4'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">"
95
+ - !ruby/object:Gem::Version
96
+ version: '4'
83
97
  description: 'A simple library for making ERC20 manipulations as easy as they can
84
98
  be for cryptocurrency newbies: checking balance, sending payments, and monitoring
85
99
  addresses for incoming payments. The library expects Etherium node to provide JSON
86
100
  RPC and Websockets API.'
87
101
  email: yegor256@gmail.com
88
- executables: []
102
+ executables:
103
+ - erc20
89
104
  extensions: []
90
105
  extra_rdoc_files:
91
106
  - README.md
@@ -117,7 +132,12 @@ files:
117
132
  - README.md
118
133
  - REUSE.toml
119
134
  - Rakefile
135
+ - bin/erc20
120
136
  - erc20.gemspec
137
+ - features/cli.feature
138
+ - features/gem_package.feature
139
+ - features/step_definitions/steps.rb
140
+ - features/support/env.rb
121
141
  - hardhat/.gitignore
122
142
  - hardhat/Dockerfile
123
143
  - hardhat/contracts/Foo.sol