cns 0.9.4 → 0.9.5

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: d70ccf3bf3c61dccaf39f5fe5e34b3f629efd8182fbd036f1d1193e2e0d842e4
4
- data.tar.gz: 969e4c7d275aa2b14a6e9b1324e007b84d9f61522b099fdbb6c6d8a9bc129708
3
+ metadata.gz: 5e6f05fc2c2fc0c7c1e34cda63d18338f37db37957be5f1af27c60041cd761b5
4
+ data.tar.gz: bab915764960144e4b713348958b173524f81ba42eb53d2d0df1242c2721d194
5
5
  SHA512:
6
- metadata.gz: c406b44bacdf24f32dc6babc0c08d51cf5fe4f88724466e1af7d8770b08ae23da74c8811cc9f0bea0bdb11cf13ffb9fe3d8080de2626f8f3a0d6f22739e1e82f
7
- data.tar.gz: 47e0b4e735ac2c3b11a11018ac5a9830ec1cf24c253b4cb7ab0b353bc2c262f55c572938668ccd00618bf367b5d1019381a30037789fecf13dd2a3b5e5a698b9
6
+ metadata.gz: 78336dc2f0cc71f52a0fffcdc0a520e62fb8b77bee5173a18c21de958f0f17df2a7042d21a344a324b1cc3861bab978b6e3a66b96aba66981bd147571e8a5fdc
7
+ data.tar.gz: cd747260647643fc61a7ac298a716489df77f71a130571f3360efe5a4268a7e27644150b6c7649d395fd900777439e78d98892a315c5423ba4fd8649eb3c2fd1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cns (0.9.4)
4
+ cns (0.9.5)
5
5
  curb
6
6
  faraday
7
7
  google-cloud-bigquery
data/lib/cns/apibc.rb CHANGED
@@ -7,141 +7,156 @@ require('json')
7
7
  module Cns
8
8
  # classe para acesso dados blockchains
9
9
  class Apibc
10
- ESPS = 10_000
11
- GMPS = 100
10
+ ESPS = 10_000 # Etherscan maximum records per page
11
+ GMPS = 100 # Greymass maximum actions per request
12
12
 
13
13
  def initialize
14
- @etherscan_conn = connection('https://api.etherscan.io')
15
- @greymass_conn = connection('https://eos.greymass.com')
14
+ @escn = connection('https://api.etherscan.io')
15
+ @gmcn = connection('https://eos.greymass.com')
16
+ @esky = ENV.fetch('ETHERSCAN_API_KEY', nil)
16
17
  end
17
18
 
18
19
  # Get account balances for multiple ETH addresses
19
- # @param addresses [Array<String>] List of ETH addresses (max 20)
20
+ # @param [Array<String>] addresses List of ETH addresses (max 20)
20
21
  # @return [Array<Hash>] List of addresses with balances
21
22
  def account_es(addresses)
22
- response = etherscan_req('balancemulti', addresses.join(','), 1, tag: 'latest')
23
- response[:status] == '1' ? response[:result] || [] : []
23
+ res = es_req('balancemulti', addresses.join(','), 1, tag: 'latest')
24
+ res[:status] == '1' ? res[:result] || [] : []
24
25
  end
25
26
 
26
27
  # Get normal transactions for ETH address
27
28
  # @param [String] address endereco ETH
28
29
  # @return [Array<Hash>] lista transacoes normais etherscan
29
30
  def norml_es(address)
30
- pag_etherscan_req('txlist', address)
31
+ pag_es_req('txlist', address)
31
32
  end
32
33
 
33
34
  # Get internal transactions for ETH address
34
35
  # @param (see norml_es)
35
36
  # @return [Array<Hash>] lista transacoes internas etherscan
36
37
  def inter_es(address)
37
- pag_etherscan_req('txlistinternal', address)
38
+ pag_es_req('txlistinternal', address)
38
39
  end
39
40
 
40
41
  # Get mined blocks for ETH address
41
42
  # @param (see norml_es)
42
43
  # @return [Array<Hash>] lista blocos etherscan
43
44
  def block_es(address)
44
- pag_etherscan_req('getminedblocks', address, blocktype: 'blocks')
45
+ pag_es_req('getminedblocks', address, blocktype: 'blocks')
45
46
  end
46
47
 
47
48
  # Get withdrawals for ETH address
48
49
  # @param (see norml_es)
