tapyrus 0.2.6 → 0.2.10

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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +37 -0
  3. data/.prettierignore +3 -0
  4. data/.prettierrc.yaml +3 -0
  5. data/.ruby-version +1 -1
  6. data/CODE_OF_CONDUCT.md +7 -7
  7. data/README.md +14 -17
  8. data/Rakefile +3 -3
  9. data/lib/openassets/marker_output.rb +0 -4
  10. data/lib/openassets/payload.rb +4 -10
  11. data/lib/openassets.rb +0 -2
  12. data/lib/schnorr/sign_to_contract.rb +51 -0
  13. data/lib/schnorr/signature.rb +3 -6
  14. data/lib/schnorr.rb +14 -9
  15. data/lib/tapyrus/base58.rb +7 -6
  16. data/lib/tapyrus/bip175.rb +67 -0
  17. data/lib/tapyrus/block.rb +1 -2
  18. data/lib/tapyrus/block_header.rb +15 -9
  19. data/lib/tapyrus/bloom_filter.rb +5 -3
  20. data/lib/tapyrus/chain_params.rb +1 -4
  21. data/lib/tapyrus/chainparams/dev.yml +3 -2
  22. data/lib/tapyrus/chainparams/prod.yml +3 -2
  23. data/lib/tapyrus/constants.rb +29 -23
  24. data/lib/tapyrus/errors.rb +1 -3
  25. data/lib/tapyrus/ext/ecdsa.rb +4 -4
  26. data/lib/tapyrus/ext/json_parser.rb +1 -4
  27. data/lib/tapyrus/ext.rb +1 -1
  28. data/lib/tapyrus/ext_key.rb +44 -32
  29. data/lib/tapyrus/key.rb +31 -35
  30. data/lib/tapyrus/key_path.rb +15 -12
  31. data/lib/tapyrus/logger.rb +20 -16
  32. data/lib/tapyrus/merkle_tree.rb +22 -20
  33. data/lib/tapyrus/message/addr.rb +1 -7
  34. data/lib/tapyrus/message/base.rb +0 -3
  35. data/lib/tapyrus/message/block.rb +2 -9
  36. data/lib/tapyrus/message/block_transaction_request.rb +3 -6
  37. data/lib/tapyrus/message/block_transactions.rb +2 -6
  38. data/lib/tapyrus/message/block_txn.rb +0 -4
  39. data/lib/tapyrus/message/cmpct_block.rb +1 -7
  40. data/lib/tapyrus/message/error.rb +1 -4
  41. data/lib/tapyrus/message/fee_filter.rb +1 -4
  42. data/lib/tapyrus/message/filter_add.rb +0 -4
  43. data/lib/tapyrus/message/filter_clear.rb +0 -4
  44. data/lib/tapyrus/message/filter_load.rb +2 -5
  45. data/lib/tapyrus/message/get_addr.rb +0 -4
  46. data/lib/tapyrus/message/get_block_txn.rb +0 -4
  47. data/lib/tapyrus/message/get_blocks.rb +0 -3
  48. data/lib/tapyrus/message/get_data.rb +1 -4
  49. data/lib/tapyrus/message/get_headers.rb +1 -3
  50. data/lib/tapyrus/message/header_and_short_ids.rb +3 -9
  51. data/lib/tapyrus/message/headers.rb +0 -4
  52. data/lib/tapyrus/message/headers_parser.rb +3 -8
  53. data/lib/tapyrus/message/inv.rb +1 -4
  54. data/lib/tapyrus/message/inventories_parser.rb +2 -7
  55. data/lib/tapyrus/message/inventory.rb +12 -5
  56. data/lib/tapyrus/message/mem_pool.rb +0 -4
  57. data/lib/tapyrus/message/merkle_block.rb +4 -9
  58. data/lib/tapyrus/message/network_addr.rb +7 -6
  59. data/lib/tapyrus/message/not_found.rb +0 -3
  60. data/lib/tapyrus/message/ping.rb +0 -3
  61. data/lib/tapyrus/message/pong.rb +0 -3
  62. data/lib/tapyrus/message/prefilled_tx.rb +0 -4
  63. data/lib/tapyrus/message/reject.rb +0 -3
  64. data/lib/tapyrus/message/send_cmpct.rb +1 -3
  65. data/lib/tapyrus/message/send_headers.rb +0 -3
  66. data/lib/tapyrus/message/tx.rb +0 -4
  67. data/lib/tapyrus/message/ver_ack.rb +1 -5
  68. data/lib/tapyrus/message/version.rb +2 -5
  69. data/lib/tapyrus/message.rb +14 -16
  70. data/lib/tapyrus/mnemonic.rb +17 -15
  71. data/lib/tapyrus/network/connection.rb +0 -3
  72. data/lib/tapyrus/network/message_handler.rb +61 -60
  73. data/lib/tapyrus/network/peer.rb +13 -12
  74. data/lib/tapyrus/network/peer_discovery.rb +10 -9
  75. data/lib/tapyrus/network/pool.rb +12 -12
  76. data/lib/tapyrus/network.rb +0 -2
  77. data/lib/tapyrus/node/cli.rb +12 -14
  78. data/lib/tapyrus/node/configuration.rb +1 -3
  79. data/lib/tapyrus/node/spv.rb +2 -3
  80. data/lib/tapyrus/node.rb +1 -1
  81. data/lib/tapyrus/opcodes.rb +9 -7
  82. data/lib/tapyrus/out_point.rb +5 -5
  83. data/lib/tapyrus/rpc/http_server.rb +21 -22
  84. data/lib/tapyrus/rpc/request_handler.rb +42 -44
  85. data/lib/tapyrus/rpc/tapyrus_core_client.rb +67 -25
  86. data/lib/tapyrus/rpc.rb +1 -0
  87. data/lib/tapyrus/script/color.rb +10 -0
  88. data/lib/tapyrus/script/multisig.rb +13 -12
  89. data/lib/tapyrus/script/script.rb +99 -88
  90. data/lib/tapyrus/script/script_error.rb +1 -4
  91. data/lib/tapyrus/script/script_interpreter.rb +439 -399
  92. data/lib/tapyrus/script/tx_checker.rb +20 -10
  93. data/lib/tapyrus/secp256k1/native.rb +14 -15
  94. data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
  95. data/lib/tapyrus/secp256k1/ruby.rb +10 -12
  96. data/lib/tapyrus/secp256k1.rb +0 -4
  97. data/lib/tapyrus/slip39/share.rb +41 -29
  98. data/lib/tapyrus/slip39/sss.rb +107 -57
  99. data/lib/tapyrus/slip39.rb +20 -5
  100. data/lib/tapyrus/store/chain_entry.rb +0 -4
  101. data/lib/tapyrus/store/db/level_db.rb +5 -9
  102. data/lib/tapyrus/store/db.rb +0 -2
  103. data/lib/tapyrus/store/spv_chain.rb +11 -17
  104. data/lib/tapyrus/store.rb +1 -3
  105. data/lib/tapyrus/tx.rb +45 -37
  106. data/lib/tapyrus/tx_builder.rb +158 -0
  107. data/lib/tapyrus/tx_in.rb +1 -6
  108. data/lib/tapyrus/tx_out.rb +2 -7
  109. data/lib/tapyrus/util.rb +20 -7
  110. data/lib/tapyrus/validation.rb +12 -11
  111. data/lib/tapyrus/version.rb +1 -1
  112. data/lib/tapyrus/wallet/account.rb +22 -18
  113. data/lib/tapyrus/wallet/base.rb +12 -9
  114. data/lib/tapyrus/wallet/db.rb +6 -9
  115. data/lib/tapyrus/wallet/master_key.rb +2 -4
  116. data/lib/tapyrus.rb +8 -30
  117. data/tapyrusrb.gemspec +13 -14
  118. metadata +26 -7
  119. data/.travis.yml +0 -14
