cns 0.8.2 → 0.8.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.
data/lib/cns/apice.rb CHANGED
@@ -7,202 +7,74 @@ require('json')
7
7
 
8
8
  # @author Hernani Rodrigues Vaz
9
9
  module Cns
10
- DC = %w[LTC NMC PPC DOGE XRP Linden USD CAD GBP ZEC BCH EURN NOKU FDZ GUSD SEED USDC].freeze
10
+ API = { de: 'https://api.bitcoin.de/v4', us: 'https://api.kraken.com/0/private' }.freeze
11
11
 
12
12
  # classe para acesso dados centralized exchanges
13
13
  class Apice
14
- # @example account_de
15
- # {
16
- # data: {
17
- # balances: {
18
- # btc: { total_amount: '0.00000000000000000000', available_amount: '0', reserved_amount: '0' },
19
- # bch: { total_amount: '0.00000000000000000000', available_amount: '0', reserved_amount: '0' },
20
- # btg: { total_amount: '0.00000000000000000000', available_amount: '0', reserved_amount: '0' },
21
- # eth: { total_amount: '0.00000000000000000000', available_amount: '0', reserved_amount: '0' },
22
- # bsv: { total_amount: '0.00000000000000000000', available_amount: '0', reserved_amount: '0' },
23
- # ltc: { total_amount: '0.00000000000000000000', available_amount: '0', reserved_amount: '0' }
24
- # },
25
- # encrypted_information: { uid: '0y...', bic_short: '0y...', bic_full: '0y...' }
26
- # },
27
- # errors: [],
28
- # credits: 23
29
- # }
30
- # @param [String] uri Uniform Resource Identifier do pedido HTTP
31
14
  # @return [Hash] saldos no bitcoinde
32
- def account_de(uri = 'https://api.bitcoin.de/v4/account')
33
- JSON.parse(
34
- Curl.get(uri) { |obj| obj.headers = hde(uri) }.body,
35
- symbolize_names: true
36
- )[:data][:balances]
37
- rescue StandardError
15
+ def account_de
16
+ uri = "#{API[:de]}/account"
17
+ parse_json(Curl.get(uri) { |obj| obj.headers = hde(uri) }).dig(:data, :balances) || {}
18
+ rescue Curl::Err::CurlError
38
19
  {}
39
20
  end
40
21
 