49
50
  # @return [Array<Hash>] lista blocos etherscan
50
51
  def withw_es(address)
51
- pag_etherscan_req('txsBeaconWithdrawal', address)
52
+ pag_es_req('txsBeaconWithdrawal', address)
52
53
  end
53
54
 
54
55
  # Get token transfers for ETH address
55
56
  # @param (see norml_es)
56
57
  # @return [Array<Hash>] lista token transfer events etherscan
57
58
  def token_es(address)
58
- pag_etherscan_req('tokentx', address)
59
+ pag_es_req('tokentx', address)
59
60
  end
60
61
 
61
62
  # Get EOS account information
62
- # @param address [String] EOS account name
63
+ # @param [String] address EOS account name
63
64
  # @return [Hash] Account details with resources
64
65
  def account_gm(address)
65
- response = greymass_req('/v1/chain/get_account', account_name: address)
66
- response[:core_liquid_balance]&.to_d&.positive? ? response : gm_erro
66
+ res = gm_req('/v1/chain/get_account', account_name: address)
67
+ res[:core_liquid_balance]&.to_d&.positive? ? res : gm_erro
67
68
  end
68
69
 
69
70
  # Get complete transaction history for EOS account
70
71
  # @param (see account_gm)
71
72
  # @return [Array<Hash>] lista completa transacoes greymass
72
73
  def ledger_gm(address)
73
- actions = []
74
+ trx = []
74
75
  pos = 0
75
76
  loop do
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
77
+ res = gm_req('/v1/history/get_actions', account_name: address, pos: pos, offset: GMPS)
78
+ bth = res[:actions] || []
79
+ trx.concat(bth)
80
+ break if bth.size < GMPS
80
81
 
81
82
  pos += GMPS
82
83
  end
83
- actions
84
+ trx
84
85
  end
85
86
 
86
87
  private
87
88
 
88
- # Reusable Faraday connection
89
- def connection(base_url)
90
- Faraday.new(base_url) do |conn|
91
- conn.request(:json) # Automatically encodes body as JSON
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
95
- conn.adapter(Faraday.default_adapter)
96
- end
97
- end
98
-
99
- # Generic Etherscan API request handler
100
- def etherscan_req(action, address, page = 1, params = {})
101
- params = {module: 'account', action: action, address: address, page: page, apikey: ENV.fetch('ETHERSCAN_API_KEY')}.merge(params)
102
- parse_json(@etherscan_conn.get('/api', params))
89
+ # Make a request to the Etherscan API
90
+ # @param [String] act API action name
91
+ # @param [String] add Blockchain address
92
+ # @param [Integer] pag Page number for pagination
93
+ # @param [Hash] prm Additional request parameters
94
+ # @return [Hash] Parsed API response
95
+ def es_req(act, add, pag = 1, prm = {})
96
+ prm = {module: 'account', action: act, address: add, page: pag, apikey: @esky}.merge(prm)
97
+ parse_json(@escn.get('/api', prm))
103
98
  rescue Faraday::Error
104
99
  {status: '0'}
105
100
  end
106
101
 
107
- # Generic method for paginated Etherscan requests
108
- # @param action [String] API action name
109
- # @param address [String] Blockchain address
110
- # @param params [Hash] Additional request parameters
102
+ # Fetch paginated results from Etherscan
103
+ # @param act [String] API action name
104
+ # @param add [String] Blockchain address
105
+ # @param prm [Hash] Additional request parameters
111
106
  # @return [Array<Hash>] Combined results from all pages
112
- def pag_etherscan_req(action, address, params = {})
113
- results = []
114
- page = 1
107
+ def pag_es_req(act, add, prm = {})
108
+ prm = prm.merge(offset: ESPS)
109
+ trx = []
110
+ pag = 1
115
111
  loop do
116
- response = etherscan_req(action, address, page, params)
117
- break unless response[:status] == '1'
112
+ res = es_req(act, add, pag, prm)
113
+ break unless res[:status] == '1'
118
114
 
119
- batch = response[:result] || []
120
- results.concat(batch)
121
- break if batch.size < ESPS
115
+ bth = res[:result] || []
116
+ trx.concat(bth)
117
+ break if bth.size < ESPS
122
118
 
123
- page += 1
119
+ pag += 1
124
120
  end
125
- results
126
- end
127
-
128
- # Generic Greymass API error
129
- def gm_erro
130
- {core_liquid_balance: 0, total_resources: {net_weight: 0, cpu_weight: 0}}
121
+ trx
131
122
  end
