tapyrus 0.2.10 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cf211d0ab36f04dbc16d8ee2c60c1f86bc33b5b2d8c68378c7c550e7c0697db
4
- data.tar.gz: 831801fc796432c6c61ee167dd6acc4778ef49853699babb95614a7765e37fd0
3
+ metadata.gz: 21c6e4a293a4eeb2945e7129cfa401927282e944913b992e837c92393a69f1bf
4
+ data.tar.gz: b03bb102f8856dce5246ba2a89ad6f648f7cf9df92c66616387bb9f1cc15810a
5
5
  SHA512:
6
- metadata.gz: 84092b5fd80adc5a7121d3923c9fa4350dde4b271b19df1ed1b39579b0589862087e9c73916650948231c4bd3f1ad9b0d58c38711bad7be2e571466f2f46b2e4
7
- data.tar.gz: 14389a4e0df4fc5eb78c5ae9c63de6aab4a2a10fe52dcc8e655fe17fa6d6056422c6f0a9233dfc452a14f95480af7081570307124203ec1cbbbb11e77a5731ef
6
+ metadata.gz: 4b15f3bc76c02d258b4f05def9f255a765e4b9f369d9d0ef5737b8a788ee7c352b605e2a2680da9e146c50567e06aa351316d3f7cbf6fe0830f39710c01616fa
7
+ data.tar.gz: 815a380de5e8c790beaf9d5508e5899d16e5ef58894de01ab9d64e011263b5d435b5c550c70f058ae640154944d99324967a9d1f74646107e08dc214317e6d8c
@@ -14,7 +14,7 @@ module Tapyrus
14
14
  class BIP175
15
15
  PURPOSE_TYPE = 175
16
16
 
17
- attr_accessor :payment_base
17
+ attr_accessor :master_ext_key, :payment_base
18
18
 
19
19
  def initialize
20
20
  @contracts = []
@@ -25,6 +25,7 @@ module Tapyrus
25
25
  raise ArgumentError, 'key should be Tapyrus::ExtKey' unless key.is_a?(Tapyrus::ExtKey)
26
26
  raise ArgumentError, 'key should be master private extended key' unless key.master?
27
27
  new.tap do |bip175|
28
+ bip175.master_ext_key = key
28
29
  bip175.payment_base =
29
30
  key.derive(PURPOSE_TYPE, true).derive(Tapyrus.chain_params.bip44_coin_type, true).ext_pubkey
30
31
  end
@@ -52,6 +53,16 @@ module Tapyrus
52
53
  Tapyrus.sha256(concatenated_hash)
53
54
  end
54
55
 
56
+ # Return pay-to-contract extended private key
57
+ # @return [Tapyrus::ExtKey] extended private key
58
+ def priv_key
59
+ key = master_ext_key.derive(PURPOSE_TYPE, true).derive(Tapyrus.chain_params.bip44_coin_type, true)
60
+
61
+ # Split every 2 bytes
62
+ paths = combined_hash.unpack('S>*')
63
+ paths.inject(key) { |key, p| key.derive(p) }
64
+ end
65
+
55
66
  # Return pay-to-contract extended public key
56
67
  # @return [Tapyrus::ExtPubkey] extended public key
57
68
  def pubkey
data/lib/tapyrus/ext.rb CHANGED
@@ -1,5 +1,21 @@
1
1
  module Tapyrus
2
2
  module Ext
3
3
  autoload :JsonParser, 'tapyrus/ext/json_parser'
4
+
5
+ refine Object do
6
+ def build_json
7
+ self.is_a?(Array) ? "[#{self.map { |o| o.to_h.to_json }.join(',')}]" : to_h.to_json
8
+ end
9
+
10
+ def to_h
11
+ return self if self.is_a?(String)
12
+ instance_variables.inject({}) do |result, var|
13
+ key = var.to_s
14
+ key.slice!(0) if key.start_with?('@')
15
+ value = instance_variable_get(var)
16
+ value.is_a?(Array) ? result.update(key => value.map { |v| v.to_h }) : result.update(key => value)
17
+ end
18
+ end
19
+ end
4
20
  end
5
21
  end
@@ -2,6 +2,8 @@ module Tapyrus
2
2
  module Network
