cns 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/cns.rb +20 -2
- data/lib/cns/apide.rb +240 -0
- data/lib/cns/apies.rb +161 -0
- data/lib/cns/apifr.rb +139 -0
- data/lib/cns/apigm.rb +181 -0
- data/lib/cns/apimt.rb +138 -0
- data/lib/cns/apius.rb +167 -0
- data/lib/cns/bigquery1.rb +114 -0
- data/lib/cns/bigquery2.rb +76 -0
- data/lib/cns/bigquery3.rb +122 -0
- data/lib/cns/bigquery4.rb +151 -0
- data/lib/cns/bitcoinde.rb +135 -0
- data/lib/cns/etherscan1.rb +118 -0
- data/lib/cns/etherscan2.rb +110 -0
- data/lib/cns/greymass1.rb +104 -0
- data/lib/cns/greymass2.rb +85 -0
- data/lib/cns/kraken.rb +132 -0
- data/lib/cns/paymium.rb +106 -0
- data/lib/cns/therock.rb +95 -0
- data/lib/cns/version.rb +3 -1
- metadata +19 -1
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @author Hernani Rodrigues Vaz
|
4
|
+
module Cns
|
5
|
+
# (see Bigquery)
|
6
|
+
class Bigquery
|
7
|
+
# @return [String] comando insert SQL formatado det (trades)
|
8
|
+
def det_ins
|
9
|
+
"insert #{BD}.det(tp,btc,eur,time,user,id,dtc,dias) VALUES#{apide.trades.map { |h| det_val1(h) }.join(',')}"
|
10
|
+
end
|
11
|
+
|
12
|
+
# @example (see Apide#trades)
|
13
|
+
# @param [Hash] htx transacao trade apide
|
14
|
+
# @return [String] valores formatados det (trades parte1)
|
15
|
+
def det_val1(htx)
|
16
|
+
"('#{htx[:type]}'," \
|
17
|
+
'cast(' \
|
18
|
+
"#{htx[:type] == 'buy' ? htx[:amount_currency_to_trade_after_fee] : "-#{htx[:amount_currency_to_trade]}"}" \
|
19
|
+
' as numeric),' \
|
20
|
+
"cast(#{htx[:volume_currency_to_pay_after_fee]} as numeric)," \
|
21
|
+
"DATETIME(TIMESTAMP('#{htx[:successfully_finished_at]}'))," \
|
22
|
+
"'#{htx[:trading_partner_information][:username]}'," \
|
23
|
+
"#{det_val2(htx)}"
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param (see #det_val1)
|
27
|
+
# @return [String] valores formatados det (trades parte2)
|
28
|
+
def det_val2(htx)
|
29
|
+
"'#{htx[:trade_id]}'," \
|
30
|
+
"DATETIME(TIMESTAMP('#{htx[:trade_marked_as_paid_at]}'))," \
|
31
|
+
"#{Integer(ops[:h][htx[:trade_id]] || 0)})"
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String] comando insert SQL formatado ust (trades)
|
35
|
+
def ust_ins
|
36
|
+
"insert #{BD}.ust(txid,ordertxid,pair,time,type,ordertype,price,cost,fee,vol,margin,misc,ledgers,dias) " \
|
37
|
+
"VALUES#{apius.trades.map { |k, v| ust_val1(k, v) }.join(',')}"
|
38
|
+
end
|
39
|
+
|
40
|
+
# @example (see Apius#trades)
|
41
|
+
# @param [String] idx identificador transacao
|
42
|
+
# @param [Hash] htx transacao trade apius
|
43
|
+
# @return [String] valores formatados ust (trades parte1)
|
44
|
+
def ust_val1(idx, htx)
|
45
|
+
"('#{idx}'," \
|
46
|
+
"'#{htx[:ordertxid]}'," \
|
47
|
+
"'#{htx[:pair]}'," \
|
48
|
+
"PARSE_DATETIME('%s', '#{String(htx[:time].round)}')," \
|
49
|
+
"'#{htx[:type]}'," \
|
50
|
+
"'#{htx[:ordertype]}'," \
|
51
|
+
"cast(#{htx[:price]} as numeric)," \
|
52
|
+
"cast(#{htx[:cost]} as numeric)," \
|
53
|
+
"cast(#{htx[:fee]} as numeric)," \
|
54
|
+
"#{ust_val2(idx, htx)}"
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param (see #ust_val1)
|
58
|
+
# @return [String] valores formatados ust (trades parte2)
|
59
|
+
def ust_val2(idx, htx)
|
60
|
+
"cast(#{htx[:vol]} as numeric)," \
|
61
|
+
"cast(#{htx[:margin]} as numeric)," \
|
62
|
+
"#{htx[:misc].to_s.empty? ? 'null' : "'#{htx[:misc]}'"}," \
|
63
|
+
"'#{apius.ledger.select { |_, v| v[:refid] == idx }.keys.join(',') || ''}'," \
|
64
|
+
"#{Integer(ops[:h][idx] || 0)})"
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String] comando insert SQL formatado del (ledger)
|
68
|
+
def del_ins
|
69
|
+
"insert #{BD}.del(time,tp,qtxt,id,qt,fee,lgid) VALUES#{apide.ledger.map { |h| del_val(h) }.join(',')}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# @example (see Apide#deposit_hash)
|
73
|
+
# @example (see Apide#withdrawal_hash)
|
74
|
+
# @param [Hash] hlx transacao uniformizada deposits + withdrawals apide
|
75
|
+
# @return [String] valores formatados del (ledger)
|
76
|
+
def del_val(hlx)
|
77
|
+
"(DATETIME(TIMESTAMP('#{hlx[:time].iso8601}'))," \
|
78
|
+
"'#{hlx[:tp]}'," \
|
79
|
+
"'#{hlx[:qtxt]}'," \
|
80
|
+
"'#{hlx[:id]}'," \
|
81
|
+
"cast(#{hlx[:tp] == 'out' ? '-' : ''}#{hlx[:qt]} as numeric)," \
|
82
|
+
"cast(#{hlx[:fee]} as numeric)," \
|
83
|
+
"#{hlx[:lgid]})"
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [String] comando insert SQL formatado usl (ledger)
|
87
|
+
def usl_ins
|
88
|
+
"insert #{BD}.usl(txid,refid,time,type,aclass,asset,amount,fee) " \
|
89
|
+
"VALUES#{apius.ledger.map { |k, v| usl_val(k, v) }.join(',')}"
|
90
|
+
end
|
91
|
+
|
92
|
+
# @example (see Apius#ledger)
|
93
|
+
# @param idx (see #ust_val1)
|
94
|
+
# @param [Hash] hlx transacao ledger apius
|
95
|
+
# @return [String] valores formatados usl (ledger)
|
96
|
+
def usl_val(idx, hlx)
|
97
|
+
"('#{idx}'," \
|
98
|
+
"'#{hlx[:refid]}'," \
|
99
|
+
"PARSE_DATETIME('%s', '#{String(hlx[:time].round)}')," \
|
100
|
+
"'#{hlx[:type]}'," \
|
101
|
+
"#{hlx[:aclass].to_s.empty? ? 'null' : "'#{hlx[:aclass]}'"}," \
|
102
|
+
"'#{hlx[:asset]}'," \
|
103
|
+
"cast(#{hlx[:amount]} as numeric)," \
|
104
|
+
"cast(#{hlx[:fee]} as numeric))"
|
105
|
+
end
|
106
|
+
|
107
|
+
# @return [String] comando insert SQL formatado fr (ledger)
|
108
|
+
def frl_ins
|
109
|
+
"insert #{BD}.fr(uuid,tipo,valor,moe,time,dias) VALUES#{apifr.ledger.map { |h| frl_val(h) }.join(',')}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# @example (see Apifr#ledger)
|
113
|
+
# @param [Hash] hlx transacao ledger apifr
|
114
|
+
# @return [String] valores formatados frl (ledger)
|
115
|
+
def frl_val(hlx)
|
116
|
+
"('#{hlx[:uuid]}'," \
|
117
|
+
"'#{hlx[:name]}'," \
|
118
|
+
"cast(#{hlx[:amount]} as numeric)," \
|
119
|
+
"'#{hlx[:currency]}'," \
|
120
|
+
"PARSE_DATETIME('%s', '#{hlx[:created_at_int]}')," \
|
121
|
+
"#{Integer(ops[:h][hlx[:uuid]] || 0)})"
|
122
|
+
end
|
123
|
+
|
124
|
+
# @return [String] comando insert SQL formatado fr (ledger)
|
125
|
+
def mtl_ins
|
126
|
+
"insert #{BD}.mt(id,time,type,valor,moe,pair,note,trade_id,dias) " \
|
127
|
+
"VALUES#{apimt.ledger.map { |h| mtl_val1(h) }.join(',')}"
|
128
|
+
end
|
129
|
+
|
130
|
+
# @example (see Apimt#ledger)
|
131
|
+
# @param [Hash] hlx transacao ledger apimt
|
132
|
+
# @return [String] valores formatados mtl (ledger parte1)
|
133
|
+
def mtl_val1(hlx)
|
134
|
+
"(#{hlx[:id]}," \
|
135
|
+
"DATETIME(TIMESTAMP('#{hlx[:date]}'))," \
|
136
|
+
"'#{hlx[:type]}'," \
|
137
|
+
"cast(#{hlx[:price]} as numeric)," \
|
138
|
+
"'#{hlx[:currency]}'," \
|
139
|
+
"#{hlx[:fund_id].to_s.empty? ? 'null' : "'#{hlx[:fund_id]}'"}," \
|
140
|
+
"#{mtl_val2(hlx)}"
|
141
|
+
end
|
142
|
+
|
143
|
+
# @param hlx (see #mtl_val1)
|
144
|
+
# @return [String] valores formatados mtl (ledger parte2)
|
145
|
+
def mtl_val2(hlx)
|
146
|
+
"#{hlx[:note].to_s.empty? ? 'null' : "'#{hlx[:note]}'"}," \
|
147
|
+
"#{hlx[:trade_id].to_s.empty? ? 'null' : (hlx[:trade_id]).to_s}," \
|
148
|
+
"#{Integer(ops[:h][String(hlx[:id])] || 0)})"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('bigdecimal/util')
|
4
|
+
|
5
|
+
# @author Hernani Rodrigues Vaz
|
6
|
+
module Cns
|
7
|
+
# classe para processar saldos & transacoes trades e ledger do bitcoinde
|
8
|
+
class Bitcoinde
|
9
|
+
# @return [Apius] API bitcoinde
|
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 trades & ledger?
|
20
|
+
# @option pop [Boolean] :t (false) mostra transacoes todas ou somente novas?
|
21
|
+
# @return [Bitcoinde] API bitcoinde - obter saldos & transacoes trades e ledger
|
22
|
+
def initialize(dad, pop)
|
23
|
+
# API bitcoinde base
|
24
|
+
@api = Apide.new
|
25
|
+
@dbq = dad
|
26
|
+
@ops = pop
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Hash] dados exchange bitcoinde - saldos & transacoes trades e ledger
|
30
|
+
def exd
|
31
|
+
@exd ||= {
|
32
|
+
sl: api.account,
|
33
|
+
tt: api.trades,
|
34
|
+
tl: api.deposits + api.withdrawals
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Array<String>] lista txid de transacoes trades
|
39
|
+
def kyt
|
40
|
+
@kyt ||= exd[:tt].map { |h| h[:trade_id] }.flatten - (ops[:t] ? [] : dbq[:nt].map { |e| e[:txid] })
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Array<Integer>] lista txid de transacoes ledger
|
44
|
+
def kyl
|
45
|
+
@kyl ||= exd[:tl].map { |h| h[:lgid] }.flatten - (ops[:t] ? [] : dbq[:nl].map { |e| e[:txid] })
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Hash] transacoes trades
|
49
|
+
def trades
|
50
|
+
@trades ||= exd[:tt].select { |h| kyt.include?(h[:trade_id]) }
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Hash] transacoes ledger
|
54
|
+
def ledger
|
55
|
+
@ledger ||= exd[:tl].select { |h| kyl.include?(h[:lgid]) }
|
56
|
+
end
|
57
|
+
|
58
|
+
# @example (see Apide#account)
|
59
|
+
# @param [String] moe codigo bitcoinde da moeda
|
60
|
+
# @param [Hash] hsx saldo bitcoinde da moeda
|
61
|
+
# @return [String] texto formatado saldos (bitcoinde)
|
62
|
+
def formata_saldos(moe, hsx)
|
63
|
+
b = dbq[:sl][moe.downcase.to_sym].to_d
|
64
|
+
e = hsx[:total_amount].to_d
|
65
|
+
format(
|
66
|
+
'%<mo>-5.5s %<ex>21.9f %<bq>21.9f %<ok>3.3s',
|
67
|
+
mo: moe.upcase,
|
68
|
+
ex: e,
|
69
|
+
bq: b,
|
70
|
+
ok: e == b ? 'OK' : 'NOK'
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @example (see Apide#trades)
|
75
|
+
# @param (see Bigquery#det_val1)
|
76
|
+
# @return [String] texto formatado transacao trade
|
77
|
+
def formata_trades(htx)
|
78
|
+
format(
|
79
|
+
'%<ky>-6.6s %<dt>19.19s %<dp>10.10s %<ty>-5.5s %<mo>-8.8s %<vl>18.8f %<co>8.2f',
|
80
|
+
ky: htx[:trade_id],
|
81
|
+
dt: Time.parse(htx[:successfully_finished_at]),
|
82
|
+
dp: Time.parse(htx[:trade_marked_as_paid_at]),
|
83
|
+
ty: htx[:type],
|
84
|
+
mo: htx[:trading_pair].upcase,
|
85
|
+
vl: htx[:amount_currency_to_trade].to_d,
|
86
|
+
co: htx[:volume_currency_to_pay].to_d
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
# @example (see Apide#deposit_hash)
|
91
|
+
# @example (see Apide#withdrawal_hash)
|
92
|
+
# @param (see Bigquery#del_val)
|
93
|
+
# @return [String] texto formatado transacao ledger
|
94
|
+
def formata_ledger(hlx)
|
95
|
+
format(
|
96
|
+
'%<ky>6i %<dt>19.19s %<ty>-10.10s %<mo>-3.3s %<pr>19.8f %<vl>18.8f',
|
97
|
+
ky: hlx[:lgid],
|
98
|
+
dt: hlx[:time],
|
99
|
+
ty: hlx[:tp],
|
100
|
+
mo: hlx[:qtxt].upcase,
|
101
|
+
pr: hlx[:qt].to_d,
|
102
|
+
vl: hlx[:fee].to_d
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [String] texto saldos & transacoes & ajuste dias
|
107
|
+
def mostra_resumo
|
108
|
+
puts("\nBITCOINDE\nmoeda saldo bitcoinde saldo bigquery")
|
109
|
+
exd[:sl].each { |k, v| puts(formata_saldos(k, v)) }
|
110
|
+
|
111
|
+
mostra_trades
|
112
|
+
mostra_ledger
|
113
|
+
return unless trades.count.positive?
|
114
|
+
|
115
|
+
puts("\nstring ajuste dias dos trades\n-h=#{kyt.map { |e| "#{e}:0" }.join(' ')}")
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [String] texto transacoes trades
|
119
|
+
def mostra_trades
|
120
|
+
return unless ops[:v] && trades.count.positive?
|
121
|
+
|
122
|
+
puts("\ntrades data hora dt criacao tipo par ---------------qtd -----eur")
|
123
|
+
trades.sort { |a, b| Time.parse(b[:successfully_finished_at]) <=> Time.parse(a[:successfully_finished_at]) }
|
124
|
+
.each { |h| puts(formata_trades(h)) }
|
125
|
+
end
|
126
|
+
|
127
|
+
# @return [String] texto transacoes ledger
|
128
|
+
def mostra_ledger
|
129
|
+
return unless ops[:v] && ledger.count.positive?
|
130
|
+
|
131
|
+
puts("\nledger data hora tipo moe ---------quantidade -------------custo")
|
132
|
+
ledger.sort { |a, b| b[:time] <=> a[:time] }.each { |h| puts(formata_ledger(h)) }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('bigdecimal/util')
|
4
|
+
|
5
|
+
# @author Hernani Rodrigues Vaz
|
6
|
+
module Cns
|
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 Cns
|
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
|