132
123
 
133
- # Generic Greymass API request handler
134
- def greymass_req(endpoint, payload)
135
- parse_json(@greymass_conn.post(endpoint) { |req| req.body = payload })
124
+ # Make a request to the Greymass API
125
+ # @param [String] url API endpoint
126
+ # @param [Hash] pyl Request payload
127
+ # @return [Hash] Parsed API response
128
+ def gm_req(url, pyl)
129
+ parse_json(@gmcn.post(url) { |r| r.body = pyl })
136
130
  rescue Faraday::Error
137
131
  gm_erro
138
132
  end
139
133
 
140
- # Safe JSON parsing with error handling
134
+ # Default error response for Greymass API
135
+ # @return [Hash] Error response with zeroed values
136
+ def gm_erro
137
+ {core_liquid_balance: 0, total_resources: {net_weight: 0, cpu_weight: 0}}
138
+ end
139
+
140
+ # Safely parse JSON response
141
+ # @param [Faraday::Response] res API response
142
+ # @return [Hash] Parsed JSON or empty hash on error
141
143
  def parse_json(res)
142
144
  JSON.parse(res.body, symbolize_names: true) || {}
143
145
  rescue JSON::ParserError
144
146
  {}
145
147
  end
148
+
149
+ # Create a Faraday connection with JSON configuration
150
+ # @param [String] url Base URL for the API
151
+ # @return [Faraday::Connection] Configured Faraday connection
152
+ def connection(url)
153
+ Faraday.new(url) do |conn|
154
+ conn.request(:json)
155
+ conn.headers = {accept: 'application/json', user_agent: 'blockchain-api-client'}
156
+ conn.options.timeout = 30
157
+ conn.options.open_timeout = 10
158
+ conn.adapter(Faraday.default_adapter)
159
+ end
160
+ end
146
161
  end
147
162
  end
data/lib/cns/apice.rb CHANGED
@@ -17,8 +17,13 @@ module Cns
17
17
  @curl.connect_timeout = 10
18
18
  @curl.follow_location = true
19
19
  @curl.ssl_verify_peer = true
20
+ @deky = ENV.fetch('BITCOINDE_API_KEY', nil)
21
+ @desc = ENV.fetch('BITCOINDE_API_SECRET', nil)
22
+ @usky = ENV.fetch('KRAKEN_API_KEY', nil)
23
+ @ussc = ENV.fetch('KRAKEN_API_SECRET', nil)
20
24
  end
21
25
 
26
+ # Get account balances from Bitcoin.de
22
27
  # @return [Hash] saldos no bitcoinde
23
28
  def account_de
24
29
  uri = "#{API[:de]}/account"
@@ -28,6 +33,7 @@ module Cns
28
33
  {}
29
34
  end
30
35
 
36
+ # Get trades from Bitcoin.de
31
37
  # @return [Array<Hash>] trades bitcoinde
32
38
  def trades_de
33
39
  pag_de_req("#{API[:de]}/trades", {state: 1}, :trades)
@@ -35,6 +41,7 @@ module Cns
35
41
  []
36
42
  end
37
43
 
44
+ # Get deposits from Bitcoin.de, uniformly formatted
38
45
  # @return [Array<Hash>] depositos uniformizados bitcoinde
39
46
  def deposits_de
40
47
  pag_de_req("#{API[:de]}/btc/deposits", {state: 2}, :deposits) { |i| i.map { |h| deposit_unif(h) } }
@@ -42,6 +49,7 @@ module Cns
42
49
  []
43
50
  end
44
51
 
52
+ # Get withdrawals from Bitcoin.de, uniformly formatted
45
53
  # @return [Array<Hash>] withdrawals uniformizadas bitcoinde
46
54
  def withdrawals_de
47
55
  pag_de_req("#{API[:de]}/btc/withdrawals", {state: 1}, :withdrawals) { |i| i.map { |h| withdrawal_unif(h) } }
@@ -49,60 +57,83 @@ module Cns
49
57
  []
50
58
  end
51
59
 
60
+ # Get account balances from Kraken
52
61
  # @return [Hash] saldos kraken
53
62
  def account_us
54
63
  uri = 'Balance'
55
64
  ops = {nonce: nnc}