3
3
  # P2P message handler used by peer connection class.
4
4
  module MessageHandler
5
+ using Tapyrus::Ext
6
+
5
7
  # handle p2p message.
6
8
  def handle(message)
7
9
  peer.last_recv = Time.now.to_i
@@ -47,32 +47,29 @@ module Tapyrus
47
47
 
48
48
  # Returns connected peer information.
49
49
  def getpeerinfo
50
- node
51
- .pool
52
- .peers
53
- .map do |peer|
54
- local_addr = "#{peer.remote_version.remote_addr.ip}:18333"
55
- {
56
- id: peer.id,
57
- addr: "#{peer.host}:#{peer.port}",
58
- addrlocal: local_addr,
59
- services: peer.remote_version.services.to_even_length_hex.rjust(16, '0'),
60
- relaytxes: peer.remote_version.relay,
61
- lastsend: peer.last_send,
62
- lastrecv: peer.last_recv,
63
- bytessent: peer.bytes_sent,
64
- bytesrecv: peer.bytes_recv,
65
- conntime: peer.conn_time,
66
- pingtime: peer.ping_time,
67
- minping: peer.min_ping,
68
- version: peer.remote_version.version,
69
- subver: peer.remote_version.user_agent,
70
- inbound: !peer.outbound?,
71
- startingheight: peer.remote_version.start_height,
72
- best_hash: peer.best_hash,
73
- best_height: peer.best_height
74
- }
75
- end
50
+ node.pool.peers.map do |peer|
51
+ local_addr = "#{peer.remote_version.remote_addr.ip}:18333"
52
+ {
53
+ id: peer.id,
54
+ addr: "#{peer.host}:#{peer.port}",
55
+ addrlocal: local_addr,
56
+ services: peer.remote_version.services.to_even_length_hex.rjust(16, '0'),
57
+ relaytxes: peer.remote_version.relay,
58
+ lastsend: peer.last_send,
59
+ lastrecv: peer.last_recv,
60
+ bytessent: peer.bytes_sent,
61
+ bytesrecv: peer.bytes_recv,
62
+ conntime: peer.conn_time,
63
+ pingtime: peer.ping_time,
64
+ minping: peer.min_ping,
65
+ version: peer.remote_version.version,
66
+ subver: peer.remote_version.user_agent,
67
+ inbound: !peer.outbound?,
68
+ startingheight: peer.remote_version.start_height,
69
+ best_hash: peer.best_hash,
70
+ best_height: peer.best_height
71
+ }
72
+ end
76
73
  end
77
74
 
78
75
  # broadcast transaction
@@ -99,7 +96,7 @@ module Tapyrus
99
96
  script = Tapyrus::Script.parse_from_payload(hex_script.htb)
100
97
  h = script.to_h
101
98
  h.delete(:hex)
102
- h[:p2sh] = script.to_p2sh.addresses.first unless script.p2sh?
99
+ h[:p2sh] = script.to_p2sh.to_addr unless script.p2sh?
103
100
  h
104
101
  rescue Exception
105
102
  raise ArgumentError.new('Script decode failed')
@@ -24,8 +24,13 @@ module Tapyrus
24
24
  @rpc_error = rpc_error
25
25
  end
26
26
 
27
- def message
28
- @message ||=
27
+ # Return response object as Hash
28
+ # @return [Hash] response
29
+ # @option response_code [Integer] HTTP status code
30
+ # @option response_msg [String] HTTP response body
31
+ # @option rpc_error [String] error message received from Tapyrus Core
32
+ def response
33
+ @response ||=
29
34
  begin
30
35
  m = { response_code: response_code, response_msg: response_msg }
31
36
  m.merge!(rpc_error: rpc_error) if rpc_error
@@ -33,8 +38,14 @@ module Tapyrus
33
38
  end
34
39
  end
35
40
 
41
+ # Return string that represents error message.
42
+ # @return [String] error message
43
+ def message
44
+ response.to_json
45
+ end
46
+
36
47
  def to_s
37
- message.to_s
48
+ message
38
49
  end
39
50
  end
40
51
 
@@ -61,7 +61,7 @@ module Tapyrus
61
61
  end
62
62
 
63
63
  # Add color identifier to existing p2pkh or p2sh
64
- # @param [ColorIdentifier] color identifier
64
+ # @param [ColorIdentifier] color_id color identifier
65
65
  # @return [Script] CP2PKH or CP2SH script
66
66
  # @raise [ArgumentError] if color_id is nil or invalid
67
67
  # @raise [RuntimeError] if script is neither p2pkh nor p2sh
@@ -75,7 +75,6 @@ module Tapyrus
75
75
  end
76
76
 
77
77
  # Remove color identifier from cp2pkh or cp2sh
78
- # @param [ColorIdentifier] color identifier
79
78
  # @return [Script] P2PKH or P2SH script
80
79
  # @raise [RuntimeError] if script is neither cp2pkh nor cp2sh
81
80
  def remove_color
@@ -118,26 +117,18 @@ module Tapyrus
118
117
  # @param [String] addr address.
119
118
  # @return [Tapyrus::Script] parsed script.
120
119
  def self.parse_from_addr(addr)
121
- begin
122
- segwit_addr = Bech32::SegwitAddr.new(addr)
123
- raise 'Invalid hrp.' unless Tapyrus.chain_params.bech32_hrp == segwit_addr.hrp
124
- Tapyrus::Script.parse_from_payload(segwit_addr.to_script_pubkey.htb)
125
- rescue Exception => e
126
- hex, addr_version = Tapyrus.decode_base58_address(addr)
127
- case addr_version
128
- when Tapyrus.chain_params.address_version
129
- Tapyrus::Script.to_p2pkh(hex)
130
- when Tapyrus.chain_params.p2sh_version
131
- Tapyrus::Script.to_p2sh(hex)
132
- when Tapyrus.chain_params.cp2pkh_version
133
- color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
134
- Tapyrus::Script.to_cp2pkh(color, hex[66..-1])
135
- when Tapyrus.chain_params.cp2sh_version
136
- color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
137
- Tapyrus::Script.to_cp2sh(color, hex[66..-1])
138
- else
139
- throw e
140
- end
120
+ hex, addr_version = Tapyrus.decode_base58_address(addr)
121
+ case addr_version
122
+ when Tapyrus.chain_params.address_version
123
+ Tapyrus::Script.to_p2pkh(hex)
124
+ when Tapyrus.chain_params.p2sh_version
125
+ Tapyrus::Script.to_p2sh(hex)
126
+ when Tapyrus.chain_params.cp2pkh_version
127
+ color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
128
+ Tapyrus::Script.to_cp2pkh(color, hex[66..-1])
129
+ when Tapyrus.chain_params.cp2sh_version
130
+ color = Tapyrus::Color::ColorIdentifier.parse_from_payload(hex[0..65].htb)
131
+ Tapyrus::Script.to_cp2sh(color, hex[66..-1])
141
132
  end
142
133
  end
143
134
 
@@ -189,6 +180,17 @@ module Tapyrus
189
180
  chunks.size == 0
190
181
  end
191
182
 
183
+ # Returns the address corresponding to this script. Return nil if there is no corresponding address.
184
+ # @return [String] address
185
+ def to_addr
186
+ return p2pkh_addr if p2pkh?
187
+ return p2sh_addr if p2sh?
188
+ return cp2pkh_addr if cp2pkh?
189
+ return cp2sh_addr if cp2sh?
190
+ nil
191
+ end
192
+
193
+ # @deprecated use #to_addr method.
192
194
  def addresses
193
195
  return [p2pkh_addr] if p2pkh?
194
196
  return [p2sh_addr] if p2sh?
@@ -212,14 +212,10 @@ module Tapyrus
212
212
  l, r = ems[0...(ems.length / 2)].htb, ems[(ems.length / 2)..-1].htb
213
213
  salt = get_salt(id)
214
214
  e = (Tapyrus::SLIP39::BASE_ITERATION_COUNT << exp) / Tapyrus::SLIP39::ROUND_COUNT
215
- Tapyrus::SLIP39::ROUND_COUNT
216
- .times
217
- .to_a
218
- .reverse
219
- .each do |i|
220
- f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
221
- l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
222
- end
215
+ Tapyrus::SLIP39::ROUND_COUNT.times.to_a.reverse.each do |i|
216
+ f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
217
+ l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
218
+ end
223
219
  (r + l).bth
