bitcoin_active_record 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +45 -0
- data/MIT-LICENSE +20 -0
- data/README.md +121 -0
- data/Rakefile +4 -0
- data/bitcoin_active_record.gemspec +15 -0
- data/lib/bitcoin_active_record/client.rb +128 -0
- data/lib/bitcoin_active_record/models/btc_address.rb +12 -0
- data/lib/bitcoin_active_record/models/payment.rb +18 -0
- data/lib/bitcoin_active_record/models/received_payment.rb +11 -0
- data/lib/bitcoin_active_record/models/sent_payment.rb +10 -0
- data/lib/bitcoin_active_record/models.rb +9 -0
- data/lib/bitcoin_active_record.rb +24 -0
- data/lib/generators/bitcoin_active_record/install_generator.rb +26 -0
- data/lib/generators/templates/create_bitcoin_active_record_models.rb +32 -0
- data/lib/generators/templates/models/btc_address.rb +3 -0
- data/lib/generators/templates/models/payment.rb +3 -0
- data/lib/generators/templates/models/received_payment.rb +3 -0
- data/lib/generators/templates/models/sent_payment.rb +3 -0
- data/test/.gitignore +18 -0
- data/test/Gemfile +20 -0
- data/test/Gemfile.lock +146 -0
- data/test/README.rdoc +28 -0
- data/test/Rakefile +6 -0
- data/test/app/assets/images/.keep +0 -0
- data/test/app/assets/javascripts/application.js +16 -0
- data/test/app/assets/stylesheets/application.css +13 -0
- data/test/app/controllers/application_controller.rb +5 -0
- data/test/app/controllers/concerns/.keep +0 -0
- data/test/app/helpers/application_helper.rb +2 -0
- data/test/app/mailers/.keep +0 -0
- data/test/app/models/.keep +0 -0
- data/test/app/models/btc_address.rb +3 -0
- data/test/app/models/concerns/.keep +0 -0
- data/test/app/models/payment.rb +3 -0
- data/test/app/models/received_payment.rb +3 -0
- data/test/app/models/sent_payment.rb +3 -0
- data/test/app/views/layouts/application.html.erb +14 -0
- data/test/bin/bundle +3 -0
- data/test/bin/rails +8 -0
- data/test/bin/rake +8 -0
- data/test/bin/spring +15 -0
- data/test/bin/testunit +7 -0
- data/test/config/application.rb +23 -0
- data/test/config/boot.rb +4 -0
- data/test/config/database.yml +25 -0
- data/test/config/environment.rb +5 -0
- data/test/config/environments/development.rb +29 -0
- data/test/config/environments/production.rb +80 -0
- data/test/config/environments/test.rb +38 -0
- data/test/config/initializers/backtrace_silencers.rb +7 -0
- data/test/config/initializers/bitcoin_active_record.rb.example +5 -0
- data/test/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/config/initializers/inflections.rb +16 -0
- data/test/config/initializers/mime_types.rb +5 -0
- data/test/config/initializers/secret_token.rb +12 -0
- data/test/config/initializers/session_store.rb +3 -0
- data/test/config/initializers/wrap_parameters.rb +14 -0
- data/test/config/locales/en.yml +23 -0
- data/test/config/routes.rb +56 -0
- data/test/config.ru +4 -0
- data/test/db/migrate/20150425185338_create_bitcoin_active_record_models.rb +32 -0
- data/test/db/schema.rb +53 -0
- data/test/db/seeds.rb +7 -0
- data/test/lib/assets/.keep +0 -0
- data/test/lib/tasks/.keep +0 -0
- data/test/log/.keep +0 -0
- data/test/public/404.html +58 -0
- data/test/public/422.html +58 -0
- data/test/public/500.html +57 -0
- data/test/public/favicon.ico +0 -0
- data/test/public/robots.txt +5 -0
- data/test/test/controllers/.keep +0 -0
- data/test/test/fixtures/.keep +0 -0
- data/test/test/helpers/.keep +0 -0
- data/test/test/integration/.keep +0 -0
- data/test/test/integration/bitcoin_payments/client_test.rb +118 -0
- data/test/test/integration/bitcoin_payments/generators_test.rb +39 -0
- data/test/test/mailers/.keep +0 -0
- data/test/test/models/.keep +0 -0
- data/test/test/test_helper.rb +18 -0
- data/test/vendor/assets/javascripts/.keep +0 -0
- data/test/vendor/assets/stylesheets/.keep +0 -0
- 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
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,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,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
|
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
|