cns 0.9.0 → 0.9.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fff5558da7a0b92a4511bf3f73b8330d3ad59d92d46c76b64a70bfd19e3dfd1e
4
- data.tar.gz: eafa8884b41f68f83fa20b547474c7a0717281f8c47d0a948805e9d0a7ae19f4
3
+ metadata.gz: 4bda8e993fc38693b8934e9b077c7eb1e7f2f005eeaa011d3495417d921b7479
4
+ data.tar.gz: e4e7bbe97475f2c4f9022073c36d5773040e985aaabf23054b6e7706b88a57d9
5
5
  SHA512:
6
- metadata.gz: 8409acef5de4ce834e309710521c44cfe35414e3ec6c3d11b8dce9173720414d828fb320c6865c693867bdac1bf14c41e8f6ac5ac5172dc11253ff77683cd307
7
- data.tar.gz: 072e66dc223d7c14c20248f25e2c5a72f5e918314881c60faf3b8377cb77d11534d9c5b6d0eaf8e2ab2c7966c4956414d3bfdf433b98e57eb3691fa0b46e78ac
6
+ metadata.gz: 103f27e4ee78a762d99947a8a7d8c7686fd4a47b9c280ee6c23855e48864731eb42960352f6c759adb6498b1dbae39592148875140f036e2a962bdc558499ff8
7
+ data.tar.gz: d93225bc64141c49ec230467c52a54e6e52619c6fa65eed618f19e781981ebfe9a7adbc4b7634179d6c0b4a72ec5c38fc00e410de46b2612f322e7f1f93c3080
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cns (0.9.0)
4
+ cns (0.9.1)
5
5
  curb
6
6
  faraday
7
7
  google-cloud-bigquery
data/lib/cns/apibc.rb CHANGED
@@ -7,12 +7,20 @@ require('json')
7
7
  module Cns
8
8
  # classe para acesso dados blockchains
9
9
  class Apibc
10
+ ESPS = 10_000
11
+ GMPS = 100
12
+
13
+ def initialize
14
+ @etherscan_conn = connection('https://api.etherscan.io')
15
+ @greymass_conn = connection('https://eos.greymass.com')
16
+ end
17
+
10
18
  # Get account balances for multiple ETH addresses
11
19
  # @param addresses [Array<String>] List of ETH addresses (max 20)
12
20
  # @return [Array<Hash>] List of addresses with balances
13
21
  def account_es(addresses)
14
22
  response = etherscan_req('balancemulti', addresses.join(','), 1, tag: 'latest')
15
- response.fetch(:status, '0') == '1' ? response.fetch(:result, []) : []
23
+ response[:status] == '1' ? response[:result] || [] : []
16
24
  end
17
25
 
18
26
  # Get normal transactions for ETH address
@@ -55,7 +63,7 @@ module Cns
55
63
  # @return [Hash] Account details with resources
56
64
  def account_gm(address)
57
65
  response = greymass_req('/v1/chain/get_account', account_name: address)
58
- response.dig(:core_liquid_balance).to_d > 0 ? response : gm_erro
66
+ response[:core_liquid_balance]&.to_d&.positive? ? response : gm_erro
59
67
  end
60
68
 
61
69
  # Get complete transaction history for EOS account
@@ -65,12 +73,12 @@ module Cns
65
73
  actions = []
66
74
  pos = 0
67
75
  loop do
68
- response = greymass_req('/v1/history/get_actions', account_name: address, pos: pos, offset: 100)
69
- batch = response.fetch(:actions, [])
70
- actions += batch
71
- break if batch.size < 100
76
+ response = greymass_req('/v1/history/get_actions', account_name: address, pos: pos, offset: GMPS)
77
+ batch = response[:actions] || []
78
+ actions.concat(batch)
79
+ break if batch.size < GMPS
72
80
 
73
- pos += 100
81
+ pos += GMPS
74
82
  end
75
83
  actions
76
84
  end
