glueby 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +3 -4
  3. data/README.md +3 -3
  4. data/glueby.gemspec +2 -1
  5. data/lib/generators/glueby/contract/templates/initializer.rb.erb +8 -8
  6. data/lib/generators/glueby/contract/templates/key_table.rb.erb +16 -16
  7. data/lib/generators/glueby/contract/templates/timestamp_table.rb.erb +2 -0
  8. data/lib/generators/glueby/contract/templates/token_metadata_table.rb.erb +13 -0
  9. data/lib/generators/glueby/contract/templates/utxo_table.rb.erb +1 -0
  10. data/lib/generators/glueby/contract/{reissuable_token_generator.rb → token_generator.rb} +12 -1
  11. data/lib/glueby/block_syncer.rb +97 -97
  12. data/lib/glueby/configuration.rb +2 -0
  13. data/lib/glueby/contract/active_record/timestamp.rb +9 -2
  14. data/lib/glueby/contract/active_record/token_metadata.rb +8 -0
  15. data/lib/glueby/contract/active_record.rb +1 -0
  16. data/lib/glueby/contract/fee_estimator/auto.rb +9 -1
  17. data/lib/glueby/contract/fee_estimator.rb +12 -5
  18. data/lib/glueby/contract/timestamp/syncer.rb +1 -1
  19. data/lib/glueby/contract/token.rb +161 -80
  20. data/lib/glueby/contract/tx_builder.rb +104 -67
  21. data/lib/glueby/fee_provider/tasks.rb +4 -1
  22. data/lib/glueby/internal/wallet/abstract_wallet_adapter.rb +26 -0
  23. data/lib/glueby/internal/wallet/active_record/key.rb +2 -2
  24. data/lib/glueby/internal/wallet/active_record/utxo.rb +9 -0
  25. data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +26 -9
  26. data/lib/glueby/internal/wallet/errors.rb +1 -0
  27. data/lib/glueby/internal/wallet/mysql_wallet_adapter.rb +17 -0
  28. data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +1 -1
  29. data/lib/glueby/internal/wallet.rb +16 -0
  30. data/lib/glueby/util/digest.rb +23 -0
  31. data/lib/glueby/utxo_provider/tasks.rb +3 -1
  32. data/lib/glueby/utxo_provider.rb +56 -9
  33. data/lib/glueby/version.rb +1 -1
  34. data/lib/tasks/glueby/block_syncer.rake +7 -0
  35. metadata +23 -5
@@ -38,10 +38,13 @@ module Glueby
38
38
 
39
39
  fee_outputs_count_to_be_created.times do
40
40
  txb.pay(address, fee_provider.fixed_fee)
41
+ sum -= fee_provider.fixed_fee
41
42
  end
43
+ fee = fee_provider.fixed_fee
44
+ fee += (sum - fee) if sum - fee < DUST_LIMIT
42
45
 
43
46
  tx = txb.change_address(address)
44
- .fee(fee_provider.fixed_fee)
47
+ .fee(fee)
45
48
  .build
46
49
  tx = wallet.sign_tx(tx)
47
50
  wallet.broadcast(tx, without_fee_provider: true)
@@ -86,6 +86,14 @@ module Glueby
86
86
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
87
87
  end
88
88
 
89
+ # Attempt to lock a specified utxo and update lock_at field
90
+ #
91
+ # @param wallet_id [String] The wallet id that is offered by `create_wallet()` method.
92
+ # @param utxo [Hash] The utxo hash object
93
+ def lock_unspent(wallet_id, utxo)
94
+ true
95
+ end
96
+
89
97
  # Sign to the transaction with a key in the wallet.
90
98
  #
91
99
  # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
@@ -157,6 +165,15 @@ module Glueby
157
165
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
158
166
  end
159
167
 
