glueby 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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