56
- run_curl(@curl, "#{API[:us]}/#{uri}", method: :post, post_data: ops, headers: hus(uri, ops))
65
+ run_curl(@curl, "#{API[:us]}/#{uri}", method: 'POST', post_data: ops, headers: hus(uri, ops))
57
66
  parse_json(@curl).fetch(:result, {})
58
67
  rescue Curl::Err::CurlError
59
68
  {}
60
69
  end
61
70
 
71
+ # Get trades from Kraken
62
72
  # @return [Hash] trades kraken
63
73
  def trades_us
64
74
  pag_us_req('TradesHistory', :trades)
65
75
  rescue Curl::Err::CurlError
66
- {}
76
+ []
67
77
  end
68
78
 
79
+ # Get ledger from Kraken
69
80
  # @return [Hash] ledger kraken
70
81
  def ledger_us
71
82
  pag_us_req('Ledgers', :ledger)
72
83
  rescue Curl::Err::CurlError
73
- {}
84
+ []
74
85
  end
75
86
 
76
87
  private
77
88
 
89
+ # Uniformly format transacao kraken
90
+ # @param [Symbol] key id da transacao
91
+ # @param [Hash] trx transacao
92
+ # @return [Hash] transacao uniformizada
93
+ def us_unif(key, trx)
94
+ t = Integer(trx[:time])
95
+ trx.merge(txid: key.to_s, srx: t, time: Time.at(t))
96
+ rescue StandardError
97
+ {}
98
+ end
99
+
78
100
  # Generic paginated request handler for Kraken
101
+ # @param [String] uri API endpoint URI
102
+ # @param [Symbol] key Key to extract from the result
103
+ # @yield [Array<Hash>] Block to process each batch of results
104
+ # @return [Array<Hash>] Combined results from all pages
79
105
  def pag_us_req(uri, key)
80
- has = {}
106
+ ary = []
81
107
  ofs = 0
82
108
  loop do
83
109
  sleep(ofs.zero? ? 0 : 2)
84
110
  ops = {nonce: nnc, ofs: ofs}
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?
111
+ run_curl(@curl, "#{API[:us]}/#{uri}", method: 'POST', post_data: ops, headers: hus(uri, ops))
112
+ bth = parse_json(@curl).fetch(:result, {}).fetch(key, []).map { |k, v| us_unif(k, v) }
113
+ break if bth.empty?
88
114
 
89
- has.merge!(batch)
90
- ofs += batch.size
115
+ ary.concat(bth)
116
+ ofs += bth.size
91
117
  end
92
- has
118
+ ary
93
119
  end
94
120
 
95
121
  # Generic paginated request handler for Bitcoin.de
96
- def pag_de_req(base_url, params, key)
122
+ # @param [String] uri Base URL for the API request
123
+ # @param [Hash] prm Additional parameters for the request
124
+ # @param [Symbol] key Key to extract from the result
125
+ # @yield [Array<Hash>] Optional block to process each batch of results
126
+ # @return [Array<Hash>] Combined results from all pages
127
+ def pag_de_req(uri, prm, key)
97
128
  ary = []
98
129
  pag = 1
99
130
  loop do
100
- url = "#{base_url}?#{URI.encode_www_form(params.merge(page: pag))}"
131
+ url = "#{uri}?#{URI.encode_www_form(prm.merge(page: pag))}"
101
132
  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)
133
+ res = parse_json(@curl)
134
+ bth = res.fetch(key, [])
135
+ ary.concat(block_given? ? yield(bth) : bth)
136
+ break if res[:page]&.[](:current)&.>= res[:page]&.[](:last)
106
137
 
107
138
  pag += 1
108
139
  end
@@ -110,64 +141,76 @@ module Cns
110
141
  end
111
142
 
112
143
  # Configure Curl object for request
113
- def run_curl(curl, url, method: :get, post_data: nil, headers: {})
144
+ # @param [Curl::Easy] curl Curl object to configure
145
+ # @param [String] url URL for the request
146
+ # @param [String] method HTTP method (GET or POST)
147
+ # @param [Hash] post_data Data to send in POST requests
148
+ # @param [Hash] headers HTTP headers for the request
149
+ def run_curl(curl, url, method: 'GET', post_data: nil, headers: {})
114
150
  curl.reset
115
151
  curl.url = url
116
- curl.http(method == :post ? 'POST' : 'GET')
152
+ curl.http(method)
117
153
  curl.headers = headers