168
+ # Create pay to contract key
169
+ # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
170
+ # @param [Tapyrus::Key] payment_base - The public key used to generate pay to contract public key
171
+ # @param [String] contents - The data to be used for generating pay-to-contract address
172
+ # @return [Tapyrus::Key] Key for pay to contract
173
+ def pay_to_contract_key(wallet_id, payment_base, contents)
174
+ raise NotImplementedError, "You must implement #{self.class}##{__method__}"
175
+ end
176
+
160
177
  # Sign to the pay to contract input
161
178
  # @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
162
179
  # @param [Tapyrus::Tx] tx - The tx that has pay to contract input in the inputs list
@@ -170,9 +187,18 @@ module Glueby
170
187
  # @param [Integer] sighashtype - The sighash flag for each signature that would be produced here.
171
188
  # @return [Tapyrus::Tx]
172
189
  # @raise [Glueby::Internal::Wallet::Errors::InvalidSighashType] when the specified sighashtype is invalid
190
+ # @raise [Glueby::Internal::Wallet::Errors::InvalidSigner] when the wallet don't have any private key of the specified payment_base
173
191
  def sign_to_pay_to_contract_address(wallet_id, tx, utxo, payment_base, contents, sighashtype: Tapyrus::SIGHASH_TYPE[:all])
174
192
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
175
193
  end
194
+
195
+ # Return if wallet has the address
196
+ # @param wallet_id [String] The wallet id that is offered by `create_wallet()` method.
197
+ # @param address [String] address
198
+ # @return [Boolean] true if the wallet has an address, false otherwise
199
+ def has_address?(wallet_id, address)
200
+ raise NotImplementedError, "You must implement #{self.class}##{__method__}"
201
+ end
176
202
  end
177
203
  end
178
204
  end
@@ -20,7 +20,7 @@ module Glueby
20
20
  end
21
21
 
22
22
  def sign(data)
23
- Tapyrus::Key.new(priv_key: self.private_key).sign(data, algo: :schnorr)
23
+ Tapyrus::Key.new(priv_key: self.private_key, key_type: Tapyrus::Key::TYPES[:compressed]).sign(data, algo: :schnorr)
24
24
  end
25
25
 
26
26
  def address
@@ -54,7 +54,7 @@ module Glueby
54
54
 
55
55
  def generate_key
56
56
  key = if private_key
57
- Tapyrus::Key.new(priv_key: private_key)
57
+ Tapyrus::Key.new(priv_key: private_key, key_type: Tapyrus::Key::TYPES[:compressed])
58
58
  else
59
59
  Tapyrus::Key.generate
60
60
  end
@@ -8,6 +8,7 @@ module Glueby
8
8
  belongs_to :key
9
9
 
10
10
  validates :txid, uniqueness: { scope: :index, case_sensitive: false }
11
+ validate :check_dust_output
11
12
 
12
13
  enum status: { init: 0, broadcasted: 1, finalized: 2 }
13
14
 
@@ -44,6 +45,14 @@ module Glueby
44
45
  )
45
46
  end
46
47
  end
48
+
49
+ private
50
+
51
+ def check_dust_output
52
+ if !color_id && value < DUST_LIMIT
53
+ errors.add(:value, "is less than dust limit(#{DUST_LIMIT})")
54
+ end
55
+ end
47
56
  end
48
57
  end
49
58
  end
@@ -84,16 +84,15 @@ module Glueby
84
84
 
85
85
  def balance(wallet_id, only_finalized = true)
86
86
  wallet = AR::Wallet.find_by(wallet_id: wallet_id)
87
- utxos = wallet.utxos
87
+ utxos = wallet.utxos.where(locked_at: nil)
88
88
  utxos = utxos.where(status: :finalized) if only_finalized
89
89
  utxos.sum(&:value)
90
90
  end
91
91
 
92
92
  def list_unspent(wallet_id, only_finalized = true, label = nil)
93
93
  wallet = AR::Wallet.find_by(wallet_id: wallet_id)
94
- utxos = wallet.utxos
94
+ utxos = wallet.utxos.where(locked_at: nil)
95
95
  utxos = utxos.where(status: :finalized) if only_finalized
96
-
97
96
  if [:unlabeled, nil].include?(label)