@@ -0,0 +1,158 @@
1
+ module Tapyrus
2
+ #
3
+ # Transaction Builder class.
4
+ #
5
+ # TxBuilder makes it easy to build transactions without having to deal with TxOut/TxIn/Script directly.
6
+ #
7
+ # @example
8
+ #
9
+ # txb = Tapyrus::TxBuilder.new
10
+ # utxo1 = {
11
+ # script_pubkey: Tapyrus::Script.parse_from_addr('mgCuyNQ1pUbKqL57tJQZX3hhUCaZcuX3RQ'),
12
+ # txid: 'e1fb3255ead43dccd3ae0ac2c4f81b32260ca52749936a739669918bbb895411',
13
+ # index: 0,
14
+ # value: 3_000
15
+ # }
16
+ # color_id = Tapyrus::Color::ColorIdentifier.nft(...)
17
+ # utxo2 = {
18
+ # script_pubkey: Tapyrus::Script.parse_from_addr('mu9QMUcB9UCHbQjZJLAuyysQhM9tmFQbPx'),
19
+ # color_id: color_id,
20
+ # txid: 'e1fb3255ead43dccd3ae0ac2c4f81b32260ca52749936a739669918bbb895411',
21
+ # index: 1,
22
+ # value: 3_000
23
+ # }
24
+ #
25
+ # tx = txb
26
+ # .add_utxo(utxo1)
27
+ # .add_utxo(utxo2)
28
+ # .data("0102030405060a0b0c")
29
+ # .reissuable(utxo1[:script_pubkey],'n4jKJN5UMLsAejL1M5CTzQ8npeWoLBLCAH', 10_000)
30
+ # .pay('n4jKJN5UMLsAejL1M5CTzQ8npeWoLBLCAH', 1_000)
31
+ # .build
32
+ #
33
+ class TxBuilder
34
+ def initialize
35
+ @utxos = []
36
+ @incomings = {}
37
+ @outgoings = {}
38
+ @outputs = []
39
+ end
40
+
41
+ # Add utxo for transaction input
42
+ # @param utxo [Hash] a hash whose fields are `txid`, `index`, `script_pubkey`, `value`, and `color_id` (color_id is optional)
43
+ def add_utxo(utxo)
44
+ @utxos << utxo
45
+ color_id = utxo[:color_id] || Tapyrus::Color::ColorIdentifier.default
46
+ @incomings[color_id] ||= 0
47
+ @incomings[color_id] += utxo[:value]
48
+ self
49
+ end
50
+
51
+ # Issue reissuable token
52
+ # @param script_pubkey [Tapyrus::Script] the script pubkey in the issue input.
53
+ # @param address [String] p2pkh or p2sh address.
54
+ # @param value [Integer] issued amount.
55
+ def reissuable(script_pubkey, address, value)
56
+ color_id = Tapyrus::Color::ColorIdentifier.reissuable(script_pubkey)
57
+ pay(address, value, color_id)
58
+ end
59
+
60
+ # Issue non reissuable token
61
+ # @param out_point [Tapyrus::OutPoint] the out point at issue input.
62
+ # @param address [String] p2pkh or p2sh address.
63
+ # @param value [Integer] issued amount.
64
+ def non_reissuable(out_point, address, value)
65
+ color_id = Tapyrus::Color::ColorIdentifier.non_reissuable(out_point)
66
+ pay(address, value, color_id)
67
+ end
68
+
69
+ # Issue NFT
70
+ # @param out_point [Tapyrus::OutPoint] the out point at issue input.
71
+ # @param address [String] p2pkh or p2sh address.
72
+ # @param value [Integer] issued amount.
73
+ def nft(out_point, address)
74
+ color_id = Tapyrus::Color::ColorIdentifier.nft(out_point)
75
+ pay(address, 1, color_id)
76
+ end
77
+
78
+ # Create payment output.
79
+ # @param address [String] tapyrus address with Base58 format
80
+ # @param value [Integer] issued or transferred amount
81
+ # @param color_id [Tapyrus::Color::ColorIdentifier] color id
82
+ def pay(address, value, color_id = Tapyrus::Color::ColorIdentifier.default)
83
+ script_pubkey = Tapyrus::Script.parse_from_addr(address)
84
+
85
+ unless color_id.default?
86
+ raise ArgumentError, 'invalid address' if !script_pubkey.p2pkh? && !script_pubkey.p2sh?
87
+ script_pubkey = script_pubkey.add_color(color_id)
88
+ end
89
+
90
+ @outgoings[color_id] ||= 0
91
+ @outgoings[color_id] += value
92
+ @outputs << Tapyrus::TxOut.new(script_pubkey: script_pubkey, value: value)
93
+ self
94
+ end
95
+
96
+ # Create data output
97
+ # @param contents [[String]] array of hex string
98
+ def data(*contents)
99
+ payload = contents.join
100
+ script = Tapyrus::Script.new << Tapyrus::Script::OP_RETURN << payload
101
+ @outputs << Tapyrus::TxOut.new(script_pubkey: script)
102
+ self
103
+ end
104
+
105
+ # Set transaction fee.
106
+ # @param fee [Integer] transaction fee
107
+ def fee(fee)
108
+ @fee = fee
109
+ self
110
+ end
111
+
112
+ # Set address for change.
113
+ # If set, #build method add output for change which has the specified address
114
+ # If not set, transaction built by #build method has no output for change.
115
+ # @param address [String] p2pkh or p2sh address.
116
+ def change_address(address)
117
+ script_pubkey = Tapyrus::Script.parse_from_addr(address)
118
+ raise ArgumentError, 'invalid address' if !script_pubkey.p2pkh? && !script_pubkey.p2sh?
119
+ @change_script_pubkey = script_pubkey
120
+ self
121
+ end
122
+
123
+ # Build transaction
124
+ def build
125
+ tx = Tapyrus::Tx.new
126
+ expand_input(tx)
127
+ @outputs.each { |output| tx.outputs << output }
128
+ add_change(tx) if @change_script_pubkey
129
+ tx
130
+ end
131
+
132
+ private
133
+
134
+ def add_change(tx)
135
+ @incomings.each do |color_id, in_amount|
136
+ out_amount = @outgoings[color_id] || 0
137
+ change, script_pubkey =
138
+ if color_id.default?
139
+ [in_amount - out_amount - estimated_fee, @change_script_pubkey]
140
+ else
141
+ [in_amount - out_amount, @change_script_pubkey.add_color(color_id)]
142
+ end
143
+ tx.outputs << Tapyrus::TxOut.new(script_pubkey: script_pubkey, value: change) if change > 0
144
+ end
145
+ end
146
+
147
+ def expand_input(tx)
148
+ @utxos.each do |utxo|
149
+ tx.inputs << Tapyrus::TxIn.new(out_point: Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:index]))
150
+ end
151
+ end
152
+
153
+ # Return transaction fee
154
+ def estimated_fee
155
+ @fee
156
+ end
157
+ end
158
+ end
data/lib/tapyrus/tx_in.rb CHANGED
@@ -2,10 +2,8 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  module Tapyrus
5
-
6
5
  # transaction input