118
154
  curl.post_body = URI.encode_www_form(post_data) if post_data
119
155
  curl.perform
120
156
  end
121
157
 
122
158
  # Safe JSON parsing with error handling
159
+ # @param [Curl::Easy] res Curl response object
160
+ # @return [Hash] Parsed JSON or empty hash on error
123
161
  def parse_json(res)
124
162
  JSON.parse(res.body_str, symbolize_names: true)
125
163
  rescue JSON::ParserError
126
164
  {}
127
165
  end
128
166
 
129
- # @return [Integer] continually-increasing unsigned integer nonce from the current Unix Time
167
+ # Generate a continually-increasing unsigned integer nonce from the current Unix Time
168
+ # @return [Integer] Nonce value
130
169
  def nnc
131
170
  Integer(Float(Time.now) * 1e6)
132
171
  end
133
172
 
173
+ # Uniformly format a deposit from Bitcoin.de
174
+ # @param [Hash] has Deposit data from Bitcoin.de
134
175
  # @return [Hash] deposito uniformizado bitcoinde
135
176
  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')
177
+ {add: has[:address], time: Time.parse(has[:created_at]), qtd: has[:amount].to_d, nxid: Integer(has[:deposit_id])}.merge(tp: 'deposit', moe: 'BTC', fee: 0.to_d)
137
178
  end
138
179
 
180
+ # Uniformly format a withdrawal from Bitcoin.de
181
+ # @param [Hash] has Withdrawal data from Bitcoin.de
139
182
  # @return [Hash] withdrawal uniformizada bitcoinde
140
183
  def withdrawal_unif(has)
141
184
  {
142
185
  add: has[:address],
143
186
  time: Time.parse(has[:transferred_at]),
144
- qt: has[:amount],
145
- fee: has[:network_fee],
146
- txid: Integer(has[:withdrawal_id]),
187
+ qtd: -1 * has[:amount].to_d,
188
+ fee: has[:network_fee].to_d,
189
+ nxid: Integer(has[:withdrawal_id]),
147
190
  tp: 'withdrawal',
148
- moe: 'btc'
191
+ moe: 'BTC'
149
192
  }
150
193
  end
151
194
 
152
- # @param [String] qde query a incluir no pedido HTTP
153
- # @param [Integer] non continually-increasing unsigned integer
154
- # @return [Hash] headers necessarios para pedido HTTP da exchange bitcoinde
195
+ # Generate headers for Bitcoin.de HTTP requests
196
+ # @param [String] qde Query string to include in the HTTP request
197
+ # @param [Integer] non Nonce value (default: generated from nnc)
198
+ # @return [Hash] Headers required for Bitcoin.de HTTP requests
155
199
  def hde(qde, non = nnc)
156
- key = ENV.fetch('BITCOINDE_API_KEY', nil)
157
- md5 = ['GET', qde, key, non, Digest::MD5.hexdigest('')].join('#')
158
- mac = OpenSSL::HMAC.hexdigest('sha256', ENV.fetch('BITCOINDE_API_SECRET', nil), md5)
159
- {'X-API-KEY': key, 'X-API-NONCE': non, 'X-API-SIGNATURE': mac}
200
+ md5 = ['GET', qde, @deky, non, Digest::MD5.hexdigest('')].join('#')
201
+ mac = OpenSSL::HMAC.hexdigest('sha256', @desc, md5)
202
+ {'X-API-KEY' => @deky, 'X-API-NONCE' => non.to_s, 'X-API-SIGNATURE' => mac}
160
203
  end
161
204
 
205
+ # Generate headers for Kraken HTTP requests
162
206
  # @param [String] qus query a incluir no pedido HTTP
163
207
  # @param [Hash] ops opcoes trabalho
164
208
  # @option ops [Hash] :nonce continually-increasing unsigned integer
165
- # @return [Hash] headers necessarios para pedido HTTP da exchange kraken
209
+ # @return [Hash] Headers required for Kraken HTTP requests
166
210
  def hus(qus, ops)
167
- key = ENV.fetch('KRAKEN_API_KEY', nil)
168
211
  sha = ['/0/private/', qus, Digest::SHA256.digest("#{ops[:nonce]}#{URI.encode_www_form(ops)}")].join