41
- # @example account_us
42
- # {
43
- # error: [],
44
- # result: {
45
- # ZEUR: '0.0038',
46
- # XXBT: '0.0000000000',
47
- # XETH: '1.0000000000',
48
- # XETC: '0.0000000000',
49
- # EOS: '0.0000001700',
50
- # BCH: '0.0000000000'
51
- # }
52
- # }
53
- # @param [String] urb Uniform Resource Base do pedido HTTP
54
- # @param uri (see account_de)
55
- # @param non (see hde)
56
- # @return [Hash] saldos no kraken
57
- def account_us(urb = 'https://api.kraken.com/0/private', uri = 'Balance', non = nnc)
58
- JSON.parse(Curl.post("#{urb}/#{uri}", nonce: non) { |obj| obj.headers = hus(uri, nonce: non) }.body, symbolize_names: true)[:result]
59
- rescue StandardError
60
- {}
61
- end
62
-
63
- # @example trades_de
64
- # {
65
- # trades: [{
66
- # trade_id: 'XUWWD3',
67
- # trading_pair: 'btceur',
68
- # is_external_wallet_trade: false,
69
- # type: 'sell',
70
- # amount_currency_to_trade: '0.1',
71
- # price: 430,
72
- # volume_currency_to_pay: 43,
73
- # volume_currency_to_pay_after_fee: 42.79,
74
- # amount_currency_to_trade_after_fee: 0.099,
75
- # fee_currency_to_pay: 0.22,
76
- # fee_currency_to_trade: '0.00100000',
77
- # created_at: '2014-03-22T08:14:48+01:00',
78
- # successfully_finished_at: '2014-03-25T14:03:22+01:00',
79
- # state: 1,
80
- # is_trade_marked_as_paid: true,
81
- # trade_marked_as_paid_at: '2014-03-22T08:20:01+01:00',
82
- # payment_method: 1,
83
- # my_rating_for_trading_partner: 'positive',
84
- # trading_partner_information: {
85
- # username: 'emax2000',
86
- # is_kyc_full: false,
87
- # trust_level: 'bronze',
88
- # amount_trades: 4,
89
- # rating: 100,
90
- # bank_name: 'CASSA DI RISPARMIO DI CIVITAVECCHIA SPA',
91
- # bic: 'CRFIIT2CXXX',
92
- # seat_of_bank: 'IT'
93
- # }
94
- # }, {}],
95
- # page: { current: 1, last: 2 },
96
- # errors: [],
97
- # credits: 22
98
- # }
99
- # @param [Integer] pag pagina dos dados
100
- # @param [Array<Hash>] ary acumulador dos dados
101
- # @param [String] uri Uniform Resource Identifier do pedido HTTP
102
- # @return [Array<Hash>] lista completa trades bitcoinde
103
- def trades_de(pag = 0, ary = [], uri = 'https://api.bitcoin.de/v4/trades')
104
- par = "#{uri}?#{URI.encode_www_form(state: 1, page: pag += 1)}"
105
- res = JSON.parse(Curl.get(par) { |obj| obj.headers = hde(par) }.body, symbolize_names: true)
106
- ary += res[:trades]
107
- rep = res[:page]
108
- rep[:current] < rep[:last] ? trades_de(pag, ary) : ary
109
- rescue StandardError
22
+ # @return [Array<Hash>] trades bitcoinde
23
+ 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
35
+ rescue Curl::Err::CurlError
110
36
  ary
111
37
  end
112
38
 
113
- # @example deposits_de
114
- # {
115
- # deposits: [
116
- # {
117
- # deposit_id: '177245',
118
- # txid: '84f9e85bc5709cd471e3d58a7d0f42d2c4a7bbd888cabf844e200efbf0a7fda2',
119
- # address: '1KK6HhG3quojFS4CY1mPcbyrjQ8BMDQxmT',
120
- # amount: '0.13283',
121
- # confirmations: 6,
122
- # state: 2,
123
- # created_at: '2014-01-31T22:01:30+01:00'
124
- # },
125
- # {}
126
- # ],
127
- # page: { current: 1, last: 1 },
128
- # errors: [],
129
- # credits: 23
130
- # }
131
- # @param (see trades_de)
132
- # @return [Array<Hash>] lista completa uniformizada depositos bitcoinde
133
- def deposits_de(pag = 0, ary = [], uri = 'https://api.bitcoin.de/v4/btc/deposits')
134
- par = "#{uri}?#{URI.encode_www_form(state: 2, page: pag += 1)}"
135
- res = JSON.parse(Curl.get(par) { |obj| obj.headers = hde(par) }.body, symbolize_names: true)
136
- ary += res[:deposits].map { |has| deposit_unif(has) }
137
- rep = res[:page]
138
- rep[:current] < rep[:last] ? deposits_de(pag, ary) : ary
139
- rescue StandardError
39
+ # @return [Array<Hash>] depositos uniformizados bitcoinde
40
+ 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
52
+ rescue Curl::Err::CurlError
140
53
  ary
141
54
  end
142
55
 
143
- # @example deposit_unif
144
- # [
145
- # {
146
- # txid: 177_245,
147
- # time: '2014-01-31T22:01:30+01:00',
148
- # tp: 'deposit',
149
- # add: '1KK6HhG3quojFS4CY1mPcbyrjQ8BMDQxmT',
150
- # qt: '0.13283',
151
- # moe: 'btc',
152
- # fee: '0'
153
- # },
154
- # {}
155
- # ]
156
- # @return [Hash] deposit uniformizado bitcoinde
56
+ # @return [Hash] deposito uniformizado bitcoinde
157
57
  def deposit_unif(has)
