Class: Tapyrus::Wallet::MasterKey

Inherits:
Object
  • Object
show all
Extended by:
Util
Includes:
HexConverter, KeyPath, Util
Defined in:
lib/tapyrus/wallet/master_key.rb

Overview

HD Wallet master seed

Constant Summary

Constants included from Util

Util::DIGEST_NAME_SHA256

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

byte_to_bit, calc_checksum, decode_base58_address, double_sha256, encode_base58_address, hash160, hmac_sha256, pack_boolean, pack_var_int, pack_var_string, padding_zero, sha256, unpack_boolean, unpack_var_int, unpack_var_int_from_io, unpack_var_string, valid_address?

Methods included from KeyPath

#parse_key_path, #to_key_path

Methods included from HexConverter

#to_hex

Constructor Details

#initialize(seed, salt: "", encrypted: false, mnemonic: nil) ⇒ MasterKey

Returns a new instance of MasterKey.



15
16
17
18
19
20
# File 'lib/tapyrus/wallet/master_key.rb', line 15

def initialize(seed, salt: "", encrypted: false, mnemonic: nil)
  @mnemonic = mnemonic
  @seed = seed
  @encrypted = encrypted
  @salt = salt
end

Instance Attribute Details

#encryptedObject

Returns the value of attribute encrypted.



12
13
14
# File 'lib/tapyrus/wallet/master_key.rb', line 12

def encrypted
  @encrypted
end

#mnemonicObject

ephemeral data existing only at initialization



13
14
15
# File 'lib/tapyrus/wallet/master_key.rb', line 13

def mnemonic
  @mnemonic
end

#saltObject

Returns the value of attribute salt.



11
12
13
# File 'lib/tapyrus/wallet/master_key.rb', line 11

def salt
  @salt
end

#seedObject (readonly)

Returns the value of attribute seed.



10
11
12
# File 'lib/tapyrus/wallet/master_key.rb', line 10

def seed
  @seed
end

Class Method Details

.generateObject

generate new master key.

Returns:

  • Tapyrus::Wallet::MasterKey



24
25
26
27
28
# File 'lib/tapyrus/wallet/master_key.rb', line 24

def self.generate
  entropy = SecureRandom.hex(32)
  mnemonic = Tapyrus::Mnemonic.new("english")
  self.recover_from_words(mnemonic.to_mnemonic(entropy))
end

.parse_from_payload(payload) ⇒ Tapyrus::Wallet::MasterKey

parse master key raw data

Parameters:

  • payload (String)

    raw data

Returns:



42
43
44
45
46
47
48
49
# File 'lib/tapyrus/wallet/master_key.rb', line 42

def self.parse_from_payload(payload)
  flag, payload = unpack_var_int(payload)
  raise "encrypted flag is invalid." unless [0, 1].include?(flag)
  salt, payload = unpack_var_string(payload)
  salt = "" unless salt
  seed, payload = unpack_var_string(payload)
  self.new(seed.bth, salt: salt.bth, encrypted: flag == 1)
end

.recover_from_words(words) ⇒ Object

recover master key from mnemonic word list.

Parameters:

  • words (Array)

    the mnemonic word list.

Returns:

  • Tapyrus::Wallet::MasterKey



33
34
35
36
37
# File 'lib/tapyrus/wallet/master_key.rb', line 33

def self.recover_from_words(words)
  mnemonic = Tapyrus::Mnemonic.new("english")
  seed = mnemonic.to_seed(words)
  self.new(seed, mnemonic: words)
end

Instance Method Details

#decrypt(passphrase) ⇒ Object

decrypt seed



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/tapyrus/wallet/master_key.rb', line 88

def decrypt(passphrase)
  raise "The wallet is not encrypted." unless encrypted
  dec = OpenSSL::Cipher.new("AES-256-CBC")
  dec.decrypt
  dec.key, dec.iv = key_iv(dec, passphrase)
  decrypted_data = ""
  decrypted_data << dec.update(seed)
  decrypted_data << dec.final
  @seed = decrypted_data
  @encrypted = false
  @salt = ""
end

#derive(path) ⇒ Tapyrus::ExtKey

derive child key using derivation path.

Returns:



67
68
69
70
71
# File 'lib/tapyrus/wallet/master_key.rb', line 67

def derive(path)
  derived_key = key
  parse_key_path(path).each { |num| derived_key = derived_key.derive(num) }
  derived_key
end

#encrypt(passphrase) ⇒ Object

encrypt seed



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/tapyrus/wallet/master_key.rb', line 74

def encrypt(passphrase)
  raise "The wallet is already encrypted." if encrypted
  @salt = SecureRandom.hex(16)
  enc = OpenSSL::Cipher.new("AES-256-CBC")
  enc.encrypt
  enc.key, enc.iv = key_iv(enc, passphrase)
  encrypted_data = ""
  encrypted_data << enc.update(seed)
  encrypted_data << enc.final
  @seed = encrypted_data
  @encrypted = true
end

#keyTapyrus::ExtKey

get master key

Returns:



60
61
62
63
# File 'lib/tapyrus/wallet/master_key.rb', line 60

def key
  raise "seed is encrypted. please decrypt the seed." if encrypted
  Tapyrus::ExtKey.generate_master(seed)
end

#to_payloadObject

generate payload with following format

encrypted(false:0, true:1)][salt(var str)][seed(var str)


53
54
55
56
# File 'lib/tapyrus/wallet/master_key.rb', line 53

def to_payload
  flg = encrypted ? 1 : 0
  pack_var_int(flg) << [salt, seed].map { |v| pack_var_string(v.htb) }.join
end