bitcoin_active_record 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +45 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +121 -0
  6. data/Rakefile +4 -0
  7. data/bitcoin_active_record.gemspec +15 -0
  8. data/lib/bitcoin_active_record/client.rb +128 -0
  9. data/lib/bitcoin_active_record/models/btc_address.rb +12 -0
  10. data/lib/bitcoin_active_record/models/payment.rb +18 -0
  11. data/lib/bitcoin_active_record/models/received_payment.rb +11 -0
  12. data/lib/bitcoin_active_record/models/sent_payment.rb +10 -0
  13. data/lib/bitcoin_active_record/models.rb +9 -0
  14. data/lib/bitcoin_active_record.rb +24 -0
  15. data/lib/generators/bitcoin_active_record/install_generator.rb +26 -0
  16. data/lib/generators/templates/create_bitcoin_active_record_models.rb +32 -0
  17. data/lib/generators/templates/models/btc_address.rb +3 -0
  18. data/lib/generators/templates/models/payment.rb +3 -0
  19. data/lib/generators/templates/models/received_payment.rb +3 -0
  20. data/lib/generators/templates/models/sent_payment.rb +3 -0
  21. data/test/.gitignore +18 -0
  22. data/test/Gemfile +20 -0
  23. data/test/Gemfile.lock +146 -0
  24. data/test/README.rdoc +28 -0
  25. data/test/Rakefile +6 -0
  26. data/test/app/assets/images/.keep +0 -0
  27. data/test/app/assets/javascripts/application.js +16 -0
  28. data/test/app/assets/stylesheets/application.css +13 -0
  29. data/test/app/controllers/application_controller.rb +5 -0
  30. data/test/app/controllers/concerns/.keep +0 -0
  31. data/test/app/helpers/application_helper.rb +2 -0
  32. data/test/app/mailers/.keep +0 -0
  33. data/test/app/models/.keep +0 -0
  34. data/test/app/models/btc_address.rb +3 -0
  35. data/test/app/models/concerns/.keep +0 -0
  36. data/test/app/models/payment.rb +3 -0
  37. data/test/app/models/received_payment.rb +3 -0
  38. data/test/app/models/sent_payment.rb +3 -0
  39. data/test/app/views/layouts/application.html.erb +14 -0
  40. data/test/bin/bundle +3 -0
  41. data/test/bin/rails +8 -0
  42. data/test/bin/rake +8 -0
  43. data/test/bin/spring +15 -0
  44. data/test/bin/testunit +7 -0
  45. data/test/config/application.rb +23 -0
  46. data/test/config/boot.rb +4 -0
  47. data/test/config/database.yml +25 -0
  48. data/test/config/environment.rb +5 -0
  49. data/test/config/environments/development.rb +29 -0
  50. data/test/config/environments/production.rb +80 -0
  51. data/test/config/environments/test.rb +38 -0
  52. data/test/config/initializers/backtrace_silencers.rb +7 -0
  53. data/test/config/initializers/bitcoin_active_record.rb.example +5 -0
  54. data/test/config/initializers/filter_parameter_logging.rb +4 -0
  55. data/test/config/initializers/inflections.rb +16 -0
  56. data/test/config/initializers/mime_types.rb +5 -0
  57. data/test/config/initializers/secret_token.rb +12 -0
  58. data/test/config/initializers/session_store.rb +3 -0
  59. data/test/config/initializers/wrap_parameters.rb +14 -0
  60. data/test/config/locales/en.yml +23 -0
  61. data/test/config/routes.rb +56 -0
  62. data/test/config.ru +4 -0
  63. data/test/db/migrate/20150425185338_create_bitcoin_active_record_models.rb +32 -0
  64. data/test/db/schema.rb +53 -0
  65. data/test/db/seeds.rb +7 -0
  66. data/test/lib/assets/.keep +0 -0
  67. data/test/lib/tasks/.keep +0 -0
  68. data/test/log/.keep +0 -0
  69. data/test/public/404.html +58 -0
  70. data/test/public/422.html +58 -0
  71. data/test/public/500.html +57 -0
  72. data/test/public/favicon.ico +0 -0
  73. data/test/public/robots.txt +5 -0
  74. data/test/test/controllers/.keep +0 -0
  75. data/test/test/fixtures/.keep +0 -0
  76. data/test/test/helpers/.keep +0 -0
  77. data/test/test/integration/.keep +0 -0
  78. data/test/test/integration/bitcoin_payments/client_test.rb +118 -0
  79. data/test/test/integration/bitcoin_payments/generators_test.rb +39 -0
  80. data/test/test/mailers/.keep +0 -0
  81. data/test/test/models/.keep +0 -0
  82. data/test/test/test_helper.rb +18 -0
  83. data/test/vendor/assets/javascripts/.keep +0 -0
  84. data/test/vendor/assets/stylesheets/.keep +0 -0
  85. metadata +230 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d56a5588b8abf5cc2c2974d5bc237e88461fdeff