98
97
  utxos = utxos.where(label: nil)
99
98
  elsif label && (label != :all)
@@ -144,7 +143,7 @@ module Glueby
144
143
  def create_pubkey(wallet_id)
145
144
  wallet = AR::Wallet.find_by(wallet_id: wallet_id)
146
145
  key = wallet.keys.create(purpose: :receive)
147
- Tapyrus::Key.new(pubkey: key.public_key)
146
+ Tapyrus::Key.new(pubkey: key.public_key, key_type: Tapyrus::Key::TYPES[:compressed])
148
147
  end
149
148
 
150
149
  def get_addresses(wallet_id, label = nil)
@@ -155,13 +154,17 @@ module Glueby
155
154
  end
156
155
 
157
156
  def create_pay_to_contract_address(wallet_id, contents)
157
+ pubkey = create_pubkey(wallet_id)
158
+ [pay_to_contract_key(wallet_id, pubkey, contents).to_p2pkh, pubkey.pubkey]
159
+ end
160
+
161
+ def pay_to_contract_key(wallet_id, pubkey, contents)
158
162
  # Calculate P + H(P || contents)G
159
163
  group = ECDSA::Group::Secp256k1
160
- pubkey = create_pubkey(wallet_id)
161
164
  p = pubkey.to_point # P
162
165
  commitment = create_pay_to_contract_commitment(pubkey, contents)
163
166
  point = p + group.generator.multiply_by_scalar(commitment) # P + H(P || contents)G
164
- [Tapyrus::Key.new(pubkey: point.to_hex(true)).to_p2pkh, pubkey.pubkey] # [p2c address, P]
167
+ Tapyrus::Key.new(pubkey: point.to_hex(true), key_type: Tapyrus::Key::TYPES[:compressed])
165
168
  end
166
169
 
167
170
  def sign_to_pay_to_contract_address(wallet_id, tx, utxo, payment_base, contents)
@@ -174,6 +177,12 @@ module Glueby
174
177
  tx
175
178
  end
176
179
 
180
+ def has_address?(wallet_id, address)
181
+ script_pubkey = Tapyrus::Script.parse_from_addr(address)
182
+ wallet = AR::Wallet.find_by(wallet_id: wallet_id)
183
+ wallet.keys.exists?(script_pubkey: script_pubkey.to_hex)
184
+ end
185
+
177
186
  private
178
187
 
179
188
  # Calculate commitment = H(P || contents)
@@ -181,22 +190,30 @@ module Glueby
181
190
  # @param [String] contents
182
191
  # @return Integer
183
192
  def create_pay_to_contract_commitment(pubkey, contents)
193
+ contents = (+contents).force_encoding('binary')
184
194
  group = ECDSA::Group::Secp256k1
185
195
  p = pubkey.to_point # P
186
- Tapyrus.sha256(p.to_hex(true).htb + contents).bth.to_i(16) % group.order # H(P || contents)
196
+ Tapyrus.sha256(p.to_hex(true).htb + contents).bth.to_i(16) % group.order # H(P || contents)
187
197
  end
188
198
 
189
199
  # @param [String] wallet_id
190
200
  # @param [String] payment_base The public key hex string
191
201
  # @param [String] contents
192
202
  # @return [Tapyrus::Key] pay to contract private key
203
+ # @raise [Errors::InvalidSigner] raises when the wallet don't have any private key of the specified payment_base
193
204
  def create_pay_to_contract_private_key(wallet_id, payment_base, contents)
194
205
  group = ECDSA::Group::Secp256k1
195
206
  wallet = AR::Wallet.find_by(wallet_id: wallet_id)
196
207
  ar_key = wallet.keys.where(public_key: payment_base).first
197
- key = Tapyrus::Key.new(pubkey: payment_base)
208
+ raise Errors::InvalidSigner, "The wallet don't have any private key of the specified payment_base" unless ar_key
209
+
210
+ key = Tapyrus::Key.new(pubkey: payment_base, key_type: Tapyrus::Key::TYPES[:compressed])
198
211
  commitment = create_pay_to_contract_commitment(key, contents)