7
6
  class TxIn
8
-
9
7
  attr_accessor :out_point
10
8
  attr_accessor :script_sig
11
9
  attr_accessor :sequence
@@ -58,11 +56,10 @@ module Tapyrus
58
56
  p
59
57
  end
60
58
 
61
-
62
59
  def to_h
63
60
  sig = script_sig.to_h
64
61
  sig.delete(:type)
65
- h = {txid: out_point.txid, vout: out_point.index, script_sig: sig }
62
+ h = { txid: out_point.txid, vout: out_point.index, script_sig: sig }
66
63
  h[:sequence] = sequence
67
64
  h
68
65
  end
@@ -76,7 +73,5 @@ module Tapyrus
76
73
  return nil unless out_point
77
74
  out_point.tx_hash
78
75
  end
79
-
80
76
  end
81
-
82
77
  end
@@ -2,10 +2,8 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  module Tapyrus
5
-
6
5
  # transaction output
7
6
  class TxOut
8
-
9
7
  include OpenAssets::MarkerOutput
10
8
  include Tapyrus::Color::ColoredOutput
11
9
 
@@ -39,7 +37,7 @@ module Tapyrus
39
37
  end
40
38
 
41
39
  def to_h
42
- {value: value_to_btc, script_pubkey: script_pubkey.to_h}
40
+ { value: value_to_btc, script_pubkey: script_pubkey.to_h }
43
41
  end