158
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')
159
59
  end
160
60
 
161
- # @example withdrawals_de
162
- # {
163
- # withdrawals: [
164
- # {
165
- # withdrawal_id: '136605',
166
- # address: '1K9YMDDrmMV25EoYNqi7KUEK57Kn3TCNUJ',
167
- # amount: '0.120087',
168
- # network_fee: '0',
169
- # comment: '',
170
- # created_at: '2014-02-05T13:01:09+01:00',
171
- # txid: '6264fe528116fcb87c812a306ca8409eecfec8fa941546c86f98984b882c8042',
172
- # transferred_at: '2014-02-05T13:05:17+01:00',
173
- # state: 1
174
- # },
175
- # {}
176
- # ],
177
- # page: { current: 1, last: 2 },
178
- # errors: [],
179
- # credits: 23
180
- # }
181
- # @param (see deposits_de)
182
- # @return [Array<Hash>] lista completa uniformizada withdrawals bitcoinde
183
- def withdrawals_de(pag = 0, ary = [], uri = 'https://api.bitcoin.de/v4/btc/withdrawals')
184
- par = "#{uri}?#{URI.encode_www_form(state: 1, page: pag += 1)}"
185
- res = JSON.parse(Curl.get(par) { |obj| obj.headers = hde(par) }.body, symbolize_names: true)
186
- ary += res[:withdrawals].map { |has| withdrawal_unif(has) }
187
- rep = res[:page]
188
- rep[:current] < rep[:last] ? withdrawals_de(pag, ary) : ary
189
- rescue StandardError
61
+ # @return [Array<Hash>] withdrawals uniformizadas bitcoinde
62
+ 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
74
+ rescue Curl::Err::CurlError
190
75
  ary
191
76
  end
192
77
 
193
- # @example withdrawal_unif
194
- # [
195
- # {
196
- # txid: 136_605,
197
- # time: '2014-02-05T13:05:17+01:00',
198
- # tp: 'withdrawal',
199
- # add: '1K9YMDDrmMV25EoYNqi7KUEK57Kn3TCNUJ',
200
- # qt: '0.120087',
201
- # fee: '0',
202
- # moe: 'btc'
203
- # },
204
- # {}
205
- # ]
206
78
  # @return [Hash] withdrawal uniformizada bitcoinde
207
79
  def withdrawal_unif(has)
208
80
  {
@@ -214,205 +86,62 @@ module Cns
214
86
  }.merge(tp: 'withdrawal', moe: 'btc')
215
87
  end
216
88
 
217
- # @example trades_us
218
- # {
219
- # error: [],
220
- # result: {
221
- # trades: {
222
- # "TVINF5-TIOUB-YFNGKE": {
223
- # ordertxid: 'ORPSUW-YKP4F-UJZOC6',
224
- # pair: 'XETHXXBT',
225
- # time: 1_463_435_684.8387,
226
- # type: 'buy',
227
- # ordertype: 'market',
228
- # price: '0.024989',
229
- # cost: '1.193973',
230
- # fee: '0.003104',
231
- # vol: '47.77994129',
232
- # margin: '0.000000',
233
- # misc: ''
234
- # },
235
- # "OUTRO-TRADE-ID": {}
236
- # },
237
- # count: 157
238
- # }
239
- # }
240
- # @param [Integer] ofs offset dos dados
241
- # @param [Hash] has acumulador dos dados
242
- # @param (see account_us)
243
- # @return [Hash] dados trades kraken
244
- def trades_us(ofs = 0, has = {}, urb = 'https://api.kraken.com/0/private', uri = 'TradesHistory', non = nnc)
245
- res = JSON.parse(
246
- Curl.post("#{urb}/#{uri}", nonce: non, ofs: ofs) { |obj| obj.headers = hus(uri, nonce: non, ofs: ofs) }.body,
247
- symbolize_names: true
248
- )[:result]
249
- has.merge!(res[:trades])
250
- sleep(2)
251
- res[:trades].count.positive? ? trades_us(ofs + res[:trades].count, has) : has
252
- rescue StandardError
253
- has
89
+ # @return [Hash] saldos kraken
90
+ def account_us
91
+ uri = 'Balance'
92
+ ops = { nonce: nnc }
93
+ parse_json(Curl.post("#{API[:us]}/#{uri}", ops) { |hed| hed.headers = hus(uri, ops) }).fetch(:result, {})
94
+ rescue Curl::Err::CurlError
95
+ {}
254
96
  end
