Class: Bitcoin::Wallet::Account

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

Overview

the account in BIP-44

Constant Summary collapse

PURPOSE_TYPE =
{legacy: 44, nested_witness: 49, native_segwit: 84}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(account_key, purpose = PURPOSE_TYPE[:native_segwit], index = 0, name = '') ⇒ Account

Returns a new instance of Account.



18
19
20
21
22
23
24
25
26
27
# File 'lib/bitcoin/wallet/account.rb', line 18

def initialize(, purpose = PURPOSE_TYPE[:native_segwit], index = 0, name = '')
  validate_params!(, purpose, index)
  @purpose = purpose
  @index = index
  @name = name
  @receive_depth = 0
  @change_depth = 0
  @lookahead = 10
  @account_key = 
end

Instance Attribute Details

#account_keyObject (readonly)

account xpub key Bitcoin::ExtPubkey



12
13
14
# File 'lib/bitcoin/wallet/account.rb', line 12

def 
  @account_key
end

#change_depthObject

change address depth(address index)



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

def change_depth
  @change_depth
end

#indexObject (readonly)

BIP-44 index



10
11
12
# File 'lib/bitcoin/wallet/account.rb', line 10

def index
  @index
end

#lookaheadObject

Returns the value of attribute lookahead.



15
16
17
# File 'lib/bitcoin/wallet/account.rb', line 15

def lookahead
  @lookahead
end

#nameObject (readonly)

account name



11
12
13
# File 'lib/bitcoin/wallet/account.rb', line 11

def name
  @name
end

#purposeObject (readonly)

either 44 or 49 or 84



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

def purpose
  @purpose
end

#receive_depthObject

receive address depth(address index)



13
14
15
# File 'lib/bitcoin/wallet/account.rb', line 13

def receive_depth
  @receive_depth
end

#walletObject

Returns the value of attribute wallet.



16
17
18
# File 'lib/bitcoin/wallet/account.rb', line 16

def wallet
  @wallet
end

Class Method Details

.parse_from_payload(payload) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/bitcoin/wallet/account.rb', line 29

def self.parse_from_payload(payload)
  buf = StringIO.new(payload)
   = 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(, purpose, index, name)
  a.receive_depth = receive_depth
  a.change_depth = change_depth
  a.lookahead = lookahead
  a
end

Instance Method Details

#create_changeBitcoin::ExtPubkey

create new change key

Returns:



65
66
67
68
69
# File 'lib/bitcoin/wallet/account.rb', line 65

def create_change
  @change_depth += 1
  save
  derive_key(1, @change_depth)
end

#create_receiveBitcoin::ExtPubkey

create new receive key

Returns:



57
58
59
60
61
# File 'lib/bitcoin/wallet/account.rb', line 57

def create_receive
  @receive_depth += 1
  save
  derive_key(0, @receive_depth)
end

#derived_change_keysArray[Bitcoin::ExtPubkey]

get the list of derived keys for change key.

Returns:



84
85
86
# File 'lib/bitcoin/wallet/account.rb', line 84

def derived_change_keys
  (change_depth + 1).times.map{|i|derive_key(1,i)}
end

#derived_receive_keysArray[Bitcoin::ExtPubkey]

get the list of derived keys for receive key.

Returns:



78
79
80
# File 'lib/bitcoin/wallet/account.rb', line 78

def derived_receive_keys
  (receive_depth + 1).times.map{|i|derive_key(0,i)}
end

#pathObject

account derivation path



103
104
105
# File 'lib/bitcoin/wallet/account.rb', line 103

def path
  "m/#{purpose}'/#{Bitcoin.chain_params.bip44_coin_type}'/#{index}'"
end

#saveObject

save this account payload to database.



72
73
74
# File 'lib/bitcoin/wallet/account.rb', line 72

def save
  wallet.db.(self)
end

#to_hObject



117
118
119
120
121
122
123
124
# File 'lib/bitcoin/wallet/account.rb', line 117

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: .to_base58, path: path, watch_only: watch_only
  }
end

#to_payloadObject



43
44
45
46
47
48
# File 'lib/bitcoin/wallet/account.rb', line 43

def to_payload
  payload = .to_payload
  payload << Bitcoin.pack_var_string(name.unpack('H*').first.htb)
  payload << [purpose, index, receive_depth, change_depth, lookahead].pack('I*')
  payload
end

#typeObject

get account type label.



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/bitcoin/wallet/account.rb', line 89

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_onlyObject



107
108
109
# File 'lib/bitcoin/wallet/account.rb', line 107

def watch_only
  false # TODO implements import watch only address.
end

#watch_targetsArray[String]

get data elements tobe monitored with Bloom Filter.

Returns:



113
114
115
# File 'lib/bitcoin/wallet/account.rb', line 113

def watch_targets
  derived_receive_keys.map(&:hash160) + derived_change_keys.map(&:hash160)
end

#witness?Boolean

whether support witness

Returns:

  • (Boolean)


51
52
53
# File 'lib/bitcoin/wallet/account.rb', line 51

def witness?
  [PURPOSE_TYPE[:nested_witness], PURPOSE_TYPE[:native_segwit]].include?(purpose)
end