glueby 0.3.0 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +35 -0
  3. data/Gemfile +1 -0
  4. data/README.md +227 -16
  5. data/glueby.gemspec +3 -2
  6. data/lib/generators/glueby/contract/reissuable_token_generator.rb +26 -0
  7. data/lib/generators/glueby/contract/templates/initializer.rb.erb +7 -2
  8. data/lib/generators/glueby/contract/templates/key_table.rb.erb +4 -3
  9. data/lib/generators/glueby/contract/templates/reissuable_token_table.rb.erb +10 -0
  10. data/lib/generators/glueby/contract/templates/system_information_table.rb.erb +2 -2
  11. data/lib/generators/glueby/contract/templates/timestamp_table.rb.erb +1 -1
  12. data/lib/generators/glueby/contract/templates/utxo_table.rb.erb +3 -2
  13. data/lib/generators/glueby/contract/templates/wallet_table.rb.erb +2 -2
  14. data/lib/glueby/block_syncer.rb +98 -0
  15. data/lib/glueby/configuration.rb +62 -0
  16. data/lib/glueby/contract/active_record/reissuable_token.rb +26 -0
  17. data/lib/glueby/contract/active_record.rb +1 -0
  18. data/lib/glueby/contract/fee_estimator.rb +38 -0
  19. data/lib/glueby/contract/payment.rb +4 -4
  20. data/lib/glueby/contract/timestamp/syncer.rb +13 -0
  21. data/lib/glueby/contract/timestamp.rb +8 -6
  22. data/lib/glueby/contract/token.rb +70 -22
  23. data/lib/glueby/contract/tx_builder.rb +22 -19
  24. data/lib/glueby/contract.rb +2 -2
  25. data/lib/glueby/fee_provider/tasks.rb +141 -0
  26. data/lib/glueby/fee_provider.rb +73 -0
  27. data/lib/glueby/generator/migrate_generator.rb +1 -1
  28. data/lib/glueby/internal/wallet/abstract_wallet_adapter.rb +25 -6
  29. data/lib/glueby/internal/wallet/active_record/utxo.rb +1 -0
  30. data/lib/glueby/internal/wallet/active_record/wallet.rb +15 -5
  31. data/lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb +14 -0
  32. data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +25 -8
  33. data/lib/glueby/internal/wallet/errors.rb +3 -0
  34. data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +42 -14
  35. data/lib/glueby/internal/wallet.rb +56 -13
  36. data/lib/glueby/railtie.rb +10 -0
  37. data/lib/glueby/version.rb +1 -1
  38. data/lib/glueby/wallet.rb +3 -2
  39. data/lib/glueby.rb +27 -12
  40. data/lib/tasks/glueby/block_syncer.rake +29 -0
  41. data/lib/tasks/glueby/contract/timestamp.rake +4 -26
  42. data/lib/tasks/glueby/fee_provider.rake +18 -0
  43. metadata +40 -16
  44. data/.travis.yml +0 -7
  45. data/lib/glueby/contract/fee_provider.rb +0 -21
  46. data/lib/tasks/glueby/contract/block_syncer.rake +0 -36
  47. data/lib/tasks/glueby/contract/wallet_adapter.rake +0 -42
@@ -3,26 +3,29 @@
3
3
  module Glueby
4
4
  module Contract
5
5
  module TxBuilder
6
+ # The amount of output in funding tx for Reissuable token.
7
+ FUNDING_TX_AMOUNT = 10_000
8
+
6
9
  def receive_address(wallet:)
7
10
  wallet.receive_address
8
11
  end
9
12
 
10
13
  # Create new public key, and new transaction that sends TPC to it
11
- def create_funding_tx(wallet:, amount:, script: nil, fee_provider: FixedFeeProvider.new)
14
+ def create_funding_tx(wallet:, script: nil, fee_estimator: FixedFeeEstimator.new)
12
15
  tx = Tapyrus::Tx.new
13
- fee = fee_provider.fee(dummy_tx(tx))
16
+ fee = fee_estimator.fee(dummy_tx(tx))
14
17
 
15
- sum, outputs = wallet.internal_wallet.collect_uncolored_outputs(fee + amount)
18
+ sum, outputs = wallet.internal_wallet.collect_uncolored_outputs(fee + FUNDING_TX_AMOUNT)
16
19
  fill_input(tx, outputs)
17
20
 
