class Bitcoin::Wallet::Account

the account in BIP-44

Constants

PURPOSE_TYPE

Attributes

account_key[R]
change_depth[RW]
index[R]
lookahead[RW]
name[R]
purpose[R]
receive_depth[RW]
wallet[RW]

Public Class Methods

new(account_key, purpose = PURPOSE_TYPE[:native_segwit], index = 0, name = '') click to toggle source
# File lib/bitcoin/wallet/account.rb, line 19
def initialize(account_key, purpose = PURPOSE_TYPE[:native_segwit], index = 0, name = '')
  validate_params!(account_key, purpose, index)
  @purpose = purpose
  @index = index
  @name = name
  @receive_depth = 0
  @change_depth = 0
  @lookahead = 10
  @account_key = account_key
end
parse_from_payload(payload) click to toggle source
# File lib/bitcoin/wallet/account.rb, line 30
def self.parse_from_payload(payload)
  buf = StringIO.new(payload)
  account_key = Bitcoin::ExtPubkey.parse_from_payload(buf.read(78))
  payload = buf.read
  name, payload = Bitcoin.unpack_var_string(payload)
  name = name.force_encoding('utf-8')
  purpose, index, receive_depth, change_depth, lookahead = payload.unpack('I*')
  a = Account.new(account_key, purpose, index, name)
  a.receive_depth = receive_depth
  a.change_depth = change_depth
  a.lookahead = lookahead
  a
end

Public Instance Methods

create_change() click to toggle source

create new change key @return [Bitcoin::ExtPubkey]

# File lib/bitcoin/wallet/account.rb, line 66
def create_change
  @change_depth += 1
  save
  save_key(1, @change_depth, derive_key(1, @change_depth))
end
create_receive() click to toggle source

create new receive key @return [Bitcoin::ExtPubkey]

# File lib/bitcoin/wallet/account.rb, line 58
def create_receive
  @receive_depth += 1
  save
  save_key(0, @receive_depth, derive_key(0, @receive_depth))
end
derived_change_keys() click to toggle source

get the list of derived keys for change key. @return [Array]

# File lib/bitcoin/wallet/account.rb, line 94
def derived_change_keys
  (change_depth + 1).times.map{|i|derive_key(1,i)}
end
derived_receive_keys() click to toggle source

get the list of derived keys for receive key. @return [Array]

# File lib/bitcoin/wallet/account.rb, line 88
def derived_receive_keys
  (receive_depth + 1).times.map{|i|derive_key(0,i)}
end
path() click to toggle source

account derivation path

# File lib/bitcoin/wallet/account.rb, line 113
def path
  "m/#{purpose}'/#{Bitcoin.chain_params.bip44_coin_type}'/#{index}'"
end
save() click to toggle source

save this account payload to database.

# File lib/bitcoin/wallet/account.rb, line 73
def save
  wallet.db.save_account(self)
  save_key(0, receive_depth, derive_key(0, receive_depth)) if receive_depth.zero?
  save_key(1, change_depth, derive_key(1, change_depth)) if change_depth.zero?
end
save_key(purpose, index, key) click to toggle source

@param purpose 0:recieve, 1:change @param index receive_depth or change_depth @param key the key to be saved

# File lib/bitcoin/wallet/account.rb, line 82
def save_key(purpose, index, key)
  wallet.db.save_key(self, purpose, index, key)
end
to_h() click to toggle source
# File lib/bitcoin/wallet/account.rb, line 127
def to_h
  {
      name: name, type: type, index: index, receive_depth: receive_depth, change_depth: change_depth,
      look_ahead: lookahead, receive_address: derive_key(0, receive_depth).addr,
      change_address: derive_key(1, change_depth).addr,
      account_key: account_key.to_base58, path: path, watch_only: watch_only
  }
end
to_payload() click to toggle source
# File lib/bitcoin/wallet/account.rb, line 44
def to_payload
  payload = account_key.to_payload
  payload << Bitcoin.pack_var_string(name.unpack1('H*').htb)
  payload << [purpose, index, receive_depth, change_depth, lookahead].pack('I*')
  payload
end
type() click to toggle source

get account type label.

# File lib/bitcoin/wallet/account.rb, line 99
def type
  case purpose
    when PURPOSE_TYPE[:legacy]
      'pubkeyhash'
    when PURPOSE_TYPE[:nested_witness]
      'p2wpkh-p2sh'
    when PURPOSE_TYPE[:native_segwit]
      'p2wpkh'
    else
      'unknown'
  end
end
watch_only() click to toggle source
# File lib/bitcoin/wallet/account.rb, line 117
def watch_only
  false # TODO implements import watch only address.
end
watch_targets() click to toggle source

get data elements tobe monitored with Bloom Filter. @return [Array]

# File lib/bitcoin/wallet/account.rb, line 123
def watch_targets
  wallet.db.get_keys(self).map { |key| Bitcoin.hash160(key) }
end
witness?() click to toggle source

whether support witness

# File lib/bitcoin/wallet/account.rb, line 52
def witness?
  [PURPOSE_TYPE[:nested_witness], PURPOSE_TYPE[:native_segwit]].include?(purpose)
end

Private Instance Methods

derive_key(branch, address_index) click to toggle source
# File lib/bitcoin/wallet/account.rb, line 138
def derive_key(branch, address_index)
  account_key.derive(branch).derive(address_index)
end
validate_params!(account_key, purpose, index) click to toggle source
# File lib/bitcoin/wallet/account.rb, line 142
def validate_params!(account_key, purpose, index)
  raise 'account_key must be an instance of Bitcoin::ExtPubkey.' unless account_key.is_a?(Bitcoin::ExtPubkey)
  raise 'Account key and index does not match.' unless account_key.number == (index + Bitcoin::HARDENED_THRESHOLD)
  version_bytes = Bitcoin::ExtPubkey.version_from_purpose(purpose + Bitcoin::HARDENED_THRESHOLD)
  raise 'The purpose and the account key do not match.' unless account_key.version == version_bytes
end