@@ -80,7 +88,10 @@ module Cns
80
88
  # Reusable Faraday connection
81
89
  def connection(base_url)
82
90
  Faraday.new(base_url) do |conn|
91
+ conn.request(:json) # Automatically encodes body as JSON
83
92
  conn.headers = { content_type: 'application/json', accept: 'application/json', user_agent: 'blockchain-api-client' }
93
+ conn.options.timeout = 30
94
+ conn.options.open_timeout = 10
84
95
  conn.adapter(Faraday.default_adapter)
85
96
  end
86
97
  end
@@ -88,7 +99,7 @@ module Cns
88
99
  # Generic Etherscan API request handler
89
100
  def etherscan_req(action, address, page = 1, params = {})
90
101
  params = { module: 'account', action: action, address: address, page: page, apikey: ENV.fetch('ETHERSCAN_API_KEY') }.merge(params)
91
- parse_json(connection('https://api.etherscan.io').get('/api', params))
102
+ parse_json(@etherscan_conn.get('/api', params))
92
103
  rescue Faraday::Error
93
104
  { status: '0' }
94
105
  end
@@ -103,11 +114,11 @@ module Cns
103
114
  page = 1
104
115
  loop do
105
116
  response = etherscan_req(action, address, page, params)
106
- break unless response.fetch(:status, '0') == '1'
117
+ break unless response[:status] == '1'
107
118
 
108
- batch = response.fetch(:result, [])
109
- results += batch
110
- break if batch.size < 10_000
119
+ batch = response[:result] || []
120
+ results.concat(batch)
121
+ break if batch.size < ESPS
111
122
 
112
123
  page += 1
113
124
  end
@@ -121,7 +132,7 @@ module Cns
121
132
 
122
133
  # Generic Greymass API request handler
123
134
  def greymass_req(endpoint, payload)
124
- parse_json((connection('https://eos.greymass.com').post(endpoint) { |req| req.body = payload.to_json }))
135
+ parse_json(@greymass_conn.post(endpoint) { |req| req.body = payload })
125
136
  rescue Faraday::Error
126
137
  gm_erro
127
138
  end
data/lib/cns/apice.rb CHANGED
@@ -11,133 +11,117 @@ module Cns
11
11
 
12
12
  # classe para acesso dados centralized exchanges
13
13
  class Apice
14
+ def initialize
15
+ @curl = Curl::Easy.new
16
+ @curl.timeout = 30
17
+ @curl.connect_timeout = 10
18
+ @curl.follow_location = true
19
+ @curl.ssl_verify_peer = true
20
+ end
21
+
14
22
  # @return [Hash] saldos no bitcoinde
15
23
  def account_de
16
24
  uri = "#{API[:de]}/account"
17
- parse_json(Curl.get(uri) { |obj| obj.headers = hde(uri) }).dig(:data, :balances) || {}
25
+ run_curl(@curl, uri, headers: hde(uri))
26
+ parse_json(@curl).dig(:data, :balances) || {}
18
27
  rescue Curl::Err::CurlError
19
28
  {}
20
29
  end
21
30
 
22
31
  # @return [Array<Hash>] trades bitcoinde
23
32
  def trades_de
24
- pag = 1
25
- ary = []
26
- loop do
27
- url = "#{API[:de]}/trades?#{URI.encode_www_form(state: 1, page: pag)}"
28
- data = parse_json(Curl.get(url) { |obj| obj.headers = hde(url) })
29
- ary += data.fetch(:trades, [])
30
- break if data[:page][:current] >= data[:page][:last]
31
-
32
- pag += 1
33
- end
34
- ary
33
+ pag_de_req("#{API[:de]}/trades", { state: 1 }, :trades)
35
34
  rescue Curl::Err::CurlError
36
- ary
35
+ []
37
36
  end
38
37
 
39
38
  # @return [Array<Hash>] depositos uniformizados bitcoinde
40
39
  def deposits_de
