bitcoin_active_record 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|