package api import ( "encoding/base64" "strconv" "time" "github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/db/historydb" "github.com/iden3/go-iden3-crypto/babyjub" ) // Commons of the API type pagination struct { TotalItems int `json:"totalItems"` LastReturnedItem int `json:"lastReturnedItem"` } type paginationer interface { GetPagination() pagination Len() int } type errorMsg struct { Message string } // History Tx related type historyTxsAPI struct { Txs []historyTxAPI `json:"transactions"` Pagination pagination `json:"pagination"` } func (htx *historyTxsAPI) GetPagination() pagination { return htx.Pagination } func (htx *historyTxsAPI) Len() int { return len(htx.Txs) } type l1Info struct { ToForgeL1TxsNum int64 `json:"toForgeL1TransactionsNum"` UserOrigin bool `json:"userOrigin"` FromEthAddr string `json:"fromEthereumAddress"` FromBJJ string `json:"fromBJJ"` LoadAmount string `json:"loadAmount"` LoadAmountUSD float64 `json:"loadAmountUSD"` EthBlockNum int64 `json:"ethereumBlockNum"` } type l2Info struct { Fee common.FeeSelector `json:"fee"` FeeUSD float64 `json:"feeUSD"` Nonce common.Nonce `json:"nonce"` } type historyTxAPI struct { IsL1 string `json:"L1orL2"` TxID common.TxID `json:"id"` Type common.TxType `json:"type"` Position int `json:"position"` FromIdx string `json:"fromAccountIndex"` ToIdx string `json:"toAccountIndex"` Amount string `json:"amount"` BatchNum *common.BatchNum `json:"batchNum"` TokenID common.TokenID `json:"tokenId"` TokenSymbol string `json:"tokenSymbol"` USD float64 `json:"historicUSD"` Timestamp time.Time `json:"timestamp"` CurrentUSD float64 `json:"currentUSD"` USDUpdate time.Time `json:"fiatUpdate"` L1Info *l1Info `json:"L1Info"` L2Info *l2Info `json:"L2Info"` } func historyTxsToAPI(dbTxs []*historydb.HistoryTx) []historyTxAPI { apiTxs := []historyTxAPI{} for i := 0; i < len(dbTxs); i++ { apiTx := historyTxAPI{ TxID: dbTxs[i].TxID, Type: dbTxs[i].Type, Position: dbTxs[i].Position, FromIdx: "hez:" + dbTxs[i].TokenSymbol + ":" + strconv.Itoa(int(dbTxs[i].FromIdx)), ToIdx: "hez:" + dbTxs[i].TokenSymbol + ":" + strconv.Itoa(int(dbTxs[i].ToIdx)), Amount: dbTxs[i].Amount.String(), TokenID: dbTxs[i].TokenID, USD: dbTxs[i].USD, BatchNum: nil, Timestamp: dbTxs[i].Timestamp, TokenSymbol: dbTxs[i].TokenSymbol, CurrentUSD: dbTxs[i].CurrentUSD, USDUpdate: dbTxs[i].USDUpdate, L1Info: nil, L2Info: nil, } bn := dbTxs[i].BatchNum if dbTxs[i].BatchNum != 0 { apiTx.BatchNum = &bn } if dbTxs[i].IsL1 { apiTx.IsL1 = "L1" apiTx.L1Info = &l1Info{ ToForgeL1TxsNum: dbTxs[i].ToForgeL1TxsNum, UserOrigin: dbTxs[i].UserOrigin, FromEthAddr: "hez:" + dbTxs[i].FromEthAddr.String(), FromBJJ: bjjToString(dbTxs[i].FromBJJ), LoadAmount: dbTxs[i].LoadAmount.String(), LoadAmountUSD: dbTxs[i].LoadAmountUSD, EthBlockNum: dbTxs[i].EthBlockNum, } } else { apiTx.IsL1 = "L2" apiTx.L2Info = &l2Info{ Fee: dbTxs[i].Fee, FeeUSD: dbTxs[i].FeeUSD, Nonce: dbTxs[i].Nonce, } } apiTxs = append(apiTxs, apiTx) } return apiTxs } func bjjToString(bjj *babyjub.PublicKey) string { pkComp := [32]byte(bjj.Compress()) sum := pkComp[0] for i := 1; i < len(pkComp); i++ { sum += pkComp[i] } bjjSum := append(pkComp[:], sum) return "hez:" + base64.RawURLEncoding.EncodeToString(bjjSum) }