199
- Tapyrus::Key.new(priv_key: ((ar_key.private_key.to_i(16) + commitment) % group.order).to_even_length_hex) # K + commitment
212
+ p2c_private_key = (ar_key.private_key.to_i(16) + commitment) % group.order # K + commitment
213
+ Tapyrus::Key.new(
214
+ priv_key: ECDSA::Format::IntegerOctetString.encode(p2c_private_key, 32).bth,
215
+ key_type: Tapyrus::Key::TYPES[:compressed]
216
+ )
200
217
  end
201
218
  end
202
219
  end
@@ -8,6 +8,7 @@ module Glueby
8
8
  class WalletAlreadyCreated < Error; end
9
9
  class WalletNotFound < Error; end
10
10
  class InvalidSighashType < Error; end
11
+ class InvalidSigner < Error; end
11
12
  end
12
13
  end
13
14
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glueby
4
+ module Internal
5
+ class Wallet
6
+ class MySQLWalletAdapter < ActiveRecordWalletAdapter
7
+ def lock_unspent(wallet_id, utxo)
8
+ ActiveRecord::Base.transaction(joinable: false, requires_new: true) do
9
+ record = AR::Utxo.lock("FOR UPDATE SKIP LOCKED").find_by(txid: utxo[:txid], index: utxo[:vout], locked_at: nil)
10
+ record&.update!(locked_at: Time.now)
11
+ record
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -149,7 +149,7 @@ module Glueby
149
149
  perform_as(wallet_id) do |client|
150
150
  address = client.getnewaddress('')
151
151
  info = client.getaddressinfo(address)
152
- Tapyrus::Key.new(pubkey: info['pubkey'])
152
+ Tapyrus::Key.new(pubkey: info['pubkey'], key_type: Tapyrus::Key::TYPES[:compressed])
153
153
  end
154
154
  end
155
155
 
@@ -31,8 +31,11 @@ module Glueby
31
31
  autoload :AR, 'glueby/internal/wallet/active_record'
32
32
  autoload :TapyrusCoreWalletAdapter, 'glueby/internal/wallet/tapyrus_core_wallet_adapter'
33
33
  autoload :ActiveRecordWalletAdapter, 'glueby/internal/wallet/active_record_wallet_adapter'
34
+ autoload :MySQLWalletAdapter, 'glueby/internal/wallet/mysql_wallet_adapter'
34
35
  autoload :Errors, 'glueby/internal/wallet/errors'
35
36
 
37
+ include GluebyLogger
38
+
36
39
  class << self
37
40
  def create(wallet_id = nil)
38
41
  begin
@@ -91,6 +94,10 @@ module Glueby
91
94
  wallet_adapter.list_unspent(id, only_finalized, label)
92
95
  end
93
96
 
97
+ def lock_unspent(utxo)
98
+ wallet_adapter.lock_unspent(id, utxo)
99
+ end
100
+
94
101
  def delete
95
102
  wallet_adapter.delete_wallet(id)
96
103
  end
@@ -118,6 +125,7 @@ module Glueby
118
125
  # @param [Proc] block The block that is called before broadcasting. It can be used to handle tx that is modified by FeeProvider.
119
126
  def broadcast(tx, without_fee_provider: false, &block)
120
127
  tx = FeeProvider.provide(tx) if !without_fee_provider && Glueby.configuration.fee_provider_bears?
128
+ logger.info("Try to broadcast a tx (tx payload: #{tx.to_hex} )")
121
129
  wallet_adapter.broadcast(id, tx, &block)
122
130
  tx
123
131
  end
@@ -158,10 +166,18 @@ module Glueby
158
166
  wallet_adapter.create_pay_to_contract_address(id, contents)
159
167
  end
160
168
 
169
+ def pay_to_contract_key(payment_base, contents)
170
+ wallet_adapter.pay_to_contract_key(id, payment_base, contents)
171
+ end
172
+
161
173
  def sign_to_pay_to_contract_address(tx, utxo, payment_base, contents)