4
+ data.tar.gz: ec4e8fde879bf7db2ca0424858fb5c0d9e16bb04
5
+ SHA512:
6
+ metadata.gz: d4aab36a9ed83ab2ead41047af48fa05b4639910ca8406d9d8f1fbff0bdf3cd7821c8c25e0baadf07a2553787864b3678dca812b451901fbae17ab2bbb289b41
7
+ data.tar.gz: d60538e623947ceace6463e9c92552fbf4ce762da0e3c6d94e542998668d1e059a9a16c4e223d336ded7310e7c823628424d2c940c9fa609e20fd9a2867ad3ac
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'http://rubygems.org/'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bitcoin_active_record (0.0.1)
5
+ auto_strip_attributes (>= 2.0.4)
6
+ httparty (>= 0.13.1)
7
+ script_utils (= 0.0.3)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activemodel (4.2.1)
13
+ activesupport (= 4.2.1)
14
+ builder (~> 3.1)
15
+ activerecord (4.2.1)
16
+ activemodel (= 4.2.1)
17
+ activesupport (= 4.2.1)
18
+ arel (~> 6.0)
19
+ activesupport (4.2.1)
20
+ i18n (~> 0.7)
21
+ json (~> 1.7, >= 1.7.7)
22
+ minitest (~> 5.1)
23
+ thread_safe (~> 0.3, >= 0.3.4)
24
+ tzinfo (~> 1.1)
25
+ arel (6.0.0)
26
+ auto_strip_attributes (2.0.6)
27
+ activerecord (>= 3.0)
28
+ builder (3.2.2)
29
+ httparty (0.13.3)
30
+ json (~> 1.8)
31
+ multi_xml (>= 0.5.2)
32
+ i18n (0.7.0)
33
+ json (1.8.2)
34
+ minitest (5.6.0)
35
+ multi_xml (0.5.5)
36
+ script_utils (0.0.3)
37
+ thread_safe (0.3.5)
38
+ tzinfo (1.2.2)
39
+ thread_safe (~> 0.1)
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ bitcoin_active_record!
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Lihan Li
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # bitcoin_active_record
2
+ Keep records of sent and received bitcoin transactions in your database using activerecord.
3
+
4
+ ## Quick start guide
5
+ * Start bitcoin-qt or bitcoind with these options set in bitcoin.conf
6
+ ```
7
+ server=1
8
+ rpcuser=change_this
9
+ rpcpassword=change_this
10
+ txindex=1 # needed for getting transaction sender keys
11
+ ```
12
+ * Add to gemfile, bundle install
13
+ * Run generator
14
+ ```
15
+ rails g bitcoin_active_record:install
16
+ ```
17
+ * Run db:migrate
18
+ * Create a bitcoin client
19
+ ```ruby
20
+ client = BitcoinActiveRecord::Client.new(
21
+ server: {
22
+ url: 'http://127.0.0.1:8332',
23
+ username: '',
24
+ password: '',
25
+ },
26
+ )
27
+ ```
28
+ * Run client.create_received_payments to create records of received payments
29
+ * Run client.pay(public_key: public_key, amount: BigDecimal.new(1), comment: 'hello') to send a payment and save a record of it in the database
30
+
31
+ ## Usage
32
+
33
+ This gem creates 4 models:
34
+
35
+ btc_address.rb
36
+
37
+ column_name | type | description
38
+ --- | --- | ---
39
+ public_key | string | public key of a bitcoin address
40
+
41
+ payment.rb
42
+
43
+ column_name | type | description
44
+ --- | --- | ---
45
+ btc_address_id | integer | foreign key
46
+ amount | decimal | transaction amount
47
+ txid | string | bitcoin transaction id
48
+
49
+ received_payment.rb
50
+
51
+ column_name | type | description
52
+ --- | --- | ---
53
+ payment_id | integer | The btc address associated with this payment id is the address of the person who sent the payment
54
+ btc_address_id | integer | This is the address in your wallet that the payment was sent to
55
+
56
+ sent_payment.rb
57
+
58
+ column_name | type | description
59
+ --- | --- | ---
60
+ payment_id | integer | foreign key
61
+
62
+ Sent payments are only recorded if you send them using the gem's api.
63
+
64
+ ### BitcoinActiveRecord::Client
65
+
66
+ Initialize options
67
+
68
+ ```ruby
69
+ client = BitcoinActiveRecord::Client.new(
70
+ # required, bitcoind server credentials
71
+ server: {
72
+ url: 'http://127.0.0.1:8332',
73
+ username: '',
74
+ password: '',
75
+ },
76
+ # optional, amounts less than this will be ignored when running create_received_payments
77
+ minimum_amount: BigDecimal.new('0.001'),
78
+ # optional, the wallet account you want to look for received transactions in
79
+ account: :foo,
80
+ )
81
+ ```
82
+
83
+ * client.request(method, *args)
84
+
85
+ Send a request to the bitcoind server.
86
+
87
+ ```ruby
88
+ client.request(:getinfo)
89
+ client.request(:sendtoaddress, '1N2ZWQszjGDjaW5y3jAStuJQW23MbG1r4N', BigDecimal.new(1))
90
+ ```
91
+
92
+ * client.get_new_address
93
+
94
+ Get a new public key from the server
95
+
96
+ * client.get_sender_address(txid)
97
+
98
+ Get the public key of the transaction sender for a transaction with id txid
99
+
100
+ * client.pay
101
+
102
+ Pay someone and save a record of it as a SentPayment
103
+
104
+ ```ruby
105
+ client.pay(
106
+ # required, public key you want to send BTC to
107
+ public_key: '1N2ZWQszjGDjaW5y3jAStuJQW23MbG1r4N',
108
+ # required, amount in BTC you want to send
109
+ amount: BigDecimal.new('1.23'),
110
+ # optional, transaction comment
111
+ comment: 'foo',
112
+ ) do |sent_payment|
113
+ # adding a block is optional
114
+ # modify the sent_payment record before it gets saved
115
+ sent_payment.custom_attribute = 'foo'
116
+ end
117
+ ```
118
+
119
+ * client.create_received_payments
120
+
121
+ Create a ReceivedPayment model for every transaction from client.account that's >= client.minimum_amount. If the latest transaction is already in the database it will assume all earlier transactions have already been saved.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ task :test do
2
+ Dir.chdir('test')
3
+ system('bin/rake test')
4
+ end
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = 'bitcoin_active_record'
3
+ gem.version = '0.0.1'
4
+ gem.summary = 'bitcoin activerecord integration'
5
+ gem.author = 'Lihan Li'
6
+ gem.email = 'frankieteardrop@gmail.com'
7
+
8
+ gem.add_dependency('httparty', '>= 0.13.1')
9
+ gem.add_dependency('auto_strip_attributes', '>= 2.0.4')
10
+ gem.add_dependency('script_utils', '0.0.3')
11
+
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.require_paths = ["lib"]
15
+ end
@@ -0,0 +1,128 @@
1
+ module BitcoinActiveRecord
2
+ class ApiError < StandardError; end
3
+
4
+ class Client
5
+ attr_accessor(:minimum_amount)
6
+ attr_accessor(:account)
7
+ attr_reader(:server)
8
+
9
+ def initialize(server: raise('server required'), minimum_amount: 0, account: '')
10
+ @server = server
11
+ @minimum_amount = minimum_amount
12
+ @account = account
13
+ @default_transaction_count = 25
14
+ end
15
+
16
+ def request(method, *args)
17
+ args.map! { |a| a.is_a?(BigDecimal) ? a.to_f : a }
18
+ raise 'payments disabled in test/development' if method.to_sym == :sendtoaddress && (Rails.env.test? || Rails.env.development?)
19
+
20
+ res = HTTParty.post(
21
+ @server[:url],
22
+ basic_auth: {
23
+ username: @server[:username],
24
+ password: @server[:password],
25
+ },
26
+ headers: {
27
+ 'Content-Type' => 'application/json',
28
+ },
29
+ body: {
30
+ method: method,
31
+ params: args,
32
+ id: 'jsonrpc',
33
+ }.to_json,
34
+ )
35
+ raise ApiError.new(res) unless res['error'].nil?
36
+
37
+ res['result']
38
+ end
39
+
40
+ def get_new_address
41
+ raise if Rails.env.test?
42
+ request(:getnewaddress, @account)
43
+ end
44
+
45
+ def get_sender_address(txid)
46
+ addresses = []
47
+ raw_tx = request('decoderawtransaction', request('getrawtransaction', txid))
48
+
49
+ raw_tx['vin'].each do |input|
50
+ input_raw_tx = request('decoderawtransaction', request('getrawtransaction', input['txid']))
51
+ addresses << input_raw_tx['vout'][input['vout']]['scriptPubKey']['addresses'][0]
52
+ end
53
+
54
+ addresses[0]
55
+ end
56
+
57
+ def pay(public_key: raise('public key required'), amount: raise('amount required'), comment: '')
58
+ raise('amount cant be zero or negative') unless amount > 0
59
+
60
+ sent_payment = SentPayment.new(
61
+ payment: Payment.new(
62
+ btc_address: BtcAddress.find_or_initialize_by(public_key: public_key),
63
+ amount: amount,
64
+ txid: request(:sendtoaddress, public_key, amount, comment),
65
+ ),
66
+ )
67
+ yield(sent_payment) if block_given?
68
+
69
+ sent_payment.save!
70
+
71
+ sent_payment
72
+ end
73
+
74
+ def create_received_payments
75
+ page = 0
76
+
77
+ while true
78
+ transactions = get_received_transactions(page: page)
79
+ return if transactions.size == 0
80
+
81
+ transactions.each do |transaction|
82
+ txid = transaction['txid']
83
+ # already created payment for this transaction and all older ones
84
+ return if Payment.where(txid: txid).count > 0
85
+
86
+ amount = transaction['amount']
87
+ from_key = get_sender_address(txid)
88
+
89
+ received_payment = ReceivedPayment.create!(
90
+ payment: Payment.new(
91
+ # payment from this address
92
+ btc_address: BtcAddress.find_or_initialize_by(
93
+ public_key: from_key
94
+ ),
95
+ amount: amount,
96
+ txid: txid,
97
+ ),
98
+ # sent to this address
99
+ btc_address: BtcAddress.find_or_initialize_by(public_key: transaction['address']),
100
+ )
101
+
102
+ puts("Received payment #{amount} BTC from #{from_key}: #{received_payment.inspect}")
103
+ end
104
+
105
+ page += 1
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def get_received_transactions(page: 0)
112
+ from = page * @default_transaction_count
113
+
114
+ request(
115
+ :listtransactions,
116
+ @account,
117
+ @default_transaction_count,
118
+ from,
119
+ ).each do |transaction|
120
+ transaction['amount'] = BigDecimal.new(transaction['amount'].to_s) if transaction['amount']
121
+ end.find_all do |transaction|
122
+ (transaction['category'] == 'receive' &&
123
+ transaction['confirmations'] > 0 &&
124
+ transaction['amount'] >= @minimum_amount)
125
+ end.reverse
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,12 @@
1
+ module BitcoinActiveRecord::Models::BtcAddress
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many(:payments, inverse_of: :btc_address)
6
+ has_many(:received_payments, inverse_of: :btc_address)
7
+
8
+ validates(:public_key, presence: true, uniqueness: { case_sensitive: true })
9
+
10
+ auto_strip_attributes(:public_key)
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module BitcoinActiveRecord::Models::Payment
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ # sender's address for received payments
6
+ # payee address for sent payments
7
+ belongs_to(:btc_address, inverse_of: :payments)
8
+
9
+ has_one(:received_payment, inverse_of: :payment)
10
+ has_one(:sent_payment, inverse_of: :payment)
11
+
12
+ validates(:txid, :btc_address, :amount, presence: true)
13
+ validates(:amount, numericality: { greater_than_or_equal_to: 0 })
14
+ validates(:txid, uniqueness: true)
15
+
16
+ auto_strip_attributes(:txid)
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module BitcoinActiveRecord::Models::ReceivedPayment
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to(:payment, inverse_of: :received_payment, dependent: :destroy)
6
+ belongs_to(:btc_address, inverse_of: :received_payments) # payment to this address
7
+
8
+ validates(:payment, presence: true)
9
+ validates(:payment_id, uniqueness: true)
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module BitcoinActiveRecord::Models::SentPayment
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to(:payment, inverse_of: :sent_payment, dependent: :destroy)
6
+
7
+ validates(:payment, presence: true)
8
+ validates(:payment_id, uniqueness: true)
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module BitcoinActiveRecord
2
+ module Models
3
+ def bitcoin_active_record_model
4
+ include "BitcoinActiveRecord::Models::#{self}".constantize
5
+ end
6
+ end
7
+ end
8
+
9
+ ActiveRecord::Base.extend(BitcoinActiveRecord::Models)
@@ -0,0 +1,24 @@
1
+ require 'active_support/dependencies'
2
+ require 'active_support/concern'
3
+ require 'httparty'
4
+ require 'bigdecimal'
5
+ require 'auto_strip_attributes'
6
+ require 'bitcoin_active_record/models'
7
+
8
+ module BitcoinActiveRecord
9
+ module_function
10
+
11
+ autoload(:Client, 'bitcoin_active_record/client')
12
+
13
+ module Models
14
+ lambda do
15
+ path_prefix = 'bitcoin_active_record/models/'
16
+
17
+ Dir["#{File.dirname(__FILE__)}/#{path_prefix}*.rb"].map do |file|
18
+ File.basename(file, '.rb')
19
+ end.each do |file_name|
20
+ autoload(file_name.camelize, "#{path_prefix}#{file_name}")
21
+ end
22
+ end.()
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ require 'rails/generators'
2
+ require "rails/generators/active_record"
3
+ require 'script_utils'
4
+
5
+ module BitcoinActiveRecord
6
+ module Generators
7
+ class InstallGenerator < ActiveRecord::Generators::Base
8
+ # ActiveRecord::Generators::Base inherits from Rails::Generators::NamedBase which requires a NAME parameter for the
9
+ # new table name. Our generator always has the same model names so we just set a random name here.
10
+ argument(:name, type: :string, default: 'random_name')
11
+
12
+ source_root(File.expand_path("../../templates", __FILE__))
13
+
14
+ def copy_models
15
+ ScriptUtils.file_names(File.expand_path('../../templates/models', __FILE__)).each do |file_name|
16
+ copy_file("models/#{file_name}", "app/models/#{file_name}")
17
+ end
18
+ end
19
+
20
+ def create_migrations
21
+ filename = 'create_bitcoin_active_record_models.rb'
22
+ migration_template(filename, "db/migrate/#{filename}")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ class CreateBitcoinActiveRecordModels < ActiveRecord::Migration
2
+ def change
3
+ create_table "payments" do |t|
4
+ t.integer "btc_address_id", null: false
5
+ t.decimal "amount", null: false
6
+ t.string "txid", null: false
7
+ t.timestamps
8
+ end
9
+ add_index "payments", ["btc_address_id"]
10
+ add_index "payments", ["txid"], unique: true
11
+
12
+ create_table "btc_addresses" do |t|
13
+ t.string "public_key", null: false
14
+ t.timestamps
15
+ end
16
+ add_index "btc_addresses", ["public_key"], unique: true
17
+
18
+ create_table "received_payments" do |t|
19
+ t.integer "payment_id", null: false
20
+ t.integer "btc_address_id", null: false
21
+ t.timestamps
22
+ end
23
+ add_index "received_payments", ["payment_id"], unique: true
24
+ add_index :received_payments, :btc_address_id
25
+
26
+ create_table "sent_payments" do |t|
27
+ t.integer "payment_id", null: false
28
+ t.timestamps
29
+ end
30
+ add_index "sent_payments", ["payment_id"], unique: true
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ class BtcAddress < ActiveRecord::Base
2
+ bitcoin_active_record_model
3
+ end
@@ -0,0 +1,3 @@
1
+ class Payment < ActiveRecord::Base
2
+ bitcoin_active_record_model
3
+ end
@@ -0,0 +1,3 @@
1
+ class ReceivedPayment < ActiveRecord::Base
2
+ bitcoin_active_record_model
3
+ end
@@ -0,0 +1,3 @@
1
+ class SentPayment < ActiveRecord::Base
2
+ bitcoin_active_record_model
3
+ end
data/test/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-journal
13
+
14
+ # Ignore all logfiles and tempfiles.
15
+ /log/*.log
16
+ /tmp
17
+
18
+ config/initializers/bitcoin_active_record.rb
data/test/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '4.2.1'
4
+
5
+ # Use sqlite3 as the database for Active Record
6
+ gem 'sqlite3'
7
+ gem 'bitcoin_active_record', path: '..'
8
+
9
+ gem 'pry-nav'
10
+ gem 'pry-rails'
11
+
12
+ group(:development) do
13
+ gem 'spring', '1.3.4'
14
+ gem 'spring-commands-testunit'
15
+ end
16
+
17
+ group :test do
18
+ gem 'mocha', '1.1.0'
19
+ gem 'minitest-reporters', '1.0.11'
20
+ end