bct 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d5c863b483ea4006cb6041d099d4e754555155fcea9855b5de2ea0e6df21d9a
4
- data.tar.gz: 89450be0aeb6aab2ffd00a8ebeb04666e320461e63131442b48ed0472b352227
3
+ metadata.gz: 31df00355fbff1327239b4a58cb208ef657ae0d2c260710557494d8b6273d9d0
4
+ data.tar.gz: 2d683c8e324fc18a78f31276447f40a39a386727f14b94528bcbcbda0a68a135
5
5
  SHA512:
6
- metadata.gz: 1620f81ae18d81dbdd788ff283889fc9fd97fdc57ff03cedd29b76fdae4f32fde368870e9a8a8422085ca729a3cd57a4fe6ed1ec3dff41b96e94bb63c056e620
7
- data.tar.gz: c7c616fba61dabbdc2694a3e3a8aab67f25c821cdadae0cd2f565696678ce12376065e9c47166f2bf59a840eb34c6383b287d815dace0a7f8164ab0d4d2d2d69
6
+ metadata.gz: 6b210ad6e12b94764f19f2e8f40d324696ae65fedda5bc3d996552607ac1086691c21cda59485b01875a21c76f268bfe5ea90e77c4741a2bf22ae219b133b1c1
7
+ data.tar.gz: 24cb2c0df27c3c49736d604106a4aaaac8f6dc9fbdbabad7ee232d40f51bc64e8ecc3cce02673d45c9d002413ff083cdc13ec7fd26b5f66614bbcf366abfc907
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bct (0.1.1)
4
+ bct (0.1.3)
5
5
  faraday
6
6
  google-cloud-bigquery
7
7
  thor
@@ -17,15 +17,16 @@ GEM
17
17
  declarative-option (0.1.0)
18
18
  faraday (1.0.1)
19
19
  multipart-post (>= 1.2, < 3)
20
- google-api-client (0.44.1)
20
+ google-api-client (0.44.2)
21
21
  addressable (~> 2.5, >= 2.5.1)
22
22
  googleauth (~> 0.9)
23
23
  httpclient (>= 2.8.1, < 3.0)
24
24
  mini_mime (~> 1.0)
25
25
  representable (~> 3.0)
26
26
  retriable (>= 2.0, < 4.0)
27
+ rexml
27
28
  signet (~> 0.12)
28
- google-cloud-bigquery (1.21.2)
29
+ google-cloud-bigquery (1.22.0)
29
30
  concurrent-ruby (~> 1.0)
30
31
  google-api-client (~> 0.33)
31
32
  google-cloud-core (~> 1.2)
@@ -58,6 +59,7 @@ GEM
58
59
  declarative-option (< 0.2.0)
59
60
  uber (< 0.2.0)
60
61
  retriable (3.1.2)
62
+ rexml (3.2.4)
61
63
  signet (0.14.0)
62
64
  addressable (~> 2.3)