44
42
 
45
43
  def ==(other)
@@ -65,11 +63,8 @@ module Tapyrus
65
63
  n_size = size
66
64
  n_size += (32 + 4 + 1 + 107 + 4)
67
65
  fee = n_size * Tapyrus.chain_params.dust_relay_fee / 1000
68
- if fee == 0 && n_size != 0
69
- fee = Tapyrus.chain_params.dust_relay_fee > 0 ? 1 : -1
70
- end
66
+ fee = Tapyrus.chain_params.dust_relay_fee > 0 ? 1 : -1 if fee == 0 && n_size != 0
71
67
  fee
72
68
  end
73
69
  end
74
-
75
70
  end
data/lib/tapyrus/util.rb CHANGED
@@ -2,12 +2,10 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  module Tapyrus
5
-
6
5
  # tapyrus utility.
7
6
  # following methods can be used as follows.
8
7
  # Tapyrus.pack_var_int(5)
9
8
  module Util
10
-
11
9
  def pack_var_string(payload)
12
10
  pack_var_int(payload.bytesize) + payload
13
11
  end
@@ -18,7 +16,7 @@ module Tapyrus
18
16
  end
19
17
 
20
18
  def pack_var_int(i)
21
- if i < 0xfd
19
+ if i < 0xfd
22
20
  [i].pack('C')
