Class: CoinOp::Bit::MultiWallet
- Inherits:
-
Object
- Object
- CoinOp::Bit::MultiWallet
show all
- Includes:
- Encodings
- Defined in:
- lib/coin-op/bit/multi_wallet.rb
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Encodings
#base58, #decode_base58, #decode_hex, #hex, #int_to_byte_array
Constructor Details
#initialize(options) ⇒ MultiWallet
Returns a new instance of MultiWallet.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 17
def initialize(options)
@private_trees = {}
@public_trees = {}
@trees = {}
if private_trees = options[:private]
private_trees.each do |name, arg|
name = name.to_sym
@private_trees[name] = @trees[name] = self.get_node(arg)
end
end
if public_trees = options[:public]
public_trees.each do |name, arg|
name = name.to_sym
@public_trees[name] = @trees[name] = self.get_node(arg)
end
end
end
|
Instance Attribute Details
#trees ⇒ Object
Returns the value of attribute trees.
15
16
17
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 15
def trees
@trees
end
|
Class Method Details
.generate(names) ⇒ Object
6
7
8
9
10
11
12
13
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 6
def self.generate(names)
masters = {}
names.each do |name|
name = name.to_sym
masters[name] = MoneyTree::Master.new
end
self.new(private: masters)
end
|
Instance Method Details
#address(path) ⇒ Object
141
142
143
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 141
def address(path)
path(path).address
end
|
#authorize(transaction, *signers) ⇒ Object
Takes a Transaction and any number of Arrays of signature dictionaries. Each sig_dict in an Array corresponds to the Input with the same index.
Uses the combined signatures from all the signers to generate and set the script_sig for each Input.
Returns the transaction.
181
182
183
184
185
186
187
188
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 181
def authorize(transaction, *signers)
transaction.set_script_sigs *signers do |input, *sig_dicts|
node = self.path(input.output.metadata[:wallet_path])
signatures = combine_signatures(*sig_dicts)
node.script_sig(signatures)
end
transaction
end
|
#combine_signatures(*sig_dicts) ⇒ Object
Takes any number of “signature dictionaries”, which are Hashes where the keys are tree names, and the values are base58-encoded signatures for a single input.
Returns an Array of the signatures in binary, sorted by their tree names.
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 195
def combine_signatures(*sig_dicts)
combined = {}
sig_dicts.each do |sig_dict|
sig_dict.each do |tree, signature|
decoded_sig = decode_base58(signature)
low_s_der_sig = Bitcoin::Script.is_low_der_signature?(decoded_sig) ?
decoded_sig : Bitcoin::OpenSSL_EC.signature_to_low_s(decoded_sig)
combined[tree] = Bitcoin::OpenSSL_EC.repack_der_signature(low_s_der_sig)
end
end
combined.sort_by { |tree, value| tree }.map { |tree, sig| sig }
end
|
#drop(*names) ⇒ Object
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 53
def drop(*names)
names = names.map(&:to_sym)
options = {:private => {}, :public => {}}
@private_trees.each do |name, node|
unless names.include?(name.to_sym)
options[:private][name] = node
end
end
@public_trees.each do |name, node|
unless names.include?(name.to_sym)
options[:private][name] = node
end
end
self.class.new options
end
|
#drop_private(*names) ⇒ Object
69
70
71
72
73
74
75
76
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 69
def drop_private(*names)
names.each do |name|
name = name.to_sym
tree = @private_trees.delete(name)
serialized_priv = tree.to_bip32
@public_trees[name] = MoneyTree::Master.from_bip32(serialized_priv)
end
end
|
#get_node(arg) ⇒ Object
42
43
44
45
46
47
48
49
50
51
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 42
def get_node(arg)
case arg
when MoneyTree::Node
arg
when String
MoneyTree::Node.from_bip32(arg)
else
raise "Unusable type: #{node.class}"
end
end
|
#import(addresses) ⇒ Object
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 78
def import(addresses)
addresses.each do |name, address|
node = MoneyTree::Master.from_bip32(address)
if node.private_key
@private_trees[name] = node
else
@public_trees[name] = node
end
end
end
|
#path(path) ⇒ Object
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 125
def path(path)
options = {
:path => path,
:private => {},
:public => {},
}
@private_trees.each do |name, node|
options[:private][name] = node.node_for_path(path)
end
@public_trees.each do |name, node|
options[:public][name] = node.node_for_path(path)
end
MultiNode.new(options)
end
|
#private_seed(name, network:) ⇒ Object
Also known as:
private_address
89
90
91
92
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 89
def private_seed(name, network:)
raise "No such node: '#{name}'" unless (node = @private_trees[name.to_sym])
node.to_bip32(:private, network: network)
end
|
#private_seeds(network:) ⇒ Object
Also known as:
private_addresses
105
106
107
108
109
110
111
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 105
def private_seeds(network:)
out = {}
@private_trees.each do |name, tree|
out[name] = self.private_address(name, network: network)
end
out
end
|
#public_seed(name, network:) ⇒ Object
Also known as:
public_address
96
97
98
99
100
101
102
103
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 96
def public_seed(name, network:)
name = name.to_sym
if node = (@public_trees[name] || @private_trees[name])
node.to_bip32(network: network)
else
raise "No such node: '#{name}'"
end
end
|
#public_seeds(network:) ⇒ Object
Also known as:
public_addresses
113
114
115
116
117
118
119
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 113
def public_seeds(network:)
out = {}
@private_trees.each do |name, node|
out[name] = node.to_bip32(network: network)
end
out
end
|
#set_sig_hashes(transaction) ⇒ Object
166
167
168
169
170
171
172
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 166
def set_sig_hashes(transaction)
transaction.inputs.each do |input|
path = input.output.metadata[:wallet_path]
node = self.path(path)
input.binary_sig_hash = transaction.sig_hash(input, node.script)
end
end
|
#signatures(transaction, names: [:primary]) ⇒ Object
Takes a Transaction ready to be signed.
Returns an Array of signature dictionaries.
157
158
159
160
161
162
163
164
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 157
def signatures(transaction, names: [:primary])
transaction.inputs.map do |input|
path = input.output.metadata[:wallet_path]
node = self.path(path)
sig_hash = transaction.sig_hash(input, node.script)
node.signatures(sig_hash, names: names)
end
end
|
#valid_output?(output) ⇒ Boolean
145
146
147
148
149
150
151
152
|
# File 'lib/coin-op/bit/multi_wallet.rb', line 145
def valid_output?(output)
if path = output.metadata.wallet_path
node = self.path(path)
node.p2sh_script.to_s == output.script.p2sh_script.to_s
else
true
end
end
|