glueby 1.1.1 → 1.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -73,6 +73,10 @@ module Glueby
73
73
  @wallet_adapter or
74
74
  raise Errors::ShouldInitializeWalletAdapter, 'You should initialize wallet adapter using `Glueby::Internal::Wallet.wallet_adapter = some wallet adapter instance`.'
75
75
  end
76
+
77
+ def get_addresses_info(addresses)
78
+ @wallet_adapter.get_addresses_info(addresses)
79
+ end
76
80
  end
77
81
 
78
82
  attr_reader :id
@@ -142,20 +146,74 @@ module Glueby
142
146
  wallet_adapter.create_pubkey(id)
143
147
  end
144
148
 
145
- def collect_uncolored_outputs(amount, label = nil, only_finalized = true, shuffle = false)
146
- utxos = list_unspent(only_finalized, label)
147
- utxos.shuffle! if shuffle
149
+ # Collect TPC UTXOs up to the specified amount.
150
+ # @param [Integer] amount The amount of colored token to collect. If the amount is nil, return all TPC UTXOs
151
+ # @param [String] label The label of UTXO to collect
152
+ # @param [Boolean] only_finalized The flag to collect only finalized UTXO
153
+ # @param [Boolean] shuffle The flag to shuffle UTXO before collecting
154
+ # @param [Boolean] lock_utxos The flag to lock returning UTXOs to prevent to be used from other threads or processes
155
+ # @param [Array<Hash] excludes The UTXO list to exclude the method result. Each hash must hub keys that are :txid and :vout
156
+ # @return [Integer] The sum of return UTXOs
157
+ # @return [Array<Hash>] An array of UTXO hash
158
+ #
159
+ # ## The UTXO structure
160
+ #
161
+ # - txid: [String] Transaction id
162
+ # - vout: [Integer] Output index
163
+ # - amount: [Integer] Amount of the UTXO as tapyrus unit
164
+ # - finalized: [Boolean] Whether the UTXO is finalized
165
+ # - script_pubkey: [String] ScriptPubkey of the UTXO
166
+ def collect_uncolored_outputs(
167
+ amount = nil,
168
+ label = nil,
169
+ only_finalized = true,
170
+ shuffle = false,
171
+ lock_utxos = false,
172
+ excludes = []
173
+ )
174
+ collect_utxos(amount, label, only_finalized, shuffle, lock_utxos, excludes) do |output|
175
+ next false unless output[:color_id].nil?
176
+ next yield(output) if block_given?
148
177
 
149
- utxos.inject([0, []]) do |sum, output|
150
- next sum if output[:color_id]
178
+ true
179
+ end
180
+ end
151
181
 
152
- new_sum = sum[0] + output[:amount]
153
- new_outputs = sum[1] << output
154
- return [new_sum, new_outputs] if new_sum >= amount
182
+ # Collect colored coin UTXOs up to the specified amount.
183
+ # @param [Tapyrus::Color::ColorIdentifier] color_id The color identifier of colored token
184
+ # @param [Integer] amount The amount of colored token to collect. If the amount is nil, return all UTXOs with color_id
185
+ # @param [String] label The label of UTXO to collect
186
+ # @param [Boolean] only_finalized The flag to collect only finalized UTXO
187
+ # @param [Boolean] shuffle The flag to shuffle UTXO before collecting
188
+ # @param [Boolean] lock_utxos The flag to lock returning UTXOs to prevent to be used from other threads or processes
189
+ # @param [Array<Hash] excludes The UTXO list to exclude the method result. Each hash must hub keys that are :txid and :vout
190
+ # @return [Integer] The sum of return UTXOs
191
+ # @return [Array<Hash>] An array of UTXO hash
192
+ #
193
+ # ## The UTXO structure
194
+ #
195
+ # - txid: [String] Transaction id
196
+ # - vout: [Integer] Output index
197
+ # - amount: [Integer] Amount of the UTXO as tapyrus unit
198
+ # - finalized: [Boolean] Whether the UTXO is finalized
199
+ # - script_pubkey: [String] ScriptPubkey of the UTXO
200
+ def collect_colored_outputs(
201
+ color_id,
202
+ amount = nil,
203
+ label = nil,
204
+ only_finalized = true,
205
+ shuffle = false,
206
+ lock_utxos = false,
207
+ excludes = []
208
+ )
209
+ collect_utxos(amount, label, only_finalized, shuffle, lock_utxos, excludes) do |output|
210
+ next false unless output[:color_id] == color_id.to_hex
211
+ next yield(output) if block_given?
155
212
 
156
- [new_sum, new_outputs]
213
+ true
157
214
  end
158
- raise Glueby::Contract::Errors::InsufficientFunds
215
+ rescue Glueby::Contract::Errors::InsufficientFunds
216
+ raise Glueby::Contract::Errors::InsufficientTokens
159
217
  end
160
218
 
161
219
  def get_addresses(label = nil)
@@ -178,11 +236,94 @@ module Glueby
178
236
  wallet_adapter.has_address?(id, address)