169
- mac = OpenSSL::HMAC.digest('sha512', Base64.decode64(ENV.fetch('KRAKEN_API_SECRET', nil)), sha)
170
- {'api-key': key, 'api-sign': Base64.strict_encode64(mac)}
212
+ mac = OpenSSL::HMAC.digest('sha512', Base64.decode64(@ussc), sha)
213
+ {'api-key' => @usky, 'api-sign' => Base64.strict_encode64(mac)}
171
214
  end
172
215
  end
173
216
  end
data/lib/cns/bigquery.rb CHANGED
@@ -44,6 +44,7 @@ module Cns
44
44
  usl: '', # ' limit 448',
45
45
  det: '', # ' limit 27',
46
46
  del: '' # ' limit 16'
47
+
47
48
  }
48
49
 
49
50
  # classe para processar bigquery
@@ -223,7 +224,7 @@ module Cns
223
224
  novx = src.send("nov#{i}")
224
225
  next if novx.empty?
225
226
 
226
- format(' %<n>i %<t>s', n: dml(ins_sql(i, %i[cust cusl].include?(i) ? novx.values : novx)), t: "#{i}")
227
+ format(' %<n>i %<t>s', n: dml(ins_sql(i, novx)), t: "#{i}")
227
228
  end
228
229
  )
229
230
  str.join
@@ -330,7 +331,7 @@ module Cns
330
331
  # @param [Hash] htx trades kraken
331
332
  # @return [String] valores formatados cust
332
333
  def cust_val(htx)
333
- fvals(htx.merge(ledgers: apius.uskl.select { |_, o| o[:refid] == htx[:txid] }.keys.join(',')), TB[:hust], :txid)
334
+ fvals(htx.merge(ledgers: apius.uskl.select { |o| o[:refid] == htx[:txid] }.map { |t| t[:txid] }.join(',')), TB[:hust], :txid)
334
335
  end
335
336
 
336
337
  # @param [Hash] htx ledger kraken
data/lib/cns/bitcoinde.rb CHANGED
@@ -100,7 +100,7 @@ module Cns
100
100
  def fol(hlx)