255
97
 
256
- # @example ledger_us
257
- # {
258
- # error: [],
259
- # result: {
260
- # ledger: {
261
- # "LXXURB-ITI7S-CXVERS": {
262
- # refid: 'ACCHF3A-RIBBMO-VYBESY',
263
- # time: 1_543_278_716.2775,
264
- # type: 'withdrawal',
265
- # subtype: '',
266
- # aclass: 'currency',
267
- # asset: 'ZEUR',
268
- # amount: '-15369.6200',
269
- # fee: '0.0900',
270
- # balance: '0.0062'
271
- # },
272
- # "OUTRO-LEDGER-ID": {}
273
- # },
274
- # count: 376
275
- # }
276
- # }
277
- # @param (see trades_us)
278
- # @return [Hash] dados ledger kraken
279
- def ledger_us(ofs = 0, has = {}, urb = 'https://api.kraken.com/0/private', uri = 'Ledgers', non = nnc)
280
- res = JSON.parse(
281
- Curl.post("#{urb}/#{uri}", nonce: non, ofs: ofs) { |obj| obj.headers = hus(uri, nonce: non, ofs: ofs) }.body,
282
- symbolize_names: true
283
- )[:result]
284
- has.merge!(res[:ledger])
285
- sleep(2)
286
- res[:ledger].count.positive? ? ledger_us(ofs + res[:ledger].count, has) : has
287
- rescue StandardError
98
+ # @return [Hash] trades kraken
99
+ 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
113
+ rescue Curl::Err::CurlError
288
114
  has
289
115
  end
290
116
 