23
21
  elsif i <= 0xffff
24
22
  [0xfd, i].pack('Cv')
@@ -111,7 +109,14 @@ module Tapyrus
111
109
  def decode_base58_address(addr)
112
110
  hex = Base58.decode(addr)
113
111
  if hex.size == 50 && calc_checksum(hex[0...-8]) == hex[-8..-1]
114
- raise 'Invalid version bytes.' unless [Tapyrus.chain_params.address_version, Tapyrus.chain_params.p2sh_version].include?(hex[0..1])
112
+ unless [Tapyrus.chain_params.address_version, Tapyrus.chain_params.p2sh_version].include?(hex[0..1])
113
+ raise 'Invalid version bytes.'
114
+ end
115
+ [hex[2...-8], hex[0..1]]
116
+ elsif hex.size == 116 && calc_checksum(hex[0...-8]) == hex[-8..-1]
117
+ unless [Tapyrus.chain_params.cp2pkh_version, Tapyrus.chain_params.cp2sh_version].include?(hex[0..1])
118
+ raise 'Invalid version bytes.'
119
+ end
115
120
  [hex[2...-8], hex[0..1]]
116
121
  else
117
122
  raise 'Invalid address.'
@@ -128,14 +133,22 @@ module Tapyrus
128
133
  OpenSSL::HMAC.digest(DIGEST_NAME_SHA256, key, data)
129
134
  end
130
135
 
136
+ # check whether +addr+ is valid address.
137
+ # @param [String] addr an address
138
+ # @return [Boolean] if valid address return true, otherwise false.
139
+ def valid_address?(addr)
140
+ begin
141
+ Tapyrus::Script.parse_from_addr(addr)
142
+ true
143
+ rescue Exception => e
144
+ false
145
+ end
146
+ end
131
147
  end
132
148
 
133
149
  module HexConverter
134
-
135
150
  def to_hex
136
151
  to_payload.bth
137
152
  end
138
-
139
153
  end
140
-
141
154
  end
@@ -1,7 +1,5 @@
1
1
  module Tapyrus
2
-
3
2
  class Validation
4
-
5
3
  # check transaction validation
6
4
  def check_tx(tx, state)
7
5
  # Basic checks that don't depend on any context
@@ -16,14 +14,20 @@ module Tapyrus
16
14
  # Check for negative or overflow output values
17
15
  amount = 0
18
16
  tx.outputs.each do |o|
19
- return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-negative') if o.value < 0
20
- return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge') if MAX_MONEY < o.value
17
+ if o.value < 0
18
+ return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-negative')
19
+ end
20
+ if MAX_MONEY < o.value
21
+ return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge')
22
+ end
21
23
  amount += o.value
22
- return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge') if MAX_MONEY < amount
24
+ if MAX_MONEY < amount
25
+ return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-vout-toolarge')
26
+ end
23
27
  end
24
28
 
25
29
  # Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
26
- out_points = tx.inputs.map{|i|i.out_point.to_payload}
30
+ out_points = tx.inputs.map { |i| i.out_point.to_payload }
27
31
  unless out_points.size == out_points.uniq.size
28
32
  return state.DoS(100, reject_code: Message::Reject::CODE_INVALID, reject_reason: 'bad-txns-inputs-duplicate')
29
33
  end
@@ -46,7 +50,6 @@ module Tapyrus
46
50
  def check_block_header(header, state)
47
51
  header.block_hash
48
52
  header.bits
49
-
50
53
  end
51
54
 
52
55
  def check_block(block, state)
@@ -63,12 +66,10 @@ module Tapyrus
63
66
 
64
67
  # check sigop count
65
68
  end
66
-
67
69
  end
68
70
 
69
71
  class ValidationState