101
101
  format(
102
102
  '%<ky>6i %<dt>19.19s %<ty>-10.10s %<mo>-3.3s %<pr>19.8f %<vl>18.8f',
103
- ky: hlx[:txid],
103
+ ky: hlx[:nxid],
104
104
  dt: hlx[:time].strftime('%F %T'),
105
105
  ty: hlx[:tp],
106
106
  mo: hlx[:moe],
@@ -150,7 +150,7 @@ module Cns
150
150
  # @param [Array<Hash>] hlx ledger bitcoinde
151
151
  # @return [Array<Hash>] transaccao filtrada
152
152
  def pdel(hlx)
153
- hlx.map { |t| pdes(:time, t).merge(qtd: (t[:tp] == 'withdrawal' ? -1 : 1) * t[:qt].to_d, nxid: t[:txid], fee: t[:fee].to_d, moe: t[:moe].upcase) }
153
+ hlx.map { |t| pdes(:time, t) }
154
154
  end
155
155
 
156
156
  # @return [Hash] dados exchange bitcoinde - saldos & trades & deposits & withdrawals
@@ -173,19 +173,19 @@ module Cns
173
173
  @kyt ||= ded[:tt].map { |t| t[:trade_id] } - bqkyt
174
174
  end
175
175
 
176
- # @return [Array<Integer>] lista txid ledger novos
176
+ # @return [Array<Integer>] lista nxid ledger novos
177
177
  def kyl
178
- @kyl ||= ded[:tl].map { |t| t[:txid] } - bqkyl
178
+ @kyl ||= ded[:tl].map { |t| t[:nxid] } - bqkyl
179
179
  end
180
180
 
181
- # @return [Array<Hash>] lista trades bitcoinde novos
181
+ # @return [Array<Hash>] lista trades novos bitcoinde
182
182
  def novcdet
183
- @novcdet ||= ded[:tt].select { |obj| kyt.include?(obj[:trade_id]) }
183
+ @novcdet ||= ded[:tt].select { |o| kyt.include?(o[:trade_id]) }
184
184
  end
185
185
 
186
- # @return [Array<Hash>] lista ledger (deposits + withdrawals) bitcoinde novos
186
+ # @return [Array<Hash>] lista ledgers (deposits + withdrawals) novos bitcoinde
187
187
  def novcdel
188
- @novcdel ||= ded[:tl].select { |obj| kyl.include?(obj[:txid]) }
188
+ @novcdel ||= ded[:tl].select { |o| kyl.include?(o[:nxid]) }
189
189
  end
190
190
  end
191
191
  end
data/lib/cns/kraken.rb CHANGED
@@ -23,7 +23,7 @@ module Cns
23
23
  @ops = pop.transform_keys(&:to_sym)
24
24
  end
25
25
 
26
- # @return [String] texto saldos & transacoes & ajuste dias
26
+ # mosta resumo saldos & transacoes & ajuste dias
27
27
  def mresumo
28
28
  puts("\nKRAKEN\ntipo kraken bigquery")
29
29
  usd[:sl].sort.each { |key, val| puts(fos(key, val)) }
@@ -33,7 +33,7 @@ module Cns
33
33
  mledger
34
34
  return if novcust.empty?
35
35
 
36
- puts("\nstring ajuste dias dos trades\n-h=#{novcust.sort_by { |_, v| -v[:srx] }.map { |k, _v| "#{k}:0" }.join(' ')}")
36
+ puts("\nstring ajuste dias dos trades\n-h=#{novcust.sort_by { |i| -i[:srx] }.map { |o| "#{o[:txid]}:0" }.join(' ')}")
37
37
  end
38
38
 
39
39
  # @return [Hash] ledgers exchange kraken
@@ -59,7 +59,7 @@ module Cns
59
59
  return unless ops[:v] && novcust.any?
60
60
 
61
61
  puts("\ntrade data hora tipo par preco volume custo")
62
- novcust.sort_by { |_, v| -v[:srx] }.each { |k, t| puts(fot(k, t)) }
62
+ novcust.sort_by { |i| -i[:srx] }.each { |o| puts(fot(o)) }
63
63
  end
64
64
 
65
65
  # mosta transacoes ledger
@@ -67,14 +67,14 @@ module Cns
67
67
  return unless ops[:v] && novcusl.any?
68
68
 
69
69
  puts("\nledger data hora tipo moeda quantidade custo")
70
- novcusl.sort_by { |_, v| -v[:srx] }.each { |k, t| puts(fol(k, t)) }
70
+ novcusl.sort_by { |i| -i[:srx] }.each { |o| puts(fol(o)) }
71
71
  end
72
72
 
73
73
  # @param [String] moe codigo kraken da moeda
74
74
  # @param [BigDecimal] sal saldo kraken da moeda
75
75
  # @return [String] texto formatado saldos
76
76
  def fos(moe, sal)
77
- vbq = bqd[:sl][moe.downcase.to_sym].to_d
77
+ vbq = (bqd[:sl]&.fetch(moe.downcase.to_sym, nil) || 0).to_d
78
78
  format(
79
79
  '%<mo>-5.5s %<kr>21.9f %<bq>21.9f %<ok>3.3s',
80
80
  mo: moe.upcase,
@@ -84,13 +84,12 @@ module Cns
84
84
  )
85
85
  end
86
86
 
87
- # @param [Symbol] idx id da transacao
88
87
  # @param [Hash] htn trades kraken
89
88
  # @return [String] texto formatado trade
90
- def fot(idx, htx)
89
+ def fot(htx)
91
90
  format(
92
91
  '%<ky>-6.6s %<dt>19.19s %<ty>-10.10s %<mo>-8.8s %<pr>8.2f %<vl>10.4f %<co>13.2f',
93
- ky: idx,
92
+ ky: htx[:txid],
94
93
  dt: htx[:time].strftime('%F %T'),
95
94
  ty: "#{htx[:type]}/#{htx[:ordertype]}",
96
95
  mo: htx[:pair],
@@ -100,13 +99,12 @@ module Cns
100
99
  )
101
100
  end
102
101
 
103
- # @param idx (see fot)
104
102
  # @param [Hash] hln ledger kraken
105
103
  # @return [String] texto formatado ledger
106
- def fol(idx, hlx)
104
+ def fol(hlx)
107
105
  format(
108
106
  '%<ky>-6.6s %<dt>19.19s %<ty>-10.10s %<mo>-4.4s %<pr>18.7f %<vl>18.7f',
109
- ky: idx,
107
+ ky: hlx[:txid],
110
108
  dt: hlx[:time].strftime('%F %T'),
111
109
  ty: hlx[:type],
112
110
  mo: hlx[:asset],
@@ -126,25 +124,16 @@ module Cns
126
124
  itm.select { |k, _| EM.include?(k) }.transform_values { |v| v.to_d }
127
125
  end
128
126
 
129
- # @param [Hash] itm transacao kraken
130
- # @return [Hash] transaccao filtrada
131
- def pusk(itm)
132
- itm.map do |k, v|
133
- t = Integer(v[:time])
134
- [k, v.merge(txid: k.to_s, srx: t, time: Time.at(t))]
135
- end.to_h
136
- end
137
-
138
- # @param [Hash] htx trade kraken
139
- # @return [Hash] transaccao filtrada
127
+ # @param [Array<Hash>] htx trades kraken
128
+ # @return [Array<Hash>] transaccoes filtradas
140
129
  def pust(htx)
141
- pusk(htx).transform_values { |t| t.merge(pair: t[:pair].upcase, price: t[:price].to_d, vol: t[:vol].to_d, cost: t[:cost].to_d) }
130
+ htx.map { |t| t.merge(pair: t[:pair].upcase, price: t[:price].to_d, vol: t[:vol].to_d, cost: t[:cost].to_d) }
142
131
  end
143
132
 
144
- # @param [Hash] hlx ledger kraken
145
- # @return [Hash] transaccao filtrada
133
+ # @param [Array<Hash>] hlx ledgers kraken
134
+ # @return [Array<Hash>] transaccoes filtradas
146
135
  def pusl(hlx)
147
- pusk(hlx).transform_values { |t| t.merge(asset: t[:asset].upcase, amount: t[:amount].to_d, fee: t[:fee].to_d) }
136
+ hlx.map { |t| t.merge(asset: t[:asset].upcase, amount: t[:amount].to_d, fee: t[:fee].to_d) }
148
137
  end
149
138
 
150
139
  # @return [Hash] dados exchange kraken - saldos & transacoes trades e ledger
@@ -152,34 +141,34 @@ module Cns
152
141
  @usd ||= {sl: pusa(api.account_us), kt: pust(api.trades_us), kl: pusl(api.ledger_us)}
153
142
  end
154
143
 
155
- # @return [Array<Symbol>] indices trades bigquery
144
+ # @return [Array<String>] indices trades bigquery
156
145
  def bqkyt
157
- @bqkyt ||= show_all? ? [] : bqd[:nt].map { |t| t[:txid].to_sym }
146
+ @bqkyt ||= show_all? ? [] : bqd[:nt].map { |t| t[:txid] }
158
147
  end
159
148
 
160
- # @return [Array<Symbol>] indices ledger bigquery
149
+ # @return [Array<String>] indices ledger bigquery
161
150
  def bqkyl
162
- @bqkyl ||= show_all? ? [] : bqd[:nl].map { |l| l[:txid].to_sym }
151
+ @bqkyl ||= show_all? ? [] : bqd[:nl].map { |l| l[:txid] }
163
152
  end
164
153
 
165
- # @return [Array<Symbol>] lista txid trades novos
154
+ # @return [Array<String>] lista txid trades novos
166
155
  def kyt
167
- @kyt ||= usd[:kt].keys - bqkyt
156
+ @kyt ||= usd[:kt].map { |t| t[:txid] } - bqkyt
168
157
  end
169
158
 
170
- # @return [Array<Symbol>] lista txid ledger novos
159
+ # @return [Array<String>] lista txid ledger novos
171
160
  def kyl
172
- @kyl ||= usd[:kl].keys - bqkyl
161
+ @kyl ||= usd[:kl].map { |t| t[:txid] } - bqkyl
173
162
  end
174
163
 
175
- # @return [Hash] trades kraken novos
164
+ # @return [Array<Hash>] trades novos kraken
176
165
  def novcust
177
- @novcust ||= usd[:kt].slice(*kyt)
166
+ @novcust ||= usd[:kt].select { |o| kyt.include?(o[:txid]) }
178
167
  end
179
168
 
180
- # @return [Hash] ledger kraken novos
169
+ # @return [Array<Hash>] ledgers novos kraken
181
170
  def novcusl
182
- @novcusl ||= usd[:kl].slice(*kyl)
171
+ @novcusl ||= usd[:kl].select { |o| kyl.include?(o[:txid]) }
183
172
  end
184
173
  end
185
174
  end
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.4'
4
+ VERSION = '0.9.5'
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cns
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hernâni Rodrigues Vaz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-04 00:00:00.000000000 Z
10
+ date: 2025-03-06 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler