cryptum 0.0.230

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +16 -0
  3. data/.gitignore +30 -0
  4. data/.rspec +3 -0
  5. data/.rspec_status +0 -0
  6. data/.rubocop.yml +5 -0
  7. data/.rubocop_todo.yml +250 -0
  8. data/.ruby-gemset +1 -0
  9. data/.ruby-version +1 -0
  10. data/CODE_OF_CONDUCT.md +84 -0
  11. data/Gemfile +36 -0
  12. data/LICENSE +674 -0
  13. data/README.md +72 -0
  14. data/Rakefile +19 -0
  15. data/bin/cryptum +72 -0
  16. data/bin/cryptum-forecast +199 -0
  17. data/bin/cryptum-repl +73 -0
  18. data/bin/cryptum_autoinc_version +38 -0
  19. data/build_cryptum_gem.sh +52 -0
  20. data/cryptum.gemspec +50 -0
  21. data/cryptum_container.sh +1 -0
  22. data/docker/cryptum.json +60 -0
  23. data/docker/cryptum_container.sh +59 -0
  24. data/docker/packer_secrets.json.EXAMPLE +7 -0
  25. data/docker/provisioners/cryptum.sh +11 -0
  26. data/docker/provisioners/docker_bashrc.sh +2 -0
  27. data/docker/provisioners/docker_rvm.sh +22 -0
  28. data/docker/provisioners/init_image.sh +28 -0
  29. data/docker/provisioners/post_install.sh +6 -0
  30. data/docker/provisioners/ruby.sh +16 -0
  31. data/docker/provisioners/upload_globals.sh +49 -0
  32. data/etc/bot_confs/.gitkeep +0 -0
  33. data/etc/bot_confs/BOT_CONF.TEMPLATE +10 -0
  34. data/etc/coinbase_pro.yaml.EXAMPLE +8 -0
  35. data/git_commit.sh +22 -0
  36. data/lib/cryptum/api.rb +693 -0
  37. data/lib/cryptum/bot_conf.rb +76 -0
  38. data/lib/cryptum/event/buy.rb +144 -0
  39. data/lib/cryptum/event/cancel.rb +49 -0
  40. data/lib/cryptum/event/history.rb +64 -0
  41. data/lib/cryptum/event/key_press.rb +64 -0
  42. data/lib/cryptum/event/sell.rb +120 -0
  43. data/lib/cryptum/event.rb +168 -0
  44. data/lib/cryptum/log.rb +34 -0
  45. data/lib/cryptum/matrix.rb +181 -0
  46. data/lib/cryptum/option/choice.rb +26 -0
  47. data/lib/cryptum/option.rb +161 -0
  48. data/lib/cryptum/order_book/generate.rb +111 -0
  49. data/lib/cryptum/order_book/indicator.rb +16 -0
  50. data/lib/cryptum/order_book/market_trend.rb +161 -0
  51. data/lib/cryptum/order_book/profit_margin.rb +55 -0
  52. data/lib/cryptum/order_book/weighted_avg.rb +157 -0
  53. data/lib/cryptum/order_book.rb +156 -0
  54. data/lib/cryptum/portfolio/balance.rb +123 -0
  55. data/lib/cryptum/portfolio.rb +15 -0
  56. data/lib/cryptum/ui/command.rb +274 -0
  57. data/lib/cryptum/ui/key_press_event.rb +22 -0
  58. data/lib/cryptum/ui/market_trend.rb +117 -0
  59. data/lib/cryptum/ui/order_execution.rb +478 -0
  60. data/lib/cryptum/ui/order_plan.rb +376 -0
  61. data/lib/cryptum/ui/order_timer.rb +119 -0
  62. data/lib/cryptum/ui/portfolio.rb +231 -0
  63. data/lib/cryptum/ui/signal_engine.rb +122 -0
  64. data/lib/cryptum/ui/terminal_window.rb +95 -0
  65. data/lib/cryptum/ui/ticker.rb +317 -0
  66. data/lib/cryptum/ui.rb +306 -0
  67. data/lib/cryptum/version.rb +5 -0
  68. data/lib/cryptum/web_sock/coinbase.rb +94 -0
  69. data/lib/cryptum/web_sock/event_machine.rb +182 -0
  70. data/lib/cryptum/web_sock.rb +16 -0
  71. data/lib/cryptum.rb +183 -0
  72. data/order_books/.gitkeep +0 -0
  73. data/reinstall_cryptum_gemset.sh +29 -0
  74. data/spec/lib/cryptum/api_spec.rb +10 -0
  75. data/spec/lib/cryptum/event_spec.rb +10 -0
  76. data/spec/lib/cryptum/log_spec.rb +10 -0
  77. data/spec/lib/cryptum/option_spec.rb +10 -0
  78. data/spec/lib/cryptum/order_book/generate_spec.rb +10 -0
  79. data/spec/lib/cryptum/order_book/market_trend_spec.rb +10 -0
  80. data/spec/lib/cryptum/order_book_spec.rb +10 -0
  81. data/spec/lib/cryptum/ui/command_spec.rb +10 -0
  82. data/spec/lib/cryptum/ui/ticker_spec.rb +10 -0
  83. data/spec/lib/cryptum/ui_spec.rb +10 -0
  84. data/spec/lib/cryptum/web_sock_spec.rb +10 -0
  85. data/spec/lib/cryptum_spec.rb +10 -0
  86. data/spec/spec_helper.rb +3 -0
  87. data/upgrade_Gemfile_gems.sh +20 -0
  88. data/upgrade_cryptum.sh +13 -0
  89. data/upgrade_gem.sh +4 -0
  90. data/upgrade_ruby.sh +46 -0
  91. metadata +472 -0
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ ## **Welcome to Cryptum!** ###
2
+ #### What ####
3
+ Cryptum is an automated, momentum-trading crypto robot written in Ruby.
4
+
5
+ #### Why ####
6
+ The goal of cryptum is three-fold:
7
+ - Identify bugs that qualify for bounty on [H1](https://hackerone.com/coinbase)
8
+ - Take the emotion out of trading crypto currency.
9
+ - Grow asset portfolios.
10
+
11
+ #### How ####
12
+ By combining real-time market data in conjunction with personalized portfolio and order history, cryptum leverages a collection of status indicators to derive probabilities to buy, sell, hold, cancel orders, or skip a respective crytpo.
13
+
14
+ Once these probabilities are derived (which occurs at a high cadence), the respective transaction will be submitted for fulfillment.
15
+
16
+ ### **Installation** ###
17
+ Tested on Linux, & OSX leveraging Ruby via RVM.
18
+
19
+ ```
20
+ $ rvm gemset create cryptum
21
+ $ rvm list gemsets
22
+ $ rvm use ruby-<VERSION>@cryptum
23
+ $ gem install --verbose cryptum
24
+ $ cryptum --help
25
+ ```
26
+
27
+ - Create a Local Coinbot Config Folder
28
+ ```
29
+ $ mkdir -p ~/cryptum/order_books
30
+ ```
31
+
32
+ - Copy the Gem etc to the Local Config Folder
33
+ ```
34
+ $ cp -a $(ruby -r 'puts "#{Gem.path.first}/gems/cryptum-#{Coinbot::VERSION}/etc"') ~/cryptum
35
+ ```
36
+
37
+ - Copy coinbase_pro.yaml.EXAMPLE to the Local Config Folder
38
+ ```
39
+ $ cp ~/cryptum/etc/coinbase_pro.yaml.EXAMPLE \
40
+ ~/cryptum/etc/coinbase_pro.yaml
41
+ ```
42
+
43
+ - Add Your API Details to ~/cryptum/etc/coinbase_pro.yaml:
44
+ ```
45
+ $ vi ~/cryptum/etc/coinbase_pro.yaml
46
+ ```
47
+
48
+
49
+ ### **Usage** ###
50
+
51
+ ```
52
+ $ rvm use ruby-<VERSION>@cryptum
53
+ $ cryptum --help
54
+ $ cryptum --symbol btc-usd \
55
+ --autotrade \
56
+ --repo-root ~/cryptum
57
+ ```
58
+
59
+ ### **Contributing** ###
60
+
61
+ For details around contributing to this project, please refer to the [Cryptum Development Guide](https://github.com/0dayinc/cryptum/blob/master/web/app/public/wiki/dev_getting_started.md).
62
+
63
+ Bug reports and pull requests are welcome on GitHub at https://github.com/0dayinc/cryptum. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/0dayinc/cryptum/blob/master/CODE_OF_CONDUCT.md).
64
+
65
+ ### **Code of Conduct** ###
66
+
67
+ Everyone interacting in the Cryptum project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/0dayinc/cryptum/blob/master/CODE_OF_CONDUCT.md).
68
+
69
+ ### **DISCLAIMER** ###
70
+ Cryptum is for educational purposes only. No information, forward looking statements, or estimations presented herein represent any final determination on investment performance. While the capabilities implemented in this project have been researched and thought to be reasonably accurate, any investment is speculative in nature.
71
+
72
+ 0day Inc. and/or its agents cannot and do not guarantee any rate of return or investment timeline based on the capabilities provided herein. Feel free to use cryptum at your own risk.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rdoc/task'
6
+ require 'rubocop/rake_task'
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ RuboCop::RakeTask.new do |rubocop|
10
+ config_file = '.rubocop.yml'
11
+ rubocop.options = ['-E', '-S', '-c', config_file]
12
+ end
13
+
14
+ RDoc::Task.new do |rdoc|
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ end
18
+
19
+ task default: %i[spec rubocop rdoc]
data/bin/cryptum ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'cryptum'
6
+
7
+ begin
8
+ start_time = Time.now.strftime('%Y-%m-%d %H:%M:%S%z')
9
+ # Initialize Driver Name & Parse cryptum Flags
10
+ driver_name = File.basename($PROGRAM_NAME)
11
+ option_choice = Cryptum::Option.parser(driver_name: driver_name)
12
+
13
+ # Initialize the Respective Environment / API Authentication Artifacts
14
+ env = Cryptum::Option.get_env(option_choice: option_choice)
15
+
16
+ # Dump out supported products if --list-products flag is passed and exit
17
+ if option_choice.list_products
18
+ Cryptum::Option.list_products_and_exit(
19
+ option_choice: option_choice,
20
+ env: env
21
+ )
22
+ end
23
+
24
+ # Instantiate Our Status Indicators & History Objects
25
+ indicator_status = Cryptum::OrderBook::Indicator.new
26
+
27
+ # Automatically Create Bot Confs if they don't
28
+ # Exist and Initialize Automated Trading Parameters
29
+ bot_conf = Cryptum::BotConf.read(option_choice: option_choice)
30
+
31
+ # Generate an Order Book for Session Tracking
32
+ # Load previous order_book_justification from
33
+ # Order Book File (if it exists) to preserve
34
+ # Order Tags and load last 180 candles from
35
+ # Coinbase
36
+ event_history = Cryptum::OrderBook::Generate.new_order_book(
37
+ start_time: start_time,
38
+ option_choice: option_choice,
39
+ env: env,
40
+ bot_conf: bot_conf
41
+ )
42
+
43
+ # Initialize Curses UI
44
+ terminal_win = Cryptum::UI.init
45
+
46
+ # Connect to WebSocket
47
+ # Trigger Events as Event Data
48
+ # is Generated via Coinbase Pro
49
+ # Web Socket HTTP Responses
50
+ # Refresh UI with Event Data
51
+ # Update "Status Indicators"
52
+ # Leverage "Status Indicators" to Initiate Actions
53
+ Cryptum::WebSock::EventMachine.run(
54
+ option_choice: option_choice,
55
+ env: env,
56
+ terminal_win: terminal_win,
57
+ event_history: event_history,
58
+ indicator_status: indicator_status,
59
+ bot_conf: bot_conf
60
+ )
61
+ rescue Interrupt
62
+ # Exit Gracefully if CTRL+C is Pressed During Session
63
+ Cryptum.exit_gracefully(
64
+ which_self: self,
65
+ event_history: event_history,
66
+ option_choice: option_choice,
67
+ env: env
68
+ )
69
+ rescue StandardError => e
70
+ # Produce a Stacktrace for anything else
71
+ raise e
72
+ end
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'optparse'
6
+ require 'cryptum'
7
+
8
+ class Choice
9
+ attr_accessor :autotrade_percent,
10
+ :cycles_complete,
11
+ :driver_name,
12
+ :proxy,
13
+ :repo_root,
14
+ :sandbox,
15
+ :symbol,
16
+ :tpm,
17
+ :total_holdings
18
+
19
+ rescue StandardError => e
20
+ # Produce a Stacktrace for anything else
21
+ raise e
22
+ end
23
+
24
+ begin
25
+ option_choice = Choice.new
26
+ option_choice.driver_name = File.basename($PROGRAM_NAME)
27
+
28
+ OptionParser.new do |options|
29
+ options.banner = "USAGE: #{option_choice.driver_name} [opts]"
30
+ options.on(
31
+ '-sSYMBOL',
32
+ '--symbol=SYMBOL',
33
+ '<Required - Crypto Symbol.(e.g. btc-usd, eth-usd, etc.)'
34
+ ) { |s| option_choice.symbol = s.to_s.gsub('-', '_').downcase.to_sym }
35
+
36
+ options.on(
37
+ '-aPERCENT',
38
+ '--autotrade=PERCENT',
39
+ '<Optional - Autotrade % (Defaults to Value in Respective Bot Conf)'
40
+ ) { |a| option_choice.autotrade_percent = a.to_f }
41
+
42
+ options.on(
43
+ '-cNUMBER',
44
+ '--cycles-completed=NUMBER',
45
+ '<Optional - Total # of Autotrade Cycles to Evaluate (Defaults to 1)">'
46
+ ) { |c| option_choice.cycles_complete = c.to_i }
47
+
48
+ options.on(
49
+ '-hHOLDINGS',
50
+ '--total-holdings=HOLDINGS',
51
+ '<Optional - Total Portfolio Holdings in USD (Defaults to Current Balance)'
52
+ ) { |h| option_choice.total_holdings = h.to_f }
53
+
54
+ options.on(
55
+ '-pPROXY',
56
+ '--proxy=PROXY',
57
+ '<Optional - HTTP Proxy e.g. "http://127.0.0.1:8080">'
58
+ ) { |p| option_choice.proxy = p }
59
+
60
+ options.on(
61
+ '-rPATH',
62
+ '--repo-root=PATH',
63
+ '<Optional - Directory of Cloned Repo (Defaults to Dir.pwd)">'
64
+ ) { |r| option_choice.repo_root = r }
65
+
66
+ options.on(
67
+ '-tTPM',
68
+ '--target-profit-margin=TPM',
69
+ '<Optional - Target Profit Margin % (Defaults to Value in Respective Bot Conf)'
70
+ ) { |t| option_choice.tpm = t.to_f }
71
+
72
+ options.on(
73
+ '-S',
74
+ '--[no-]sandbox',
75
+ '<Optional - Use Coinbase Sandbox Environment for Testing Ideas>'
76
+ ) { |n| option_choice.sandbox = n }
77
+ end.parse!
78
+
79
+ # Conditions to display cryptum usage
80
+ if option_choice.symbol.nil?
81
+ usage = true
82
+ reason = :symbol
83
+ end
84
+
85
+ option_choice.repo_root = Dir.pwd if option_choice.repo_root.nil?
86
+
87
+ if option_choice.autotrade_percent.to_f > 100
88
+ usage = true
89
+ reason = :autotrade_percent
90
+ end
91
+
92
+ unless Dir.exist?(option_choice.repo_root)
93
+ usage = true
94
+ reason = :repo_root
95
+ end
96
+
97
+ if usage
98
+ case reason
99
+ when :autotrade_percent
100
+ puts 'ERROR: --autotrade PERCENT value cannot exceed 100'
101
+ when :symbol
102
+ puts "ERROR: --symbol Flag is Required.\n\n"
103
+ when :repo_root
104
+ puts "ERROR: #{option_choice.repo_root} does not exist.\n\n"
105
+ end
106
+
107
+ puts `#{option_choice.driver_name} --help`
108
+ exit 1
109
+ end
110
+
111
+ autotrade_cycle_tot = option_choice.cycles_complete
112
+ autotrade_cycle_tot = 1 unless option_choice.cycles_complete.to_i.positive?
113
+
114
+ # Initialize the Respective Environment / API Authentication Artifacts
115
+ env = Cryptum::Option.get_env(option_choice: option_choice)
116
+
117
+ # Read in Bot Conf Values
118
+ bot_conf = Cryptum::BotConf.read(option_choice: option_choice)
119
+
120
+ products = Cryptum::API.get_products(
121
+ option_choice: option_choice,
122
+ env: env
123
+ )
124
+
125
+ crypto = products.last[:base_currency]
126
+ fiat = products.last[:quote_currency]
127
+ fiat_portfolio_file = "#{option_choice.repo_root}/order_books/#{fiat}_PORTFOLIO.json"
128
+
129
+ portfolio = Cryptum::API.get_portfolio(
130
+ option_choice: option_choice,
131
+ env: env,
132
+ crypto: crypto,
133
+ fiat: fiat,
134
+ fiat_portfolio_file: fiat_portfolio_file
135
+ )
136
+
137
+ fiat_portfolio = JSON.parse(
138
+ File.read(fiat_portfolio_file),
139
+ symbolize_names: true
140
+ )
141
+
142
+ holdings = fiat_portfolio.last[:total_holdings].to_f
143
+ holdings = option_choice.total_holdings.to_f if option_choice.total_holdings.to_f.positive?
144
+
145
+ autotrade = bot_conf[:autotrade_portfolio_percent].to_f / 100
146
+ autotrade = option_choice.autotrade_percent.to_f / 100 if option_choice.autotrade_percent.to_f.positive?
147
+
148
+ gross_tpm = bot_conf[:target_profit_margin_percent].to_f / 100
149
+ gross_tpm = option_choice.tpm.to_f if option_choice.tpm.to_f.positive?
150
+
151
+ fees = Cryptum::API.get_fees(
152
+ option_choice: option_choice,
153
+ env: env
154
+ )
155
+ taker_fee = format('%0.4f', fees[:taker_fee_rate].to_f)
156
+ total_cycle_fees = taker_fee.to_f * 2
157
+ net_tpm = gross_tpm - total_cycle_fees
158
+
159
+ beautify_holdings = Cryptum.beautify_large_number(
160
+ value: format('%0.2f', holdings)
161
+ )
162
+
163
+ print "Initial Holdings: $#{beautify_holdings} | "
164
+ print "Autotrade: #{format('%0.2f', autotrade * 100)}% | "
165
+ print "Gross TPM: #{format('%0.2f', gross_tpm * 100)}% | "
166
+ print "Fee: #{format('%0.2f', total_cycle_fees * 100)}% | "
167
+ puts "Net TPM: #{format('%0.2f', net_tpm * 100)}%"
168
+
169
+ (1..autotrade_cycle_tot).each do |autotrade_cycle|
170
+ risk_alloc = holdings * autotrade
171
+ bal = risk_alloc
172
+ bal += bal * net_tpm
173
+ profit = bal - risk_alloc
174
+ holdings += profit
175
+
176
+ beautify_risk_alloc = Cryptum.beautify_large_number(
177
+ value: format('%0.2f', risk_alloc)
178
+ )
179
+
180
+ beautify_profit = Cryptum.beautify_large_number(
181
+ value: format('%0.2f', profit)
182
+ )
183
+
184
+ beautify_holdings = Cryptum.beautify_large_number(
185
+ value: format('%0.2f', holdings)
186
+ )
187
+
188
+ print "##{autotrade_cycle} | "
189
+ print "Risk Alloc: $#{beautify_risk_alloc} | "
190
+ print "Profit: $#{beautify_profit} | "
191
+ puts "Holdings: $#{beautify_holdings}"
192
+ end
193
+ rescue Interrupt
194
+ # Exit Gracefully if CTRL+C is Pressed During Session
195
+ puts "Interrupt detected in #{self}...goodbye."
196
+ rescue StandardError => e
197
+ # Produce a Stacktrace for anything else
198
+ raise e
199
+ end
data/bin/cryptum-repl ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'cryptum'
5
+ require 'pry'
6
+ require 'tty-prompt'
7
+ require 'tty-reader'
8
+
9
+ begin
10
+ # TODO: Remove once this feature is available in mainline
11
+ class Pry
12
+ # Overwrite Pry::History.push method in History class to get duplicate history entries
13
+ # in order to properly replay automation in this prototyping driver
14
+ class History
15
+ def push(line)
16
+ return line if line.empty? || invalid_readline_line?(line)
17
+
18
+ # begin
19
+ # last_line = @history.last
20
+ # rescue IndexError
21
+ # last_line = nil
22
+ # end
23
+ # return line if line == last_line
24
+
25
+ @history << line
26
+ @history_line_count += 1
27
+ @saver.call(line) if !should_ignore?(line) && Pry.config.history_save
28
+
29
+ line
30
+ end
31
+ alias << push
32
+ end
33
+ end
34
+
35
+ cli = Pry
36
+
37
+ cli.config.hooks.add_hook(:before_eval, :autocomplete) do
38
+ # prompt = TTY::Prompt.new
39
+ reader = TTY::Reader.new
40
+ reader.on(:keypress) { |key_event| prompt(key_event) }
41
+ end
42
+
43
+ cli::Commands.create_command 'toggle-pager' do
44
+ description 'Toggle less on returned objects surpassing the terminal.'
45
+
46
+ def process
47
+ # Toggle pager from true to false via XOR
48
+ pry_instance.config.pager ^= true
49
+ end
50
+ end
51
+
52
+ # Custom Main & Wait (Multi-Line) Prompts
53
+ title = "\001\e[1m\002\001\e[31m\002cryptum\001\e[0m\002" # Bold Red
54
+ version = "\001\e[36m\002v#{Cryptum::VERSION}\001\e[0m\002" # Cyan
55
+ arrow = "\001\e[32m\002>>>\001\e[0m\002" # Green
56
+ splat = "\001\e[33m\002***\001\e[0m\002" # Yellow
57
+
58
+ prompt = [
59
+ proc do |_target_self, _nest_level, pry|
60
+ line_pad = format('%0.3d', pry.input_ring.size)
61
+ line_count = "\001\e[34m\002#{line_pad}\001\e[0m\002" # Blue
62
+ "#{title}[#{version}]:#{line_count} #{arrow} ".to_s.scrub
63
+ end,
64
+ proc do |_target_self, _nest_level, pry|
65
+ line_pad = format('%0.3d', pry.input_ring.size)
66
+ line_count = "\001\e[34m\002#{line_pad}\001\e[0m\002" # Blue
67
+ "#{title}[#{version}]:#{line_count} #{splat} ".to_s.scrub
68
+ end
69
+ ]
70
+ cli.start(self, prompt: Pry::Prompt.new(:cryptum, 'CRYPTUM_PROTOTYPING_DRIVER', prompt))
71
+ rescue StandardError => e
72
+ raise e
73
+ end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'cryptum'
6
+
7
+ old_rev = Cryptum::VERSION
8
+ placeholder_arr = old_rev.split('.')
9
+ major = placeholder_arr[0].to_i
10
+ minor = placeholder_arr[1].to_i
11
+ hotfix = placeholder_arr[2].to_i
12
+
13
+ if hotfix < 999
14
+ hotfix += 1
15
+ placeholder_arr[2] = hotfix.to_s
16
+ else
17
+ # TODO: Tag master branch once minor version is reached
18
+ placeholder_arr[2] = '0'
19
+ if minor < 9
20
+ minor += 1
21
+ placeholder_arr[1] = minor.to_s
22
+ else
23
+ placeholder_arr[1] = '0'
24
+ major += 1
25
+ placeholder_arr[0] = major.to_s
26
+ end
27
+ end
28
+
29
+ new_rev = placeholder_arr.join('.')
30
+
31
+ puts "Upgrading to #{new_rev}..."
32
+ File.open('./lib/cryptum/version.rb', 'w') do |f|
33
+ f.puts '# frozen_string_literal: true'
34
+ f.puts "\n"
35
+ f.puts 'module Cryptum'
36
+ f.puts " VERSION = '#{new_rev}'"
37
+ f.puts 'end'
38
+ end
@@ -0,0 +1,52 @@
1
+ #!/bin/bash --login
2
+ if [[ $CRYPTUM_ROOT == '' ]]; then
3
+ if [[ ! -d '/opt/cryptum' ]]; then
4
+ cryptum_root=$(pwd)
5
+ else
6
+ cryptum_root='/opt/cryptum'
7
+ fi
8
+ else
9
+ cryptum_root="${CRYPTUM_ROOT}"
10
+ fi
11
+
12
+ ls pkg/*.gem 2> /dev/null | while read previous_gems; do
13
+ rvmsudo rm $previous_gems
14
+ done
15
+ old_ruby_version=`cat ${cryptum_root}/.ruby-version`
16
+ # Default Strategy is to merge codebase
17
+ # rvmsudo git config pull.rebase false
18
+ # rvmsudo git pull origin master
19
+ git config pull.rebase false
20
+ git pull origin master
21
+ new_ruby_version=`cat ${cryptum_root}/.ruby-version`
22
+
23
+ rvm list gemsets | grep `cat ${cryptum_root}/.ruby-gemset`
24
+ if [[ $? != 0 ]]; then
25
+ echo "Ruby v${new_ruby_version} is not installed. Installing..."
26
+ cd $cryptum_root && ./upgrade_ruby.sh $new_ruby_version
27
+ # Rely on RVM to creeate gemset
28
+ cd / && cd $cryptum_root
29
+ fi
30
+
31
+ if [[ $old_ruby_version == $new_ruby_version ]]; then
32
+ export rvmsudo_secure_path=1
33
+ rvmsudo /bin/bash --login -c "cd ${cryptum_root} && ./reinstall_cryptum_gemset.sh"
34
+ rvmsudo rake
35
+ rvmsudo rake install
36
+ rvmsudo rake rerdoc
37
+ rvmsudo gem update --system
38
+ rvmsudo gem rdoc --rdoc --ri --overwrite -V cryptum
39
+ echo "Invoking bundle-audit Gemfile Scanner..."
40
+ rvmsudo bundle-audit
41
+ else
42
+ cd $cryptum_root && ./upgrade_ruby.sh $new_ruby_version $old_ruby_version
43
+ fi
44
+
45
+ unpriv_user=`echo $USER`
46
+ if [[ $unpriv_user != 'root' ]]; then
47
+ if [[ $(uname -s) == 'Darwin' ]]; then
48
+ rvmsudo chown -R $unpriv_user $cryptum_root
49
+ else
50
+ rvmsudo chown -R $unpriv_user:$unpriv_user $cryptum_root
51
+ fi
52
+ fi
data/cryptum.gemspec ADDED
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'cryptum/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.required_ruby_version = ">= #{File.read('.ruby-version')}"
9
+ spec.name = 'cryptum'
10
+ spec.version = Cryptum::VERSION
11
+ spec.authors = ['0day Inc.']
12
+ spec.email = ['request.pentest@0dayinc.com']
13
+ spec.summary = 'Coinbase Pro High-Frequency Trading Bot'
14
+ spec.description = 'Personalized High-Frequency Trading Bot'
15
+ spec.homepage = 'https://github.com/0dayinc/cryptum'
16
+ spec.license = 'GPL'
17
+ spec.metadata['rubygems_mfa_required'] = 'true'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ['lib']
23
+
24
+ dev_dependency_arr = %i[
25
+ bundler
26
+ rake
27
+ rdoc
28
+ rspec
29
+ ]
30
+
31
+ File.readlines('./Gemfile').each do |line|
32
+ columns = line.chomp.split
33
+ next unless columns.first == 'gem'
34
+
35
+ gem_name = columns[1].delete("'").delete(',')
36
+ gem_version = columns.last.delete("'")
37
+
38
+ if dev_dependency_arr.include?(gem_name.to_sym)
39
+ spec.add_development_dependency(
40
+ gem_name,
41
+ gem_version
42
+ )
43
+ else
44
+ spec.add_runtime_dependency(
45
+ gem_name,
46
+ gem_version
47
+ )
48
+ end
49
+ end
50
+ end
@@ -0,0 +1 @@
1
+ docker/cryptum_container.sh
@@ -0,0 +1,60 @@
1
+ {
2
+ "variables": {
3
+ "ssh_auth_sock": "{{env `SSH_AUTH_SOCK`}}",
4
+ "repository": "{{env `REPOSITORY`}}",
5
+ "aws_access_key": "{{env `AWS_ACCESS_KEY`}}",
6
+ "aws_secret_key": "{{env `AWS_SECRET_KEY`}}",
7
+ "aws_token": "{{env `AWS_TOKEN`}}",
8
+ "aws_profile": "{{env `AWS_PROFILE`}}",
9
+ "login_server": "{{env `LOGIN_SERVER`}}"
10
+ },
11
+ "builders": [{
12
+ "type": "docker",
13
+ "image": "kalilinux/kali-rolling",
14
+ "commit": true,
15
+ "volumes": {
16
+ "{{user `ssh_auth_sock` }}": "/ssh-agent"
17
+ },
18
+ "changes": [
19
+ "EXPOSE 9999"
20
+ ],
21
+ "run_command": [
22
+ "--detach",
23
+ "--interactive",
24
+ "--tty",
25
+ "--name=cryptum",
26
+ "--entrypoint=/bin/bash",
27
+ "{{.Image}}"
28
+ ]
29
+ }],
30
+ "provisioners": [{
31
+ "type": "shell",
32
+ "scripts": [
33
+ "provisioners/upload_globals.sh",
34
+ "provisioners/init_image.sh",
35
+ "provisioners/docker_rvm.sh",
36
+ "provisioners/docker_bashrc.sh",
37
+ "provisioners/ruby.sh",
38
+ "provisioners/cryptum.sh",
39
+ "provisioners/post_install.sh"
40
+ ],
41
+ "pause_before": "1s"
42
+ }],
43
+ "post-processors": [
44
+ [
45
+ {
46
+ "type": "docker-tag",
47
+ "repository": "{{user `repository`}}",
48
+ "tag": "latest"
49
+ },
50
+ {
51
+ "type": "docker-push",
52
+ "ecr_login": true,
53
+ "aws_access_key": "{{user `aws_access_key`}}",
54
+ "aws_secret_key": "{{user `aws_secret_key`}}",
55
+ "login_server": "https://{{user `repository`}}",
56
+ "keep_input_artifact": false
57
+ }
58
+ ]
59
+ ]
60
+ }
@@ -0,0 +1,59 @@
1
+ #!/bin/bash --login
2
+ debug=false
3
+ export PACKER_LOG=1
4
+ set -e
5
+
6
+ function usage() {
7
+ echo -e "USAGE: ${0} <build || debug>"
8
+ exit 1
9
+ }
10
+
11
+ function pack() {
12
+ packer_provider_template=$1
13
+ debug=$2
14
+ packer_secrets='./packer_secrets.json'
15
+
16
+ if [[ $CRYPTUM_ROOT == '' ]]; then
17
+ if [[ ! -d '/opt/cryptum' ]]; then
18
+ cryptum_root=$(pwd)
19
+ else
20
+ cryptum_root='/opt/cryptum'
21
+ fi
22
+ else
23
+ cryptum_root="${CRYPTUM_ROOT}"
24
+ fi
25
+
26
+ cd $cryptum_root/docker
27
+
28
+ if $debug; then
29
+ packer build \
30
+ -debug \
31
+ -only docker \
32
+ -var "box_version=latest" \
33
+ -var "ssh_auth_sock=${SSH_AUTH_SOCK}" \
34
+ -var-file=$packer_secrets \
35
+ $packer_provider_template
36
+ else
37
+ packer build \
38
+ -only docker \
39
+ -var "box_version=latest" \
40
+ -var "ssh_auth_sock=${SSH_AUTH_SOCK}" \
41
+ -var-file=$packer_secrets \
42
+ $packer_provider_template
43
+ fi
44
+ }
45
+
46
+ if [[ $# < 1 ]]; then
47
+ usage
48
+ fi
49
+
50
+ action="${1}"
51
+
52
+ case $action in
53
+ 'build')
54
+ pack ./cryptum.json false;;
55
+ 'debug')
56
+ pack ./cryptum.json true;;
57
+ '*')
58
+ usage;;
59
+ esac