70
-
71
- MODE = {valid: 0, invlid: 1, error: 2}
72
+ MODE = { valid: 0, invlid: 1, error: 2 }
72
73
 
73
74
  attr_accessor :mode
74
75
  attr_accessor :n_dos
@@ -107,4 +108,4 @@ module Tapyrus
107
108
  mode == MODE[:error]
108
109
  end
109
110
  end
110
- end
111
+ end
@@ -1,3 +1,3 @@
1
1
  module Tapyrus
2
- VERSION = "0.2.6"
2
+ VERSION = '0.2.10'
3
3
  end
@@ -1,11 +1,10 @@
1
1
  module Tapyrus
2
2
  module Wallet
3
-
4
3
  # the account in BIP-44
5
4
  class Account
6
5
  include Tapyrus::HexConverter
7
6
 
8
- PURPOSE_TYPE = {legacy: 44, nested_witness: 49, native_segwit: 84}
7
+ PURPOSE_TYPE = { legacy: 44, nested_witness: 49, native_segwit: 84 }
9
8
 
10
9
  attr_reader :purpose # either 44 or 49 or 84
11
10
  attr_reader :index # BIP-44 index
@@ -86,26 +85,26 @@ module Tapyrus
86
85
  # get the list of derived keys for receive key.
87
86
  # @return [Array[Tapyrus::ExtPubkey]]
88
87
  def derived_receive_keys
89
- (receive_depth + 1).times.map{|i|derive_key(0,i)}
88
+ (receive_depth + 1).times.map { |i| derive_key(0, i) }
90
89
  end
91
90
 
92
91
  # get the list of derived keys for change key.
93
92
  # @return [Array[Tapyrus::ExtPubkey]]
94
93
  def derived_change_keys
95
- (change_depth + 1).times.map{|i|derive_key(1,i)}
94
+ (change_depth + 1).times.map { |i| derive_key(1, i) }
96
95
  end
97
96
 
98
97
  # get account type label.
99
98
  def type
100
99
  case purpose
101
- when PURPOSE_TYPE[:legacy]
102
- 'pubkeyhash'
103
- when PURPOSE_TYPE[:nested_witness]
104
- 'p2wpkh-p2sh'
105
- when PURPOSE_TYPE[:native_segwit]
106
- 'p2wpkh'
107
- else
108
- 'unknown'
100
+ when PURPOSE_TYPE[:legacy]
101
+ 'pubkeyhash'
102
+ when PURPOSE_TYPE[:nested_witness]
103
+ 'p2wpkh-p2sh'
104
+ when PURPOSE_TYPE[:native_segwit]
105
+ 'p2wpkh'
106
+ else
107
+ 'unknown'
109
108
  end
110
109
  end
111
110
 
@@ -126,10 +125,17 @@ module Tapyrus
126
125
 
127
126
  def to_h
128
127
  {
129
- name: name, type: type, index: index, receive_depth: receive_depth, change_depth: change_depth,
130
- look_ahead: lookahead, receive_address: derive_key(0, receive_depth).addr,
131
- change_address: derive_key(1, change_depth).addr,
132
- account_key: account_key.to_base58, path: path, watch_only: watch_only
128
+ name: name,
129
+ type: type,
130
+ index: index,
131
+ receive_depth: receive_depth,
132
+ change_depth: change_depth,
133
+ look_ahead: lookahead,
134
+ receive_address: derive_key(0, receive_depth).addr,
135
+ change_address: derive_key(1, change_depth).addr,
136
+ account_key: account_key.to_base58,
137
+ path: path,
138
+ watch_only: watch_only
133
139
  }
134
140
  end
135
141
 
@@ -145,8 +151,6 @@ module Tapyrus
145
151
  version_bytes = Tapyrus::ExtPubkey.version_from_purpose(purpose + Tapyrus::HARDENED_THRESHOLD)
146
152
  raise 'The purpose and the account key do not match.' unless account_key.version == version_bytes
147
153
  end
148
-
149
154
  end
150
-
151
155
  end
152
156
  end
@@ -2,9 +2,7 @@ require 'leveldb-native'
2
2
 
3
3
  module Tapyrus
4
4
  module Wallet
5
-
6
5
  class Base
7
-
8
6
  attr_accessor :wallet_id
9
7
  attr_reader :db
10
8
  attr_reader :path