18
21
  receiver_script = script ? script : Tapyrus::Script.parse_from_addr(wallet.internal_wallet.receive_address)
19
- tx.outputs << Tapyrus::TxOut.new(value: amount, script_pubkey: receiver_script)
22
+ tx.outputs << Tapyrus::TxOut.new(value: FUNDING_TX_AMOUNT, script_pubkey: receiver_script)
20
23
 
21
- fill_change_tpc(tx, wallet, sum - fee - amount)
24
+ fill_change_tpc(tx, wallet, sum - fee - FUNDING_TX_AMOUNT)
22
25
  wallet.internal_wallet.sign_tx(tx)
23
26
  end
24
27
 
25
- def create_issue_tx_for_reissuable_token(funding_tx:, issuer:, amount:, fee_provider: FixedFeeProvider.new)
28
+ def create_issue_tx_for_reissuable_token(funding_tx:, issuer:, amount:, fee_estimator: FixedFeeEstimator.new)
26
29
  tx = Tapyrus::Tx.new
27
30
 
28
31
  out_point = Tapyrus::OutPoint.from_txid(funding_tx.txid, 0)
@@ -34,7 +37,7 @@ module Glueby
34
37
  receiver_colored_script = receiver_script.add_color(color_id)
35
38
  tx.outputs << Tapyrus::TxOut.new(value: amount, script_pubkey: receiver_colored_script)
36
39
 
37
- fee = fee_provider.fee(dummy_tx(tx))
40
+ fee = fee_estimator.fee(dummy_tx(tx))
38
41
  fill_change_tpc(tx, issuer, output.value - fee)
