Skip to content

Commit c4fe2da

Browse files
committed
hd wallet support
1 parent 3b4dd8a commit c4fe2da

12 files changed

Lines changed: 119 additions & 7 deletions

app/models/project.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
class Project < ActiveRecord::Base
22
acts_as_paranoid
33

4-
has_many :deposits # todo: only confirmed deposits
4+
belongs_to :wallet
5+
has_many :deposits # TODO: only confirmed deposits
56
has_many :tips, inverse_of: :project
67
accepts_nested_attributes_for :tips
78
has_many :collaborators, autosave: true
@@ -19,6 +20,8 @@ class Project < ActiveRecord::Base
1920
end
2021
end
2122

23+
after_create :generate_bitcoin_address
24+
2225
# before_save :check_tips_to_pay_against_avaiable_amount
2326

2427
def update_bitcoin_address
@@ -263,4 +266,12 @@ def unarchive_address!
263266
return nil
264267
end
265268
end
269+
270+
def generate_bitcoin_address
271+
wallet = Wallet.order(created_at: :asc).last
272+
return unless wallet
273+
self.wallet = wallet
274+
self.bitcoin_address = wallet.generate_address
275+
save
276+
end
266277
end

app/models/wallet.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Wallet < ActiveRecord::Base
2+
3+
validates :name, :xpub, presence: true
4+
5+
def generate_address
6+
address = hd_wallet.node_for_path("0/#{last_address_index}.pub").to_address
7+
self.last_address_index += 1
8+
save
9+
address
10+
end
11+
12+
def address_by_index(index)
13+
hd_wallet.node_for_path("0/#{index}.pub").to_address
14+
end
15+
16+
private
17+
18+
def hd_wallet
19+
MoneyTree::Node.from_bip32(xpub)
20+
end
21+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class CreateWallets < ActiveRecord::Migration
2+
def change
3+
create_table :wallets do |t|
4+
t.string :name
5+
t.string :xpub
6+
t.integer :last_address_index, default: 1, limit: 4
7+
8+
t.timestamps null: false
9+
end
10+
end
11+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddWalletIdToProjects < ActiveRecord::Migration
2+
def change
3+
add_column :projects, :wallet_id, :integer
4+
end
5+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddLegacyAddressesToProjects < ActiveRecord::Migration
2+
def change
3+
add_column :projects, :legacy_address, :string
4+
end
5+
end

db/schema.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
# It's strongly recommended that you check this file into your version control system.
1313

14-
ActiveRecord::Schema.define(version: 20151219081507) do
14+
ActiveRecord::Schema.define(version: 20170308163825) do
1515

1616
create_table "collaborators", force: :cascade do |t|
1717
t.integer "project_id"
@@ -56,6 +56,8 @@
5656
t.string "avatar_url", limit: 255
5757
t.datetime "deleted_at"
5858
t.string "bitcoin_address2"
59+
t.integer "wallet_id"
60+
t.string "legacy_address"
5961
end
6062

6163
add_index "projects", ["full_name"], name: "index_projects_on_full_name", unique: true
@@ -131,4 +133,12 @@
131133
add_index "users", ["email"], name: "index_users_on_email", unique: true
132134
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
133135

136+
create_table "wallets", force: :cascade do |t|
137+
t.string "name"
138+
t.string "xpub"
139+
t.integer "last_address_index", limit: 4, default: 1
140+
t.datetime "created_at", null: false
141+
t.datetime "updated_at", null: false
142+
end
143+
134144
end

spec/factories/project.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
url "MyString"
44
full_name "test/test"
55
github_id "1234567890"
6-
bitcoin_address "bitcoin_address"
76

87
trait :github do
98
host 'github'

spec/factories/wallets.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FactoryGirl.define do
2+
factory :wallet do
3+
name 'test wallet'
4+
xpub 'xpub661MyMwAqRbcFepxYZyGLKMTkTPDvbfLaoYDbw4d4iQT5SycGiJQREuraJ2N6Uh' \
5+
'LGPcjXDhnARdtcUhgqN3a2dgQ3Dx8u1chtk8Rx16LrWg'
6+
end
7+
end

spec/models/deposit_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'spec_helper'
22

3-
describe Deposit do
3+
describe Deposit, type: :model do
44
let(:deposit) { create(:deposit) }
55

66
describe 'Associations' do
@@ -36,4 +36,4 @@ def with_custom_fee
3636
CONFIG["our_fee"] = old_fee
3737
end
3838

39-
end
39+
end

spec/models/project_spec.rb

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
require 'spec_helper'
22

3-
describe Project do
3+
describe Project, type: :model do
44
let(:project) { create(:project) }
55
let(:project_of_bitbucket) { create(:project, :bitbucket) }
66

77
describe 'Associations' do
88
it { should have_many(:deposits) }
99
it { should have_many(:tips) }
10+
it { should belong_to(:wallet) }
1011
end
1112

1213
describe 'Validations' do
@@ -18,6 +19,27 @@
1819
it { should ensure_inclusion_of(:host).in_array([ "github", "bitbucket" ]) }
1920
end
2021

22+
describe 'bitcoin_address' do
23+
let(:wallet) { create(:wallet) }
24+
25+
before do
26+
create(:wallet, xpub: 'xpub1key')
27+
wallet
28+
end
29+
30+
it 'should generate a bitcoin address' do
31+
expect(project.bitcoin_address).not_to be_blank
32+
end
33+
34+
it 'should connect project to the last wallet' do
35+
expect(project.wallet).to eq wallet
36+
end
37+
38+
it 'should increment wallet\'s last_address_index' do
39+
expect { project }.to change { wallet.reload.last_address_index }.by 1
40+
end
41+
end
42+
2143
describe '#repository_client' do
2244
context 'when host is github' do
2345
it 'returns Github instance' do

0 commit comments

Comments
 (0)