bct 0.1.1 → 0.1.3

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: 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: []