glueby 0.4.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +477 -387
  3. data/glueby.gemspec +33 -33
  4. data/lib/generators/glueby/contract/templates/initializer.rb.erb +8 -8
  5. data/lib/generators/glueby/contract/templates/key_table.rb.erb +16 -16
  6. data/lib/generators/glueby/contract/templates/timestamp_table.rb.erb +4 -1
  7. data/lib/generators/glueby/contract/templates/utxo_table.rb.erb +16 -16
  8. data/lib/glueby/block_syncer.rb +97 -97
  9. data/lib/glueby/configuration.rb +32 -2
  10. data/lib/glueby/contract/active_record/timestamp.rb +3 -1
  11. data/lib/glueby/contract/errors.rb +1 -0
  12. data/lib/glueby/contract/fee_estimator.rb +5 -1
  13. data/lib/glueby/contract/timestamp/syncer.rb +13 -13
  14. data/lib/glueby/contract/timestamp.rb +153 -102
  15. data/lib/glueby/contract/token.rb +270 -244
  16. data/lib/glueby/contract/tx_builder.rb +97 -30
  17. data/lib/glueby/fee_provider/tasks.rb +140 -140
  18. data/lib/glueby/fee_provider.rb +11 -0
  19. data/lib/glueby/internal/wallet/abstract_wallet_adapter.rb +153 -151
  20. data/lib/glueby/internal/wallet/active_record/utxo.rb +51 -51
  21. data/lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb +13 -13
  22. data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +159 -151
  23. data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +194 -186
  24. data/lib/glueby/internal/wallet.rb +164 -162
  25. data/lib/glueby/railtie.rb +10 -9
  26. data/lib/glueby/utxo_provider/tasks.rb +135 -0
  27. data/lib/glueby/utxo_provider.rb +85 -0
  28. data/lib/glueby/version.rb +3 -3
  29. data/lib/glueby.rb +40 -39
  30. data/lib/tasks/glueby/block_syncer.rake +28 -28
  31. data/lib/tasks/glueby/contract/timestamp.rake +46 -39
  32. data/lib/tasks/glueby/fee_provider.rake +18 -18
  33. data/lib/tasks/glueby/utxo_provider.rake +18 -0
  34. metadata +5 -2
