hermez-node/api/dbtoapistructs.go
api/dbtoapistructs.goRaw
1package api
2
3import (
4 "encoding/base64"
5 "strconv"
6 "time"
7
8 ethCommon "github.com/ethereum/go-ethereum/common"
9 "github.com/hermeznetwork/hermez-node/common"
10 "github.com/hermeznetwork/hermez-node/db"
11 "github.com/hermeznetwork/hermez-node/db/historydb"
12 "github.com/iden3/go-iden3-crypto/babyjub"
13 "github.com/iden3/go-merkletree"
14)
15
16type errorMsg struct {
17 Message string
18}
19
20func bjjToString(bjj *babyjub.PublicKey) string {
21 pkComp := [32]byte(bjj.Compress())
22 sum := pkComp[0]
23 for i := 1; i < len(pkComp); i++ {
24 sum += pkComp[i]
25 }
26 bjjSum := append(pkComp[:], sum)
27 return "hez:" + base64.RawURLEncoding.EncodeToString(bjjSum)
28}
29
30func ethAddrToHez(addr ethCommon.Address) string {
31 return "hez:" + addr.String()
32}
33
34func idxToHez(idx common.Idx, tokenSymbol string) string {
35 return "hez:" + tokenSymbol + ":" + strconv.Itoa(int(idx))
36}
37
38// History Tx
39
40type historyTxsAPI struct {
41 Txs []historyTxAPI `json:"transactions"`
42 Pagination *db.Pagination `json:"pagination"`
43}
44
45func (htx *historyTxsAPI) GetPagination() *db.Pagination {
46 if htx.Txs[0].ItemID < htx.Txs[len(htx.Txs)-1].ItemID {
47 htx.Pagination.FirstReturnedItem = htx.Txs[0].ItemID
48 htx.Pagination.LastReturnedItem = htx.Txs[len(htx.Txs)-1].ItemID
49 } else {
50 htx.Pagination.LastReturnedItem = htx.Txs[0].ItemID
51 htx.Pagination.FirstReturnedItem = htx.Txs[len(htx.Txs)-1].ItemID
52 }
53 return htx.Pagination
54}
55func (htx *historyTxsAPI) Len() int { return len(htx.Txs) }
56
57type l1Info struct {
58 ToForgeL1TxsNum *int64 `json:"toForgeL1TransactionsNum"`
59 UserOrigin bool `json:"userOrigin"`
60 FromEthAddr string `json:"fromHezEthereumAddress"`
61 FromBJJ string `json:"fromBJJ"`
62 LoadAmount string `json:"loadAmount"`
63 HistoricLoadAmountUSD *float64 `json:"historicLoadAmountUSD"`
64 EthBlockNum int64 `json:"ethereumBlockNum"`
65}
66
67type l2Info struct {
68 Fee common.FeeSelector `json:"fee"`
69 HistoricFeeUSD *float64 `json:"historicFeeUSD"`
70 Nonce common.Nonce `json:"nonce"`
71}
72
73type historyTxAPI struct {
74 IsL1 string `json:"L1orL2"`
75 TxID string `json:"id"`
76 ItemID int `json:"itemId"`
77 Type common.TxType `json:"type"`
78 Position int `json:"position"`
79 FromIdx *string `json:"fromAccountIndex"`
80 ToIdx string `json:"toAccountIndex"`
81 Amount string `json:"amount"`
82 BatchNum *common.BatchNum `json:"batchNum"`
83 HistoricUSD *float64 `json:"historicUSD"`
84 Timestamp time.Time `json:"timestamp"`
85 L1Info *l1Info `json:"L1Info"`
86 L2Info *l2Info `json:"L2Info"`
87 Token tokenAPI `json:"token"`
88}
89
90func historyTxsToAPI(dbTxs []historydb.HistoryTx) []historyTxAPI {
91 apiTxs := []historyTxAPI{}
92 for i := 0; i < len(dbTxs); i++ {
93 apiTx := historyTxAPI{
94 TxID: dbTxs[i].TxID.String(),
95 ItemID: dbTxs[i].ItemID,
96 Type: dbTxs[i].Type,
97 Position: dbTxs[i].Position,
98 ToIdx: idxToHez(dbTxs[i].ToIdx, dbTxs[i].TokenSymbol),
99 Amount: dbTxs[i].Amount.String(),
100 HistoricUSD: dbTxs[i].HistoricUSD,
101 BatchNum: dbTxs[i].BatchNum,
102 Timestamp: dbTxs[i].Timestamp,
103 Token: tokenAPI{
104 TokenID: dbTxs[i].TokenID,
105 EthBlockNum: dbTxs[i].TokenEthBlockNum,
106 EthAddr: dbTxs[i].TokenEthAddr,
107 Name: dbTxs[i].TokenName,
108 Symbol: dbTxs[i].TokenSymbol,
109 Decimals: dbTxs[i].TokenDecimals,
110 USD: dbTxs[i].TokenUSD,
111 USDUpdate: dbTxs[i].TokenUSDUpdate,
112 },
113 L1Info: nil,
114 L2Info: nil,
115 }
116 if dbTxs[i].FromIdx != nil {
117 fromIdx := new(string)
118 *fromIdx = idxToHez(*dbTxs[i].FromIdx, dbTxs[i].TokenSymbol)
119 apiTx.FromIdx = fromIdx
120 }
121 if dbTxs[i].IsL1 {
122 apiTx.IsL1 = "L1"
123 apiTx.L1Info = &l1Info{
124 ToForgeL1TxsNum: dbTxs[i].ToForgeL1TxsNum,
125 UserOrigin: *dbTxs[i].UserOrigin,
126 FromEthAddr: ethAddrToHez(*dbTxs[i].FromEthAddr),
127 FromBJJ: bjjToString(dbTxs[i].FromBJJ),
128 LoadAmount: dbTxs[i].LoadAmount.String(),
129 HistoricLoadAmountUSD: dbTxs[i].HistoricLoadAmountUSD,
130 EthBlockNum: dbTxs[i].EthBlockNum,
131 }
132 } else {
133 apiTx.IsL1 = "L2"
134 apiTx.L2Info = &l2Info{
135 Fee: *dbTxs[i].Fee,
136 HistoricFeeUSD: dbTxs[i].HistoricFeeUSD,
137 Nonce: *dbTxs[i].Nonce,
138 }
139 }
140 apiTxs = append(apiTxs, apiTx)
141 }
142 return apiTxs
143}
144
145// Exit
146
147type exitsAPI struct {
148 Exits []exitAPI `json:"exits"`
149 Pagination *db.Pagination `json:"pagination"`
150}
151
152func (e *exitsAPI) GetPagination() *db.Pagination {
153 if e.Exits[0].ItemID < e.Exits[len(e.Exits)-1].ItemID {
154 e.Pagination.FirstReturnedItem = e.Exits[0].ItemID
155 e.Pagination.LastReturnedItem = e.Exits[len(e.Exits)-1].ItemID
156 } else {
157 e.Pagination.LastReturnedItem = e.Exits[0].ItemID
158 e.Pagination.FirstReturnedItem = e.Exits[len(e.Exits)-1].ItemID
159 }
160 return e.Pagination
161}
162func (e *exitsAPI) Len() int { return len(e.Exits) }
163
164type exitAPI struct {
165 ItemID int `json:"itemId"`
166 BatchNum common.BatchNum `json:"batchNum"`
167 AccountIdx string `json:"accountIndex"`
168 MerkleProof *merkletree.CircomVerifierProof `json:"merkleProof"`
169 Balance string `json:"balance"`
170 InstantWithdrawn *int64 `json:"instantWithdrawn"`
171 DelayedWithdrawRequest *int64 `json:"delayedWithdrawRequest"`
172 DelayedWithdrawn *int64 `json:"delayedWithdrawn"`
173 Token tokenAPI `json:"token"`
174}
175
176func historyExitsToAPI(dbExits []historydb.HistoryExit) []exitAPI {
177 apiExits := []exitAPI{}
178 for i := 0; i < len(dbExits); i++ {
179 apiExits = append(apiExits, exitAPI{
180 ItemID: dbExits[i].ItemID,
181 BatchNum: dbExits[i].BatchNum,
182 AccountIdx: idxToHez(dbExits[i].AccountIdx, dbExits[i].TokenSymbol),
183 MerkleProof: dbExits[i].MerkleProof,
184 Balance: dbExits[i].Balance.String(),
185 InstantWithdrawn: dbExits[i].InstantWithdrawn,
186 DelayedWithdrawRequest: dbExits[i].DelayedWithdrawRequest,
187 DelayedWithdrawn: dbExits[i].DelayedWithdrawn,
188 Token: tokenAPI{
189 TokenID: dbExits[i].TokenID,
190 EthBlockNum: dbExits[i].TokenEthBlockNum,
191 EthAddr: dbExits[i].TokenEthAddr,
192 Name: dbExits[i].TokenName,
193 Symbol: dbExits[i].TokenSymbol,
194 Decimals: dbExits[i].TokenDecimals,
195 USD: dbExits[i].TokenUSD,
196 USDUpdate: dbExits[i].TokenUSDUpdate,
197 },
198 })
199 }
200 return apiExits
201}
202
203// Tokens
204
205type tokensAPI struct {
206 Tokens []tokenAPI `json:"tokens"`
207 Pagination *db.Pagination `json:"pagination"`
208}
209
210func (t *tokensAPI) GetPagination() *db.Pagination {
211 if t.Tokens[0].ItemID < t.Tokens[len(t.Tokens)-1].ItemID {
212 t.Pagination.FirstReturnedItem = t.Tokens[0].ItemID
213 t.Pagination.LastReturnedItem = t.Tokens[len(t.Tokens)-1].ItemID
214 } else {
215 t.Pagination.LastReturnedItem = t.Tokens[0].ItemID
216 t.Pagination.FirstReturnedItem = t.Tokens[len(t.Tokens)-1].ItemID
217 }
218 return t.Pagination
219}
220func (t *tokensAPI) Len() int { return len(t.Tokens) }
221
222type tokenAPI struct {
223 ItemID int `json:"itemId"`
224 TokenID common.TokenID `json:"id"`
225 EthBlockNum int64 `json:"ethereumBlockNum"` // Ethereum block number in which this token was registered
226 EthAddr ethCommon.Address `json:"ethereumAddress"`
227 Name string `json:"name"`
228 Symbol string `json:"symbol"`
229 Decimals uint64 `json:"decimals"`
230 USD *float64 `json:"USD"`
231 USDUpdate *time.Time `json:"fiatUpdate"`
232}
233
234func tokensToAPI(dbTokens []historydb.TokenRead) []tokenAPI {
235 apiTokens := []tokenAPI{}
236 for i := 0; i < len(dbTokens); i++ {
237 apiTokens = append(apiTokens, tokenAPI{
238 ItemID: dbTokens[i].ItemID,
239 TokenID: dbTokens[i].TokenID,
240 EthBlockNum: dbTokens[i].EthBlockNum,
241 EthAddr: dbTokens[i].EthAddr,
242 Name: dbTokens[i].Name,
243 Symbol: dbTokens[i].Symbol,
244 Decimals: dbTokens[i].Decimals,
245 USD: dbTokens[i].USD,
246 USDUpdate: dbTokens[i].USDUpdate,
247 })
248 }
249 return apiTokens
250}