179
237
  end
180
238
 
239
+ # Fill inputs in the tx up to target_amount of TPC from UTXOs in the wallet.
240
+ # This method should be called before adding change output and script_sig in outputs.
241
+ # FeeEstimator.dummy_tx returns fee amount to the TX that will be added one TPC input, a change TPC output and
242
+ # script sigs in outputs.
243
+ # @param [Tapyrus::Tx] tx The tx that will be filled the inputs
244
+ # @param [Integer] target_amount The tapyrus amount the tx is expected to be added in this method
245
+ # @param [Integer] current_amount The tapyrus amount the tx already has in its inputs
246
+ # @param [Glueby::Contract::FeeEstimator] fee_estimator
247
+ # @return [Tapyrus::Tx] tx The tx that is added inputs
248
+ # @return [Integer] fee The final fee after the inputs are filled
249
+ # @return [Integer] current_amount The final amount of the tx inputs
250
+ # @return [Array<Hash>] provided_utxos The utxos that are added to the tx inputs
251
+ def fill_uncolored_inputs(
252
+ tx,
253
+ target_amount: ,
254
+ current_amount: 0,
255
+ fee_estimator: Contract::FeeEstimator::Fixed.new,
256
+ &block
257
+ )
258
+ fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(tx, dummy_input_count: 0))
259
+ provided_utxos = []
260
+
261
+ while current_amount - fee < target_amount
262
+ sum, utxos = collect_uncolored_outputs(
263
+ fee + target_amount - current_amount,
264
+ nil, nil, true, true,
265
+ provided_utxos,
266
+ &block
267
+ )
268
+
269
+ utxos.each do |utxo|
270
+ tx.inputs << Tapyrus::TxIn.new(out_point: Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:vout]))
271
+ provided_utxos << utxo
272
+ end
273
+ current_amount += sum
274
+
275
+ new_fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(tx, dummy_input_count: 0))
276
+ fee = new_fee
277
+ end
278
+
279
+ [tx, fee, current_amount, provided_utxos]
280
+ end
281
+
181
282
  private
182
283
 
183
284
  def wallet_adapter
184
285
  self.class.wallet_adapter
185
286
  end
287
+
288
+ def collect_utxos(
289
+ amount,
290
+ label,
291
+ only_finalized,
292
+ shuffle = true,
293
+ lock_utxos = false,
294
+ excludes = []
295
+ )
296
+ collect_all = amount.nil?
297
+
298
+ raise Glueby::ArgumentError, 'amount must be positive' unless collect_all || amount.positive?
299
+ utxos = list_unspent(only_finalized, label)
300
+ utxos = utxos.shuffle if shuffle
301
+
302
+ r = utxos.inject([0, []]) do |(sum, outputs), output|
303
+ if excludes.is_a?(Array) &&
304
+ !excludes.empty? &&
305
+ excludes.find { |i| i[:txid] == output[:txid] && i[:vout] == output[:vout] }
306
+ next [sum, outputs]
307
+ end
308
+
309
+ if block_given?
310
+ next [sum, outputs] unless yield(output)
311
+ end
312
+
313
+ if lock_utxos
314
+ next [sum, outputs] unless lock_unspent(output)
315
+ end
316
+
317
+ sum += output[:amount]
318
+ outputs << output
319
+ return [sum, outputs] unless collect_all || sum < amount
320
+
321
+ [sum, outputs]
322
+ end
323
+ raise Glueby::Contract::Errors::InsufficientFunds unless collect_all
324
+
325
+ r
326
+ end
186
327
  end
187
328
  end
188
329
  end
@@ -2,5 +2,6 @@ module Glueby
2
2
  module Internal
3
3
  autoload :Wallet, 'glueby/internal/wallet'
4
4
  autoload :RPC, 'glueby/internal/rpc'
5
+ autoload :ContractBuilder, 'glueby/internal/contract_builder'
5
6
  end
6
7
  end
@@ -1,8 +1,6 @@
1
1
  module Glueby
2
2
  class UtxoProvider
3
3
  class Tasks
4
- include Glueby::Contract::TxBuilder
5
-
6
4
  attr_reader :utxo_provider
7
5
 
