gtmtech-crypto 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 262dc2d5d049a25d80227742c81eccc6307ac364
4
+ data.tar.gz: 67f33bbf9667ac1f4e3d4fe2c4aa4b49aa3f4e58
5
+ SHA512:
6
+ metadata.gz: f0fda99a14c4ec5c039a4f7edeb3d9db64e44b31256461c47e94f5cf56ea617329cfbea447678cbd5400ae5117a0a7c9342db2b46f12c7963b83c1b57c21d031
7
+ data.tar.gz: a817e4aa4ad4c30c26224d659c74f5724f4a206946017caf0cf996b5d8afb2193f240b121162e9780c01d4d245f200c55cfcb23f4ebc247cfd47e91f62f66223
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ .idea
2
+ *.iml
3
+ *.gradle
4
+ pkg/
5
+ tmp/
6
+ .DS_Store
7
+ .rvmrc
8
+ .ruby-gemset
9
+ Gemfile.lock
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Geoff Meakin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ crypto
2
+ ======
3
+
4
+ crypto is a utiity for keeping track of all your cryptocurrency accounts. It aims to do the following
5
+
6
+ * Log transactions
7
+ * Provide account statements
8
+ * Provide detailed transaction history
9
+
10
+ in order that:
11
+
12
+ * You understand where your money is
13
+ * You can provide records for tax purposes
14
+
15
+
16
+ Setup:
17
+ ======
18
+
19
+ First install ruby/rubygems. Then install this
20
+
21
+ ```
22
+ gem install gtmtech-crypto
23
+ ```
24
+
25
+
26
+ Usage:
27
+ ======
28
+
29
+ Firstly set up some accounts
30
+
31
+ ```
32
+ $ crypto new account --name barclays --currencies GBP --type bank
33
+ $ crypto new account --name kraken --currencies GBP,BTC --type exchange
34
+ $ crypto new account --name ledger --currencies BTC,ETH --type wallet
35
+ ```
36
+
37
+ Then trade
38
+
39
+ ```
40
+ $ crypto new txn --from barclays.GBP=200 --to bitbargain.GBP
41
+ $ crypto new txn --from kraken.GBP=150 --to kraken.BTC=0.08
42
+ ```
43
+
44
+ some transactions have fees associated with them
45
+
46
+ ```
47
+ $ crypto new txn --from kraken.BTC=0.08 --to ledger.BTC=0.078 # implicit fees of 0.0002 BTC
48
+ $ crypto new txn --from kraken.BTC=0.08 --to ledger.BTC --fees.BTC=0.002 # extra fees paid at source (kraken)
49
+ ```
50
+
51
+ Output transaction history
52
+
53
+ ```
54
+ $ crypto list txn # all transactions
55
+ $ crypto list txn --account barclays # all barclays transactions
56
+ $ crypto list txn --currency BTC # all bitcoin transactions
57
+ ```
58
+
59
+ Output pnl sheet
60
+
61
+ ```
62
+ $ crypto list pnl # profit-and-loss
63
+ ```
64
+
65
+
66
+ Building
67
+ ========
68
+
69
+ Install chruby and ruby-build
70
+
71
+ * OSX: https://gist.github.com/andrewroycarter/6815905
72
+
73
+ Install version 2.0.0 of ruby using chruby
74
+
75
+ ```
76
+ $ ruby-install ruby 2.0.0
77
+ or $ ruby-build ruby 2.0.0
78
+ ```
79
+
80
+ Build the gem
81
+
82
+ ```
83
+ $ ./build.sh
84
+ ```
85
+
86
+ Disclaimer
87
+ ==========
88
+
89
+ Please see LICENSE.TXT for usage of this software.
90
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/crypto ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'gtmtech/crypto/CLI'
5
+
6
+ begin
7
+ Gtmtech::Crypto::CLI.parse
8
+ rescue StandardError => e
9
+ puts e.message
10
+ puts e.backtrace.join("\n")
11
+ exit 1
12
+ end
13
+
14
+ begin
15
+ Gtmtech::Crypto::CLI.execute
16
+ rescue StandardError => e
17
+ puts e.message
18
+ puts e.backtrace.join("\n")
19
+ exit 1
20
+ end
data/build.sh ADDED
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+
3
+ set -x -e -o pipefail
4
+
5
+ gem uninstall gtmtech-crypto --executables
6
+ RAKE_OUT=$(rake build)
7
+ echo "${RAKE_OUT}"
8
+
9
+ VERSION=$(echo "${RAKE_OUT}" | awk '{print $2}')
10
+ echo "Installing version: ${VERSION} ..."
11
+
12
+ gem install pkg/gtmtech-crypto-${VERSION}.gem
13
+ crypto version
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "gtmtech-crypto"
7
+ gem.version = "0.0.1"
8
+ gem.description = "Simple tool for accounting of cryptocurrencies"
9
+ gem.summary = "Simple tool for accounting of cryptocurrencies"
10
+ gem.author = "Geoff Meakin"
11
+ gem.license = "MIT"
12
+
13
+ gem.homepage = "http://github.com/gtmtechltd/crypto"
14
+ gem.files = `git ls-files`.split($/).reject { |file| file =~ /^features.*$/ }
15
+ gem.executables << "crypto"
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+ gem.add_dependency('trollop', '~> 2.0')
19
+ end
@@ -0,0 +1,9 @@
1
+ module Gtmtech
2
+ module Crypto
3
+
4
+ VERSION = "0.0.1"
5
+ DESCRIPTION = "crypto is a cli tool for simple accounting of cryptocurrencies"
6
+
7
+ end
8
+ end
9
+
@@ -0,0 +1,43 @@
1
+ require 'gtmtech/crypto/utils'
2
+ require 'gtmtech/crypto/subcommand'
3
+
4
+ module Gtmtech
5
+ module Crypto
6
+ class CLI
7
+
8
+ attr_reader :subcommands
9
+
10
+ def self.parse
11
+
12
+ Utils.require_dir 'gtmtech/crypto/subcommands'
13
+ @@subcommands = Utils.find_all_subclasses_of({ :parent_class => Gtmtech::Crypto::Subcommands }).collect {|classname| Utils.snakecase classname}
14
+
15
+ subcommand = ARGV.shift
16
+ subcommand = case subcommand
17
+ when nil
18
+ ARGV.delete_if {true}
19
+ "unknown_command"
20
+ when /^\-/
21
+ ARGV.delete_if {true}
22
+ "help"
23
+ else
24
+ subcommand
25
+ end
26
+
27
+ @@command_class = Subcommand.find subcommand
28
+ @@options = @@command_class.parse
29
+
30
+ end
31
+
32
+ def self.execute
33
+ @@command_class.execute
34
+ end
35
+
36
+ def self.subcommands
37
+ @@subcommands
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,88 @@
1
+ require 'securerandom'
2
+ require 'gtmtech/crypto/utils'
3
+
4
+ module Gtmtech
5
+ module Crypto
6
+ class Data
7
+
8
+ def self.load
9
+ @@path = "#{ENV['HOME']}/.crypto.yaml"
10
+ unless File.exist? @@path
11
+ File.open(@@path, 'w') do |file|
12
+ file.write("---\naccounts: {}\ntransactions: []\n")
13
+ end
14
+ end
15
+ @@document = YAML.load(File.read(@@path))
16
+ end
17
+
18
+ def self.add_account name, currency, type, url
19
+ if @@document[ "accounts" ].key? name
20
+ currencies = @@document[ "accounts" ][ name ][ "currencies" ]
21
+ currencies << currency
22
+ @@document[ "accounts" ][ name ][ "currencies" ] = currencies.uniq.sort
23
+ @@document[ "accounts" ][ name ][ "type" ] = type if type
24
+ @@document[ "accounts" ][ name ][ "url" ] = url if url
25
+ else
26
+ @@document[ "accounts" ][ name ] = { "currencies" => [ currency ], "type" => type, "url" => url }
27
+ end
28
+ end
29
+
30
+ def self.list_accounts
31
+ printf("%-10s %-10s %-60s\n", "name", "type", "currencies")
32
+ puts "-" * 80
33
+ @@document[ "accounts" ].each do |name, account_info|
34
+ printf("%-10s %-10s %-60s\n", name, account_info[ "type" ], account_info[ "currencies" ].join(","))
35
+ end
36
+ end
37
+
38
+ def self.account_exists? name, currency
39
+ return false unless @@document[ "accounts" ].key? name
40
+ return false unless @@document[ "accounts" ][ name ][ "currencies" ].include? currency
41
+ true
42
+ end
43
+
44
+ def self.add_transaction date, source_account, source_currency, source_amount, dest_account, dest_currency, dest_amount, fees_account, fees_currency, fees_amount
45
+ if date.downcase == "now"
46
+ date = Time.now.to_s.split(" ").take(2).join(",")
47
+ end
48
+
49
+ source_amount = Utils.make_decimal source_amount
50
+ dest_amount = Utils.make_decimal dest_amount
51
+
52
+ id = SecureRandom.uuid.to_s
53
+ @@document[ "transactions" ][ id ] = { "date" => date,
54
+ "source_account" => source_account,
55
+ "source_currency" => source_currency,
56
+ "source_amount" => source_amount,
57
+ "dest_account" => dest_account,
58
+ "dest_currency" => dest_currency,
59
+ "dest_amount" => dest_amount,
60
+ "fees_account" => fees_account,
61
+ "fees_currency" => fees_currency,
62
+ "fees_amount" => fees_amount }
63
+ end
64
+
65
+ def self.list_transactions
66
+ printf("%-36s %-20s %-15s %-15s %-15s %-15s\n", "id", "date", "src account", "src amount", "dest account", "dest amount")
67
+ puts "-" * 120
68
+ @@document[ "transactions" ].each do |id, txn|
69
+ printf("%-36s %-20s %-15s %-15s %-15s %-15s\n", id, txn["date"], "#{txn["source_account"]}.#{txn["source_currency"]}", txn["source_amount"], "#{txn["dest_account"]}.#{txn["dest_currency"]}", txn["dest_amount"])
70
+ if txn["fees_account"]
71
+ printf("%-36s %-20s %-15s %-15s %-15s %-15s\n", id, txn["date"], "#{txn["fees_account"]}.#{txn["fees_currency"]}", txn["fees_amount"], "fees.#{txn["fees_currency"]}", txn["fees_amount"])
72
+ end
73
+ end
74
+ end
75
+
76
+ def self.delete_transaction id
77
+ @@document[ "transactions" ].delete( id )
78
+ end
79
+
80
+ def self.save
81
+ File.open(@@path, 'w') do |file|
82
+ file.write( @@document.to_yaml )
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,111 @@
1
+ require 'base64'
2
+ require 'yaml'
3
+ require 'trollop'
4
+ # require 'gtmtech/crypto/subcommands/unknown_command'
5
+ require 'gtmtech/crypto'
6
+
7
+ module Gtmtech
8
+ module Crypto
9
+
10
+ class Subcommand
11
+
12
+ class << self
13
+ attr_accessor :global_options, :options, :helptext
14
+ end
15
+
16
+ @@global_options = [
17
+ {:name => :version,
18
+ :description => "Show version information"},
19
+ {:name => :help,
20
+ :description => "Information on how to use this command",
21
+ :short => 'h'}
22
+ ]
23
+
24
+ def self.all_options
25
+ options = @@global_options.dup
26
+ options += self.options if self.options
27
+ { :options => options }
28
+ end
29
+
30
+ def self.find commandname = "unknown_command"
31
+ begin
32
+ require "gtmtech/crypto/subcommands/#{commandname.downcase}"
33
+ rescue Exception => e
34
+ require "gtmtech/crypto/subcommands/unknown_command"
35
+ return Gtmtech::Crypto::Subcommands::UnknownCommand
36
+ end
37
+ command_module = Module.const_get('Gtmtech').const_get('Crypto').const_get('Subcommands')
38
+ command_class = Utils.find_closest_class :parent_class => command_module, :class_name => commandname
39
+ if command_class
40
+ command_class
41
+ else
42
+ require "gtmtech/crypto/subcommands/unknown_command"
43
+ Gtmtech::Crypto::Subcommands::UnknownCommand
44
+ end
45
+ end
46
+
47
+ def self.parse
48
+
49
+ me = self
50
+ all = self.all_options
51
+
52
+ @@options = Trollop::options do
53
+
54
+ version "gtmtech-crypto version " + Gtmtech::Crypto::VERSION.to_s
55
+ banner "#{me.usage}\n\n"
56
+
57
+ all[:options].each do |available_option|
58
+
59
+ skeleton = {:description => "",
60
+ :short => :none}
61
+
62
+ skeleton.merge! available_option
63
+ opt skeleton[:name],
64
+ skeleton[:desc] || skeleton[:description], #legacy plugins
65
+ :short => skeleton[:short],
66
+ :default => skeleton[:default],
67
+ :type => skeleton[:type]
68
+
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ def self.validate args
76
+ args
77
+ end
78
+
79
+ def self.usage
80
+ "Usage: \ncrypto #{self.prettyname} [global-options] [options]\nDescription: #{self.description}"
81
+ end
82
+
83
+ def self.description
84
+ "no description"
85
+ end
86
+
87
+ def self.helptext
88
+ "Usage: crypto #{self.prettyname} [options]"
89
+ end
90
+
91
+ def self.execute
92
+ raise StandardError, "This command is not implemented yet (#{self.to_s.split('::').last})"
93
+ end
94
+
95
+ def self.prettyname
96
+ Utils.snakecase self.to_s.split('::').last
97
+ end
98
+
99
+ def self.hidden?
100
+ false
101
+ end
102
+
103
+ def self.error message
104
+ puts "Error:"
105
+ puts message
106
+ exit 1
107
+ end
108
+
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,79 @@
1
+ require 'gtmtech/crypto/subcommand'
2
+ require 'gtmtech/crypto/data'
3
+ require 'yaml'
4
+
5
+ module Gtmtech
6
+ module Crypto
7
+ module Subcommands
8
+
9
+ class Account < Subcommand
10
+
11
+ def self.description
12
+ "manage accounts"
13
+ end
14
+
15
+ def self.usage
16
+ <<-EOS
17
+ Usage (crypto #{self.prettyname})
18
+
19
+ crypto #{self.prettyname} new --name=<s> --currencies=<s> [--type=<s> --url=<s>]
20
+ - create a new account
21
+
22
+ crypto #{self.prettyname} list
23
+ - list all accounts
24
+
25
+ Options:
26
+ EOS
27
+ end
28
+
29
+ def self.options
30
+ [{:name => :name,
31
+ :description => "Name of the account",
32
+ :short => 'n',
33
+ :type => :string},
34
+ {:name => :currencies,
35
+ :description => "Comma separated list of currencies this account supports",
36
+ :short => 'c',
37
+ :type => :string},
38
+ {:name => :type,
39
+ :description => "(optional) Type of account - options are wallet,exchange,bank",
40
+ :short => 't',
41
+ :type => :string},
42
+ {:name => :url,
43
+ :description => "(optional) URL for account website",
44
+ :short => 'u',
45
+ :type => :string}
46
+ ]
47
+ end
48
+
49
+ def self.create
50
+ self.error "--name required" unless @@options[:name_given]
51
+ self.error "--currencies required" unless @@options[:currencies_given]
52
+
53
+ Data.load
54
+ Data.add_account( @@options[:name], @@options[:currencies], @@options[:type], @@options[:url] )
55
+ Data.save
56
+ end
57
+
58
+ def self.list
59
+ Data.load
60
+ Data.list_accounts
61
+ end
62
+
63
+ def self.execute
64
+ verb = ARGV.shift
65
+ case verb
66
+ when "new", "create"
67
+ self.create
68
+ when "list"
69
+ self.list
70
+ else
71
+ self.error "account takes an action [new, list] . See --help for more info"
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,41 @@
1
+ require 'gtmtech/crypto/subcommand'
2
+ require 'gtmtech/crypto'
3
+ require 'gtmtech/crypto/CLI'
4
+
5
+ module Gtmtech
6
+ module Crypto
7
+ module Subcommands
8
+
9
+ class Help < Subcommand
10
+
11
+ def self.options
12
+ []
13
+ end
14
+
15
+ def self.execute
16
+ puts <<-EOS
17
+ Welcome to gtmtech-crypto #{Gtmtech::Crypto::VERSION}
18
+
19
+ Usage:
20
+ crypto <subcommand> ... [global-opts] [subcommand-opts]
21
+
22
+ Available subcommands:
23
+ #{Gtmtech::Crypto::CLI.subcommands.collect {|command|
24
+ command_class = Gtmtech::Crypto::Subcommands.const_get(Utils.camelcase command)
25
+ sprintf "%15s: %-65s", command.downcase, command_class.description unless command_class.hidden?
26
+ }.compact.join("\n")}
27
+
28
+ For more help on an individual command, use --help on that command
29
+
30
+ EOS
31
+ end
32
+
33
+ def self.description
34
+ "print help message"
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,127 @@
1
+ require 'gtmtech/crypto/subcommand'
2
+
3
+ module Gtmtech
4
+ module Crypto
5
+ module Subcommands
6
+
7
+ class Txn < Subcommand
8
+
9
+ def self.description
10
+ "manage accounts"
11
+ end
12
+
13
+ def self.usage
14
+ <<-EOS
15
+ Usage (crypto #{self.prettyname})
16
+
17
+ crypto #{self.prettyname} new --date=<s> --from=<s> --to=<s> [--fees=<s>]
18
+ - create a new transaction
19
+
20
+ crypto #{self.prettyname} delete --id=<s>
21
+ - delete a transaction
22
+
23
+ crypto #{self.prettyname} list
24
+ - list all transactions
25
+
26
+
27
+ Options:
28
+ EOS
29
+ end
30
+
31
+ def self.options
32
+ [{:name => :date,
33
+ :description => "Date of transaction (in format 2017-06-24,11:23:45 or \"now\")",
34
+ :short => 'd',
35
+ :type => :string},
36
+ {:name => :from,
37
+ :description => "Source of the transaction in the form <name>.<currency>=<sent amount> e.g. barclays.GBP=20.50",
38
+ :short => 'n',
39
+ :type => :string},
40
+ {:name => :to,
41
+ :description => "Destination of the transaction in the form <name>.<currency>=<received amount> e.g. kraken.BTC=0.40503",
42
+ :short => 't',
43
+ :type => :string},
44
+ {:name => :fees,
45
+ :description => "Any fees EXTERNAL to the transaction, in the form <name>.<currency>=<amount> e.g. kraken.BTC=0.00001",
46
+ :short => 'f',
47
+ :type => :string},
48
+ {:name => :id,
49
+ :description => "Specify the id you wish to amend/delete in a delete operation",
50
+ :short => 'i',
51
+ :type => :string}
52
+ ]
53
+ end
54
+
55
+ def self.create
56
+ self.error "--date required" unless @@options[:date_given]
57
+ self.error "--date must be in format \"now\" or YYYY-MM-DD,hh:mm:ss" unless (@@options[:date] == "now" or @@options[:date] =~ /\d\d\d\d\-\d\d\-\d\d,\d\d:\d\d:\d\d/)
58
+
59
+ self.error "--from required" unless @@options[:from_given]
60
+ self.error "--from must be in format <name>.<currency>=<amount>" unless @@options[:from] =~ /^\w+\.\w+=[\d\.]+$/
61
+
62
+ self.error "--to required" unless @@options[:to_given]
63
+ self.error "--to must be in format <name>.<currency>=<amount>" unless @@options[:to] =~ /^\w+\.\w+=[\d\.]+$/
64
+
65
+ if @@options[:fees_given]
66
+ self.error "--fees must be in format <name>.<currency>=<amount>" unless @@options[:fees] =~ /^\w+\.\w+=[\d\.]+$/
67
+ end
68
+
69
+ source_account = @@options[:from].split(".")[0]
70
+ source_currency = @@options[:from].split(".")[1].split("=")[0]
71
+ source_amount = @@options[:from].split("=")[1]
72
+ self.error "--from: txn amount must be a decimal or integer" unless source_amount =~ /^\d*\.\d+$/ or source_amount =~ /^\d+$/
73
+
74
+ dest_account = @@options[:to].split(".")[0]
75
+ dest_currency = @@options[:to].split(".")[1].split("=")[0]
76
+ dest_amount = @@options[:to].split("=")[1]
77
+ self.error "--to: txn amount must be a decimal or integer" unless dest_amount =~ /^\d*\.\d+$/ or dest_amount =~ /^\d+$/
78
+
79
+ self.error "cannot create a self-referential transaction" if source_account == dest_account and source_currency == dest_currency
80
+
81
+ fees_account = nil
82
+ fees_currency = nil
83
+ fees_amount = nil
84
+ if @@options[:fees_given]
85
+ fees_account = @@options[:fees].split(".")[0]
86
+ fees_currency = @@options[:fees].split(".")[1].split("=")[0]
87
+ fees_amount = @@options[:fees].split("=")[1]
88
+ end
89
+
90
+ Data.load
91
+ self.error "The account #{source_account}.#{source_currency} does not yet exist" unless Data.account_exists? source_account, source_currency
92
+ self.error "The account #{dest_account}.#{dest_currency} does not yet exist" unless Data.account_exists? dest_account, dest_currency
93
+ Data.add_transaction @@options[:date], source_account, source_currency, source_amount, dest_account, dest_currency, dest_amount, fees_account, fees_currency, fees_amount
94
+ Data.save
95
+ end
96
+
97
+ def self.list
98
+ Data.load
99
+ Data.list_transactions
100
+ end
101
+
102
+ def self.delete
103
+ self.error "--id required" unless @@options[:id_given]
104
+ Data.load
105
+ Data.delete_transaction @@options[:id]
106
+ Data.save
107
+ end
108
+
109
+ def self.execute
110
+ verb = ARGV.shift
111
+ case verb
112
+ when "new", "create"
113
+ self.create
114
+ when "list"
115
+ self.list
116
+ when "delete"
117
+ self.delete
118
+ else
119
+ self.error "transaction takes an action [new, list, delete] . See --help for more info"
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,21 @@
1
+ require 'gtmtech/crypto/subcommand'
2
+
3
+ module Gtmtech
4
+ module Crypto
5
+ module Subcommands
6
+
7
+ class UnknownCommand < Subcommand
8
+
9
+ def self.options
10
+ []
11
+ end
12
+
13
+ def self.execute
14
+ puts "Unknown command"
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'gtmtech/crypto/subcommand'
2
+ require 'gtmtech/crypto'
3
+
4
+ module Gtmtech
5
+ module Crypto
6
+ module Subcommands
7
+
8
+ class Version < Subcommand
9
+
10
+ def self.options
11
+ []
12
+ end
13
+
14
+ def self.execute
15
+ puts "gtmtech-crypto v#{Gtmtech::Crypto::VERSION}"
16
+ end
17
+
18
+ def self.description
19
+ "output version information"
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,63 @@
1
+ require 'fileutils'
2
+
3
+ module Gtmtech
4
+ module Crypto
5
+ class Utils
6
+
7
+ def self.camelcase string
8
+ return string if string !~ /_/ && string =~ /[A-Z]+.*/
9
+ string.split('_').map{|e| e.capitalize}.join
10
+ end
11
+
12
+ def self.snakecase string
13
+ return string if string !~ /[A-Z]/
14
+ string.split(/(?=[A-Z])/).collect {|x| x.downcase}.join("_")
15
+ end
16
+
17
+ def self.find_closest_class args
18
+ parent_class = args[ :parent_class ]
19
+ class_name = args[ :class_name ]
20
+ constants = parent_class.constants
21
+ candidates = []
22
+ constants.each do | candidate |
23
+ candidates << candidate.to_s if candidate.to_s.downcase == class_name.downcase
24
+ end
25
+ if candidates.count > 0
26
+ parent_class.const_get candidates.first
27
+ else
28
+ nil
29
+ end
30
+ end
31
+
32
+ def self.require_dir classdir
33
+ num_class_hierarchy_levels = self.to_s.split("::").count - 1
34
+ root_folder = File.dirname(__FILE__) + "/" + Array.new(num_class_hierarchy_levels).fill("..").join("/")
35
+ class_folder = root_folder + "/" + classdir
36
+ Dir[File.expand_path("#{class_folder}/*.rb")].uniq.each do |file|
37
+ require file
38
+ end
39
+ end
40
+
41
+ def self.find_all_subclasses_of args
42
+ parent_class = args[ :parent_class ]
43
+ constants = parent_class.constants
44
+ candidates = []
45
+ constants.each do | candidate |
46
+ candidates << candidate.to_s.split('::').last if parent_class.const_get(candidate).class.to_s == "Class"
47
+ end
48
+ candidates
49
+ end
50
+
51
+ def self.make_decimal digits
52
+ if digits.start_with? "."
53
+ "0#{digits}"
54
+ elsif digits =~ /^\d+$/
55
+ "#{digits}.0"
56
+ else
57
+ digits
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gtmtech-crypto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Geoff Meakin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: trollop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ description: Simple tool for accounting of cryptocurrencies
28
+ email:
29
+ executables:
30
+ - crypto
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - .ruby-version
36
+ - Gemfile
37
+ - LICENSE.txt
38
+ - README.md
39
+ - Rakefile
40
+ - bin/crypto
41
+ - build.sh
42
+ - gtmtech-crypto.gemspec
43
+ - lib/gtmtech/crypto.rb
44
+ - lib/gtmtech/crypto/CLI.rb
45
+ - lib/gtmtech/crypto/data.rb
46
+ - lib/gtmtech/crypto/subcommand.rb
47
+ - lib/gtmtech/crypto/subcommands/account.rb
48
+ - lib/gtmtech/crypto/subcommands/help.rb
49
+ - lib/gtmtech/crypto/subcommands/txn.rb
50
+ - lib/gtmtech/crypto/subcommands/unknown_command.rb
51
+ - lib/gtmtech/crypto/subcommands/version.rb
52
+ - lib/gtmtech/crypto/utils.rb
53
+ homepage: http://github.com/gtmtechltd/crypto
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.0.14
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Simple tool for accounting of cryptocurrencies
77
+ test_files: []