@@ -24,6 +22,7 @@ module Tapyrus
24
22
  def self.create(wallet_id = 1, path_prefix = default_path_prefix)
25
23
  raise ArgumentError, "wallet_id : #{wallet_id} already exist." if self.exist?(wallet_id, path_prefix)
26
24
  w = self.new(wallet_id, path_prefix)
25
+
27
26
  # generate seed
28
27
  raise RuntimeError, 'the seed already exist.' if w.db.registered_master?
29
28
  master = Tapyrus::Wallet::MasterKey.generate
@@ -122,14 +121,20 @@ module Tapyrus
122
121
 
123
122
  # decrypt wallet
124
123
  # @param [String] passphrase the wallet passphrase
125
- def decrypt(passphrase)
126
-
127
- end
124
+ def decrypt(passphrase); end
128
125
 
129
126
  # wallet information
130
127
  def to_h
131
128
  a = accounts.map(&:to_h)
132
- { wallet_id: wallet_id, version: version, account_depth: a.size, accounts: a, master: {encrypted: master_key.encrypted} }
129
+ {
130
+ wallet_id: wallet_id,
131
+ version: version,
132
+ account_depth: a.size,
133
+ accounts: a,
134
+ master: {
135
+ encrypted: master_key.encrypted
136
+ }
137
+ }
133
138
  end
134
139
 
135
140
  # get data elements tobe monitored with Bloom Filter.
@@ -153,10 +158,8 @@ module Tapyrus
153
158
 
154
159
  # find account using +account_name+
155
160
  def find_account(account_name, purpose = nil)
156
- accounts(purpose).find{|a| a.name == account_name}
161
+ accounts(purpose).find { |a| a.name == account_name }
157
162
  end
158
-
159
163
  end
160
-
161
164
  end
162
165
  end
@@ -1,13 +1,11 @@
1
1
  module Tapyrus
2
2
  module Wallet
3
-
4
3
  class DB
5
-
6
4
  KEY_PREFIX = {
7
- account: 'a', # key: account index, value: Account raw data.
8
- master: 'm', # value: wallet seed.
9
- version: 'v', # value: wallet version
10
- key: 'k', # key: path to the key, value: public key
5
+ account: 'a', # key: account index, value: Account raw data.
6
+ master: 'm', # value: wallet seed.
7
+ version: 'v', # value: wallet version
8
+ key: 'k' # key: path to the key, value: public key
11
9
  }
12
10
 
13
11
  attr_reader :level_db
@@ -27,7 +25,7 @@ module Tapyrus
27
25
  def accounts
28
26
  from = KEY_PREFIX[:account] + '00000000'
29
27
  to = KEY_PREFIX[:account] + 'ffffffff'
30
- level_db.each(from: from, to: to).map { |k, v| v}
28
+ level_db.each(from: from, to: to).map { |k, v| v }
31
29
  end
32
30
 
33
31
  def save_account(account)
@@ -50,7 +48,7 @@ module Tapyrus
50
48
  id = [account.purpose, account.index].pack('I*').bth
51
49
  from = KEY_PREFIX[:key] + id + '00000000'
52
50
  to = KEY_PREFIX[:key] + id + 'ffffffff'
53
- level_db.each(from: from, to: to).map { |k, v| v}
51
+ level_db.each(from: from, to: to).map { |k, v| v }
54
52
  end
55
53
 
56
54
  # get master_key
@@ -75,7 +73,6 @@ module Tapyrus
75
73
  def version
76
74
  level_db.get(KEY_PREFIX[:version]).to_i
77
75
  end
78
-
79
76
  end
80
77
  end
81
78
  end
@@ -1,6 +1,5 @@
1
1
  module Tapyrus
2
2
  module Wallet
3
-
4
3
  # HD Wallet master seed
5
4
  class MasterKey
6
5
  include Tapyrus::HexConverter
@@ -53,7 +52,7 @@ module Tapyrus
53
52
  # [encrypted(false:0, true:1)][salt(var str)][seed(var str)]
54
53
  def to_payload
55
54
  flg = encrypted ? 1 : 0
56
- pack_var_int(flg) << [salt, seed].map{|v|pack_var_string(v.htb)}.join
55
+ pack_var_int(flg) << [salt, seed].map { |v| pack_var_string(v.htb) }.join
57
56
  end
58
57
 
59
58
  # get master key