41
- pag = 1
42
- ary = []
43
- loop do
44
- url = "#{API[:de]}/btc/deposits?#{URI.encode_www_form(state: 2, page: pag)}"
45
- data = parse_json(Curl.get(url) { |obj| obj.headers = hde(url) })
46
- ary += data.fetch(:deposits, []).map { |has| deposit_unif(has) }
47
- break if data[:page][:current] >= data[:page][:last]
48
-
49
- pag += 1
50
- end
51
- ary
40
+ pag_de_req("#{API[:de]}/btc/deposits", { state: 2 }, :deposits) { |i| i.map { |h| deposit_unif(h) } }
52
41
  rescue Curl::Err::CurlError
53
- ary
54
- end
55
-
56
- # @return [Hash] deposito uniformizado bitcoinde
57
- def deposit_unif(has)
58
- { add: has[:address], time: Time.parse(has[:created_at]), qt: has[:amount], txid: Integer(has[:deposit_id]) }.merge(tp: 'deposit', moe: 'btc', fee: '0')
42
+ []
59
43
  end
60
44
 
61
45
  # @return [Array<Hash>] withdrawals uniformizadas bitcoinde
62
46
  def withdrawals_de
63
- ary = []
64
- pag = 1
65
- loop do
66
- url = "#{API[:de]}/btc/withdrawals?#{URI.encode_www_form(state: 1, page: pag)}"
67
- data = parse_json(Curl.get(url) { |obj| obj.headers = hde(url) })
68
- ary += data.fetch(:withdrawals, []).map { |has| withdrawal_unif(has) }
69
- break if data[:page][:current] >= data[:page][:last]
70
-
71
- pag += 1
72
- end
73
- ary
47
+ pag_de_req("#{API[:de]}/btc/withdrawals", { state: 1 }, :withdrawals) { |i| i.map { |h| withdrawal_unif(h) } }
74
48
  rescue Curl::Err::CurlError
75
- ary
76
- end
77
-
78
- # @return [Hash] withdrawal uniformizada bitcoinde
79
- def withdrawal_unif(has)
80
- {
81
- add: has[:address],
82
- time: Time.parse(has[:transferred_at]),
83
- qt: has[:amount],
84
- fee: has[:network_fee],
85
- txid: Integer(has[:withdrawal_id])
86
- }.merge(tp: 'withdrawal', moe: 'btc')
49
+ []
87
50
  end
88
51
 
89
52
  # @return [Hash] saldos kraken
90
53
  def account_us
91
54
  uri = 'Balance'
92
55
  ops = { nonce: nnc }
93
- parse_json(Curl.post("#{API[:us]}/#{uri}", ops) { |hed| hed.headers = hus(uri, ops) }).fetch(:result, {})
56
+ run_curl(@curl, "#{API[:us]}/#{uri}", method: :post, post_data: ops, headers: hus(uri, ops))
57
+ parse_json(@curl).fetch(:result, {})
94
58
  rescue Curl::Err::CurlError
95
59
  {}
96
60
  end
97
61
 
98
62
  # @return [Hash] trades kraken
99
63
  def trades_us
100
- uri = 'TradesHistory'
101
- has = {}
102
- ofs = 0
103
- loop do
104
- sleep(1)
105
- ops = { nonce: nnc, ofs: ofs }
106
- result = parse_json(Curl.post("#{API[:us]}/#{uri}", ops) { |hed| hed.headers = hus(uri, ops) }).fetch(:result, {})
107
- break if result.fetch(:trades, []).empty?
108
-
109
- has.merge!(result[:trades])
110
- ofs += result[:trades].size
111
- end
112
- has
64
+ pag_us_req('TradesHistory', :trades)
113
65
  rescue Curl::Err::CurlError
114
- has
66
+ {}
115
67
  end
116
68
 
117
69
  # @return [Hash] ledger kraken
118
70
  def ledger_us