63
65
  faraday (>= 0.17.3, < 2.0)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Bct [![Build Status](https://travis-ci.com/hernanirvaz/bct.svg?branch=master)](https://travis-ci.com/hernanirvaz/bct)
2
2
 
3
- Arquiva transactions etherscan/bloks no bigquery. Pode ajustar dias para reposicionamento temporal.
3
+ Arquiva transactions etherscan/greymass no bigquery. Pode ajustar dias para reposicionamento temporal.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['Hernâni Rodrigues Vaz']
9
9
  spec.email = ['hernanirvaz@gmail.com']
10
10
 
11
- spec.summary = 'Arquiva transactions etherscan/bloks no bigquery.'
11
+ spec.summary = 'Arquiva transactions etherscan/greymass no bigquery.'
12
12
  spec.description = "#{spec.summary} Pode ajustar dias para reposicionamento temporal."
13
13
  spec.homepage = 'https://github.com/hernanirvaz/bct'
14
14
  spec.license = 'MIT'
data/lib/bct.rb CHANGED
@@ -1,18 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require('thor')
4
+ require('bct/apies')
5
+ require('bct/apigm')
6
+ require('bct/bigquery1')
7
+ require('bct/bigquery2')
8
+ require('bct/etherscan1')
9
+ require('bct/etherscan2')
10
+ require('bct/greymass1')
11
+ require('bct/greymass2')
4
12
  require('bct/version')
5
13
 
6
14
  module Bct
7
- class Error < StandardError; end
15
+ # classe para erros desta gem
16
+ class Erro < StandardError
17
+ # @return [StandardError] personalizacao dos erros
18
+ def initialize(msg)
19
+ super(msg)
20
+ end
21
+ end
8
22
 
9
- # classe para carregar/mostrar dados transacoes kraken no bigquery
23
+ # classe para carregar/mostrar dados transacoes eth & eos no bigquery
10
24
  class CLI < Thor
11
25
  desc 'work', 'carrega transacoes novas no bigquery'
12
26
  option :h, type: :hash, default: {}, desc: 'configuracao ajuste reposicionamento temporal'
13
27
  # carrega transacoes novas no bigquery
14
28
  def work
15
- Bigquery.new(options).processa_tudo
29
+ Bct::Bigquery.new(options).processa_tudo
16
30
  end
17
31
 
18
32
  desc 'show', 'mostra resumo transacoes'
@@ -20,7 +34,7 @@ module Bct
20
34
  option :t, type: :boolean, default: false, desc: 'mostra transacoes todas ou somente novas'
21
35
  # mostra resumo transacoes
22
36
  def show
23
- Bigquery.new(options).mostra_tudo
37
+ Bct::Bigquery.new(options).mostra_tudo
24
38
  end
25
39
 
26
40
  default_task :show
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('faraday')
4
+ require('json')
5
+
6
+ # @author Hernani Rodrigues Vaz
7
+ module Bct
8
+ # classe para acesso dados blockchain ETH
9
+ class Apies
10
+ # @return [String] apikey a juntar aos pedidos HTTP url:
11
+ attr_reader :key
12
+ # @return [String] base URL to use as a prefix for all requests
13
+ attr_reader :url
14
+
15
+ # @param [String] chv apikey a juntar aos pedidos HTTP url:
16
+ # @param [String] www base URL to use as a prefix for all requests
17
+ # @return [Apies] API etherscan base
18
+ def initialize(chv: ENV['ETHERSCAN_API_KEY'], www: 'https://api.etherscan.io/')
19
+ @key = chv
20
+ @url = www
21
+ end
22
+
23
+ # @return [<Symbol>] adapter for the connection - default :net_http
24
+ def adapter
25
+ @adapter ||= Faraday.default_adapter
26
+ end
27
+
28
+ # @return [<Faraday::Connection>] connection object with an URL & adapter
29
+ def conn
30
+ @conn ||=
31
+ Faraday.new(url: url) do |c|
32
+ c.request(:url_encoded)
33
+ c.adapter(adapter)
34
+ end
35
+ end
36
+
37
+ # @example
38
+ # [
39
+ # { account: '0x...', balance: '4000000000000000000' },
40
+ # { account: '0x...', balance: '87000000000000000000' }
41
+ # ]
42
+ # @param [String] ads lista enderecos carteiras ETH (max 20)
43
+ # @return [Array<Hash>] devolve lista com dados & saldo de carteiras ETH
44
+ def account(ads)
45
+ raise(Erro, 'maximo de 20 enderecos') if ads.size > 20
46
+
47
+ get(action: 'balancemulti', address: ads.join(','), tag: 'latest')[:result]
48
+ end
49
+
50
+ # @example
51
+ # [
52
+ # {
53
+ # blockNumber: '4984535',
54
+ # timeStamp: '1517094794',
55
+ # hash: '0x...',
56
+ # nonce: '10',
57
+ # blockHash: '0x...',
58
+ # transactionIndex: '17',
59
+ # from: '0x...',
60
+ # to: '0x...',
61
+ # value: '52627271000000000000',
62
+ # gas: '21000',
63
+ # gasPrice: '19000000000',
64
+ # isError: '0',
65
+ # txreceipt_status: '1',
66
+ # input: '0x',
67
+ # contractAddress: '',
68
+ # gasUsed: '21000',
69
+ # cumulativeGasUsed: '566293',
70
+ # confirmations: '5848660'
71
+ # },
72
+ # {}
73
+ # ]
74
+ # @param [String] add endereco carteira ETH
75
+ # @param [Hash] arg argumentos trabalho
76
+ # @option arg [Integer] :start_block starting blockNo to retrieve results
77
+ # @option arg [Integer] :end_block ending blockNo to retrieve results
78
+ # @option arg [String] :sort asc -> ascending order, desc -> descending order
79
+ # @option arg [Integer] :page to get paginated results
80
+ # @option arg [Integer] :offset max records to return
81
+ # @return [Array<Hash>] lista de transacoes
82
+ def norml_tx(add, **arg)
83
+ raise(Erro, 'endereco tem de ser definido') if add.nil? || add.empty?
84
+
85
+ ledger(**arg.merge(action: 'txlist', address: add))
86
+ end
87
+
88
+ # @example registo duplicado
89
+ # [
90
+ # {
91
+ # blockNumber: '3967652',
92
+ # timeStamp: '1499081515',
93
+ # hash: '0x registo duplicado com todos os dados iguais',
94
+ # nonce: '3',
95
+ # blockHash: '0x00a49e999036dc13dc6c4244bb1d51d3146fe7f00bfb500a7624d82e299c7328',
96
+ # from: '0xd0a6e6c54dbc68db5db3a091b171a77407ff7ccf',
97
+ # contractAddress: '0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0',
98
+ # to: '0x...',
99
+ # value: '0',
100
+ # tokenName: 'EOS',
101
+ # tokenSymbol: 'EOS',
102
+ # tokenDecimal: '18',
103
+ # transactionIndex: '83',
104
+ # gas: '173399',
105
+ # gasPrice: '21000000000',
106
+ # gasUsed: '173398',
107
+ # input: 'deprecated',
108
+ # cumulativeGasUsed: '7484878',
109
+ # confirmations: '3442641'
110
+ # },
111
+ # {}
112
+ # ]
113
+ # @param add (see norml_tx)
114
+ # @param [String] cdd token address (nil to get a list of all ERC20 transactions)
115
+ # @param arg (see norml_tx)
116
+ # @option arg (see norml_tx)
117
+ # @return [Array<Hash>] lista de token transfer events
118
+ def token_tx(add, cdd = nil, **arg)
119
+ raise(Erro, 'contrato ou endereco tem de estar definido') if (cdd || add).nil? || (cdd || add).empty?
120
+
121
+ # registos duplicados aparecem em token events (ver exemplo acima)
122
+ # -quando ha erros na blockchain (acho)
123
+ # -quando ha token events identicos no mesmo block (acho)
124
+ ledger(**arg.merge(action: 'tokentx', address: add, contractaddress: cdd))
125
+ end
126
+
127
+ # @param [Integer] pag pagina das transacoes a devolver
128
+ # @param [Array<Hash>] ary lista acumuladora das transacoes a devolver
129
+ # @param arg (see norml_tx)
130
+ # @option arg (see norml_tx)
131
+ # @return [Array<Hash>] devolve lista de transacoes/token transfer events
132
+ def ledger(pag = 0, ary = [], **arg)
133
+ r = get(**arg.merge(page: pag + 1, offset: 10_000))[:result]
134
+ ary += r
135
+ r.count < 10_000 ? ary : ledger(pag + 1, ary, **arg)
136
+ rescue StandardError
137
+ ary
138
+ end
139
+
140
+ private
141
+
142
+ # @example
143
+ # {
144
+ # status: '1',
145
+ # message: 'OK',
146
+ # result: []
147
+ # }
148
+ # @return [Hash] resultado do HTTP request
149
+ def get(**arg)
150
+ JSON.parse(
151
+ (conn.get('api') do |o|
152
+ o.headers = { content_type: 'application/json', accept: 'application/json', user_agent: 'etherscan;ruby' }
153
+ o.params = arg.merge(module: 'account', apikey: key).reject { |_, v| v.nil? }
154
+ end).body,
155
+ symbolize_names: true
156
+ )
157
+ rescue StandardError
158
+ { result: [] }
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('faraday')
4
+ require('json')
5
+
6
+ module Bct
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,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('google/cloud/bigquery')
4
+ require('bigdecimal/util')
5
+
6
+ # @author Hernani Rodrigues Vaz
7
+ module Bct
8
+ BD = 'hernanirvaz.coins'
9
+
10
+ # (see Bigquery)
11
+ class Bigquery
12
+ # @return [Google::Cloud::Bigquery] API bigquery
13
+ attr_reader :api
14
+ # @return [Google::Cloud::Bigquery::QueryJob] job bigquery
15
+ attr_reader :job
16
+ # @return [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho
17
+ attr_reader :ops
18
+ # @return (see sql)
19
+ attr_reader :sqr
20
+
21
+ # @param [Thor::CoreExt::HashWithIndifferentAccess] pop opcoes trabalho
22
+ # @option pop [Hash] :h ({}) configuracao ajuste reposicionamento temporal
23
+ # @option pop [Boolean] :v (false) mostra transacoes normais & token?
24
+ # @option pop [Boolean] :t (false) mostra transacoes todas ou somente novas?
25
+ # @return [Bigquery] API bigquery & API etherscan
26
+ def initialize(pop)
27
+ # usa env GOOGLE_APPLICATION_CREDENTIALS para obter credentials
28
+ # @see https://cloud.google.com/bigquery/docs/authentication/getting-started
29
+ @api = Google::Cloud::Bigquery.new
30
+ @ops = pop
31
+ end
32
+
33
+ # @return [Etherscan] API etherscan
34
+ def apies
35
+ @apies ||= Etherscan.new(
36
+ {
37
+ wb: sql("select * from #{BD}.walletEth order by 2"),
38
+ nt: sql("select itx,iax from #{BD}.ethtx"),
39
+ nk: sql("select itx,iax from #{BD}.ethkx")
40
+ },
41
+ ops
42
+ )
43
+ end
44
+
45
+ # @return [Greymass] API greymass
46
+ def apigm
47
+ @apigm ||= Greymass.new(
48
+ {
49
+ wb: sql("select * from #{BD}.walletEos order by 2"),
50
+ nt: sql("select itx,iax from #{BD}.eostx")
51
+ },
52
+ ops
53
+ )
54
+ end
55
+
56
+ # mostra resumos e transacoes etherscan & greymass
57
+ def mostra_tudo
58
+ apies.mostra_resumo
59
+ apigm.mostra_resumo
60
+ end
61
+
62
+ # insere transacoes novas nas tabelas todas etht, ethk, eos
63
+ def processa_tudo
64
+ processa_eth
65
+ puts(format("%<n>2i LINHAS INSERIDAS #{BD}.eos ", n: apigm.novax.count.positive? ? dml(eost_ins) : 0))
66
+ end
67
+
68
+ # insere transacoes novas nas tabelas etht (trx normais), ethk (trx token)
69
+ def processa_eth
70
+ puts(format("%<n>2i LINHAS INSERIDAS #{BD}.etht", n: apies.novtx.count.positive? ? dml(etht_ins) : 0))
71
+ puts(format("%<n>2i LINHAS INSERIDAS #{BD}.ethk", n: apies.novkx.count.positive? ? dml(ethk_ins) : 0))
72
+ end
73
+
74
+ # cria job bigquery & verifica execucao
75
+ #
76
+ # @param cmd (see sql)
77
+ # @return [Boolean] job ok?
78
+ def job?(cmd)
79
+ @job = api.query_job(cmd)
80
+ @job.wait_until_done!
81
+ puts(@job.error['message']) if @job.failed?
82
+ @job.failed?
83
+ end
84
+
85
+ # cria Structured Query Language (SQL) job bigquery
86
+ #
87
+ # @param [String] cmd comando SQL a executar
88
+ # @param [String] red resultado quando SQL tem erro
89
+ # @return [Google::Cloud::Bigquery::Data] resultado do SQL
90
+ def sql(cmd, red = [])
91
+ @sqr = job?(cmd) ? red : job.data
92
+ end
93
+
94
+ # cria Data Manipulation Language (DML) job bigquery
95
+ #
96
+ # @param cmd (see sql)
97
+ # @return [Integer] numero linhas afetadas
98
+ def dml(cmd)
99
+ job?(cmd) ? 0 : job.num_dml_affected_rows
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('google/cloud/bigquery')
4
+ require('bigdecimal/util')
5
+
6
+ # @author Hernani Rodrigues Vaz
7
+ module Bct
8
+ # classe para processar etherscan/greymass & bigquery
9
+ class Bigquery
10
+ # @return [String] comando insert SQL formatado etht (trx normais)
11
+ def etht_ins
12
+ "insert #{BD}.etht(blocknumber,timestamp,txhash,nonce,blockhash,transactionindex,axfrom,axto,iax," \
13
+ 'value,gas,gasprice,gasused,iserror,txreceipt_status,input,contractaddress,dias' \
14
+ ") VALUES#{apies.novtx.map { |e| etht_val1(e) }.join(',')}"
15
+ end
16
+
17
+ # @return [String] valores formatados etht (trx normais parte1)
18
+ def etht_val1(htx)
19
+ "(#{Integer(htx[:blockNumber])}," \
20
+ "#{Integer(htx[:timeStamp])}," \
21
+ "'#{htx[:hash]}'," \
22
+ "#{Integer(htx[:nonce])}," \
23
+ "'#{htx[:blockHash]}'," \
24
+ "#{Integer(htx[:transactionIndex])}," \
25
+ "'#{htx[:from]}'," \
26
+ "'#{htx[:to]}'," \
27
+ "'#{htx[:iax]}'," \
28
+ "#{etht_val2(htx)}"
29
+ end
30
+
31
+ # @return [String] valores formatados etht (trx normais parte2)
32
+ def etht_val2(htx)
33
+ "cast('#{htx[:value]}' as numeric)," \
34
+ "cast('#{htx[:gas]}' as numeric)," \
35
+ "cast('#{htx[:gasPrice]}' as numeric)," \
36
+ "cast('#{htx[:gasUsed]}' as numeric)," \
37
+ "#{Integer(htx[:isError])}," \
38
+ "#{htx[:txreceipt_status].length.zero? ? 'null' : htx[:txreceipt_status]}," \
39
+ "#{etht_val3(htx)}"
40
+ end
41
+
42
+ # @return [String] valores formatados etht (trx normais parte3)
43
+ def etht_val3(htx)
44
+ "#{htx[:input].length.zero? ? 'null' : "'#{htx[:input]}'"}," \
45
+ "#{htx[:contractAddress].length.zero? ? 'null' : "'#{htx[:contractAddress]}'"}," \
46
+ "#{Integer(ops[:h][htx[:blockNumber]] || 0)})"
47
+ end
48
+
49
+ # @return [String] comando insert SQL formatado ethk (trx token)
50
+ def ethk_ins
51
+ "insert #{BD}.ethk(blocknumber,timestamp,txhash,nonce,blockhash,transactionindex,axfrom,axto,iax," \
52
+ 'value,tokenname,tokensymbol,tokendecimal,gas,gasprice,gasused,input,contractaddress,dias' \
53
+ ") VALUES#{apies.novkx.map { |e| ethk_val1(e) }.join(',')}"
54
+ end
55
+
56
+ # @return [String] valores formatados ethk (trx token parte1)
57
+ def ethk_val1(hkx)
58
+ "(#{Integer(hkx[:blockNumber])}," \
59
+ "#{Integer(hkx[:timeStamp])}," \
60
+ "'#{hkx[:hash]}'," \
61
+ "#{Integer(hkx[:nonce])}," \
62
+ "'#{hkx[:blockHash]}'," \
63
+ "#{Integer(hkx[:transactionIndex])}," \
64
+ "'#{hkx[:from]}'," \
65
+ "'#{hkx[:to]}'," \
66
+ "'#{hkx[:iax]}'," \
67
+ "#{ethk_val2(hkx)}"
68
+ end
69
+
70
+ # @return [String] valores formatados ethk (trx token parte2)
71
+ def ethk_val2(hkx)
72
+ "cast('#{hkx[:value]}' as numeric)," \
73
+ "'#{hkx[:tokenName]}'," \
74
+ "'#{hkx[:tokenSymbol]}'," \
75
+ "#{Integer(hkx[:tokenDecimal])}," \
76
+ "cast('#{hkx[:gas]}' as numeric)," \
77
+ "cast('#{hkx[:gasPrice]}' as numeric)," \
78
+ "cast('#{hkx[:gasUsed]}' as numeric)," \
79
+ "#{ethk_val3(hkx)}"
80
+ end
81
+
82
+ # @return [String] valores formatados ethk (trx token parte3)
83
+ def ethk_val3(hkx)
84
+ "#{hkx[:input].length.zero? ? 'null' : "'#{hkx[:input]}'"}," \
85
+ "#{hkx[:contractAddress].length.zero? ? 'null' : "'#{hkx[:contractAddress]}'"}," \
86
+ "#{Integer(ops[:h][hkx[:blockNumber]] || 0)})"
87
+ end
88
+
89
+ # @return [String] comando insert SQL formatado eos
90
+ def eost_ins
91
+ "insert #{BD}.eos(gseq,aseq,bnum,time,contract,action,acfrom,acto,iax,amount,moeda,memo,dias" \
92
+ ") VALUES#{apigm.novax.map { |e| eost_val1(e) }.join(',')}"
93
+ end
94
+
95
+ # @param [Hash] htx transacao ligadas a uma carteira - sem elementos irrelevantes
96
+ # @return [String] valores formatados para insert eos (parte1)
97
+ def eost_val1(htx)
98
+ a = htx[:action_trace][:act]
99
+ "(#{htx[:global_action_seq]}," \
100
+ "#{htx[:account_action_seq]}," \
101
+ "#{htx[:block_num]}," \
102
+ "DATETIME(TIMESTAMP('#{htx[:block_time]}'))," \
103
+ "'#{a[:account]}'," \
104
+ "'#{a[:name]}'," \
105
+ "#{eost_val2(htx, a)}"
106
+ end
107
+
108
+ # @param [Hash] htx transacao ligadas a uma carteira - sem elementos irrelevantes
109
+ # @return [String] valores formatados para insert eos (parte2)
110
+ def eost_val2(htx, act)
111
+ d = act[:data]
112
+ q = d[:quantity].to_s
113
+ s = d[:memo].inspect
114
+ "'#{d[:from]}'," \
115
+ "'#{d[:to]}'," \
116
+ "'#{htx[:iax]}'," \
117
+ "#{q.to_d},'#{q[/[[:upper:]]+/]}'," \
118
+ "nullif('#{s.gsub(/['"]/, '')}','nil')," \
119
+ "#{ops[:h][String(htx[:itx])] || 0})"
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('bigdecimal/util')
4
+
5
+ # @author Hernani Rodrigues Vaz
6
+ module Bct
7
+ # chaves a eliminar da API - resultado deve ser ignirado pois muda a cada pedido API feito
8
+ DL = %i[cumulativeGasUsed confirmations].freeze
9
+
10
+ # (see Etherscan)
11
+ class Etherscan
12
+ # @return [Apies] API etherscan
13
+ attr_reader :api
14
+ # @return [Array<Hash>] todos os dados bigquery
15
+ attr_reader :dbq
16
+ # @return [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho
17
+ attr_reader :ops
18
+
19
+ # @param [Hash] dad todos os dados bigquery
20
+ # @param [Thor::CoreExt::HashWithIndifferentAccess] pop opcoes trabalho
21
+ # @option pop [Hash] :h ({}) configuracao dias ajuste reposicionamento temporal
22
+ # @option pop [Boolean] :v (false) mostra dados transacoes normais & tokens?
23
+ # @return [Etherscan] API etherscan - processar transacoes normais e tokens
24
+ def initialize(dad, pop)
25
+ @api = Apies.new
26
+ @dbq = dad
27
+ @ops = pop
28
+ end
29
+
30
+ # @return [Array<String>] lista dos meus enderecos
31
+ def lax
32
+ @lax ||= dbq[:wb].map { |h| h[:ax] }
33
+ end
34
+
35
+ # @return [Array<Hash>] todos os dados etherscan - saldos & transacoes
36
+ def dbc
37
+ @dbc ||= api.account(lax).map { |e| base_bc(e) }
38
+ end
39
+
40
+ # @return [Array<Hash>] todos os dados juntos bigquery & etherscan
41
+ def dados
42
+ @dados ||= dbq[:wb].map { |b| bq_bc(b, dbc.select { |s| b[:ax] == s[:ax] }.first) }
43
+ end
44
+
45
+ # @return [Array<Integer>] lista indices transacoes normais novas
46
+ def bnt
47
+ @bnt ||= (dbc.map { |e| e[:tx].map { |n| n[:itx] } }.flatten - (ops[:t] ? [] : dbq[:nt].map { |t| t[:itx] }))
48
+ end
49
+
50
+ # @return [Array<Integer>] lista indices transacoes token novas
51
+ def bnk
52
+ @bnk ||= (dbc.map { |e| e[:kx].map { |n| n[:itx] } }.flatten - (ops[:t] ? [] : dbq[:nk].map { |t| t[:itx] }))
53
+ end
54
+
55
+ # @return [Array<Hash>] lista transacoes normais novas
56
+ def novtx
57
+ @novtx ||= dbc.map { |e| e[:tx].select { |n| bnt.include?(n[:itx]) } }.flatten
58
+ end
59
+
60
+ # @return [Array<Hash>] lista transacoes token novas
61
+ def novkx
62
+ @novkx ||= dbc.map { |e| e[:kx].select { |n| bnk.include?(n[:itx]) } }.flatten
63
+ end
64
+
65
+ # @param [Hash] hbc dados etherscan
66
+ # @return [Hash] dados etherscan - address, saldo & transacoes
67
+ def base_bc(hbc)
68
+ a = hbc[:account]
69
+ {
70
+ ax: a,
71
+ sl: (hbc[:balance].to_d / 10**18).round(10),
72
+ tx: filtrar_tx(a, api.norml_tx(a)),
73
+ kx: filtrar_tx(a, api.token_tx(a))
74
+ }
75
+ end
76
+
77
+ # @param [Hash] hbq dados bigquery
78
+ # @param hbc (see base_bc)
79
+ # @return [Hash] dados juntos bigquery & etherscan
80
+ def bq_bc(hbq, hbc)
81
+ {
82
+ id: hbq[:id],
83
+ ax: hbq[:ax],
84
+ bs: hbq[:sl],
85
+ bt: dbq[:nt].select { |t| t[:iax] == hbq[:ax] },
86
+ bk: dbq[:nk].select { |t| t[:iax] == hbq[:ax] },
87
+ es: hbc[:sl],
88
+ et: hbc[:tx],
89
+ ek: hbc[:kx]
90
+ }
91
+ end
92
+
93
+ # @param [String] add endereco carteira ETH
94
+ # @param [Array<Hash>] ary lista das transacoes
95
+ # @return [Array<Hash>] devolve lista de transacoes/token transfer events filtrada
96
+ def filtrar_tx(add, ary)
97
+ # elimina transferencia from: (lax) to: (add) - esta transferencia aparece em from: (add) to: (lax)
98
+ # elimina chaves irrelevantes (DL) & adiciona chave indice itx & adiciona identificador da carteira iax
99
+ ary.delete_if { |h| h[:to] == add && lax.include?(h[:from]) }
100
+ .map { |h| h.delete_if { |k, _| DL.include?(k) }.merge(itx: Integer(h[:blockNumber]), iax: add) }
101
+ end
102
+
103
+ # @return [Array<Hash>] lista ordenada transacoes normais novas
104
+ def sortx
105
+ novtx.sort { |a, b| a[:itx] <=> b[:itx] }
106
+ end
107
+
108
+ # @return [Array<Hash>] lista ordenada transacoes token novas
109
+ def sorkx
110
+ novkx.sort { |a, b| a[:itx] <=> b[:itx] }
111
+ end
112
+
113
+ # @return [Array<Hash>] lista ordenada transacoes (normais & token) novas
114
+ def sorax
115
+ (novtx + novkx).sort { |a, b| a[:itx] <=> b[:itx] }
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @author Hernani Rodrigues Vaz
4
+ module Bct
5
+ # classe para processar carteiras & transacoes normais e tokens
6
+ class Etherscan
7
+ # @param [Hash] hjn dados juntos bigquery & etherscan
8
+ # @return [String] texto formatado duma carteira
9
+ def formata_carteira(hjn)
10
+ format(
11
+ '%<s1>-6.6s %<s2>-32.32s ',
12
+ s1: hjn[:id],
13
+ s2: formata_endereco(hjn[:ax], 32)
14
+ ) + formata_valores(hjn)
15
+ end
16
+
17
+ # @param (see formata_carteira)
18
+ # @return [String] texto formatado valores duma carteira
19
+ def formata_valores(hjn)
20
+ format(
21
+ '%<v1>11.6f %<n1>2i %<n3>2i %<v2>12.6f %<n2>2i %<n4>2i %<ok>-3s',
22
+ v1: hjn[:bs],
23
+ n1: hjn[:bt].count,
24
+ n3: hjn[:bk].count,
25
+ v2: hjn[:es],
26
+ n2: hjn[:et].count,
27
+ n4: hjn[:ek].count,
28
+ ok: ok?(hjn) ? 'OK' : 'NOK'
29
+ )
30
+ end
31
+
32
+ # @param (see formata_carteira)
33
+ # @return [Boolean] carteira tem transacoes novas(sim=NOK, nao=OK)?
34
+ def ok?(hjn)
35
+ hjn[:bs] == hjn[:es] && hjn[:bt].count == hjn[:et].count && hjn[:bk].count == hjn[:ek].count
36
+ end
37
+
38
+ # @example ether address inicio..fim
39
+ # 0x10f3a0cf0b534c..c033cf32e8a03586
40
+ # @param add (see filtrar_tx)
41
+ # @param [Integer] max chars a mostrar
42
+ # @return [String] endereco formatado
43
+ def formata_endereco(add, max)
44
+ i = Integer((max - 2) / 2)
45
+ e = (max <= 20 ? dbq[:wb].select { |s| s[:ax] == add }.first : nil) || { id: add }
46
+ max < 7 ? 'erro' : "#{e[:id][0, i - 3]}..#{add[-i - 3..]}"
47
+ end
48
+
49
+ # @param [Hash] htx transacao normal
50
+ # @return [String] texto formatado transacao normal
51
+ def formata_transacao_norml(htx)
52
+ format(
53
+ '%<bn>9i %<fr>-20.20s %<to>-20.20s %<dt>10.10s %<vl>17.6f',
54
+ bn: htx[:blockNumber],
55
+ fr: formata_endereco(htx[:from], 20),
56
+ to: formata_endereco(htx[:to], 20),
57
+ dt: Time.at(Integer(htx[:timeStamp])),
58
+ vl: (htx[:value].to_d / 10**18).round(10)
59
+ )
60
+ end
61
+
62
+ # @param [Hash] hkx transacao token
63
+ # @return [String] texto formatado transacao token
64
+ def formata_transacao_token(hkx)
65
+ format(
66
+ '%<bn>9i %<fr>-20.20s %<to>-20.20s %<dt>10.10s %<vl>11.3f %<sy>-5.5s',
67
+ bn: hkx[:blockNumber],
68
+ fr: formata_endereco(hkx[:from], 20),
69
+ to: formata_endereco(hkx[:to], 20),
70
+ dt: Time.at(Integer(hkx[:timeStamp])),
71
+ vl: (hkx[:value].to_d / 10**18).round(10),
72
+ sy: hkx[:tokenSymbol]
73
+ )
74
+ end
75
+
76
+ # @return [String] texto carteiras & transacoes & ajuste dias
77
+ def mostra_resumo
78
+ return unless dados.count.positive?
79
+
80
+ puts("\nid address bigquery nm tk etherscan nm tk")
81
+ dados.each { |e| puts(formata_carteira(e)) }
82
+ mostra_transacao_norml
83
+ mostra_transacao_token
84
+ mostra_configuracao_ajuste_dias
85
+ end
86
+
87
+ # @return [String] texto transacoes normais
88
+ def mostra_transacao_norml
89
+ return unless ops[:v] && novtx.count.positive?
90
+
91
+ puts("\ntx normal from to data valor")
92
+ sortx.each { |e| puts(formata_transacao_norml(e)) }
93
+ end
94
+
95
+ # @return [String] texto transacoes token
96
+ def mostra_transacao_token
97
+ return unless ops[:v] && novkx.count.positive?
98
+
99
+ puts("\ntx token from to data valor")
100
+ sorkx.each { |e| puts(formata_transacao_token(e)) }
101
+ end
102
+
103
+ # @return [String] texto configuracao ajuste dias das transacoes (normais & token)
104
+ def mostra_configuracao_ajuste_dias
105
+ return unless (novtx.count + novkx.count).positive?
106
+
107
+ puts("\nstring ajuste dias\n-h=#{sorax.map { |e| "#{e[:blockNumber]}:0" }.join(' ')}")
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('bigdecimal/util')
4
+
5
+ # @author Hernani Rodrigues Vaz
6
+ module Bct
7
+ # (see Greymass)
8
+ class Greymass
9
+ # @return [Apigm] API greymass
10
+ attr_reader :api
11
+ # @return [Array<Hash>] todos os dados bigquery
12
+ attr_reader :dbq
13
+ # @return [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho
14
+ attr_reader :ops
15
+
16
+ # @param [Hash] dad todos os dados bigquery
17
+ # @param [Thor::CoreExt::HashWithIndifferentAccess] pop opcoes trabalho
18
+ # @option pop [Hash] :h ({}) configuracao dias ajuste reposicionamento temporal
19
+ # @option pop [Boolean] :v (false) mostra dados transacoes?
20
+ # @option pop [Boolean] :t (false) mostra transacoes todas ou somente novas?
21
+ # @return [Greymass] API greymass - processar transacoes
22
+ def initialize(dad, pop)
23
+ @api = Apigm.new
24
+ @dbq = dad
25
+ @ops = pop
26
+ end
27
+
28
+ # @return [Array<String>] lista dos meus enderecos
29
+ def lax
30
+ @lax ||= dbq[:wb].map { |h| h[:ax] }
31
+ end
32
+
33
+ # @return [Array<Hash>] todos os dados greymass - saldos & transacoes
34
+ def dbc
35
+ @dbc ||= dbq[:wb].map { |e| base_bc(e) }
36
+ end
37
+
38
+ # @return [Array<Hash>] todos os dados juntos bigquery & greymass
39
+ def dados
40
+ @dados ||= dbq[:wb].map { |b| bq_bc(b, dbc.select { |s| b[:ax] == s[:ax] }.first) }
41
+ end
42
+
43
+ # @return [Array<Integer>] lista indices transacoes novas
44
+ def bnt
45
+ @bnt ||= (dbc.map { |e| e[:tx].map { |n| n[:itx] } }.flatten - (ops[:t] ? [] : dbq[:nt].map { |t| t[:itx] }))
46
+ end
47
+
48
+ # @return [Array<Hash>] lista transacoes novas
49
+ def novax
50
+ @novax ||= dbc.map { |e| e[:tx].select { |s| bnt.include?(s[:itx]) } }.flatten
51
+ end
52
+
53
+ # @param [Hash] hbq dados bigquery wallet
54
+ # @return [Hash] dados greymass - address, saldo & transacoes
55
+ def base_bc(hbq)
56
+ a = hbq[:ax]
57
+ {
58
+ ax: a,
59
+ sl: greymass_sl(a).inject(:+),
60
+ tx: filtrar_tx(a, api.all_tx(a))
61
+ }
62
+ end
63
+
64
+ # @param hbq (see base_bc)
65
+ # @param [Hash] hbc dados greymass
66
+ # @return [Hash] dados juntos bigquery & greymass
67
+ def bq_bc(hbq, hbc)
68
+ {
69
+ id: hbq[:id],
70
+ ax: hbq[:ax],
71
+ bs: hbq[:sl],
72
+ bt: dbq[:nt].select { |t| t[:iax] == hbq[:ax] },
73
+ es: hbc[:sl],
74
+ et: hbc[:tx]
75
+ }
76
+ end
77
+
78
+ # @param (see filtrar_tx)
79
+ # @return [Array<BigDecimal>] lista recursos - liquido, net, spu
80
+ def greymass_sl(add)
81
+ v = api.account(account_name: add)
82
+ [
83
+ v[:core_liquid_balance].to_d,
84
+ v[:total_resources][:net_weight].to_d,
85
+ v[:total_resources][:cpu_weight].to_d
86
+ ]
87
+ end
88
+
89
+ # @param [String] add endereco carteira EOS
90
+ # @param [Array<Hash>] ary lista das transacoes
91
+ # @return [Array<Hash>] lista transacoes ligadas a uma carteira filtrada
92
+ def filtrar_tx(add, ary)
93
+ # elimina transferencia from: (lax) to: (add) - esta transferencia aparece em from: (add) to: (lax)
94
+ # adiciona chave indice itx & adiciona identificador da carteira iax
95
+ ary.delete_if { |h| act_data(h)[:to] == add && lax.include?(act_data(h)[:from]) }
96
+ .map { |h| h.merge(itx: h[:global_action_seq], iax: add) }
97
+ end
98
+
99
+ # @return [Array<Hash>] lista ordenada transacoes novas
100
+ def sorax
101
+ novax.sort { |a, b| b[:itx] <=> a[:itx] }
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @author Hernani Rodrigues Vaz
4
+ module Bct
5
+ # classe para processar carteiras & transacoes
6
+ class Greymass
7
+ # @param [Hash] hjn dados juntos bigquery & greymass
8
+ # @return [String] texto formatado duma carteira
9
+ def formata_carteira(hjn)
10
+ format(
11
+ '%<s1>-12.12s %<v1>14.4f %<n1>4i %<v2>14.4f %<n2>4i %<ok>-3s',
12
+ s1: hjn[:ax],
13
+ v1: hjn[:bs],
14
+ n1: hjn[:bt].count,
15
+ v2: hjn[:es],
16
+ n2: hjn[:et].count,
17
+ ok: ok?(hjn) ? 'OK' : 'NOK'
18
+ )
19
+ end
20
+
21
+ # @param (see formata_carteira)
22
+ # @return [Boolean] carteira tem transacoes novas(sim=NOK, nao=OK)?
23
+ def ok?(hjn)
24
+ hjn[:bs] == hjn[:es] && hjn[:bt].count == hjn[:et].count
25
+ end
26
+
27
+ # @param [Hash] htx transacao
28
+ # @return [String] texto formatado transacao
29
+ def formata_transacao(htx)
30
+ format(
31
+ '%<bn>12i %<fr>-12.12s %<to>-12.12s %<ac>-10.10s %<dt>10.10s %<vl>12.4f %<sy>-6.6s',
32
+ bn: htx[:itx],
33
+ fr: act_data(htx)[:from],
34
+ to: act_data(htx)[:to],
35
+ ac: act(htx)[:name],
36
+ dt: Date.parse(htx[:block_time]),
37
+ vl: act_data_quantity(htx).to_d,
38
+ sy: act_data_quantity(htx)[/[[:upper:]]+/]
39
+ )
40
+ end
41
+
42
+ # @param (see formata_transacao)
43
+ # @return [Hash] dados da acao
44
+ def act(htx)
45
+ htx[:action_trace][:act]
46
+ end
47
+
48
+ # @param (see formata_transacao)
49
+ # @return [Hash] dados da acao
50
+ def act_data(htx)
51
+ act(htx)[:data]
52
+ end
53
+
54
+ # @param (see formata_transacao)
55
+ # @return [String] dados da quantidade
56
+ def act_data_quantity(htx)
57
+ act_data(htx)[:quantity].to_s
58
+ end
59
+
60
+ # @return [String] texto carteiras & transacoes & ajuste dias
61
+ def mostra_resumo
62
+ return unless dados.count.positive?
63
+
64
+ puts("\naddress bigquery ntx greymass ntx")
65
+ dados.each { |e| puts(formata_carteira(e)) }
66
+ mostra_transacoes_novas
67
+ mostra_configuracao_ajuste_dias
68
+ end
69
+
70
+ # @return [String] texto transacoes
71
+ def mostra_transacoes_novas
72
+ return unless ops[:v] && novax.count.positive?
73
+
74
+ puts("\nsequence num from to accao data valor moeda")
75
+ sorax.each { |e| puts(formata_transacao(e)) }
76
+ end
77
+
78
+ # @return [String] texto configuracao ajuste dias das transacoes
79
+ def mostra_configuracao_ajuste_dias
80
+ return unless novax.count.positive?
81
+
82
+ puts("\nstring ajuste dias\n-h=#{sorax.map { |e| "#{e[:itx]}:0" }.join(' ')}")
83
+ end
84
+ end
85
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bct
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hernâni Rodrigues Vaz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-10 00:00:00.000000000 Z
11
+ date: 2020-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,8 +94,8 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: Arquiva transactions etherscan/bloks no bigquery. Pode ajustar dias para
98
- reposicionamento temporal.
97
+ description: Arquiva transactions etherscan/greymass no bigquery. Pode ajustar dias
98
+ para reposicionamento temporal.
99
99
  email:
100
100
  - hernanirvaz@gmail.com
101
101
  executables:
@@ -117,6 +117,14 @@ files:
117
117
  - bin/setup
118
118
  - exe/bct
119
119
  - lib/bct.rb
120
+ - lib/bct/apies.rb
121
+ - lib/bct/apigm.rb
122
+ - lib/bct/bigquery1.rb
123
+ - lib/bct/bigquery2.rb
124
+ - lib/bct/etherscan1.rb
125
+ - lib/bct/etherscan2.rb
126
+ - lib/bct/greymass1.rb
127
+ - lib/bct/greymass2.rb
120
128
  - lib/bct/version.rb
121
129
  homepage: https://github.com/hernanirvaz/bct
122
130
  licenses:
@@ -142,5 +150,5 @@ requirements: []
142
150
  rubygems_version: 3.1.2
143
151
  signing_key:
144
152
  specification_version: 4
145
- summary: Arquiva transactions etherscan/bloks no bigquery.
153
+ summary: Arquiva transactions etherscan/greymass no bigquery.
146
154
  test_files: []