Class: Bitcoin::Wallet::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin/wallet/base.rb

Constant Summary collapse

VERSION =
1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#dbObject (readonly)

Returns the value of attribute db.



8
9
10
# File 'lib/bitcoin/wallet/base.rb', line 8

def db
  @db
end

#pathObject (readonly)

Returns the value of attribute path.



9
10
11
# File 'lib/bitcoin/wallet/base.rb', line 9

def path
  @path
end

#wallet_idObject

Returns the value of attribute wallet_id.



7
8
9
# File 'lib/bitcoin/wallet/base.rb', line 7

def wallet_id
  @wallet_id
end

Class Method Details

.create(wallet_id = 1, path_prefix = default_path_prefix, purpose = Account::PURPOSE_TYPE[:native_segwit]) ⇒ Bitcoin::Wallet::Base

Create new wallet. If wallet already exist, throw error. The wallet generates a seed using SecureRandom and store to db at initialization.

Parameters:

  • wallet_id (String) (defaults to: 1)

    new wallet id.

  • path_prefix (String) (defaults to: default_path_prefix)

    wallet file path prefix.

Returns:

Raises:

  • (ArgumentError)


23
24
25
26
27
28
29
30
31
32
# File 'lib/bitcoin/wallet/base.rb', line 23

def self.create(wallet_id = 1, path_prefix = default_path_prefix, purpose = Account::PURPOSE_TYPE[:native_segwit])
  raise ArgumentError, "wallet_id : #{wallet_id} already exist." if self.exist?(wallet_id, path_prefix)
  w = self.new(wallet_id, path_prefix)
  # generate seed
  raise RuntimeError, 'the seed already exist.' if w.db.registered_master?
  master = Bitcoin::Wallet::MasterKey.generate
  w.db.register_master_key(master)
  w.(purpose, 'Default')
  w
end

.current_wallet(path_prefix = default_path_prefix) ⇒ Object

get current wallet



48
49
50
51
52
53
54
# File 'lib/bitcoin/wallet/base.rb', line 48

def self.current_wallet(path_prefix = default_path_prefix)
  path = wallet_paths(path_prefix).first # TODO default wallet selection
  return nil unless path
  path.slice!(path_prefix + 'wallet')
  path.slice!('/')
  self.load(path.to_i, path_prefix)
end

.default_path_prefixObject

get wallet dir path



14
15
16
# File 'lib/bitcoin/wallet/base.rb', line 14

def self.default_path_prefix
  "#{Bitcoin.base_dir}/db/wallet/"
end

.load(wallet_id, path_prefix = default_path_prefix) ⇒ Bitcoin::Wallet::Base

load wallet with specified wallet_id

Returns:

Raises:

  • (ArgumentError)


36
37
38
39
# File 'lib/bitcoin/wallet/base.rb', line 36

def self.load(wallet_id, path_prefix = default_path_prefix)
  raise ArgumentError, "wallet_id : #{wallet_id} dose not exist." unless self.exist?(wallet_id, path_prefix)
  self.new(wallet_id, path_prefix)
end

.wallet_paths(path_prefix = default_path_prefix) ⇒ Array

get wallets path

Returns:

  • (Array)

    Array of paths for each wallet dir.



43
44
45
# File 'lib/bitcoin/wallet/base.rb', line 43

def self.wallet_paths(path_prefix = default_path_prefix)
  Dir.glob("#{path_prefix}wallet*/").sort
end

Instance Method Details

#accounts(purpose = nil) ⇒ Object

get account list based on BIP-44



57
58
59
60
61
62
63
64
65
66
# File 'lib/bitcoin/wallet/base.rb', line 57

def accounts(purpose = nil)
  list = []
  db.accounts.each do |raw|
    a = Account.parse_from_payload(raw)
    next if purpose && purpose != a.purpose
    a.wallet = self
    list << a
  end
  list
end

#closeObject

close database wallet



105
106
107
# File 'lib/bitcoin/wallet/base.rb', line 105

def close
  db.close
end

#create_account(purpose = , name) ⇒ Bitcoin::Wallet::Account

create new account

Parameters:

  • purpose (Integer) (defaults to: )

    BIP44’s purpose.

  • name (String)

    a account name.

Returns:

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
81
# File 'lib/bitcoin/wallet/base.rb', line 72

def (purpose = Account::PURPOSE_TYPE[:native_segwit], name)
  raise ArgumentError.new('Account already exists.') if (name, purpose)
  index = accounts.size
  path = "m/#{purpose}'/#{Bitcoin.chain_params.bip44_coin_type}'/#{index}'"
   = master_key.derive(path).ext_pubkey
   = Account.new(, purpose, index, name)
  .wallet = self
  .save
  
end

#decrypt(passphrase) ⇒ Object

decrypt wallet

Parameters:

  • passphrase (String)

    the wallet passphrase



124
125
126
# File 'lib/bitcoin/wallet/base.rb', line 124

def decrypt(passphrase)

end

#encrypt(passphrase) ⇒ Object

encrypt wallet

Parameters:

  • passphrase (String)

    the wallet passphrase



117
118
119
120
# File 'lib/bitcoin/wallet/base.rb', line 117

def encrypt(passphrase)
  master_key.encrypt(passphrase)
  db.register_master_key(master_key)
end

#generate_new_address(account_name) ⇒ String

create new bitcoin address for receiving payments.

Parameters:

  • account_name (String)

    an account name.

Returns:

  • (String)

    generated address.

Raises:

  • (ArgumentError)


93
94
95
96
97
# File 'lib/bitcoin/wallet/base.rb', line 93

def generate_new_address()
   = ()
  raise ArgumentError.new('Account does not exist.') unless 
  .create_receive.addr
end

#get_balance(account) ⇒ Object

get wallet balance.

Parameters:



85
86
87
88
# File 'lib/bitcoin/wallet/base.rb', line 85

def get_balance()
  # TODO get from utxo db.
  0.00000000
end

#master_keyBitcoin::Wallet::MasterKey

get master key



111
112
113
# File 'lib/bitcoin/wallet/base.rb', line 111

def master_key
  db.master_key
end

#to_hObject

wallet information



129
130
131
132
# File 'lib/bitcoin/wallet/base.rb', line 129

def to_h
  a = accounts.map(&:to_h)
  { wallet_id: wallet_id, version: version, account_depth: a.size, accounts: a, master: {encrypted: master_key.encrypted} }
end

#versionObject

get wallet version.



100
101
102
# File 'lib/bitcoin/wallet/base.rb', line 100

def version
  db.version
end

#watch_targetsArray[String]

get data elements tobe monitored with Bloom Filter.

Returns:



136
137
138
# File 'lib/bitcoin/wallet/base.rb', line 136

def watch_targets
  accounts.map(&:watch_targets).flatten
end