119
- uri = 'Ledgers'
71
+ pag_us_req('Ledgers', :ledger)
72
+ rescue Curl::Err::CurlError
73
+ {}
74
+ end
75
+
76
+ private
77
+
78
+ # Generic paginated request handler for Kraken
79
+ def pag_us_req(uri, key)
120
80
  has = {}
121
81
  ofs = 0
122
82
  loop do
123
- sleep(2)
83
+ sleep(ofs.zero? ? 0 : 2)
124
84
  ops = { nonce: nnc, ofs: ofs }
125
- result = parse_json(Curl.post("#{API[:us]}/#{uri}", ops) { |hed| hed.headers = hus(uri, ops) }).fetch(:result, {})
126
- break if result.fetch(:ledger, []).empty?
85
+ run_curl(@curl, "#{API[:us]}/#{uri}", method: :post, post_data: ops, headers: hus(uri, ops))
86
+ batch = parse_json(@curl).fetch(:result, {}).fetch(key, [])
87
+ break if batch.empty?
127
88
 
128
- has.merge!(result[:ledger])
129
- ofs += result[:ledger].size
89
+ has.merge!(batch)
90
+ ofs += batch.size
130
91
  end
131
92
  has
132
- rescue Curl::Err::CurlError
133
- has
134
93
  end
135
94
 
136
- private
95
+ # Generic paginated request handler for Bitcoin.de
96
+ def pag_de_req(base_url, params, key)
97
+ ary = []
98
+ pag = 1
99
+ loop do
100
+ url = "#{base_url}?#{URI.encode_www_form(params.merge(page: pag))}"
101
+ run_curl(@curl, url, headers: hde(url))
102
+ result = parse_json(@curl)
103
+ batch = result.fetch(key, [])
104
+ ary.concat(block_given? ? yield(batch) : batch)
105
+ break if result[:page]&.[](:current)&.>= result[:page]&.[](:last)
106
+
107
+ pag += 1
108
+ end
109
+ ary
110
+ end
111
+
112
+ # Configure Curl object for request
113
+ def run_curl(curl, url, method: :get, post_data: nil, headers: {})
114
+ curl.reset
115
+ curl.url = url
116
+ curl.http(method == :post ? 'POST' : 'GET')
117
+ curl.headers = headers
118
+ curl.post_body = URI.encode_www_form(post_data) if post_data
119
+ curl.perform
120
+ end
137
121
 
138
122
  # Safe JSON parsing with error handling
139
123
  def parse_json(res)
140
- JSON.parse(res.body, symbolize_names: true) || {}
124
+ JSON.parse(res.body_str, symbolize_names: true)
141
125
  rescue JSON::ParserError
142
126
  {}
143
127
  end
@@ -147,6 +131,24 @@ module Cns
147
131
  Integer(Float(Time.now) * 1e6)
148
132
  end
149
133
 
134
+ # @return [Hash] deposito uniformizado bitcoinde
135
+ def deposit_unif(has)
136
+ { add: has[:address], time: Time.parse(has[:created_at]), qt: has[:amount], txid: Integer(has[:deposit_id]) }.merge(tp: 'deposit', moe: 'btc', fee: '0')
137
+ end
138
+
139
+ # @return [Hash] withdrawal uniformizada bitcoinde
140
+ def withdrawal_unif(has)
141
+ {
142
+ add: has[:address],
143
+ time: Time.parse(has[:transferred_at]),
144
+ qt: has[:amount],
145
+ fee: has[:network_fee],
146
+ txid: Integer(has[:withdrawal_id]),
147
+ tp: 'withdrawal',
148
+ moe: 'btc'
149
+ }
150
+ end
151
+
150
152
  # @param [String] qde query a incluir no pedido HTTP
151
153
  # @param [Integer] non continually-increasing unsigned integer
152
154
  # @return [Hash] headers necessarios para pedido HTTP da exchange bitcoinde
data/lib/cns/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cns
4
- VERSION = '0.9.0'
4
+ VERSION = '0.9.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hernâni Rodrigues Vaz