162
174
  wallet_adapter.sign_to_pay_to_contract_address(id, tx, utxo, payment_base, contents)
163
175
  end
164
176
 
177
+ def has_address?(address)
178
+ wallet_adapter.has_address?(id, address)
179
+ end
180
+
165
181
  private
166
182
 
167
183
  def wallet_adapter
@@ -0,0 +1,23 @@
1
+ module Glueby
2
+ module Util
3
+ module Digest
4
+ # Hash content with specified digest algorithm
5
+ #
6
+ # @param content [String] content to be hashed
7
+ # @param digest [Symbol] The symbol represents algorithm used for hashing. :sha256, :double_sha256, :none are available
8
+ # @return [String] hex string hashed from content
9
+ def digest_content(content, digest)
10
+ case digest&.downcase
11
+ when :sha256
12
+ Tapyrus.sha256(content).bth
13
+ when :double_sha256
14
+ Tapyrus.double_sha256(content).bth
15
+ when :none
16
+ content
17
+ else
18
+ raise Glueby::Contract::Errors::UnsupportedDigestType
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -15,7 +15,7 @@ module Glueby
15
15
  }
16
16
 
17
17
  def initialize
18
- @utxo_provider = Glueby::UtxoProvider.new
18
+ @utxo_provider = Glueby::UtxoProvider.instance
19
19
  end
20
20
 
21
21
  # Create UTXOs for paying tpc
@@ -46,6 +46,8 @@ module Glueby
46
46
  return if added_outputs == 0
47
47
 
48
48
  fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(txb.build))
49
+ fee += (sum - fee) if sum - fee < DUST_LIMIT
50
+
49
51
  tx = txb.change_address(utxo_provider.address)
50
52
  .fee(fee)
51
53
  .build
@@ -1,6 +1,7 @@
1
1
  module Glueby
2
2
  class UtxoProvider
3
3
  include Glueby::Contract::TxBuilder
4
+ include Singleton
4
5
 
5
6
  autoload :Tasks, 'glueby/utxo_provider/tasks'
6
7
 
@@ -63,6 +64,41 @@ module Glueby
63
64
  [signed_tx, 0]
64
65
  end
65
66
 
67
+ # Fill inputs in the tx up to target_amount of TPC from UTXO pool
68
+ # This method should be called before adding change output and script_sig in outputs.
69
+ # FeeEstimator.dummy_tx returns fee amount to the TX that will be added one TPC input, a change TPC output and
70
+ # script sigs in outputs.
71
+ # @param [Tapyrus::Tx] tx The tx that will be filled the inputs
72
+ # @param [Integer] target_amount The tapyrus amount the tx is expected to be added in this method
73
+ # @param [Integer] current_amount The tapyrus amount the tx already has in its inputs
74
+ # @param [Glueby::Contract::FeeEstimator] fee_estimator
75
+ # @return [Tapyrus::Tx] tx The tx that is added inputs
76
+ # @return [Integer] fee The final fee after the inputs are filled
77
+ # @return [Integer] current_amount The final amount of the tx inputs
78
+ # @return [Array<Hash>] provided_utxos The utxos that are added to the tx inputs
79
+ 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
97
+ end
98
+
99
+ [tx, fee, current_amount, provided_utxos]
100
+ end
101
+
66
102
  def default_value
67
103
  @default_value ||=
68
104
  (
@@ -110,16 +146,27 @@ module Glueby
110
146
  end
111
147
  end
112
148
 
113
- def collect_uncolored_outputs(wallet, amount)
114
- utxos = wallet.list_unspent.select { |o| !o[:color_id] && o[:amount] == default_value }
149
+ # Collects and returns TPC UTXOs.
150
+ # @param [Glueby::Internal::Wallet] wallet The wallet that funds the caller
151
+ # @param [Integer] amount The target amount which to be collected
152
+ # @param [Array<Hash>] excludes The exclusion UTXO list. It excludes this UTXOs from the targets that will be collected TPC UTXOs.
153
+ # @return [Integer] sum The sum amount of the funds
154
+ # @return [Array<Hash>] outputs The UTXO set of the funds
155
+ 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
115
161
  utxos.shuffle!
116
-
117
- utxos.inject([0, []]) do |sum, output|
118
- new_sum = sum[0] + output[:amount]
119
- new_outputs = sum[1] << output
120
- return [new_sum, new_outputs] if new_sum >= amount
121
-
122
- [new_sum, new_outputs]
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]
123
170
  end