8
6
  STATUS = {
@@ -1,6 +1,5 @@
1
1
  module Glueby
2
2
  class UtxoProvider
3
- include Glueby::Contract::TxBuilder
4
3
  include Singleton
5
4
 
6
5
  autoload :Tasks, 'glueby/utxo_provider/tasks'
@@ -77,26 +76,20 @@ module Glueby
77
76
  # @return [Integer] current_amount The final amount of the tx inputs
78
77
  # @return [Array<Hash>] provided_utxos The utxos that are added to the tx inputs
79
78
  def fill_inputs(tx, target_amount: , current_amount: 0, fee_estimator: Contract::FeeEstimator::Fixed.new)
80
- fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(tx, dummy_input_count: 0))
81
- provided_utxos = []
82
-
83
- # If the change output value is less than DUST_LIMIT, tapyrus core returns "dust" error while broadcasting.
84
- target_amount += DUST_LIMIT if target_amount < DUST_LIMIT
85
-
86
- while current_amount - fee < target_amount
87
- sum, utxos = collect_uncolored_outputs(wallet, fee + target_amount - current_amount, provided_utxos)
88
-
89
- utxos.each do |utxo|
90
- tx.inputs << Tapyrus::TxIn.new(out_point: Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:vout]))
91
- provided_utxos << utxo
92
- end
93
- current_amount += sum
94
-
95
- new_fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(tx, dummy_input_count: 0))
96
- fee = new_fee
79
+ wallet.fill_uncolored_inputs(
80
+ tx,
81
+ target_amount: target_amount,
82
+ current_amount: current_amount,
83
+ fee_estimator: fee_estimator
84
+ ) do |utxo|
85
+ # It must use only UTXOs that has defalut_value amount.
86
+ utxo[:amount] == default_value
97
87
  end
88
+ end
89
+ alias fill_uncolored_inputs fill_inputs
98
90
 
99
- [tx, fee, current_amount, provided_utxos]
91
+ def change_address
92
+ wallet.change_address
100
93
  end
101
94
 
102
95
  def default_value
@@ -153,22 +146,10 @@ module Glueby
153
146
  # @return [Integer] sum The sum amount of the funds
154
147
  # @return [Array<Hash>] outputs The UTXO set of the funds
155
148
  def collect_uncolored_outputs(wallet, amount, excludes = [])
156
- utxos = wallet.list_unspent.select do |o|
157
- !o[:color_id] &&
158
- o[:amount] == default_value &&
159
- !excludes.find { |i| i[:txid] == o[:txid] && i[:vout] == o[:vout] }
160
- end
161
- utxos.shuffle!
162
-
163
- utxos.inject([0, []]) do |(sum, outputs), output|
164
- if wallet.lock_unspent(output)
165
- sum += output[:amount]
166
- outputs << output
167
- return [sum, outputs] if sum >= amount
168
- end
169
- [sum, outputs]
149
+ wallet.collect_uncolored_outputs(amount, nil, true, true, true) do |utxo|
150
+ utxo[:amount] == default_value &&
151
+ !excludes.find { |i| i[:txid] == utxo[:txid] && i[:vout] == utxo[:vout] }
170
152
  end
171
- raise Glueby::Contract::Errors::InsufficientFunds
172
153
  end
173
154
 
174
155
  def validate_config!
@@ -1,3 +1,3 @@
1
1
  module Glueby
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0.beta.1"
3
3
  end
@@ -3,7 +3,6 @@ module Glueby
3
3
  module Task
4
4
  module Timestamp
5
5
  module_function
6
- extend Glueby::Contract::TxBuilder
7
6
 
8
7
  def create
9
8
  timestamps = Glueby::Contract::AR::Timestamp.where(status: :init)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glueby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-07 00:00:00.000000000 Z
11
+ date: 2023-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tapyrus
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 6.1.3
33
+ version: 7.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 6.1.3
40
+ version: 7.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 6.1.3
75
+ version: 7.0.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 6.1.3
82
+ version: 7.0.0
83
83
  description: A Ruby library of smart contracts that can be used on Tapyrus.
84
84
  email:
85
85
  - azuchi@chaintope.com
@@ -142,6 +142,7 @@ files:
142
142
  - lib/glueby/generator.rb
143
143
  - lib/glueby/generator/migrate_generator.rb
144
144
  - lib/glueby/internal.rb
145
+ - lib/glueby/internal/contract_builder.rb
145
146
  - lib/glueby/internal/rpc.rb
146
147
  - lib/glueby/internal/wallet.rb
147
148
  - lib/glueby/internal/wallet/abstract_wallet_adapter.rb
@@ -172,7 +173,7 @@ metadata:
172
173
  homepage_uri: https://github.com/chaintope/glueby
173
174
  source_code_uri: https://github.com/chaintope/glueby
174
175
  changelog_uri: https://github.com/chaintope/glueby
175
- post_install_message:
176
+ post_install_message:
176
177
  rdoc_options: []
177
178
  require_paths:
178
179
  - lib
@@ -180,15 +181,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
181
  requirements:
181
182
  - - ">="
182
183
  - !ruby/object:Gem::Version
183
- version: 2.3.0
184
+ version: 2.7.0
184
185
  required_rubygems_version: !ruby/object:Gem::Requirement
185
186
  requirements:
186
- - - ">="
187
+ - - ">"
187
188
  - !ruby/object:Gem::Version
188
- version: '0'
189
+ version: 1.3.1
189
190
  requirements: []
190
- rubygems_version: 3.2.3
191
- signing_key:
191
+ rubygems_version: 3.4.10
192
+ signing_key:
192
193
  specification_version: 4
193
194
  summary: A Ruby library of smart contracts that can be used on Tapyrus.
194
195
  test_files: []