glueby 0.4.3 → 0.4.4

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.
@@ -1,165 +1,162 @@
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
-
121
- block.call(tx) if block
122
-
123
- wallet_adapter.broadcast(id, tx)
124
- tx
125
- end
126
-
127
- def receive_address(label = nil)
128
- wallet_adapter.receive_address(id, label)
129
- end
130
-
131
- def change_address
132
- wallet_adapter.change_address(id)
133
- end
134
-
135
- def create_pubkey
136
- wallet_adapter.create_pubkey(id)
137
- end
138
-
139
- def collect_uncolored_outputs(amount, label = nil, only_finalized = true)
140
- utxos = list_unspent(only_finalized, label)
141
-
142
- utxos.inject([0, []]) do |sum, output|
143
- next sum if output[:color_id]
144
-
145
- new_sum = sum[0] + output[:amount]
146
- new_outputs = sum[1] << output
147
- return [new_sum, new_outputs] if new_sum >= amount
148
-
149
- [new_sum, new_outputs]
150
- end
151
- raise Glueby::Contract::Errors::InsufficientFunds
152
- end
153
-
154
- def get_addresses(label = nil)
155
- wallet_adapter.get_addresses(id, label)
156
- end
157
-
158
- private
159
-
160
- def wallet_adapter
161
- self.class.wallet_adapter
162
- end
163
- end
164
- end
165
- 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 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,10 +1,10 @@
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
+ end
9
+ end
10
10
  end
@@ -1,3 +1,3 @@
1
- module Glueby
2
- VERSION = "0.4.3"
3
- end
1
+ module Glueby
2
+ VERSION = "0.4.4"
3
+ end
data/lib/glueby.rb CHANGED
@@ -1,39 +1,39 @@
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
+
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,29 +1,29 @@
1
- namespace :glueby do
2
- namespace :contract do
3
- namespace :block_syncer do
4
- desc '[Deprecated use glueby:block_syncer:start instead] sync block into database'
5
- task :start, [] => [:environment] do |_, _|
6
- puts '[Deprecated] glueby:contract:block_syncer:start is deprecated. Use \'glueby:block_syncer:start\''
7
- Rake::Task['glueby:block_syncer:start'].execute
8
- end
9
- end
10
- end
11
- end
12
-
13
-
14
- namespace :glueby do
15
- namespace :block_syncer do
16
- desc 'sync block into database'
17
- task :start, [] => [:environment] do |_, _|
18
- latest_block_num = Glueby::Internal::RPC.client.getblockcount
19
- synced_block = Glueby::AR::SystemInformation.synced_block_height
20
- (synced_block.int_value + 1..latest_block_num).each do |height|
21
- ::ActiveRecord::Base.transaction do
22
- Glueby::BlockSyncer.new(height).run
23
- synced_block.update(info_value: height.to_s)
24
- end
25
- puts "success in synchronization (block height=#{height})"
26
- end
27
- end
28
- end
1
+ namespace :glueby do
2
+ namespace :contract do
3
+ namespace :block_syncer do
4
+ desc '[Deprecated use glueby:block_syncer:start instead] sync block into database'
5
+ task :start, [] => [:environment] do |_, _|
6
+ puts '[Deprecated] glueby:contract:block_syncer:start is deprecated. Use \'glueby:block_syncer:start\''
7
+ Rake::Task['glueby:block_syncer:start'].execute
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+
14
+ namespace :glueby do
15
+ namespace :block_syncer do
16
+ desc 'sync block into database'
17
+ task :start, [] => [:environment] do |_, _|
18
+ latest_block_num = Glueby::Internal::RPC.client.getblockcount
19
+ synced_block = Glueby::AR::SystemInformation.synced_block_height
20
+ (synced_block.int_value + 1..latest_block_num).each do |height|
21
+ ::ActiveRecord::Base.transaction do
22
+ Glueby::BlockSyncer.new(height).run
23
+ synced_block.update(info_value: height.to_s)
24
+ end
25
+ puts "success in synchronization (block height=#{height})"
26
+ end
27
+ end
28
+ end
29
29
  end