291
- # @example account_fr
292
- # {
293
- # name: '...',
294
- # email: '...',
295
- # locale: 'en',
296
- # channel_id: '...',
297
- # meta_state: 'approved',
298
- # balance_eur: '0.0',
299
- # locked_eur: '0.0',
300
- # balance_btc: '0.0',
301
- # locked_btc: '0.0',
302
- # balance_lbtc: '0.0',
303
- # locked_lbtc: '0.0'
304
- # }
305
- # @param (see account_de)
306
- # @return [Hash] saldos no paymium
307
- # def account_fr(uri = 'https://paymium.com/api/v1/user')
308
- # JSON.parse(
309
- # Curl.get(uri) { |obj| obj.headers = hfr(uri) }.body,
310
- # symbolize_names: true
311
- # )
312
- # rescue StandardError
313
- # {}
314
- # end
315
- #
316
- # @example account_mt
317
- # {
318
- # balances: [
319
- # { currency: 'BTC', balance: 0.0, trading_balance: 0.0 },
320
- # { currency: 'ETH', balance: 0.0, trading_balance: 0.0 },
321
- # { currency: 'EUR', balance: 0.0, trading_balance: 0.0 },
322
- # { currency: 'DAI', balance: 0.0, trading_balance: 0.0 },
323
- # ]
324
- # }
325
- # @param (see account_de)
326
- # @return [Array<Hash>] lista saldos no therock
327
- # def account_mt(uri = 'https://api.therocktrading.com/v1/balances')
328
- # JSON.parse(
329
- # Curl.get(uri) { |obj| obj.headers = hmt(uri) }.body,
330
- # symbolize_names: true
331
- # )[:balances]
332
- # .delete_if { |del| DC.include?(del[:currency]) }
333
- # .sort { |oba, obb| oba[:currency] <=> obb[:currency] }
334
- # rescue StandardError
335
- # []
336
- # end
337
- #
338
- # @example ledger_fr
339
- # [
340
- # {
341
- # uuid: '50551e61-4e74-4ae7-85fd-9c2040542818',
342
- # currency_amount: nil,
343
- # state: 'executed',
344
- # btc_fee: '0.0',
345
- # currency_fee: '0.0',
346
- # created_at: '2014-03-04T09:00Z',
347
- # updated_at: '2014-03-04T09:00Z',
348
- # currency: 'EUR',
349
- # comment: '5723',
350
- # amount: '100.0',
351
- # type: 'WireDeposit',
352
- # account_operations: [{
353
- # uuid: 'b5058a68-cf99-4438-86d3-e773eba418ec',
354
- # name: 'wire_deposit',
355
- # amount: '100.0',
356
- # currency: 'EUR',
357
- # created_at: '2014-03-04T09:00Z',
358
- # created_at_int: 1_393_923_644,
359
- # is_trading_account: false
360
- # }, {}]
361
- # },
362
- # {}
363
- # ]
364
- # @param (see trades_de)
365
- # @return [Array<Hash>] lista ledger paymium
366
- # def ledger_fr(pag = 0, ary = [], uri = 'https://paymium.com/api/v1/user/orders')
367
- # res = JSON.parse(
368
- # Curl.get(uri, offset: pag) { |obj| obj.headers = hfr("#{uri}?#{URI.encode_www_form(offset: pag)}") }.body,
369
- # symbolize_names: true
370
- # )
371
- # res.empty? ? ary : ledger_fr(pag + res.size, ary + res)
372
- # rescue StandardError
373
- # ary
374
- # end
375
- #
376
- # @example ledger_mt
377
- # {
378
- # transactions: [
379
- # {
380
- # id: 305_445,
381
- # date: '2014-03-06T10:59:13.000Z',
382
- # type: 'withdraw',
383
- # price: 97.47,
384
- # currency: 'EUR',
385
- # fund_id: nil,
386
- # order_id: nil,
387
- # trade_id: nil,
388
- # note: 'BOV withdraw',
389
- # transfer_detail: nil
390
- # },
391
- # {}
392
- # ],
393
- # meta: {
394
- # total_count: nil,
395
- # first: { page: 1, href: 'https://api.therocktrading.com/v1/transactions?page=1' },
396
- # previous: nil,
397
- # current: { page: 1, href: 'https://api.therocktrading.com/v1/transactions?page=1' },
398
- # next: { page: 2, href: 'https://api.therocktrading.com/v1/transactions?page=2' },
399
- # last: nil
400
- # }
401
- # }
402
- # @param (see trades_de)
403
- # @return [Array<Hash>] lista ledger therock
404
- # def ledger_mt(pag = 1, ary = [], uri = 'https://api.therocktrading.com/v1/transactions')
405
- # res = JSON.parse(
406
- # Curl.get(uri, page: pag) { |obj| obj.headers = hmt("#{uri}?#{URI.encode_www_form(page: pag)}") }.body,
407
- # symbolize_names: true
408
- # )[:transactions]
409
- # res.empty? ? ary : ledger_mt(pag + res.size, ary + res)
410
- # rescue StandardError
411
- # ary
412
- # end
117
+ # @return [Hash] ledger kraken
118
+ def ledger_us
119
+ uri = 'Ledgers'
120
+ has = {}
121
+ ofs = 0
122
+ loop do
123
+ sleep(2)
124
+ 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?
127
+
128
+ has.merge!(result[:ledger])
129
+ ofs += result[:ledger].size
130
+ end
131
+ has
132
+ rescue Curl::Err::CurlError
133
+ has
134
+ end
413
135
 
414
136
  private
415
137
 
138
+ # Safe JSON parsing with error handling
139
+ def parse_json(res)
140
+ JSON.parse(res.body, symbolize_names: true) || {}
141
+ rescue JSON::ParserError
142
+ {}
143
+ end
144
+
416
145
  # @return [Integer] continually-increasing unsigned integer nonce from the current Unix Time