@@ -1,162 +1,164 @@
1
- module Glueby
2
- module Internal
3
- # # Glueby::Internal::Wallet
4
- #
5
- # This module provides the way to deal about wallet that includes key management, address management, getting UTXOs.
6
- #
7
- # ## How to use
8
- #
9
- # First, you need to configure which wallet implementation is used in Glueby::Internal::Wallet. For now, below wallets are
10
- # supported.
11
- #
12
- # * [Tapyrus Core](https://github.com/chaintope/tapyrus-core)
13
- #
14
- # Here shows an example to use Tapyrus Core wallet.
15
- #
16
- # ```ruby
17
- # # Setup Tapyrus Core RPC connection
18
- # config = {schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass'}
19
- # Glueby::Internal::RPC.configure(config)
20
- #
21
- # # Setup wallet adapter
22
- # Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::TapyrusCoreWalletAdapter.new
23
- #
24
- # # Create wallet
25
- # wallet = Glueby::Internal::Wallet.create
26
- # wallet.balance # => 0
27
- # wallet.list_unspent
28
- # ```
29
- class Wallet
30
- autoload :AbstractWalletAdapter, 'glueby/internal/wallet/abstract_wallet_adapter'
31
- autoload :AR, 'glueby/internal/wallet/active_record'
32
- autoload :TapyrusCoreWalletAdapter, 'glueby/internal/wallet/tapyrus_core_wallet_adapter'
33
- autoload :ActiveRecordWalletAdapter, 'glueby/internal/wallet/active_record_wallet_adapter'
34
- autoload :Errors, 'glueby/internal/wallet/errors'
35
-
36
- class << self
37
- def create(wallet_id = nil)
38
- begin
39
- wallet_id = wallet_adapter.create_wallet(wallet_id)
40
- rescue Errors::WalletAlreadyCreated => _
41
- # Ignore when wallet is already created.
42
- end
43
- new(wallet_id)
44
- end
45
-
46
- def load(wallet_id)
47
- begin
48
- wallet_adapter.load_wallet(wallet_id)
49
- rescue Errors::WalletAlreadyLoaded => _
50
- # Ignore when wallet is already loaded.
51
- end
52
- new(wallet_id)
53
- end
54
-
55
- def wallets
56
- wallet_adapter.wallets.map { |id| new(id) }
57
- end
58
-
59
- def wallet_adapter=(adapter)
60
- if adapter.is_a?(ActiveRecordWalletAdapter)
61
- BlockSyncer.register_syncer(ActiveRecordWalletAdapter::Syncer)
62
- else
63
- BlockSyncer.unregister_syncer(ActiveRecordWalletAdapter::Syncer)
64
- end
65
-
66
- @wallet_adapter = adapter
67
- end
68
-
69
- def wallet_adapter
70
- @wallet_adapter or
71
- raise Errors::ShouldInitializeWalletAdapter, 'You should initialize wallet adapter using `Glueby::Internal::Wallet.wallet_adapter = some wallet adapter instance`.'
72
- end
73
- end
74
-
75
- attr_reader :id
76
-
77
- def initialize(wallet_id)
78
- @id = wallet_id
79
- end
80
-
81
- def balance(only_finalized = true)
82
- wallet_adapter.balance(id, only_finalized)
83
- end
84
-
85
- # @param only_finalized [Boolean] The flag to get a UTXO with status only finalized
86
- # @param label [String] This label is used to filtered the UTXOs with labeled if a key or Utxo is labeled.
87
- # - If label is not specified (label=nil), all UTXOs will be returned.
88
- # - If label=:unlabeled, only unlabeled UTXOs will be returned.
89
- def list_unspent(only_finalized = true, label = nil)
90
- wallet_adapter.list_unspent(id, only_finalized, label)
91
- end
92
-
93
- def delete
94
- wallet_adapter.delete_wallet(id)
95
- end
96
-
97
- # @param [Tapyrus::Tx] tx The tx that is signed
98
- # @param [Array<Hash>] prev_txs An array of hash that represents unbroadcasted transaction outputs used by signing tx
99
- # @option prev_txs [String] :txid
100
- # @option prev_txs [Integer] :vout
101
- # @option prev_txs [String] :scriptPubkey
102
- # @option prev_txs [Integer] :amount
103
- # @param [Boolean] for_fee_provider_input The flag to notify whether the caller is FeeProvider and called for signing a input that is by FeeProvider.
104
- def sign_tx(tx, prev_txs = [], for_fee_provider_input: false)
105
- sighashtype = Tapyrus::SIGHASH_TYPE[:all]
106
-
107
- if !for_fee_provider_input && Glueby.configuration.fee_provider_bears?
108
- sighashtype |= Tapyrus::SIGHASH_TYPE[:anyonecanpay]
109
- end
110
-
111
- wallet_adapter.sign_tx(id, tx, prev_txs, sighashtype: sighashtype)
112
- end
113
-
114
- # Broadcast a transaction via Tapyrus Core RPC
115
- # @param [Tapyrus::Tx] tx The tx that would be broadcasted
116
- # @option [Boolean] without_fee_provider The flag to avoid to use FeeProvider temporary.
117
- # @param [Proc] block The block that is called before broadcasting. It can be used to handle tx that is modified by FeeProvider.
118
- def broadcast(tx, without_fee_provider: false, &block)
119
- tx = FeeProvider.provide(tx) if !without_fee_provider && Glueby.configuration.fee_provider_bears?
120
- wallet_adapter.broadcast(id, tx, &block)
121
- tx
122
- end
123
-
124
- def receive_address(label = nil)
125
- wallet_adapter.receive_address(id, label)
126
- end
127
-
128
- def change_address
129
- wallet_adapter.change_address(id)
130
- end
131
-
132
- def create_pubkey
133
- wallet_adapter.create_pubkey(id)
134
- end
135
-
136
- def collect_uncolored_outputs(amount, label = nil, only_finalized = true)
137
- utxos = list_unspent(only_finalized, label)
138
-
139
- utxos.inject([0, []]) do |sum, output|
140
- next sum if output[:color_id]
141
-
142
- new_sum = sum[0] + output[:amount]
143
- new_outputs = sum[1] << output
144
- return [new_sum, new_outputs] if new_sum >= amount
145
-
146
- [new_sum, new_outputs]
147
- end
148
- raise Glueby::Contract::Errors::InsufficientFunds
149
- end
150
-
151
- def get_addresses(label = nil)
152
- wallet_adapter.get_addresses(id, label)
153
- end
154
-
155
- private
156
-
157
- def wallet_adapter
158
- self.class.wallet_adapter
159
- end
160
- end
161
- end
162
- end
1
+ module Glueby
2
+ module Internal
3
+ # # Glueby::Internal::Wallet
4
+ #
5
+ # This module provides the way to deal about wallet that includes key management, address management, getting UTXOs.
6
+ #
7
+ # ## How to use
8
+ #
9
+ # First, you need to configure which wallet implementation is used in Glueby::Internal::Wallet. For now, below wallets are
10
+ # supported.
11
+ #
12
+ # * [Tapyrus Core](https://github.com/chaintope/tapyrus-core)
13
+ #
14
+ # Here shows an example to use Tapyrus Core wallet.
15
+ #
16
+ # ```ruby
17
+ # # Setup Tapyrus Core RPC connection
18
+ # config = {schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass'}
19
+ # Glueby::Internal::RPC.configure(config)
20
+ #
21
+ # # Setup wallet adapter
22
+ # Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::TapyrusCoreWalletAdapter.new
23
+ #
24
+ # # Create wallet
25
+ # wallet = Glueby::Internal::Wallet.create
26
+ # wallet.balance # => 0
27
+ # wallet.list_unspent
28
+ # ```
29
+ class Wallet
30
+ autoload :AbstractWalletAdapter, 'glueby/internal/wallet/abstract_wallet_adapter'
31
+ autoload :AR, 'glueby/internal/wallet/active_record'
32
+ autoload :TapyrusCoreWalletAdapter, 'glueby/internal/wallet/tapyrus_core_wallet_adapter'
33
+ autoload :ActiveRecordWalletAdapter, 'glueby/internal/wallet/active_record_wallet_adapter'
34
+ autoload :Errors, 'glueby/internal/wallet/errors'
35
+
36
+ class << self
37
+ def create(wallet_id = nil)
38
+ begin
39
+ wallet_id = wallet_adapter.create_wallet(wallet_id)
40
+ rescue Errors::WalletAlreadyCreated => _
41
+ # Ignore when wallet is already created.
42
+ end
43
+ new(wallet_id)
44
+ end
45
+
46
+ def load(wallet_id)
47
+ begin
48
+ wallet_adapter.load_wallet(wallet_id)
49
+ rescue Errors::WalletAlreadyLoaded => _
50
+ # Ignore when wallet is already loaded.
51
+ end
52
+ new(wallet_id)
53
+ end
54
+
55
+ def wallets
56
+ wallet_adapter.wallets.map { |id| new(id) }
57
+ end
58
+
59
+ def wallet_adapter=(adapter)
60
+ if adapter.is_a?(ActiveRecordWalletAdapter)
61
+ BlockSyncer.register_syncer(ActiveRecordWalletAdapter::Syncer)
62
+ else
63
+ BlockSyncer.unregister_syncer(ActiveRecordWalletAdapter::Syncer)
64
+ end
65
+
66
+ @wallet_adapter = adapter
67
+ end
68
+
69
+ def wallet_adapter
70
+ @wallet_adapter or
71
+ raise Errors::ShouldInitializeWalletAdapter, 'You should initialize wallet adapter using `Glueby::Internal::Wallet.wallet_adapter = some wallet adapter instance`.'
72
+ end
73
+ end
74
+
75
+ attr_reader :id
76
+
77
+ def initialize(wallet_id)
78
+ @id = wallet_id
79
+ end
80
+
81
+ def balance(only_finalized = true)
82
+ wallet_adapter.balance(id, only_finalized)
83
+ end
84
+
85
+ # @param only_finalized [Boolean] The flag to get a UTXO with status only finalized
86
+ # @param label [String] This label is used to filtered the UTXOs with labeled if a key or Utxo is labeled.
87
+ # - If label is nil or :unlabeled, only unlabeled UTXOs will be returned.
88
+ # - If label=:all, all UTXOs will be returned.
89
+ def list_unspent(only_finalized = true, label = :unlabeled)
90
+ label = :unlabeled unless label
91
+ wallet_adapter.list_unspent(id, only_finalized, label)
92
+ end
93
+
94
+ def delete
95
+ wallet_adapter.delete_wallet(id)
96
+ end
97
+
98
+ # @param [Tapyrus::Tx] tx The tx that is signed
99
+ # @param [Array<Hash>] prev_txs An array of hash that represents unbroadcasted transaction outputs used by signing tx
100
+ # @option prev_txs [String] :txid
101
+ # @option prev_txs [Integer] :vout
102
+ # @option prev_txs [String] :scriptPubkey
103
+ # @option prev_txs [Integer] :amount
104
+ # @param [Boolean] for_fee_provider_input The flag to notify whether the caller is FeeProvider and called for signing a input that is by FeeProvider.
105
+ def sign_tx(tx, prev_txs = [], for_fee_provider_input: false)
106
+ sighashtype = Tapyrus::SIGHASH_TYPE[:all]
107
+
108
+ if !for_fee_provider_input && Glueby.configuration.fee_provider_bears?
109
+ sighashtype |= Tapyrus::SIGHASH_TYPE[:anyonecanpay]
110
+ end
111
+
112
+ wallet_adapter.sign_tx(id, tx, prev_txs, sighashtype: sighashtype)
113
+ end
114
+
115
+ # Broadcast a transaction via Tapyrus Core RPC
116
+ # @param [Tapyrus::Tx] tx The tx that would be broadcasted
117
+ # @option [Boolean] without_fee_provider The flag to avoid to use FeeProvider temporary.
118
+ # @param [Proc] block The block that is called before broadcasting. It can be used to handle tx that is modified by FeeProvider.
119
+ def broadcast(tx, without_fee_provider: false, &block)
120
+ tx = FeeProvider.provide(tx) if !without_fee_provider && Glueby.configuration.fee_provider_bears?
121
+ wallet_adapter.broadcast(id, tx, &block)
122
+ tx
123
+ end
124
+
125
+ def receive_address(label = nil)
126
+ wallet_adapter.receive_address(id, label)
127
+ end
128
+
129
+ def change_address
130
+ wallet_adapter.change_address(id)
131
+ end
132
+
133
+ def create_pubkey
134
+ wallet_adapter.create_pubkey(id)
135
+ end
136
+
137
+ def collect_uncolored_outputs(amount, label = nil, only_finalized = true, shuffle = false)
138
+ utxos = list_unspent(only_finalized, label)
139
+ utxos.shuffle! if shuffle
140
+
141
+ utxos.inject([0, []]) do |sum, output|
142
+ next sum if output[:color_id]
143
+
144
+ new_sum = sum[0] + output[:amount]
145
+ new_outputs = sum[1] << output
146
+ return [new_sum, new_outputs] if new_sum >= amount
147
+
148
+ [new_sum, new_outputs]
149
+ end
150
+ raise Glueby::Contract::Errors::InsufficientFunds
151
+ end
152
+
153
+ def get_addresses(label = nil)
154
+ wallet_adapter.get_addresses(id, label)
155
+ end
156
+
157
+ private
158
+
159
+ def wallet_adapter
160
+ self.class.wallet_adapter
161
+ end
162
+ end
163
+ end
164
+ end
@@ -1,10 +1,11 @@
1
- module Glueby
2
- class Railtie < ::Rails::Railtie
3
- rake_tasks do
4
- load "tasks/glueby/contract.rake"
5
- load "tasks/glueby/contract/timestamp.rake"
6
- load "tasks/glueby/block_syncer.rake"
7
- load "tasks/glueby/fee_provider.rake"
8
- end
9
- end
1
+ module Glueby
2
+ class Railtie < ::Rails::Railtie
3
+ rake_tasks do
4
+ load "tasks/glueby/contract.rake"
5
+ load "tasks/glueby/contract/timestamp.rake"
6
+ load "tasks/glueby/block_syncer.rake"
7
+ load "tasks/glueby/fee_provider.rake"
8
+ load "tasks/glueby/utxo_provider.rake"
9
+ end
10
+ end
10
11
  end
