cns 0.1.0 → 0.1.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.
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('openssl')
4
+ require('base64')
5
+ require('curb')
6
+ require('json')
7
+
8
+ # @author Hernani Rodrigues Vaz
9
+ module Cns
10
+ # classe para processar dados no paymium
11
+ class Apifr
12
+ # @return [String] API key
13
+ attr_reader :aky
14
+ # @return [String] API secret
15
+ attr_reader :asc
16
+ # @return [String] API url base
17
+ attr_reader :urb
18
+
19
+ # @param [String] pky API key
20
+ # @param [String] psc API secret
21
+ # @param [Hash] ops parametrizacao base da API
22
+ # @return [Apius] API paymium base
23
+ def initialize(
24
+ pky: ENV['PAYMIUM_API_KEY'],
25
+ psc: ENV['PAYMIUM_API_SECRET'],
26
+ ops: { www: 'https://paymium.com', ver: 1 }
27
+ )
28
+ @aky = pky
29
+ @asc = psc
30
+ @urb = "#{ops[:www]}/api/v#{ops[:ver]}"
31
+ end
32
+
33
+ # @example
34
+ # {
35
+ # name: '...',
36
+ # email: '...',
37
+ # locale: 'en',
38
+ # channel_id: '...',
39
+ # meta_state: 'approved',
40
+ # balance_eur: '0.0',
41
+ # locked_eur: '0.0',
42
+ # balance_btc: '0.0',
43
+ # locked_btc: '0.0',
44
+ # balance_lbtc: '0.0',
45
+ # locked_lbtc: '0.0'
46
+ # }
47
+ # @return [Hash] saldos no paymium
48
+ def account
49
+ api_get('user')
50
+ end
51
+
52
+ # @example
53
+ # [
54
+ # {
55
+ # uuid: '50551e61-4e74-4ae7-85fd-9c2040542818',
56
+ # currency_amount: nil,
57
+ # state: 'executed',
58
+ # btc_fee: '0.0',
59
+ # currency_fee: '0.0',
60
+ # created_at: '2014-03-04T09:00Z',
61
+ # updated_at: '2014-03-04T09:00Z',
62
+ # currency: 'EUR',
63
+ # comment: '5723',
64
+ # amount: '100.0',
65
+ # type: 'WireDeposit',
66
+ # account_operations: [{
67
+ # uuid: 'b5058a68-cf99-4438-86d3-e773eba418ec',
68
+ # name: 'wire_deposit',
69
+ # amount: '100.0',
70
+ # currency: 'EUR',
71
+ # created_at: '2014-03-04T09:00Z',
72
+ # created_at_int: 1_393_923_644,
73
+ # is_trading_account: false
74
+ # }, {}]
75
+ # }, {}
76
+ # ]
77
+ # @return [Hash] ledger no paymium
78
+ def ledger(pag = 0, ary = [])
79
+ r = api_get('user/orders', offset: pag)
80
+ r.empty? ? ary : ledger(pag + r.size, ary + r)
81
+ rescue StandardError
82
+ ary
83
+ end
84
+
85
+ private
86
+
87
+ # HTTP GET request for public paymium API queries.
88
+ def api_get(uri, **ops)
89
+ resposta(Curl.get("#{urb}/#{uri}", ops) { |r| r.headers = hdrs(url(uri, ops), nonce, {}) })
90
+ end
91
+
92
+ # HTTP POST request for private paymium API queries involving user credentials.
93
+ def api_post(uri, **ops)
94
+ resposta(Curl.post("#{urb}/#{uri}", ops) { |r| r.headers = hdrs(uri, nonce, ops) })
95
+ end
96
+
97
+ # @return [String] URL do pedido formatado com todos os parametros
98
+ def url(uri, ops)
99
+ ops.empty? ? uri : "#{uri}?#{URI.encode_www_form(ops)}"
100
+ end
101
+
102
+ # @return [Hash] headers necessarios para pedido HTTP
103
+ def hdrs(qry, non, ops)
104
+ {
105
+ content_type: 'application/json',
106
+ 'Api-Key': aky,
107
+ 'Api-Nonce': non,
108
+ 'Api-Signature': auth(qry, non, URI.encode_www_form(ops))
109
+ }
110
+ end
111
+
112
+ # @return [String] assinarura codificada dos pedidos HTTP
113
+ def auth(qry, non, par)
114
+ raise(ArgumentError, 'API Key is not set') unless aky
115
+ raise(ArgumentError, 'API Secret is not set') unless asc
116
+
117
+ OpenSSL::HMAC.hexdigest('sha256', asc, [non, "#{urb}/#{qry}", par].join)
118
+ end
119
+
120
+ # @return [Integer] continually-increasing unsigned integer nonce from the current Unix Time
121
+ def nonce
122
+ Integer(Float(Time.now) * 1e6)
123
+ end
124
+
125
+ # @return [Hash] resposta do pedido HTTP
126
+ def resposta(http)
127
+ http.response_code == 200 ? JSON.parse(http.body, symbolize_names: true) : http.status
128
+ rescue JSON::ParserError,
129
+ EOFError,
130
+ Errno::ECONNRESET,
131
+ Errno::EINVAL,
132
+ Net::HTTPBadResponse,
133
+ Net::HTTPHeaderSyntaxError,
134
+ Net::ProtocolError,
135
+ Timeout::Error => e
136
+ "Erro da API paymium #{e.inspect}"
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('faraday')
4
+ require('json')
5
+
6
+ module Cns
7
+ # classe para acesso dados blockchain EOS
8
+ class Apigm
9
+ # @return [String] base URL to use as a prefix for all requests
10
+ attr_reader :url
11
+
12
+ # @param [String] www base URL to use as a prefix for all requests
13
+ # @return [Apigm] acesso dados blockchain EOS
14
+ def initialize(www: 'https://eos.greymass.com')
15
+ @url = www
16
+ end
17
+
18
+ # @return [<Symbol>] adapter for the connection - default :net_http
19
+ def adapter
20
+ @adapter ||= Faraday.default_adapter
21
+ end
22
+
23
+ # @return [<Faraday::Connection>] connection object with an URL & adapter
24
+ def conn
25
+ @conn ||=
26
+ Faraday.new(url: url) do |c|
27
+ c.request(:url_encoded)
28
+ c.adapter(adapter)
29
+ end
30
+ end
31
+
32
+ # @example
33
+ # {
34
+ # account_name: '...',
35
+ # head_block_num: 141_391_122,
36
+ # head_block_time: '2020-09-11T16:05:51.000',
37
+ # privileged: false,
38
+ # last_code_update: '1970-01-01T00:00:00.000',
39
+ # created: '2018-06-09T13:14:37.000',
40
+ # core_liquid_balance: '1232.0228 EOS',
41
+ # ram_quota: 9548,
42
+ # net_weight: 10_001_142,
43
+ # cpu_weight: 10_001_144,
44
+ # net_limit: { used: 0, available: 1_066_648_346, max: 1_066_648_346 },
45
+ # cpu_limit: { used: 338, available: 88_498, max: 88_836 },
46
+ # ram_usage: 3574,
47
+ # permissions: [
48
+ # {
49
+ # perm_name: 'active',
50
+ # parent: 'owner',
51
+ # required_auth: {
52
+ # threshold: 1, keys: [{ key: 'EOS...', weight: 1 }], accounts: [], waits: []
53
+ # }
54
+ # },
55
+ # {
56
+ # perm_name: 'owner',
57
+ # parent: '',
58
+ # required_auth: {
59
+ # threshold: 1, keys: [{ key: 'EOS...', weight: 1 }], accounts: [], waits: []
60
+ # }
61
+ # }
62
+ # ],
63
+ # total_resources: { owner: '...', net_weight: '1000.1142 EOS', cpu_weight: '1000.1144 EOS', ram_bytes: 8148 },
64
+ # self_delegated_bandwidth: { from: '...', to: '...', net_weight: '1000.1142 EOS', cpu_weight: '1000.1144 EOS' },
65
+ # refund_request: nil,
66
+ # voter_info: {
67
+ # owner: '...',
68
+ # proxy: '...',
69
+ # producers: [],
70
+ # staked: 20_002_286,
71
+ # last_vote_weight: '17172913021904.12109375000000000',
72
+ # proxied_vote_weight: '0.00000000000000000',
73
+ # is_proxy: 0,
74
+ # flags1: 0,
75
+ # reserved2: 0,
76
+ # reserved3: '0.0000 EOS'
77
+ # },
78
+ # rex_info: nil
79
+ # }
80
+ # @param [Hash] arg argumentos trabalho
81
+ # @option arg [String] :account_name endereco carteira EOS
82
+ # @return [Hash] dados & saldo duma carteira EOS
83
+ def account(**arg)
84
+ raise(Erro, 'endereco tem de ser definido') if arg[:account_name].nil? || arg[:account_name].empty?
85
+
86
+ get('/v1/chain/get_account', **arg)
87
+ end
88
+
89
+ # @example
90
+ # {
91
+ # actions: [
92
+ # {
93
+ # account_action_seq: 964,
94
+ # action_trace: {
95
+ # account_ram_deltas: [],
96
+ # act: {
97
+ # account: 'voicebestapp',
98
+ # authorization: [
99
+ # { actor: 'thetruevoice', permission: 'active' },
100
+ # { actor: 'voicebestapp', permission: 'active' }
101
+ # ],
102
+ # data: { from: 'voicebestapp', memo: '...', quantity: '1.0001 MESSAGE', to: '...' },
103
+ # hex_data: '...',
104
+ # name: 'transfer'
105
+ # },
106
+ # action_ordinal: 10,
107
+ # block_num: 141_345_345,
108
+ # block_time: '2020-09-11T09:44:04.500',
109
+ # closest_unnotified_ancestor_action_ordinal: 5,
110
+ # context_free: false,
111
+ # creator_action_ordinal: 5,
112
+ # elapsed: 6,
113
+ # producer_block_id: '...',
114
+ # receipt: {
115
+ # abi_sequence: 1,
116
+ # act_digest: '...',
117
+ # auth_sequence: [['thetruevoice', 6_778_215], ['voicebestapp', 435_346]],
118
+ # code_sequence: 1,
119
+ # global_sequence: 233_283_589_258,
120
+ # receiver: '...',
121
+ # recv_sequence: 927
122
+ # },
123
+ # receiver: '...',
124
+ # trx_id: '...'
125
+ # },
126
+ # block_num: 141_345_345,
127
+ # block_time: '2020-09-11T09:44:04.500',
128
+ # global_action_seq: 233_283_589_258,
129
+ # irreversible: true
130
+ # },
131
+ # {}
132
+ # ],
133
+ # head_block_num: 141_721_698,
134
+ # last_irreversible_block: 141_721_371
135
+ # }
136
+ # @param [String] add endereco carteira EOS
137
+ # @param [Hash] arg argumentos trabalho
138
+ # @option arg [String] :account_name endereco carteira EOS
139
+ # @option arg [Integer] :pos posicao da primeira transacao a devolver
140
+ # @option arg [Integer] :offset numero maximo transacoes a devolver
141
+ # @option arg [String] :filter filtro a aplicar na resposta
142
+ # @option arg [String] :sort ordenacao asc/desc
143
+ # @option arg [String] :after time inicio "2020-09-13T13:44:03.105Z"
144
+ # @option arg [String] :before time fim "2020-09-13T13:44:03.105Z"
145
+ # @option arg [Integer] :parent transacao pai
146
+ # @return [Array<Hash>] devolve lista de transacoes
147
+ def all_tx(add, **arg)
148
+ raise(Erro, 'endereco tem de ser definido') if add.nil? || add.empty?
149
+
150
+ ledger(**arg.merge(account_name: add))
151
+ end
152
+
153
+ # @param [Integer] pos posicao das transacoes a devolver
154
+ # @param [Array<Hash>] ary lista acumuladora das transacoes a devolver
155
+ # @param arg (see all_tx)
156
+ # @option arg (see all_tx)
157
+ # @return [Array<Hash>] lista das transacoes ligadas a uma carteira EOS
158
+ def ledger(pos = 0, ary = [], **arg)
159
+ r = get('/v1/history/get_actions', **arg.merge(pos: pos, offset: 100))[:actions]
160
+ ary += r
161
+ r.count < 100 ? ary : ledger(pos + r.count, ary, **arg)
162
+ rescue StandardError
163
+ ary
164
+ end
165
+
166
+ private
167
+
168
+ # @param [String] uri identificacao do recurso a questionar
169
+ # @param arg (see all_tx)
170
+ # @option arg (see all_tx)
171
+ # @return [Hash] resultado do HTTP request
172
+ def get(uri, **arg)
173
+ JSON.parse(
174
+ conn.post(uri, arg.to_json, content_type: 'application/json').body,
175
+ symbolize_names: true
176
+ )
177
+ rescue StandardError
178
+ { actions: [] }
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('openssl')
4
+ require('base64')
5
+ require('curb')
6
+ require('json')
7
+
8
+ # @author Hernani Rodrigues Vaz
9
+ module Cns
10
+ DC = %w[LTC NMC PPC DOGE XRP Linden USD CAD GBP ZEC BCH EURN NOKU FDZ GUSD SEED USDC].freeze
11
+
12
+ # classe para processar dados no therock
13
+ class Apimt
14
+ # @return [String] API key
15
+ attr_reader :aky
16
+ # @return [String] API secret
17
+ attr_reader :asc
18
+ # @return [String] API url base
19
+ attr_reader :urb
20
+
21
+ # @param [String] pky API key
22
+ # @param [String] psc API secret
23
+ # @param [Hash] ops parametrizacao base da API
24
+ # @return [Apius] API therock base
25
+ def initialize(
26
+ pky: ENV['THEROCK_API_KEY'],
27
+ psc: ENV['THEROCK_API_SECRET'],
28
+ ops: { www: 'https://api.therocktrading.com', ver: 1 }
29
+ )
30
+ @aky = pky
31
+ @asc = psc
32
+ @urb = "#{ops[:www]}/v#{ops[:ver]}"
33
+ end
34
+
35
+ # @example
36
+ # {
37
+ # balances: [
38
+ # { currency: 'BTC', balance: 0.0, trading_balance: 0.0 },
39
+ # { currency: 'ETH', balance: 0.0, trading_balance: 0.0 },
40
+ # { currency: 'EUR', balance: 0.0, trading_balance: 0.0 },
41
+ # { currency: 'DAI', balance: 0.0, trading_balance: 0.0 },
42
+ # ]
43
+ # }
44
+ # @return [Hash] saldos no therock
45
+ def account
46
+ api_get('balances')[:balances].delete_if { |e| DC.include?(e[:currency]) }
47
+ .sort { |a, b| a[:currency] <=> b[:currency] }
48
+ end
49
+
50
+ # @example
51
+ # {
52
+ # transactions: [
53
+ # {
54
+ # id: 305_445,
55
+ # date: '2014-03-06T10:59:13.000Z',
56
+ # type: 'withdraw',
57
+ # price: 97.47,
58
+ # currency: 'EUR',
59
+ # fund_id: nil,
60
+ # order_id: nil,
61
+ # trade_id: nil,
62
+ # note: 'BOV withdraw',
63
+ # transfer_detail: nil
64
+ # },
65
+ # {}
66
+ # ],
67
+ # meta: {
68
+ # total_count: nil,
69
+ # first: { page: 1, href: 'https://api.therocktrading.com/v1/transactions?page=1' },
70
+ # previous: nil,
71
+ # current: { page: 1, href: 'https://api.therocktrading.com/v1/transactions?page=1' },
72
+ # next: { page: 2, href: 'https://api.therocktrading.com/v1/transactions?page=2' },
73
+ # last: nil
74
+ # }
75
+ # }
76
+ # @return [Hash] ledger no therock
77
+ def ledger(pag = 1, ary = [])
78
+ r = api_get('transactions', page: pag)[:transactions]
79
+ r.empty? ? ary : ledger(pag + r.size, ary + r)
80
+ rescue StandardError
81
+ ary
82
+ end
83
+
84
+ private
85
+
86
+ # HTTP GET request for public therock API queries.
87
+ def api_get(uri, **ops)
88
+ resposta(Curl.get("#{urb}/#{uri}", ops) { |r| r.headers = hdrs(url(uri, ops), nonce, {}) })
89
+ end
90
+
91
+ # HTTP POST request for private therock API queries involving user credentials.
92
+ def api_post(uri, **ops)
93
+ resposta(Curl.post("#{urb}/#{uri}", ops) { |r| r.headers = hdrs(uri, nonce, ops) })
94
+ end
95
+
96
+ # @return [String] URL do pedido formatado com todos os parametros
97
+ def url(uri, ops)
98
+ ops.empty? ? uri : "#{uri}?#{URI.encode_www_form(ops)}"
99
+ end
100
+
101
+ # @return [Hash] headers necessarios para pedido HTTP
102
+ def hdrs(qry, non, ops)
103
+ {
104
+ content_type: 'application/json',
105
+ 'X-TRT-KEY': aky,
106
+ 'X-TRT-NONCE': non,
107
+ 'X-TRT-SIGN': auth(qry, non, URI.encode_www_form(ops))
108
+ }
109
+ end
110
+
111
+ # @return [String] assinarura codificada dos pedidos HTTP
112
+ def auth(qry, non, par)
113
+ raise(ArgumentError, 'API Key is not set') unless aky
114
+ raise(ArgumentError, 'API Secret is not set') unless asc
115
+
116
+ OpenSSL::HMAC.hexdigest('sha512', asc, [non, "#{urb}/#{qry}", par].join)
117
+ end
118
+
119
+ # @return [Integer] continually-increasing unsigned integer nonce from the current Unix Time
120
+ def nonce
121
+ Integer(Float(Time.now) * 1e6)
122
+ end
123
+
124
+ # @return [Hash] resposta do pedido HTTP
125
+ def resposta(http)
126
+ http.response_code == 200 ? JSON.parse(http.body, symbolize_names: true) : http.status
127
+ rescue JSON::ParserError,
128
+ EOFError,
129
+ Errno::ECONNRESET,
130
+ Errno::EINVAL,
131
+ Net::HTTPBadResponse,
132
+ Net::HTTPHeaderSyntaxError,
133
+ Net::ProtocolError,
134
+ Timeout::Error => e
135
+ "Erro da API therock #{e.inspect}"
136
+ end
137
+ end
138
+ end