39
42
  prev_txs = [{
40
43
  txid: funding_tx.txid,
@@ -45,18 +48,18 @@ module Glueby
45
48
  issuer.internal_wallet.sign_tx(tx, prev_txs)
46
49
  end
47
50
 
48
- def create_issue_tx_for_non_reissuable_token(issuer:, amount:, fee_provider: FixedFeeProvider.new)
49
- create_issue_tx_from_out_point(token_type: Tapyrus::Color::TokenTypes::NON_REISSUABLE, issuer: issuer, amount: amount, fee_provider: fee_provider)
51
+ def create_issue_tx_for_non_reissuable_token(issuer:, amount:, fee_estimator: FixedFeeEstimator.new)
52
+ create_issue_tx_from_out_point(token_type: Tapyrus::Color::TokenTypes::NON_REISSUABLE, issuer: issuer, amount: amount, fee_estimator: fee_estimator)
50
53
  end
51
54
 
52
- def create_issue_tx_for_nft_token(issuer:, fee_provider: FixedFeeProvider.new)
53
- create_issue_tx_from_out_point(token_type: Tapyrus::Color::TokenTypes::NFT, issuer: issuer, amount: 1, fee_provider: fee_provider)
55
+ def create_issue_tx_for_nft_token(issuer:, fee_estimator: FixedFeeEstimator.new)
56
+ create_issue_tx_from_out_point(token_type: Tapyrus::Color::TokenTypes::NFT, issuer: issuer, amount: 1, fee_estimator: fee_estimator)
54
57
  end
55
58
 
56
- def create_issue_tx_from_out_point(token_type:, issuer:, amount:, fee_provider: FixedFeeProvider.new)
59
+ def create_issue_tx_from_out_point(token_type:, issuer:, amount:, fee_estimator: FixedFeeEstimator.new)
57
60
  tx = Tapyrus::Tx.new
58
61
 
59
- fee = fee_provider.fee(dummy_issue_tx_from_out_point)
62
+ fee = fee_estimator.fee(dummy_issue_tx_from_out_point)
60
63
  sum, outputs = issuer.internal_wallet.collect_uncolored_outputs(fee)
61
64
  fill_input(tx, outputs)
62
65
 
@@ -78,7 +81,7 @@ module Glueby
78
81
  issuer.internal_wallet.sign_tx(tx)
79
82
  end
80
83
 
81
- def create_reissue_tx(funding_tx:, issuer:, amount:, color_id:, fee_provider: FixedFeeProvider.new)
84
+ def create_reissue_tx(funding_tx:, issuer:, amount:, color_id:, fee_estimator: FixedFeeEstimator.new)
82
85
  tx = Tapyrus::Tx.new
83
86
 
84
87
  out_point = Tapyrus::OutPoint.from_txid(funding_tx.txid, 0)
@@ -89,7 +92,7 @@ module Glueby
89
92
  receiver_colored_script = receiver_script.add_color(color_id)
90
93
  tx.outputs << Tapyrus::TxOut.new(value: amount, script_pubkey: receiver_colored_script)
91
94
 
92
- fee = fee_provider.fee(dummy_tx(tx))
95
+ fee = fee_estimator.fee(dummy_tx(tx))
93
96
  fill_change_tpc(tx, issuer, output.value - fee)
94
97
  prev_txs = [{
95
98
  txid: funding_tx.txid,
@@ -100,7 +103,7 @@ module Glueby
100
103
  issuer.internal_wallet.sign_tx(tx, prev_txs)
101
104
  end
102
105
 
103
- def create_transfer_tx(color_id:, sender:, receiver_address:, amount:, fee_provider: FixedFeeProvider.new)
106
+ def create_transfer_tx(color_id:, sender:, receiver_address:, amount:, fee_estimator: FixedFeeEstimator.new)
104
107
  tx = Tapyrus::Tx.new
105
108
 
106
109
  utxos = sender.internal_wallet.list_unspent
@@ -113,7 +116,7 @@ module Glueby
113
116
 
114
117
  fill_change_token(tx, sender, sum_token - amount, color_id)
115
118
 
116
- fee = fee_provider.fee(dummy_tx(tx))
119
+ fee = fee_estimator.fee(dummy_tx(tx))
117
120
  sum_tpc, outputs = sender.internal_wallet.collect_uncolored_outputs(fee)
118
121
  fill_input(tx, outputs)
119
122
 
@@ -121,7 +124,7 @@ module Glueby
121
124
  sender.internal_wallet.sign_tx(tx)
122
125
  end
123
126
 
124
- def create_burn_tx(color_id:, sender:, amount: 0, fee_provider: FixedFeeProvider.new)
127
+ def create_burn_tx(color_id:, sender:, amount: 0, fee_estimator: FixedFeeEstimator.new)
125
128
  tx = Tapyrus::Tx.new
126
129
 
127
130
  utxos = sender.internal_wallet.list_unspent
@@ -130,7 +133,7 @@ module Glueby
130
133
 
131
134
  fill_change_token(tx, sender, sum_token - amount, color_id) if amount.positive?
132
135
 
133
- fee = fee_provider.fee(dummy_tx(tx))
136
+ fee = fee_estimator.fee(dummy_tx(tx))
134
137
 
135
138
  dust = 600 # in case that the wallet has output which has just fee amount.
136
139
  sum_tpc, outputs = sender.internal_wallet.collect_uncolored_outputs(fee + dust)
@@ -1,8 +1,8 @@
1
1
  module Glueby
2
2
  module Contract
3
3
  autoload :Errors, 'glueby/contract/errors'
4
- autoload :FeeProvider, 'glueby/contract/fee_provider'
5
- autoload :FixedFeeProvider, 'glueby/contract/fee_provider'
4
+ autoload :FeeEstimator, 'glueby/contract/fee_estimator'
5
+ autoload :FixedFeeEstimator, 'glueby/contract/fee_estimator'
6
6
  autoload :Payment, 'glueby/contract/payment'
7
7
  autoload :Timestamp, 'glueby/contract/timestamp'
8
8
  autoload :Token, 'glueby/contract/token'
@@ -0,0 +1,141 @@
1
+ module Glueby
2
+ class FeeProvider
3
+ class Tasks
4
+ attr_reader :fee_provider
5
+
6
+ STATUS = {
7
+ # FeeProvider is ready to pay fees.
8
+ ready: 'Ready',
9
+ # FeeProvider is ready to pay fees, but it doesn't have enough amount to fill the UTXO pool by UTXOs which is for paying fees.
10
+ insufficient_amount: 'Insufficient Amount',
11
+ # FeeProvider is not ready to pay fees. It has no UTXOs for paying fee and amounts.
12
+ not_ready: 'Not Ready'
13
+ }
14
+
15
+ def initialize
16
+ @fee_provider = Glueby::FeeProvider.new
17
+ end
18
+
19
+ # Create UTXOs for paying fee from TPC amount of the wallet FeeProvider has. Then show the status.
20
+ #
21
+ # About the UTXO Pool
22
+ # FeeProvider have the UTXO pool. the pool is manged to keep some number of UTXOs that have fixed fee value. The
23
+ # value is configurable by :fixed_fee. This method do the management to the pool.
24
+ def manage_utxo_pool
25
+ txb = Tapyrus::TxBuilder.new
26
+
27
+ sum, utxos = collect_outputs
28
+ return if utxos.empty?
29
+
30
+ utxos.each { |utxo| txb.add_utxo(utxo) }
31
+ address = wallet.receive_address
32
+
33
+ shortage = [fee_provider.utxo_pool_size - current_utxo_pool_size, 0].max
34
+ can_create = (sum - fee_provider.fixed_fee) / fee_provider.fixed_fee
35
+ fee_outputs_count_to_be_created = [shortage, can_create].min
36
+
37
+ return if fee_outputs_count_to_be_created == 0
38
+
39
+ fee_outputs_count_to_be_created.times do
40
+ txb.pay(address, fee_provider.fixed_fee)
41
+ end
42
+
43
+ tx = txb.change_address(address)
44
+ .fee(fee_provider.fixed_fee)
45
+ .build
46
+ tx = wallet.sign_tx(tx)
47
+ wallet.broadcast(tx, without_fee_provider: true)
48
+ ensure
49
+ status
50
+ end
51
+
52
+ # Show the status of the UTXO pool
53
+ def status
54
+ status = :ready
55
+
56
+ if current_utxo_pool_size < fee_provider.utxo_pool_size
57
+ if tpc_amount < value_to_fill_utxo_pool
58
+ status = :insufficient_amount
59
+ message = <<~MESSAGE
60
+ 1. Please replenishment TPC which is for paying fee to FeeProvider.
61
+ FeeProvider needs #{value_to_fill_utxo_pool} tapyrus at least for paying 20 transaction fees.
62
+ FeeProvider wallet's address is '#{wallet.receive_address}'
63
+ 2. Then create UTXOs for paying in UTXO pool with 'rake glueby:fee_provider:manage_utxo_pool'
64
+ MESSAGE
65
+ else
66
+ message = "Please create UTXOs for paying in UTXO pool with 'rake glueby:fee_provider:manage_utxo_pool'\n"
67
+ end
68
+ end
69
+
70
+ status = :not_ready if current_utxo_pool_size == 0
71
+
72
+ puts <<~EOS
73
+ Status: #{STATUS[status]}
74
+ TPC amount: #{delimit(tpc_amount)}
75
+ UTXO pool size: #{delimit(current_utxo_pool_size)}
76
+ #{"\n" if message}#{message}
77
+ Configuration:
78
+ fixed_fee = #{delimit(fee_provider.fixed_fee)}
79
+ utxo_pool_size = #{delimit(fee_provider.utxo_pool_size)}
80
+ EOS
81
+ end
82
+
83
+ # Show the address of Fee Provider
84
+ def address
85
+ puts wallet.receive_address
86
+ end
87
+
88
+ private
89
+
90
+ def check_wallet_amount!
91
+ if tpc_amount < fee_provider.fixed_fee
92
+ raise InsufficientTPC, <<~MESSAGE
93
+ FeeProvider has insufficient TPC to create fee outputs to fill the UTXO pool.
94
+ 1. Please replenishment TPC which is for paying fee to FeeProvider. FeeProvider needs #{fee_provider.utxo_pool_size * fee_provider.fixed_fee} tapyrus at least. FeeProvider wallet's address is '#{wallet.receive_address}'
95
+ 2. Then create UTXOs for paying in UTXO pool with 'rake glueby:fee_provider:manage_utxo_pool'
96
+ MESSAGE
97
+ end
98
+ end
99
+
100
+ def tpc_amount
101
+ wallet.balance(false)
102
+ end
103
+
104
+ def collect_outputs
105
+ wallet.list_unspent.inject([0, []]) do |sum, output|
106
+ next sum if output[:color_id] || output[:amount] == fee_provider.fixed_fee
107
+
108
+ new_sum = sum[0] + output[:amount]
109
+ new_outputs = sum[1] << {
110
+ txid: output[:txid],
111
+ script_pubkey: output[:script_pubkey],
112
+ value: output[:amount],
113
+ index: output[:vout] ,
114
+ finalized: output[:finalized]
115
+ }
116
+ return [new_sum, new_outputs] if new_sum >= value_to_fill_utxo_pool
117
+
118
+ [new_sum, new_outputs]
119
+ end
120
+ end
121
+
122
+ def current_utxo_pool_size
123
+ wallet
124
+ .list_unspent(false)
125
+ .count { |o| !o[:color_id] && o[:amount] == fee_provider.fixed_fee }
126
+ end
127
+
128
+ def value_to_fill_utxo_pool
129
+ fee_provider.fixed_fee * (fee_provider.utxo_pool_size + 1) # +1 is for paying fee
130
+ end
131
+
132
+ def wallet
133
+ fee_provider.wallet
134
+ end
135
+
136
+ def delimit(num)
137
+ num.to_s.reverse.scan(/.{1,3}/).join('_').reverse
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,73 @@
1
+ module Glueby
2
+ class FeeProvider
3
+
4
+ autoload :Tasks, 'glueby/fee_provider/tasks'
5
+
6
+ class NoUtxosInUtxoPool < StandardError; end
7
+
8
+ WALLET_ID = 'FEE_PROVIDER_WALLET'
9
+ DEFAULT_FIXED_FEE = 1000
10
+ DEFAULT_UTXO_POOL_SIZE = 20
11
+
12
+ attr_reader :fixed_fee, :utxo_pool_size, :wallet,
13
+
14
+ class << self
15
+ attr_reader :config
16
+
17
+ # @param [Hash] config
18
+ # @option config [Integer] :fixed_fee The amount of fee which FeeProvider would provide to the txs
19
+ # @option opts [Integer] :utxo_pool_size The number of UTXOs in UTXO pool that is managed by FeeProvider
20
+ def configure(config)
21
+ @config = config
22
+ end
23
+
24
+ def provide(tx)
25
+ new.provide(tx)
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ @wallet = begin
31
+ Internal::Wallet.load(WALLET_ID)
32
+ rescue Internal::Wallet::Errors::WalletNotFound => _
33
+ Internal::Wallet.create(WALLET_ID)
34
+ end
35
+
36
+ @fixed_fee = (FeeProvider.config && FeeProvider.config[:fixed_fee]) || DEFAULT_FIXED_FEE
37
+ @utxo_pool_size = (FeeProvider.config && FeeProvider.config[:utxo_pool_size]) || DEFAULT_UTXO_POOL_SIZE
38
+ end
39
+
40
+ # Provide an input for fee to the tx.
41
+ # @param [Tapyrus::Tx] tx - The tx that is provided fee as a input. It should be signed with ANYONECANPAY flag.
42
+ # @return [Tapyrus::Tx]
43
+ # @raise [ArgumentError] If the signatures that the tx inputs has don't have ANYONECANPAY flag.
44
+ # @raise [Glueby::FeeProvider::NoUtxosInUtxoPool] If there are no UTXOs for paying fee in FeeProvider's UTXO pool
45
+ def provide(tx)
46
+ tx.inputs.each do |txin|
47
+ sig = get_signature(txin.script_sig)
48
+ unless sig[-1].unpack1('C') & Tapyrus::SIGHASH_TYPE[:anyonecanpay] == Tapyrus::SIGHASH_TYPE[:anyonecanpay]
49
+ raise ArgumentError, 'All the signatures that the tx inputs has should have ANYONECANPAY flag.'
50
+ end
51
+ end
52
+
53
+ utxo = utxo_for_fee
54
+ out_point = Tapyrus::OutPoint.new(utxo[:txid].rhex, utxo[:vout])
55
+ tx.inputs << Tapyrus::TxIn.new(out_point: out_point)
56
+
57
+ wallet.sign_tx(tx, for_fee_provider_input: true)
58
+ end
59
+
60
+ private
61
+
62
+ def utxo_for_fee
63
+ utxo = wallet.list_unspent.select { |o| !o[:color_id] && o[:amount] == fixed_fee }.sample
64
+ raise NoUtxosInUtxoPool, 'No UTXOs in Fee Provider UTXO pool. UTXOs should be created with "glueby:fee_provider:manage_utxo_pool" rake task' unless utxo
65
+ utxo
66
+ end
67
+
68
+ # Get Signature from P2PKH or CP2PKH script sig
69
+ def get_signature(script_sig)
70
+ script_sig.chunks.first.pushed_data
71
+ end
72
+ end
73
+ end
@@ -28,7 +28,7 @@ module Glueby
28
28
 
29
29
  def table_options
30
30
  if mysql?
31
- ', { options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci" }'
31
+ ', :options => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"'
32
32
  else
33
33
  ""
34
34
  end
@@ -7,8 +7,10 @@ module Glueby
7
7
  class AbstractWalletAdapter
8
8
  # Creates a new wallet inside the wallet component and returns `wallet_id`. The created
9
9
  # wallet is loaded from at first.
10
+ # @params [String] wallet_id - Option. The wallet id that if for the wallet to be created. If this is nil, wallet adapter generates it.
10
11
  # @return [String] wallet_id
11
- def create_wallet
12
+ # @raise [Glueby::Internal::Wallet::Errors::WalletAlreadyCreated] when the specified wallet has been already created.
13
+ def create_wallet(wallet_id = nil)
12
14
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
13
15
  end
14
16
 
@@ -32,6 +34,7 @@ module Glueby
32
34
  #
33
35
  # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
34
36
  # @raise [Glueby::Internal::Wallet::Errors::WalletAlreadyLoaded] when the specified wallet has been already loaded.
37
+ # @raise [Glueby::Internal::Wallet::Errors::WalletNotFound] when the specified wallet is not found.
35
38
  def load_wallet(wallet_id)
36
39
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
37
40
  end
@@ -62,11 +65,13 @@ module Glueby
62
65
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
63
66
  end
64
67
 
65
- # Returns all the UTXOs that the wallet has.
68
+ # Returns the UTXOs that the wallet has.
69
+ # If label is specified, return UTXOs filtered with label
66
70
  #
67
71
  # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
68
72
  # @param [Boolean] only_finalized - The UTXOs includes only finalized UTXO value if it
69
73
  # is true. Default is true.
74
+ # @param [String] label - Label for filtering UTXOs
70
75
  # @return [Array of UTXO]
71
76
  #
72
77
  # ## The UTXO structure
@@ -75,7 +80,7 @@ module Glueby
75
80
  # - vout: [Integer] Output index
76
81
  # - amount: [Integer] Amount of the UTXO as tapyrus unit
77
82
  # - finalized: [Boolean] Whether the UTXO is finalized
78
- def list_unspent(wallet_id, only_finalized = true)
83
+ def list_unspent(wallet_id, only_finalized = true, label = nil)
79
84
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
80
85
  end
81
86
 
@@ -83,10 +88,12 @@ module Glueby
83
88
  #
84
89
  # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
85
90
  # @param [Tapyrus::Tx] tx - The transaction will be signed.
86
- # @param [Array] prevtxs array of hash that represents unbroadcasted transaction outputs used by signing tx.
91
+ # @param [Array] prevtxs - array of hash that represents unbroadcasted transaction outputs used by signing tx.
87
92
  # Each hash has `txid`, `vout`, `scriptPubKey`, `amount` fields.
93
+ # @param [Integer] sighashtype - The sighash flag for each signature that would be produced here.
88
94
  # @return [Tapyrus::Tx]
89
- def sign_tx(wallet_id, tx, prevtxs = [])
95
+ # @raise [Glueby::Internal::Wallet::Errors::InvalidSighashType] when the specified sighashtype is invalid
96
+ def sign_tx(wallet_id, tx, prevtxs = [], sighashtype: Tapyrus::SIGHASH_TYPE[:all])
90
97
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
91
98
  end
92
99
 
@@ -102,8 +109,9 @@ module Glueby
102
109
  # Returns an address to receive coin.
103
110
  #
104
111
  # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
112
+ # @param [String] label The label associated with this address.
105
113
  # @return [String] P2PKH address
106
- def receive_address(wallet_id)
114
+ def receive_address(wallet_id, label = nil)
107
115
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
108
116
  end
109
117
 
@@ -125,6 +133,17 @@ module Glueby
125
133
  def create_pubkey(wallet_id)
126
134
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
127
135
  end
136
+
137
+ # Returns an array of addresses
138
+ #
139
+ # This method is expected to return the list of addresses that wallet has.
140
+ #
141
+ # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
142
+ # @param [String] label The label to filter the addresses.
143
+ # @return [Array<String>] array of P2PKH address
144
+ def get_addresses(wallet_id, label = nil)
145
+ raise NotImplementedError, "You must implement #{self.class}##{__method__}"
146
+ end
128
147
  end
129
148
  end
130
149
  end
@@ -36,6 +36,7 @@ module Glueby
36
36
 
37
37
  utxo = Utxo.find_or_initialize_by(txid: tx.txid, index: index)
38
38
  utxo.update!(
39
+ label: key.label,
39
40
  script_pubkey: output.script_pubkey.to_hex,
40
41
  value: output.value,
41
42
  status: status,