@@ -67,7 +66,7 @@ module Tapyrus
67
66
  # @return [Tapyrus::ExtKey]
68
67
  def derive(path)
69
68
  derived_key = key
70
- parse_key_path(path).each{|num| derived_key = derived_key.derive(num)}
69
+ parse_key_path(path).each { |num| derived_key = derived_key.derive(num) }
71
70
  derived_key
72
71
  end
73
72
 
@@ -105,7 +104,6 @@ module Tapyrus
105
104
  key_iv = OpenSSL::PKCS5.pbkdf2_hmac_sha1(passphrase, salt, 2000, enc.key_len + enc.iv_len)
106
105
  [key_iv[0, enc.key_len], key_iv[enc.key_len, enc.iv_len]]
107
106
  end
108
-
109
107
  end
110
108
  end
111
109
  end
data/lib/tapyrus.rb CHANGED
@@ -13,7 +13,6 @@ require_relative 'openassets'
13
13
  require_relative 'schnorr'
14
14
 
15
15
  module Tapyrus
16
-
17
16
  autoload :Ext, 'tapyrus/ext'
18
17
  autoload :Util, 'tapyrus/util'
19
18
  autoload :ChainParams, 'tapyrus/chain_params'
@@ -49,6 +48,8 @@ module Tapyrus
49
48
  autoload :SLIP39, 'tapyrus/slip39'
50
49
  autoload :Color, 'tapyrus/script/color'
51
50
  autoload :Errors, 'tapyrus/errors'
51
+ autoload :TxBuilder, 'tapyrus/tx_builder'
52
+ autoload :BIP175, 'tapyrus/bip175'
52
53
 
53
54
  require_relative 'tapyrus/constants'
54
55
  require_relative 'tapyrus/ext/ecdsa'
@@ -59,7 +60,7 @@ module Tapyrus
59
60
 
60
61
  # set tapyrus network chain params
61
62
  def self.chain_params=(name)
62
- raise "chain params for #{name} is not defined." unless %i(prod dev).include?(name.to_sym)
63
+ raise "chain params for #{name} is not defined." unless %i[prod dev].include?(name.to_sym)
63
64
  @current_chain = nil
64
65
  @chain_param = name.to_sym
65
66
  end
@@ -118,14 +119,7 @@ module Tapyrus
118
119
 
119
120
  # get opcode
120
121
  def opcode
121
- case encoding
122
- when Encoding::ASCII_8BIT
123
- each_byte.next
124
- when Encoding::US_ASCII
125
- ord
126
- else
127
- to_i
128
- end
122
+ force_encoding(Encoding::ASCII_8BIT).ord
129
123
  end
130
124
 
131
125
  def opcode?
@@ -160,17 +154,11 @@ module Tapyrus
160
154
  def valid_hex?
161
155
  !self[/\H/]
162
156
  end
163
-
164
157
  end
165
158
 
166
159
  class ::Object
167
-
168
160
  def build_json
169
- if self.is_a?(Array)
170
- "[#{self.map{|o|o.to_h.to_json}.join(',')}]"
171
- else
172
- to_h.to_json
173
- end
161
+ self.is_a?(Array) ? "[#{self.map { |o| o.to_h.to_json }.join(',')}]" : to_h.to_json
174
162
  end
175
163
 
176
164
  def to_h
@@ -179,14 +167,9 @@ module Tapyrus
179
167
  key = var.to_s
180
168
  key.slice!(0) if key.start_with?('@')
181
169
  value = instance_variable_get(var)
182
- if value.is_a?(Array)
183
- result.update(key => value.map{|v|v.to_h})
184
- else
185
- result.update(key => value)
186
- end
170
+ value.is_a?(Array) ? result.update(key => value.map { |v| v.to_h }) : result.update(key => value)
187
171
  end
188
172
  end
189
-
190
173
  end
191
174
 
192
175
  class ::Integer
@@ -200,13 +183,8 @@ module Tapyrus
200
183
  end
201
184
 
202
185
  # convert bit string
203
- def to_bits(length = nil )
204
- if length
205
- to_s(2).rjust(length, '0')
206
- else
207
- to_s(2)
208
- end
186
+ def to_bits(length = nil)
187
+ length ? to_s(2).rjust(length, '0') : to_s(2)
209
188
  end
210
189
  end
211
-
212
190
  end