224
220
  end
225
221
 
@@ -234,13 +230,10 @@ module Tapyrus
234
230
  l, r = s[0...(s.bytesize / 2)], s[(s.bytesize / 2)..-1]
235
231
  salt = get_salt(id)
236
232
  e = (Tapyrus::SLIP39::BASE_ITERATION_COUNT << exp) / Tapyrus::SLIP39::ROUND_COUNT
237
- Tapyrus::SLIP39::ROUND_COUNT
238
- .times
239
- .to_a
240
- .each do |i|
241
- f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
242
- l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
243
- end
233
+ Tapyrus::SLIP39::ROUND_COUNT.times.to_a.each do |i|
234
+ f = OpenSSL::PKCS5.pbkdf2_hmac((i.itb + passphrase), salt + r, e, r.bytesize, 'sha256')
235
+ l, r = padding_zero(r, r.bytesize), padding_zero((l.bti ^ f.bti).itb, r.bytesize)
236
+ end
244
237
  (r + l).bth
245
238
  end
246
239
 
@@ -31,6 +31,8 @@ module Tapyrus
31
31
  # .build
32
32
  #
33
33
  class TxBuilder
34
+ attr_reader :outputs, :utxos
35
+
34
36
  def initialize
35
37
  @utxos = []
36
38
  @incomings = {}
@@ -1,3 +1,3 @@
1
1
  module Tapyrus
2
- VERSION = '0.2.10'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/tapyrus.rb CHANGED
@@ -156,22 +156,6 @@ module Tapyrus
156
156
  end
157
157
  end
158
158
 
159
- class ::Object
160
- def build_json
161
- self.is_a?(Array) ? "[#{self.map { |o| o.to_h.to_json }.join(',')}]" : to_h.to_json
162
- end
163
-
164
- def to_h
165
- return self if self.is_a?(String)
166
- instance_variables.inject({}) do |result, var|
167
- key = var.to_s
168
- key.slice!(0) if key.start_with?('@')
169
- value = instance_variable_get(var)
170
- value.is_a?(Array) ? result.update(key => value.map { |v| v.to_h }) : result.update(key => value)
171
- end
172
- end
173
- end
174
-
175
159
  class ::Integer
176
160
  def to_even_length_hex
177
161
  hex = to_s(16)
data/tapyrusrb.gemspec CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency 'leveldb-native'
37
37
 
38
38
  spec.add_development_dependency 'bundler'
39
- spec.add_development_dependency 'prettier'
39
+ spec.add_development_dependency 'prettier', '2.0.0'
40
40
  spec.add_development_dependency 'rake', '>= 12.3.3'
41
41
  spec.add_development_dependency 'rspec', '~> 3.0'
42
42
  spec.add_development_dependency 'timecop'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapyrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.10
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-11 00:00:00.000000000 Z
11
+ date: 2022-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ecdsa
@@ -210,16 +210,16 @@ dependencies:
210
210
  name: prettier
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
- - - ">="
213
+ - - '='
214
214
  - !ruby/object:Gem::Version
215
- version: '0'
215
+ version: 2.0.0
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
- - - ">="
220
+ - - '='
221
221
  - !ruby/object:Gem::Version
222
- version: '0'
222
+ version: 2.0.0
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: rake
225
225
  requirement: !ruby/object:Gem::Requirement
@@ -425,7 +425,7 @@ homepage: https://github.com/chaintope/tapyrusrb
425
425
  licenses:
426
426
  - MIT
427
427
  metadata: {}
428
- post_install_message:
428
+ post_install_message:
429
429
  rdoc_options: []
430
430
  require_paths:
431
431
  - lib
@@ -440,8 +440,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
440
440
  - !ruby/object:Gem::Version
441
441
  version: '0'
442
442
  requirements: []
443
- rubygems_version: 3.2.22
444
- signing_key:
443
+ rubygems_version: 3.0.6
444
+ signing_key:
445
445
  specification_version: 4
446
446
  summary: The implementation of Tapyrus Protocol for Ruby.
447
447
  test_files: []