peatio-dao 3.1.3

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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +30 -0
  3. data/.gitignore +16 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +148 -0
  6. data/.simplecov +17 -0
  7. data/.travis.yml +18 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +242 -0
  10. data/README.md +47 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/peatio +12 -0
  14. data/bin/setup +8 -0
  15. data/lib/peatio/adapter_registry.rb +25 -0
  16. data/lib/peatio/auth/error.rb +18 -0
  17. data/lib/peatio/auth/jwt_authenticator.rb +127 -0
  18. data/lib/peatio/block.rb +29 -0
  19. data/lib/peatio/blockchain/abstract.rb +161 -0
  20. data/lib/peatio/blockchain/error.rb +37 -0
  21. data/lib/peatio/blockchain/registry.rb +16 -0
  22. data/lib/peatio/command/base.rb +11 -0
  23. data/lib/peatio/command/db.rb +20 -0
  24. data/lib/peatio/command/inject.rb +13 -0
  25. data/lib/peatio/command/root.rb +14 -0
  26. data/lib/peatio/command/security.rb +29 -0
  27. data/lib/peatio/command/service.rb +40 -0
  28. data/lib/peatio/error.rb +18 -0
  29. data/lib/peatio/executor.rb +64 -0
  30. data/lib/peatio/injectors/peatio_events.rb +240 -0
  31. data/lib/peatio/logger.rb +39 -0
  32. data/lib/peatio/metrics/server.rb +15 -0
  33. data/lib/peatio/mq/client.rb +51 -0
  34. data/lib/peatio/ranger/connection.rb +117 -0
  35. data/lib/peatio/ranger/events.rb +11 -0
  36. data/lib/peatio/ranger/router.rb +234 -0
  37. data/lib/peatio/ranger/web_socket.rb +68 -0
  38. data/lib/peatio/security/key_generator.rb +26 -0
  39. data/lib/peatio/sql/client.rb +19 -0
  40. data/lib/peatio/sql/schema.rb +72 -0
  41. data/lib/peatio/transaction.rb +137 -0
  42. data/lib/peatio/upstream/base.rb +116 -0
  43. data/lib/peatio/upstream/registry.rb +14 -0
  44. data/lib/peatio/version.rb +3 -0
  45. data/lib/peatio/wallet/abstract.rb +189 -0
  46. data/lib/peatio/wallet/error.rb +37 -0
  47. data/lib/peatio/wallet/registry.rb +16 -0
  48. data/lib/peatio.rb +47 -0
  49. data/peatio-dao.gemspec +53 -0
  50. metadata +455 -0
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio::Ranger
4
+ def self.run(jwt_public_key, exchange_name, opts={})
5
+ host = opts[:ranger_host] || ENV["RANGER_HOST"] || "0.0.0.0"
6
+ port = opts[:ranger_port] || ENV["RANGER_PORT"] || "8081"
7
+
8
+ authenticator = Peatio::Auth::JWTAuthenticator.new(jwt_public_key)
9
+
10
+ logger = Peatio::Logger.logger
11
+ logger.info "Starting the server on port #{port}"
12
+
13
+ client = Peatio::MQ::Client.new
14
+ router = Peatio::Ranger::Router.new(opts[:registry])
15
+ client.subscribe(exchange_name, &router.method(:on_message))
16
+
17
+ if opts[:display_stats]
18
+ EM.add_periodic_timer(opts[:stats_period]) do
19
+ Peatio::Logger.logger.info { router.stats }
20
+ Peatio::Logger.logger.debug { router.debug }
21
+ end
22
+ end
23
+
24
+ EM::WebSocket.start(host: host, port: port, secure: false) do |socket|
25
+ connection = Peatio::Ranger::Connection.new(router, socket, logger)
26
+ socket.onopen do |hs|
27
+ connection.handshake(authenticator, hs)
28
+ router.on_connection_open(connection)
29
+ end
30
+
31
+ socket.onmessage do |msg|
32
+ connection.handle(msg)
33
+ end
34
+
35
+ socket.onping do |value|
36
+ logger.debug { "Received ping: #{value}" }
37
+ end
38
+
39
+ socket.onclose do
40
+ logger.debug { "Websocket connection closed" }
41
+ router.on_connection_close(connection)
42
+ end
43
+
44
+ socket.onerror do |e|
45
+ logger.error { "WebSocket Error: #{e.message}\n" + e.backtrace.join("\n") }
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.run!(jwt_public_key, exchange_name, opts={})
51
+ metrics_host = opts[:metrics_host] || ENV["METRICS_HOST"] || "0.0.0.0"
52
+ metrics_port = opts[:metrics_port] || ENV["METRICS_PORT"] || "8082"
53
+
54
+ EM.run do
55
+ run(jwt_public_key, exchange_name, opts)
56
+
57
+ if opts[:registry]
58
+ thin = Rack::Handler.get("thin")
59
+ thin.run(Peatio::Metrics::Server.app(opts[:registry]), Host: metrics_host, Port: metrics_port)
60
+ end
61
+
62
+ trap("INT") do
63
+ puts "\nSIGINT received, stopping ranger..."
64
+ EM.stop
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,26 @@
1
+ require 'fileutils'
2
+
3
+ module Peatio::Security
4
+ class KeyGenerator
5
+
6
+ attr_reader :public, :private
7
+
8
+ def initialize
9
+ OpenSSL::PKey::RSA.generate(2048).tap do |pkey|
10
+ @public = pkey.public_key.to_pem
11
+ @private = pkey.to_pem
12
+ end
13
+ end
14
+
15
+ def save(folder)
16
+ FileUtils.mkdir_p(folder) unless File.exist?(folder)
17
+
18
+ write(File.join(folder, 'rsa-key'), @private)
19
+ write(File.join(folder, 'rsa-key.pub'), @public)
20
+ end
21
+
22
+ def write(filename, text)
23
+ File.open(filename, 'w') { |file| file.write(text) }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module Peatio::Sql
2
+ class Client
3
+ attr_accessor :client, :config
4
+
5
+ def initialize
6
+ @config = {
7
+ host: ENV["DATABASE_HOST"] || "localhost",
8
+ username: ENV["DATABASE_USER"] || "root",
9
+ password: ENV["DATABASE_PASS"] || "",
10
+ port: ENV["DATABASE_PORT"] || "3306",
11
+ database: ENV["DATABASE_NAME"] || "peatio_development",
12
+ }
13
+ end
14
+
15
+ def connect
16
+ @client = Mysql2::Client.new(config)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,72 @@
1
+ module Peatio::Sql
2
+ class Schema
3
+ attr_accessor :client
4
+
5
+ def initialize(sql_client)
6
+ @client = sql_client
7
+ end
8
+
9
+ def create_database(name)
10
+ client.query("CREATE DATABASE IF NOT EXISTS `#{ name }`;")
11
+ end
12
+
13
+ def create_tables(options = {})
14
+ statements = []
15
+ statements << "DROP TABLE IF EXISTS `operations`;" if options[:drop_if_exists]
16
+ statements << <<-EOF
17
+ CREATE TABLE IF NOT EXISTS `operations` (
18
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT,
19
+ code TINYINT UNSIGNED NOT NULL,
20
+ account_id INT UNSIGNED NOT NULL,
21
+ reference INT UNSIGNED NOT NULL,
22
+ debit DECIMAL(32, 16) NOT NULL,
23
+ credit DECIMAL(32, 16) NOT NULL,
24
+ created_at DATETIME NOT NULL,
25
+ updated_at DATETIME NOT NULL,
26
+ PRIMARY KEY (id),
27
+ INDEX `balance_key` (account_id, debit, credit)
28
+ ) ENGINE = InnoDB;
29
+ EOF
30
+
31
+ statements << "DROP TABLE IF EXISTS `orders`;" if options[:drop_if_exists]
32
+ statements << <<EOF
33
+ CREATE TABLE IF NOT EXISTS`orders` (
34
+ `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
35
+ `uid` INT(11) UNSIGNED NOT NULL,
36
+ `bid` VARCHAR(5) NOT NULL,
37
+ `ask` VARCHAR(5) NOT NULL,
38
+ `market` VARCHAR(10) NOT NULL,
39
+ `price` DECIMAL(32,16) DEFAULT NULL,
40
+ `volume` DECIMAL(32,16) NOT NULL,
41
+ `fee` DECIMAL(32,16) NOT NULL DEFAULT '0.0000000000000000',
42
+ `type` TINYINT UNSIGNED NOT NULL,
43
+ `state` TINYINT UNSIGNED NOT NULL,
44
+ `created_at` DATETIME NOT NULL,
45
+ `updated_at` DATETIME NOT NULL,
46
+ PRIMARY KEY (`id`)
47
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
48
+ EOF
49
+
50
+ statements << "DROP TABLE IF EXISTS `trades`;" if options[:drop_if_exists]
51
+ statements << <<EOF
52
+ CREATE TABLE IF NOT EXISTS `trades` (
53
+ `id` int(11) NOT NULL AUTO_INCREMENT,
54
+ `market` varchar(10) NOT NULL,
55
+ `volume` decimal(32,16) NOT NULL,
56
+ `price` decimal(32,16) NOT NULL,
57
+ `ask_id` int(11) NOT NULL,
58
+ `bid_id` int(11) NOT NULL,
59
+ `ask_uid` int(11) NOT NULL,
60
+ `bid_uid` int(11) NOT NULL,
61
+ `created_at` datetime NOT NULL,
62
+ `updated_at` datetime NOT NULL,
63
+ PRIMARY KEY (`id`)
64
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
65
+ EOF
66
+ statements.each do |statement|
67
+ puts statement
68
+ client.query(statement)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,137 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/string/inquiry'
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'active_model'
5
+
6
+ module Peatio #:nodoc:
7
+
8
+ # This class represents blockchain transaction.
9
+ #
10
+ # Using the instant of this class the peatio application will send/recieve
11
+ # income/outcome transactions from a peatio pluggable blockchain.
12
+ #
13
+ # @example
14
+ #
15
+ # Peatio::Transaction.new(
16
+ # {
17
+ # hash: '0x5d0ef9697a2f3ea561c9fbefb48e380a4cf3d26ad2be253177c472fdd0e8b486',
18
+ # txout: 1,
19
+ # to_address: '0x9af4f143cd5ecfba0fcdd863c5ef52d5ccb4f3e5',
20
+ # amount: 0.01,
21
+ # fee: 0.0004,
22
+ # block_number: 7732274,
23
+ # currency_id: 'eth',
24
+ # fee_currency_id: 'eth',
25
+ # status: 'success'
26
+ # }
27
+ # )
28
+ #
29
+ # @author
30
+ # Maksym Naichuk <naichuk.maks@gmail.com> (https://github.com/mnaichuk)
31
+ class Transaction
32
+ include ActiveModel::Model
33
+
34
+ # List of statuses supported by peatio.
35
+ #
36
+ # @note Statuses list:
37
+ #
38
+ # pending - the transaction is unconfirmed in the blockchain or
39
+ # wasn't created yet.
40
+ #
41
+ # success - the transaction is a successfull,
42
+ # the transaction amount has been successfully transferred
43
+ #
44
+ # failed - the transaction is failed in the blockchain.
45
+ #
46
+ # rejected - the transaction is rejected by user.
47
+
48
+ STATUSES = %w[success pending failed rejected].freeze
49
+
50
+ DEFAULT_STATUS = 'pending'.freeze
51
+
52
+ # @!attribute [rw] hash
53
+ # return [String] transaction hash
54
+ attr_accessor :hash
55
+
56
+ # @!attribute [rw] txout
57
+ # return [Integer] transaction number in send-to-many request
58
+ attr_accessor :txout
59
+
60
+ # @!attribute [rw] from_address
61
+ # return [Array<String>] transaction source addresses
62
+ attr_accessor :from_addresses
63
+
64
+ # @!attribute [rw] to_address
65
+ # return [String] transaction recepient address
66
+ attr_accessor :to_address
67
+
68
+ # @!attribute [rw] amount
69
+ # return [Decimal] amount of the transaction
70
+ attr_accessor :amount
71
+
72
+ # @!attribute [rw] fee
73
+ # return [Decimal] fee of the transaction
74
+ attr_accessor :fee
75
+
76
+ # @!attribute [rw] block_number
77
+ # return [Integer] transaction block number
78
+ attr_accessor :block_number
79
+
80
+ # @!attribute [rw] currency_id
81
+ # return [String] transaction currency id
82
+ attr_accessor :currency_id
83
+
84
+ # @!attribute [rw] fee_currency_id
85
+ # return [String] transaction fee currency id
86
+ attr_accessor :fee_currency_id
87
+
88
+ # @!attribute [rw] options
89
+ # return [JSON] transaction options
90
+ attr_accessor :options
91
+
92
+ validates :to_address,
93
+ :amount,
94
+ :currency_id,
95
+ :status,
96
+ presence: true
97
+
98
+ validates :hash,
99
+ :block_number,
100
+ presence: { if: -> (t){ t.status.failed? || t.status.success? } }
101
+
102
+ validates :txout,
103
+ presence: { if: -> (t){ t.status.success? } }
104
+
105
+ validates :block_number,
106
+ numericality: { greater_than_or_equal_to: 0, only_integer: true }
107
+
108
+ validates :amount,
109
+ numericality: { greater_than_or_equal_to: 0 }
110
+
111
+ validates :fee,
112
+ numericality: { greater_than_or_equal_to: 0 }, allow_blank: true
113
+
114
+ validates :status, inclusion: { in: STATUSES }
115
+
116
+ def initialize(attributes={})
117
+ super
118
+ @status = @status.present? ? @status.to_s : DEFAULT_STATUS
119
+ end
120
+
121
+ # Status for specific transaction.
122
+ #
123
+ # @!method status
124
+ #
125
+ # @example
126
+ #
127
+ # status.failed? # true if transaction status 'failed'
128
+ # status.success? # true if transaction status 'success'
129
+ def status
130
+ @status&.inquiry
131
+ end
132
+
133
+ def status=(s)
134
+ @status = s.to_s
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio
4
+ module Upstream
5
+ class Base
6
+ DEFAULT_DELAY = 1
7
+ WEBSOCKET_CONNECTION_RETRY_DELAY = 2
8
+
9
+ attr_accessor :logger
10
+
11
+ def initialize(config)
12
+ @host = config["rest"]
13
+ @adapter = config[:faraday_adapter] || :em_synchrony
14
+ @config = config
15
+ @ws_status = false
16
+ @market = config['source']
17
+ @target = config['target']
18
+ @public_trades_cb = []
19
+ @logger = Peatio::Logger.logger
20
+ @peatio_mq = config['amqp']
21
+ mount
22
+ end
23
+
24
+ def mount
25
+ @public_trades_cb << method(:on_trade)
26
+ end
27
+
28
+ def ws_connect
29
+ logger.info { "Websocket connecting to #{@ws_url}" }
30
+ raise "websocket url missing for account #{id}" unless @ws_url
31
+
32
+ @ws = WebSocket::Client::Simple.connect @ws_url
33
+
34
+ @ws.on(:open) do |_e|
35
+ subscribe_trades(@target, @ws)
36
+ subscribe_orderbook(@target, @ws)
37
+ logger.info { "Websocket connected" }
38
+ end
39
+
40
+ @ws.on(:message) do |msg|
41
+ ws_read_message(msg)
42
+ end
43
+
44
+ @ws.on(:close) do |e|
45
+ @ws = nil
46
+ @ws_status = false
47
+ logger.error "Websocket disconnected: #{e.code} Reason: #{e.reason}"
48
+ Fiber.new do
49
+ EM::Synchrony.sleep(WEBSOCKET_CONNECTION_RETRY_DELAY)
50
+ ws_connect
51
+ end.resume
52
+ end
53
+ end
54
+
55
+ def ws_connect_public
56
+ ws_connect
57
+ end
58
+
59
+ def subscribe_trades(_market, _ws)
60
+ method_not_implemented
61
+ end
62
+
63
+ def subscribe_orderbook(_market, _ws)
64
+ method_not_implemented
65
+ end
66
+
67
+ def ws_read_public_message(msg)
68
+ logger.info { "received public message: #{msg}" }
69
+ end
70
+
71
+ def ws_read_message(msg)
72
+ logger.debug {"received websocket message: #{msg.data}" }
73
+
74
+ object = JSON.parse(msg.data)
75
+ ws_read_public_message(object)
76
+ end
77
+
78
+ def on_trade(trade)
79
+ logger.info { "Publishing trade event: #{trade.inspect}" }
80
+ @peatio_mq.enqueue_event("public", @market, "trades", {trades: [trade]})
81
+ @peatio_mq.publish :trade, trade_json(trade), {
82
+ headers: {
83
+ type: :upstream,
84
+ market: @market,
85
+ }
86
+ }
87
+ end
88
+
89
+ def trade_json(trade)
90
+ trade.deep_symbolize_keys!
91
+ {
92
+ id: trade[:tid],
93
+ price: trade[:price],
94
+ amount: trade[:amount],
95
+ market_id: @market,
96
+ created_at: Time.at(trade[:date]).utc.iso8601,
97
+ taker_type: trade[:taker_type]
98
+ }
99
+ end
100
+
101
+ def notify_public_trade(trade)
102
+ @public_trades_cb.each {|cb| cb&.call(trade) }
103
+ end
104
+
105
+ def to_s
106
+ "Exchange::#{self.class} config: #{@opts}"
107
+ end
108
+
109
+ def build_error(response)
110
+ JSON.parse(response.body)
111
+ rescue StandardError => e
112
+ "Code: #{response.env.status} Message: #{response.env.reason_phrase}"
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio
4
+ module Upstream
5
+ class << self
6
+ def registry
7
+ @registry ||= Registry.new
8
+ end
9
+
10
+ class Registry < Peatio::AdapterRegistry
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Peatio
2
+ VERSION = "3.1.3"
3
+ end
@@ -0,0 +1,189 @@
1
+ module Peatio
2
+ module Wallet
3
+ # @abstract Represents basic wallet interface.
4
+ #
5
+ # Subclass and override abstract methods to implement
6
+ # a peatio plugable wallet.
7
+ # Than you need to register your wallet implementation.
8
+ #
9
+ # @see Bitcoin::Wallet Bitcoin as example of Abstract imlementation.
10
+ #
11
+ # @example
12
+ #
13
+ # class MyWallet < Peatio::Abstract::Wallet
14
+ # def create_address(options = {})
15
+ # # do something
16
+ # end
17
+ # ...
18
+ # end
19
+ #
20
+ # # Register MyWallet as peatio plugable wallet.
21
+ # Peatio::Wallet.registry[:my_wallet] = MyWallet.new
22
+ #
23
+ # @author
24
+ # Yaroslav Savchuk <savchukyarpolk@gmail.com> (https://github.com/ysv)
25
+ class Abstract
26
+ # Current wallet settings for performing API calls.
27
+ #
28
+ # @abstract
29
+ #
30
+ # @!attribute [r] settings
31
+ # @return [Hash] current wallet settings.
32
+ attr_reader :settings
33
+
34
+ # List of configurable settings.
35
+ #
36
+ # @see #configure
37
+ SUPPORTED_SETTINGS = %i[wallet currency].freeze
38
+
39
+ # Hash of features supported by wallet.
40
+ #
41
+ # @abstract
42
+ #
43
+ # @see Abstract::SUPPORTED_FEATURES for list of features supported by peatio.
44
+ #
45
+ # @!attribute [r] features
46
+ # @return [Hash] list of features supported by wallet.
47
+ attr_reader :features
48
+
49
+ # List of features supported by peatio.
50
+ #
51
+ # @note Features list:
52
+ #
53
+ # skip_deposit_collection - defines if deposit will be collected to
54
+ # hot, warm, cold wallets.
55
+ SUPPORTED_FEATURES = %i[skip_deposit_collection].freeze
56
+
57
+ # Abstract constructor.
58
+ #
59
+ # @abstract
60
+ #
61
+ # @example
62
+ # class MyWallet< Peatio::Abstract::Wallet
63
+ #
64
+ # # You could customize your wallet by passing features.
65
+ # def initialize(my_custom_features = {})
66
+ # @features = my_custom_features
67
+ # end
68
+ # ...
69
+ # end
70
+ #
71
+ # # Register MyWallet as peatio plugable wallet.
72
+ # custom_features = {cash_addr_format: true}
73
+ # Peatio::Wallet.registry[:my_wallet] = MyWallet.new(custom_features)
74
+ def initialize(*)
75
+ abstract_method
76
+ end
77
+
78
+ # Merges given configuration parameters with defined during initialization
79
+ # and returns the result.
80
+ #
81
+ # @abstract
82
+ #
83
+ # @param [Hash] settings configurations to use.
84
+ # @option settings [Hash] :wallet Wallet settings for performing API calls.
85
+ # With :address required key other settings could be customized
86
+ # using Wallet#settings.
87
+ # @option settings [Array<Hash>] :currencies List of currency hashes
88
+ # with :id,:base_factor,:options(deprecated) keys.
89
+ # Custom keys could be added by defining them in Currency #options.
90
+ #
91
+ # @return [Hash] merged settings.
92
+ #
93
+ # @note Be careful with your wallet state after configure.
94
+ # Clean everything what could be related to other wallet configuration.
95
+ # E.g. client state.
96
+ def configure(settings = {})
97
+ abstract_method
98
+ end
99
+
100
+ # Performs API call for address creation and returns it.
101
+ #
102
+ # @abstract
103
+ #
104
+ # @param [Hash] options
105
+ # @options options [String] :uid User UID which requested address creation.
106
+ #
107
+ # @return [Hash] newly created blockchain address.
108
+ #
109
+ # @raise [Peatio::Blockchain::ClientError] if error was raised
110
+ # on wallet API call.
111
+ #
112
+ # @example
113
+ # { address: :fake_address,
114
+ # secret: :changeme,
115
+ # details: { uid: account.member.uid } }
116
+ def create_address!(options = {})
117
+ abstract_method
118
+ end
119
+
120
+ # Performs API call for creating transaction and returns updated transaction.
121
+ #
122
+ # @abstract
123
+ #
124
+ # @param [Peatio::Transaction] transaction transaction with defined
125
+ # to_address, amount & currency_id.
126
+ #
127
+ # @param [Hash] options
128
+ # @options options [String] :subtract_fee Defines if you need to subtract
129
+ # fee from amount defined in transaction.
130
+ # It means that you need to deduct fee from amount declared in
131
+ # transaction and send only remaining amount.
132
+ # If transaction amount is 1.0 and estimated fee
133
+ # for sending transaction is 0.01 you need to send 0.09
134
+ # so 1.0 (0.9 + 0.1) will be subtracted from wallet balance
135
+ #
136
+ # @options options [String] custon options for wallet client.
137
+ #
138
+ # @return [Peatio::Transaction] transaction with updated hash.
139
+ #
140
+ # @raise [Peatio::Blockchain::ClientError] if error was raised
141
+ # on wallet API call.
142
+ def create_transaction!(transaction, options = {})
143
+ abstract_method
144
+ end
145
+
146
+ # Fetches address balance of specific currency.
147
+ #
148
+ # @note Optional. Don't override this method if your blockchain
149
+ # doesn't provide functionality to get balance by address.
150
+ #
151
+ # @return [BigDecimal] the current address balance.
152
+ #
153
+ # @raise [Peatio::Blockchain::ClientError,Peatio::Blockchain::UnavailableAddressBalanceError]
154
+ # if error was raised on wallet API call ClientError is raised.
155
+ # if wallet API call was successful but we can't detect balance
156
+ # for address Error is raised.
157
+ def load_balance!
158
+ raise Peatio::Wallet::UnavailableAddressBalanceError
159
+ end
160
+
161
+ # Performs API call(s) for preparing for deposit collection.
162
+ # E.g deposits ETH for collecting ERC20 tokens in case of Ethereum blockchain.
163
+ #
164
+ # @note Optional. Override this method only if you need additional step
165
+ # before deposit collection.
166
+ #
167
+ # @param [Peatio::Transaction] deposit_transaction transaction which
168
+ # describes received deposit.
169
+ #
170
+ # @param [Array<Peatio::Transaction>] spread_transactions result of deposit
171
+ # spread between wallets.
172
+ #
173
+ # @return [Array<Peatio::Transaction>] transaction created for
174
+ # deposit collection preparing.
175
+ # By default return empty [Array]
176
+ def prepare_deposit_collection!(deposit_transaction, spread_transactions, deposit_currency)
177
+ # This method is mostly used for coins which needs additional fees
178
+ # to be deposited before deposit collection.
179
+ []
180
+ end
181
+
182
+ private
183
+
184
+ def abstract_method
185
+ method_not_implemented
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,37 @@
1
+ module Peatio
2
+ module Wallet
3
+ Error = Class.new(StandardError)
4
+
5
+ class ClientError < Error
6
+
7
+ attr_reader :wrapped_ex
8
+
9
+ def initialize(ex_or_string)
10
+ @wrapped_ex = nil
11
+
12
+ if ex_or_string.respond_to?(:backtrace)
13
+ super(ex_or_string.message)
14
+ @wrapped_exception = ex_or_string
15
+ else
16
+ super(ex_or_string.to_s)
17
+ end
18
+ end
19
+ end
20
+
21
+ class MissingSettingError < Error
22
+ def initialize(key)
23
+ super "#{key.capitalize} setting is missing"
24
+ end
25
+ end
26
+
27
+ class UnavailableAddressBalanceError < Error
28
+ def initialize(address)
29
+ @address = address
30
+ end
31
+
32
+ def message
33
+ "Unable to load #{@address} balance"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,16 @@
1
+ require "peatio/adapter_registry"
2
+
3
+ module Peatio
4
+ module Wallet
5
+
6
+ VERSION = "1.0.0".freeze
7
+
8
+ class << self
9
+ def registry
10
+ @registry ||= Registry.new
11
+ end
12
+ end
13
+ class Registry < Peatio::AdapterRegistry
14
+ end
15
+ end
16
+ end