417
146
  def nnc
418
147
  Integer(Float(Time.now) * 1e6)
@@ -423,56 +152,20 @@ module Cns
423
152
  # @return [Hash] headers necessarios para pedido HTTP da exchange bitcoinde
424
153
  def hde(qde, non = nnc)
425
154
  key = ENV.fetch('BITCOINDE_API_KEY', nil)
426
- {
427
- 'X-API-KEY': key,
428
- 'X-API-NONCE': non,
429
- 'X-API-SIGNATURE': OpenSSL::HMAC.hexdigest(
430
- 'sha256',
431
- ENV.fetch('BITCOINDE_API_SECRET', nil),
432
- ['GET', qde, key, non, Digest::MD5.hexdigest('')].join('#')
433
- )
434
- }
155
+ md5 = ['GET', qde, key, non, Digest::MD5.hexdigest('')].join('#')
156
+ mac = OpenSSL::HMAC.hexdigest('sha256', ENV.fetch('BITCOINDE_API_SECRET', nil), md5)
157
+ { 'X-API-KEY': key, 'X-API-NONCE': non, 'X-API-SIGNATURE': mac }
435
158
  end
436
159
 
437
- # @param [String] qfr query a incluir no pedido HTTP
438
- # @param non (see hde)
439
- # @return [Hash] headers necessarios para pedido HTTP da exchange paymium
440
- # def hfr(qfr, non = nnc)
441
- # {
442
- # content_type: 'application/json',
443
- # 'Api-Key': ENV['PAYMIUM_API_KEY'],
444
- # 'Api-Nonce': non,
445
- # 'Api-Signature': OpenSSL::HMAC.hexdigest('sha256', ENV['PAYMIUM_API_SECRET'], [non, qfr].join)
446
- # }
447
- # end
448
- #
449
- # @param [String] qmt query a incluir no pedido HTTP
450
- # @param non (see hde)
451
- # @return [Hash] headers necessarios para pedido HTTP da exchange therock
452
- # def hmt(qmt, non = nnc)
453
- # {
454
- # content_type: 'application/json',
455
- # 'X-TRT-KEY': ENV['THEROCK_API_KEY'],
456
- # 'X-TRT-NONCE': non,
457
- # 'X-TRT-SIGN': OpenSSL::HMAC.hexdigest('sha512', ENV['THEROCK_API_SECRET'], [non, qmt].join)
458
- # }
459
- # end
460
-
461
160
  # @param [String] qus query a incluir no pedido HTTP
462
161
  # @param [Hash] ops opcoes trabalho
463
162
  # @option ops [Hash] :nonce continually-increasing unsigned integer
464
163
  # @return [Hash] headers necessarios para pedido HTTP da exchange kraken
465
164
  def hus(qus, ops)
466
- {
467
- 'api-key': ENV.fetch('KRAKEN_API_KEY', nil),
468
- 'api-sign': Base64.strict_encode64(
469
- OpenSSL::HMAC.digest(
470
- 'sha512',
471
- Base64.decode64(ENV.fetch('KRAKEN_API_SECRET', nil)),
472
- ['/0/private/', qus, Digest::SHA256.digest("#{ops[:nonce]}#{URI.encode_www_form(ops)}")].join
473
- )
474
- )
475
- }
165
+ key = ENV.fetch('KRAKEN_API_KEY', nil)
166
+ sha = ['/0/private/', qus, Digest::SHA256.digest("#{ops[:nonce]}#{URI.encode_www_form(ops)}")].join
167
+ mac = OpenSSL::HMAC.digest('sha512', Base64.decode64(ENV.fetch('KRAKEN_API_SECRET', nil)), sha)
168
+ { 'api-key': key, 'api-sign': Base64.strict_encode64(mac) }
476
169
  end
477
170
  end
478
171
  end