124
171
  raise Glueby::Contract::Errors::InsufficientFunds
125
172
  end
@@ -1,3 +1,3 @@
1
1
  module Glueby
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -25,5 +25,12 @@ namespace :glueby do
25
25
  puts "success in synchronization (block height=#{height})"
26
26
  end
27
27
  end
28
+
29
+ desc 'Update the block height in Glueby::AR::SystemInformation and do not run Glueby::BlockSyncer. This task is intended to skip the synchronization process until the latest block height.'
30
+ task :update_height, [] => [:environment] do |_, _|
31
+ new_height = Glueby::Internal::RPC.client.getblockcount
32
+ synced_block = Glueby::AR::SystemInformation.synced_block_height
33
+ synced_block.update(info_value: new_height.to_s)
34
+ end
28
35
  end
29
36
  end
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.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-07 00:00:00.000000000 Z
11
+ date: 2023-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tapyrus
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.13
19
+ version: 0.3.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.13
26
+ version: 0.3.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mysql2
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rails
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -88,15 +102,16 @@ files:
88
102
  - glueby.gemspec
89
103
  - lib/generators/glueby/contract/block_syncer_generator.rb
90
104
  - lib/generators/glueby/contract/initializer_generator.rb
91
- - lib/generators/glueby/contract/reissuable_token_generator.rb
92
105
  - lib/generators/glueby/contract/templates/initializer.rb.erb
93
106
  - lib/generators/glueby/contract/templates/key_table.rb.erb
94
107
  - lib/generators/glueby/contract/templates/reissuable_token_table.rb.erb
95
108
  - lib/generators/glueby/contract/templates/system_information_table.rb.erb
96
109
  - lib/generators/glueby/contract/templates/timestamp_table.rb.erb
110
+ - lib/generators/glueby/contract/templates/token_metadata_table.rb.erb
97
111
  - lib/generators/glueby/contract/templates/utxo_table.rb.erb
98
112
  - lib/generators/glueby/contract/templates/wallet_table.rb.erb
99
113
  - lib/generators/glueby/contract/timestamp_generator.rb
114
+ - lib/generators/glueby/contract/token_generator.rb
100
115
  - lib/generators/glueby/contract/wallet_adapter_generator.rb
101
116
  - lib/glueby.rb
102
117
  - lib/glueby/active_record.rb
@@ -108,6 +123,7 @@ files:
108
123
  - lib/glueby/contract/active_record.rb
109
124
  - lib/glueby/contract/active_record/reissuable_token.rb
110
125
  - lib/glueby/contract/active_record/timestamp.rb
126
+ - lib/glueby/contract/active_record/token_metadata.rb
111
127
  - lib/glueby/contract/errors.rb
112
128
  - lib/glueby/contract/fee_estimator.rb
113
129
  - lib/glueby/contract/fee_estimator/auto.rb
@@ -136,8 +152,10 @@ files:
136
152
  - lib/glueby/internal/wallet/active_record_wallet_adapter.rb
137
153
  - lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb
138
154
  - lib/glueby/internal/wallet/errors.rb
155
+ - lib/glueby/internal/wallet/mysql_wallet_adapter.rb
139
156
  - lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb
140
157
  - lib/glueby/railtie.rb
158
+ - lib/glueby/util/digest.rb
141
159
  - lib/glueby/utxo_provider.rb
142
160
  - lib/glueby/utxo_provider/tasks.rb
143
161
  - lib/glueby/version.rb