@@ -0,0 +1,135 @@
1
+ module Glueby
2
+ class UtxoProvider
3
+ class Tasks
4
+ include Glueby::Contract::TxBuilder
5
+
6
+ attr_reader :utxo_provider
7
+
8
+ STATUS = {
9
+ # UtxoProvider is ready to pay tpcs.
10
+ ready: 'Ready',
11
+ # UtxoProvider is ready to pay tpcs, but it doesn't have enough amount to fill the UTXO pool by UTXOs which is for paying tpcs.
12
+ insufficient_amount: 'Insufficient Amount',
13
+ # UtxoProvider is not ready to pay tpcs. It has no UTXOs for paying amounts.
14
+ not_ready: 'Not Ready'
15
+ }
16
+
17
+ def initialize
18
+ @utxo_provider = Glueby::UtxoProvider.new
19
+ end
20
+
21
+ # Create UTXOs for paying tpc
22
+ #
23
+ # UtxoProvider have the UTXO pool. the pool is manged to keep some number of UTXOs that have fixed value. The
24
+ # value is configurable by :default_value. This method do the management to the pool.
25
+ def manage_utxo_pool
26
+ txb = Tapyrus::TxBuilder.new
27
+
28
+ sum, utxos = collect_outputs
29
+ return if utxos.empty?
30
+
31
+ utxos.each { |utxo| txb.add_utxo(utxo) }
32
+ address = wallet.receive_address
33
+
34
+ shortage = [utxo_provider.utxo_pool_size - current_utxo_pool_size, 0].max
35
+ return if shortage == 0
36
+
37
+ added_outputs = 0
38
+ shortage.times do
39
+ fee = utxo_provider.fee_estimator.fee(dummy_tx(txb.build))
40
+ break if (sum - fee) < utxo_provider.default_value
41
+ txb.pay(address, utxo_provider.default_value)
42
+ sum -= utxo_provider.default_value
43
+ added_outputs += 1
44
+ end
45
+
46
+ return if added_outputs == 0
47
+
48
+ fee = utxo_provider.fee_estimator.fee(dummy_tx(txb.build))
49
+ tx = txb.change_address(address)
50
+ .fee(fee)
51
+ .build
52
+ tx = wallet.sign_tx(tx)
53
+ wallet.broadcast(tx)
54
+ ensure
55
+ status
56
+ end
57
+
58
+ # Show the status of the UTXO pool
59
+ def status
60
+ status = :ready
61
+
62
+ if current_utxo_pool_size < utxo_provider.utxo_pool_size
63
+ if tpc_amount < value_to_fill_utxo_pool
64
+ status = :insufficient_amount
65
+ message = <<~MESSAGE
66
+ 1. Please replenishment TPC which is for paying tpc to UtxoProvider.
67
+ UtxoProvider needs #{value_to_fill_utxo_pool} tapyrus in UTXO pool.
68
+ UtxoProvider wallet's address is '#{wallet.receive_address}'
69
+ 2. Then create UTXOs for paying in UTXO pool with 'rake glueby:utxo_provider:manage_utxo_pool'
70
+ MESSAGE
71
+ else
72
+ message = "Please create UTXOs for paying in UTXO pool with 'rake glueby:utxo_provider:manage_utxo_pool'\n"
73
+ end
74
+ end
75
+
76
+ status = :not_ready if current_utxo_pool_size == 0
77
+
78
+ puts <<~EOS
79
+ Status: #{STATUS[status]}
80
+ TPC amount: #{delimit(tpc_amount)}
81
+ UTXO pool size: #{delimit(current_utxo_pool_size)}
82
+ #{"\n" if message}#{message}
83
+ Configuration:
84
+ default_value = #{delimit(utxo_provider.default_value)}
85
+ utxo_pool_size = #{delimit(utxo_provider.utxo_pool_size)}
86
+ EOS
87
+ end
88
+
89
+ # Show the address of Utxo Provider
90
+ def print_address
91
+ puts wallet.receive_address
92
+ end
93
+
94
+ private
95
+
96
+ def tpc_amount
97
+ wallet.balance(false)
98
+ end
99
+
100
+ def collect_outputs
101
+ wallet.list_unspent.inject([0, []]) do |sum, output|
102
+ next sum if output[:color_id] || output[:amount] == utxo_provider.default_value
103
+
104
+ new_sum = sum[0] + output[:amount]
105
+ new_outputs = sum[1] << {
106
+ txid: output[:txid],
107
+ script_pubkey: output[:script_pubkey],
108
+ value: output[:amount],
109
+ index: output[:vout] ,
110
+ finalized: output[:finalized]
111
+ }
112
+ [new_sum, new_outputs]
113
+ end
114
+ end
115
+
116
+ def current_utxo_pool_size
117
+ wallet
118
+ .list_unspent(false)
119
+ .count { |o| !o[:color_id] && o[:amount] == utxo_provider.default_value }
120
+ end
121
+
122
+ def value_to_fill_utxo_pool
123
+ utxo_provider.default_value * utxo_provider.utxo_pool_size
124
+ end
125
+
126
+ def wallet
127
+ utxo_provider.wallet
128
+ end
129
+
130
+ def delimit(num)
131
+ num.to_s.reverse.scan(/.{1,3}/).join('_').reverse
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,85 @@
1
+ module Glueby
2
+ class UtxoProvider
3
+ include Glueby::Contract::TxBuilder
4
+
5
+ autoload :Tasks, 'glueby/utxo_provider/tasks'
6
+
7
+ WALLET_ID = 'UTXO_PROVIDER_WALLET'
8
+ DEFAULT_VALUE = 1_000
9
+ DEFAULT_UTXO_POOL_SIZE = 20
10
+ MAX_UTXO_POOL_SIZE = 2_000
11
+
12
+ class << self
13
+ attr_reader :config
14
+
15
+ # @param [Hash] config
16
+ # @option config [Integer] :default_value
17
+ # @option opts [Integer] :utxo_pool_size
18
+ # @option opts [Glueby::Contract::FeeEstimator] :fee_estimator
19
+ def configure(config)
20
+ @config = config
21
+ end
22
+ end
23
+
24
+ def initialize
25
+ @wallet = load_wallet
26
+ validate_config!
27
+ @fee_estimator = (UtxoProvider.config && UtxoProvider.config[:fee_estimator]) || Glueby::Contract::FixedFeeEstimator.new
28
+ @default_value = (UtxoProvider.config && UtxoProvider.config[:default_value]) || DEFAULT_VALUE
29
+ @utxo_pool_size = (UtxoProvider.config && UtxoProvider.config[:utxo_pool_size]) || DEFAULT_UTXO_POOL_SIZE
30
+ end
31
+
32
+ attr_reader :wallet, :fee_estimator, :default_value, :utxo_pool_size
33
+
34
+ # Provide a UTXO
35
+ # @param [Tapyrus::Script] script_pubkey The script to be provided
36
+ # @param [Integer] value The tpc amount to be provided
37
+ # @return [Array<(Tapyrus::Tx, Integer)>]
38
+ # The tx that has a UTXO to be provided in its outputs.
39
+ # The output index in the tx to indicate the place of a provided UTXO.
40
+ # @raise [Glueby::Contract::Errors::InsufficientFunds] if provider does not have any utxo which has specified value.
41
+ def get_utxo(script_pubkey, value = DEFAULT_VALUE)
42
+ txb = Tapyrus::TxBuilder.new
43
+ txb.pay(script_pubkey.addresses.first, value)
44
+
45
+ fee = fee_estimator.fee(dummy_tx(txb.build))
46
+ # The outputs need to be shuffled so that no utxos are spent twice as possible.
47
+ sum, outputs = wallet.collect_uncolored_outputs(fee + value, nil, true, true)
48
+
49
+ outputs.each do |utxo|
50
+ txb.add_utxo({
51
+ script_pubkey: Tapyrus::Script.parse_from_payload(utxo[:script_pubkey].htb),
52
+ txid: utxo[:txid],
53
+ index: utxo[:vout],
54
+ value: utxo[:amount]
55
+ })
56
+ end
57
+
58
+ txb.fee(fee).change_address(wallet.change_address)
59
+
60
+ tx = txb.build
61
+ signed_tx = wallet.sign_tx(tx)
62
+ [signed_tx, 0]
63
+ end
64
+
65
+ private
66
+
67
+ # Create wallet for provider
68
+ def load_wallet
69
+ begin
70
+ Glueby::Internal::Wallet.load(WALLET_ID)
71
+ rescue Glueby::Internal::Wallet::Errors::WalletNotFound => _
72
+ Glueby::Internal::Wallet.create(WALLET_ID)
73
+ end
74
+ end
75
+
76
+ def validate_config!
77
+ if UtxoProvider.config
78
+ utxo_pool_size = UtxoProvider.config[:utxo_pool_size]
79
+ if utxo_pool_size && (!utxo_pool_size.is_a?(Integer) || utxo_pool_size > MAX_UTXO_POOL_SIZE)
80
+ raise Glueby::Configuration::Errors::InvalidConfiguration, "utxo_pool_size(#{utxo_pool_size}) should not be greater than #{MAX_UTXO_POOL_SIZE}"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,3 +1,3 @@
1
- module Glueby
2
- VERSION = "0.4.4"
3
- end
1
+ module Glueby
2
+ VERSION = "0.6.0"
3
+ end
data/lib/glueby.rb CHANGED
@@ -1,39 +1,40 @@
1
- require "glueby/version"
2
- require 'tapyrus'
3
-
4
- module Glueby
5
- autoload :Contract, 'glueby/contract'
6
- autoload :Generator, 'glueby/generator'
7
- autoload :Wallet, 'glueby/wallet'
8
- autoload :Internal, 'glueby/internal'
9
- autoload :AR, 'glueby/active_record'
10
- autoload :FeeProvider, 'glueby/fee_provider'
11
- autoload :Configuration, 'glueby/configuration'
12
- autoload :BlockSyncer, 'glueby/block_syncer'
13
-
14
- if defined? ::Rails::Railtie
15
- require 'glueby/railtie'
16
- end
17
-
18
- # Add prefix to activerecord table names
19
- def self.table_name_prefix
20
- 'glueby_'
21
- end
22
-
23
- # Returns the global [Configuration](RSpec/Core/Configuration) object.
24
- def self.configuration
25
- @configuration ||= Glueby::Configuration.new
26
- end
27
-
28
- # Yields the global configuration to a block.
29
- # @yield [Configuration] global configuration
30
- #
31
- # @example
32
- # Glueby.configure do |config|
33
- # config.wallet_adapter = :activerecord
34
- # config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
35
- # end
36
- def self.configure
37
- yield configuration if block_given?
38
- end
39
- end
1
+ require "glueby/version"
2
+ require 'tapyrus'
3
+
4
+ module Glueby
5
+ autoload :Contract, 'glueby/contract'
6
+ autoload :Generator, 'glueby/generator'
7
+ autoload :Wallet, 'glueby/wallet'
8
+ autoload :Internal, 'glueby/internal'
9
+ autoload :AR, 'glueby/active_record'
10
+ autoload :FeeProvider, 'glueby/fee_provider'
11
+ autoload :Configuration, 'glueby/configuration'
12
+ autoload :BlockSyncer, 'glueby/block_syncer'
13
+ autoload :UtxoProvider, 'glueby/utxo_provider'
14
+
15
+ if defined? ::Rails::Railtie
16
+ require 'glueby/railtie'
17
+ end
18
+
19
+ # Add prefix to activerecord table names
20
+ def self.table_name_prefix
21
+ 'glueby_'
22
+ end
23
+
24
+ # Returns the global [Configuration](RSpec/Core/Configuration) object.
25
+ def self.configuration
26
+ @configuration ||= Glueby::Configuration.new
27
+ end
28
+
29
+ # Yields the global configuration to a block.
30
+ # @yield [Configuration] global configuration
31
+ #
32
+ # @example
33
+ # Glueby.configure do |config|
34
+ # config.wallet_adapter = :activerecord
35
+ # config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
36
+ # end
37
+ def self.configure
38
+ yield configuration if block_given?
39
+ end
40
+ end