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