github.com/cryptohub-digital/blockbook-fork@v0.0.0-20230713133354-673c927af7f1/api/types.go (about)

     1  package api
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"math/big"
     7  	"sort"
     8  	"time"
     9  
    10  	"github.com/cryptohub-digital/blockbook-fork/bchain"
    11  	"github.com/cryptohub-digital/blockbook-fork/bchain/coins/eth"
    12  	"github.com/cryptohub-digital/blockbook-fork/bchain/coins/xcb"
    13  	"github.com/cryptohub-digital/blockbook-fork/common"
    14  	"github.com/cryptohub-digital/blockbook-fork/db"
    15  )
    16  
    17  const maxUint32 = ^uint32(0)
    18  const maxInt = int(^uint(0) >> 1)
    19  const maxInt64 = int64(^uint64(0) >> 1)
    20  
    21  // AccountDetails specifies what data returns GetAddress and GetXpub calls
    22  type AccountDetails int
    23  
    24  const (
    25  	// AccountDetailsBasic - only that address is indexed and some basic info
    26  	AccountDetailsBasic AccountDetails = iota
    27  	// AccountDetailsTokens - basic info + tokens
    28  	AccountDetailsTokens
    29  	// AccountDetailsTokenBalances - basic info + token with balance
    30  	AccountDetailsTokenBalances
    31  	// AccountDetailsTxidHistory - basic + token balances + txids, subject to paging
    32  	AccountDetailsTxidHistory
    33  	// AccountDetailsTxHistoryLight - basic + tokens + easily obtained tx data (not requiring requests to backend), subject to paging
    34  	AccountDetailsTxHistoryLight
    35  	// AccountDetailsTxHistory - basic + tokens + full tx data, subject to paging
    36  	AccountDetailsTxHistory
    37  )
    38  
    39  // ErrUnsupportedXpub is returned when coin type does not support xpub address derivation or provided string is not an xpub
    40  var ErrUnsupportedXpub = errors.New("XPUB not supported")
    41  
    42  // APIError extends error by information if the error details should be returned to the end user
    43  type APIError struct {
    44  	Text   string
    45  	Public bool
    46  }
    47  
    48  func (e *APIError) Error() string {
    49  	return e.Text
    50  }
    51  
    52  // NewAPIError creates ApiError
    53  func NewAPIError(s string, public bool) error {
    54  	return &APIError{
    55  		Text:   s,
    56  		Public: public,
    57  	}
    58  }
    59  
    60  // Amount is datatype holding amounts
    61  type Amount big.Int
    62  
    63  // IsZeroBigInt if big int has zero value
    64  func IsZeroBigInt(b *big.Int) bool {
    65  	return len(b.Bits()) == 0
    66  }
    67  
    68  // Compare returns an integer comparing two Amounts. The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
    69  // Nil Amount is always less then non nil amount, two nil Amounts are equal
    70  func (a *Amount) Compare(b *Amount) int {
    71  	if b == nil {
    72  		if a == nil {
    73  			return 0
    74  		}
    75  		return 1
    76  	}
    77  	if a == nil {
    78  		return -1
    79  	}
    80  	return (*big.Int)(a).Cmp((*big.Int)(b))
    81  }
    82  
    83  // MarshalJSON Amount serialization
    84  func (a *Amount) MarshalJSON() (out []byte, err error) {
    85  	if a == nil {
    86  		return []byte(`"0"`), nil
    87  	}
    88  	return []byte(`"` + (*big.Int)(a).String() + `"`), nil
    89  }
    90  
    91  func (a *Amount) String() string {
    92  	if a == nil {
    93  		return ""
    94  	}
    95  	return (*big.Int)(a).String()
    96  }
    97  
    98  // DecimalString returns amount with decimal point placed according to parameter d
    99  func (a *Amount) DecimalString(d int) string {
   100  	return bchain.AmountToDecimalString((*big.Int)(a), d)
   101  }
   102  
   103  // AsBigInt returns big.Int type for the Amount (empty if Amount is nil)
   104  func (a *Amount) AsBigInt() big.Int {
   105  	if a == nil {
   106  		return *new(big.Int)
   107  	}
   108  	return big.Int(*a)
   109  }
   110  
   111  // AsInt64 returns Amount as int64 (0 if Amount is nil).
   112  // It is used only for legacy interfaces (socket.io)
   113  // and generally not recommended to use for possible loss of precision.
   114  func (a *Amount) AsInt64() int64 {
   115  	if a == nil {
   116  		return 0
   117  	}
   118  	return (*big.Int)(a).Int64()
   119  }
   120  
   121  // Vin contains information about single transaction input
   122  type Vin struct {
   123  	Txid      string                   `json:"txid,omitempty"`
   124  	Vout      uint32                   `json:"vout,omitempty"`
   125  	Sequence  int64                    `json:"sequence,omitempty"`
   126  	N         int                      `json:"n"`
   127  	AddrDesc  bchain.AddressDescriptor `json:"-"`
   128  	Addresses []string                 `json:"addresses,omitempty"`
   129  	IsAddress bool                     `json:"isAddress"`
   130  	IsOwn     bool                     `json:"isOwn,omitempty"`
   131  	ValueSat  *Amount                  `json:"value,omitempty"`
   132  	Hex       string                   `json:"hex,omitempty"`
   133  	Asm       string                   `json:"asm,omitempty"`
   134  	Coinbase  string                   `json:"coinbase,omitempty"`
   135  }
   136  
   137  // Vout contains information about single transaction output
   138  type Vout struct {
   139  	ValueSat    *Amount                  `json:"value,omitempty"`
   140  	N           int                      `json:"n"`
   141  	Spent       bool                     `json:"spent,omitempty"`
   142  	SpentTxID   string                   `json:"spentTxId,omitempty"`
   143  	SpentIndex  int                      `json:"spentIndex,omitempty"`
   144  	SpentHeight int                      `json:"spentHeight,omitempty"`
   145  	Hex         string                   `json:"hex,omitempty"`
   146  	Asm         string                   `json:"asm,omitempty"`
   147  	AddrDesc    bchain.AddressDescriptor `json:"-"`
   148  	Addresses   []string                 `json:"addresses"`
   149  	IsAddress   bool                     `json:"isAddress"`
   150  	IsOwn       bool                     `json:"isOwn,omitempty"`
   151  	Type        string                   `json:"type,omitempty"`
   152  }
   153  
   154  // MultiTokenValue contains values for contract with id and value (like ERC1155)
   155  type MultiTokenValue struct {
   156  	Id    *Amount `json:"id,omitempty"`
   157  	Value *Amount `json:"value,omitempty"`
   158  }
   159  
   160  // Token contains info about tokens held by an address
   161  type Token struct {
   162  	Type             bchain.TokenTypeName `json:"type" ts_type:"'XPUBAddress' | 'ERC20' | 'ERC721' | 'ERC1155'"`
   163  	Name             string               `json:"name"`
   164  	Path             string               `json:"path,omitempty"`
   165  	Contract         string               `json:"contract,omitempty"`
   166  	Transfers        int                  `json:"transfers"`
   167  	Symbol           string               `json:"symbol,omitempty"`
   168  	Decimals         int                  `json:"decimals,omitempty"`
   169  	BalanceSat       *Amount              `json:"balance,omitempty"`
   170  	BaseValue        float64              `json:"baseValue,omitempty"`        // value in the base currency (ETH for Ethereum)
   171  	SecondaryValue   float64              `json:"secondaryValue,omitempty"`   // value in secondary (fiat) currency, if specified
   172  	Ids              []Amount             `json:"ids,omitempty"`              // multiple ERC721 tokens
   173  	MultiTokenValues []MultiTokenValue    `json:"multiTokenValues,omitempty"` // multiple ERC1155 tokens
   174  	TotalReceivedSat *Amount              `json:"totalReceived,omitempty"`
   175  	TotalSentSat     *Amount              `json:"totalSent,omitempty"`
   176  	ContractIndex    string               `json:"-"`
   177  }
   178  
   179  // Tokens is array of Token
   180  type Tokens []Token
   181  
   182  func (a Tokens) Len() int      { return len(a) }
   183  func (a Tokens) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
   184  func (a Tokens) Less(i, j int) bool {
   185  	ti := &a[i]
   186  	tj := &a[j]
   187  	// sort by BaseValue descending  and then Name and then by Contract
   188  	if ti.BaseValue < tj.BaseValue {
   189  		return false
   190  	} else if ti.BaseValue > tj.BaseValue {
   191  		return true
   192  	}
   193  	if ti.Name == "" {
   194  		if tj.Name != "" {
   195  			return false
   196  		}
   197  	} else {
   198  		if tj.Name == "" {
   199  			return true
   200  		}
   201  		return ti.Name < tj.Name
   202  	}
   203  	return ti.Contract < tj.Contract
   204  }
   205  
   206  // TokenTransfer contains info about a token transfer done in a transaction
   207  type TokenTransfer struct {
   208  	Type             bchain.TokenTypeName `json:"type"`
   209  	From             string               `json:"from"`
   210  	To               string               `json:"to"`
   211  	Contract         string               `json:"contract"`
   212  	Name             string               `json:"name"`
   213  	Symbol           string               `json:"symbol"`
   214  	Decimals         int                  `json:"decimals"`
   215  	Value            *Amount              `json:"value,omitempty"`
   216  	MultiTokenValues []MultiTokenValue    `json:"multiTokenValues,omitempty"`
   217  }
   218  
   219  type EthereumInternalTransfer struct {
   220  	Type  bchain.EthereumInternalTransactionType `json:"type"`
   221  	From  string                                 `json:"from"`
   222  	To    string                                 `json:"to"`
   223  	Value *Amount                                `json:"value"`
   224  }
   225  
   226  // EthereumSpecific contains ethereum specific transaction data
   227  type EthereumSpecific struct {
   228  	Type              bchain.EthereumInternalTransactionType `json:"type,omitempty"`
   229  	CreatedContract   string                                 `json:"createdContract,omitempty"`
   230  	Status            eth.TxStatus                           `json:"status"` // 1 OK, 0 Fail, -1 pending
   231  	Error             string                                 `json:"error,omitempty"`
   232  	Nonce             uint64                                 `json:"nonce"`
   233  	GasLimit          *big.Int                               `json:"gasLimit"`
   234  	GasUsed           *big.Int                               `json:"gasUsed,omitempty"`
   235  	GasPrice          *Amount                                `json:"gasPrice"`
   236  	Data              string                                 `json:"data,omitempty"`
   237  	ParsedData        *bchain.EthereumParsedInputData        `json:"parsedData,omitempty"`
   238  	InternalTransfers []EthereumInternalTransfer             `json:"internalTransfers,omitempty"`
   239  }
   240  
   241  // CoreCoinSpecific contains core coin specific transaction data
   242  type CoreCoinSpecific struct {
   243  	Status      xcb.TxStatus `json:"status"` // 1 OK, 0 Fail, -1 pending
   244  	Nonce       uint64       `json:"nonce"`
   245  	EnergyLimit *big.Int     `json:"energyLimit"`
   246  	EnergyUsed  *big.Int     `json:"energyUsed,omitempty"`
   247  	EnergyPrice *Amount      `json:"energyPrice"`
   248  	Data        string       `json:"data,omitempty"`
   249  }
   250  
   251  type AddressAlias struct {
   252  	Type  string
   253  	Alias string
   254  }
   255  type AddressAliasesMap map[string]AddressAlias
   256  
   257  // Tx holds information about a transaction
   258  type Tx struct {
   259  	Txid                   string            `json:"txid"`
   260  	Version                int32             `json:"version,omitempty"`
   261  	Locktime               uint32            `json:"lockTime,omitempty"`
   262  	Vin                    []Vin             `json:"vin"`
   263  	Vout                   []Vout            `json:"vout"`
   264  	Blockhash              string            `json:"blockHash,omitempty"`
   265  	Blockheight            int               `json:"blockHeight"`
   266  	Confirmations          uint32            `json:"confirmations"`
   267  	ConfirmationETABlocks  uint32            `json:"confirmationETABlocks,omitempty"`
   268  	ConfirmationETASeconds int64             `json:"confirmationETASeconds,omitempty"`
   269  	Blocktime              int64             `json:"blockTime"`
   270  	Size                   int               `json:"size,omitempty"`
   271  	VSize                  int               `json:"vsize,omitempty"`
   272  	ValueOutSat            *Amount           `json:"value"`
   273  	ValueInSat             *Amount           `json:"valueIn,omitempty"`
   274  	FeesSat                *Amount           `json:"fees,omitempty"`
   275  	Hex                    string            `json:"hex,omitempty"`
   276  	Rbf                    bool              `json:"rbf,omitempty"`
   277  	CoinSpecificData       json.RawMessage   `json:"coinSpecificData,omitempty" ts_type:"any"`
   278  	TokenTransfers         []TokenTransfer   `json:"tokenTransfers,omitempty"`
   279  	EthereumSpecific       *EthereumSpecific `json:"ethereumSpecific,omitempty"`
   280  	CoreCoinSpecific       *CoreCoinSpecific `json:"corecoinSpecific,omitempty"`
   281  	AddressAliases         AddressAliasesMap `json:"addressAliases,omitempty"`
   282  }
   283  
   284  // FeeStats contains detailed block fee statistics
   285  type FeeStats struct {
   286  	TxCount         int       `json:"txCount"`
   287  	TotalFeesSat    *Amount   `json:"totalFeesSat"`
   288  	AverageFeePerKb int64     `json:"averageFeePerKb"`
   289  	DecilesFeePerKb [11]int64 `json:"decilesFeePerKb"`
   290  }
   291  
   292  // Paging contains information about paging for address, blocks and block
   293  type Paging struct {
   294  	Page        int `json:"page,omitempty"`
   295  	TotalPages  int `json:"totalPages,omitempty"`
   296  	ItemsOnPage int `json:"itemsOnPage,omitempty"`
   297  }
   298  
   299  // TokensToReturn specifies what tokens are returned by GetAddress and GetXpubAddress
   300  type TokensToReturn int
   301  
   302  const (
   303  	// AddressFilterVoutOff disables filtering of transactions by vout
   304  	AddressFilterVoutOff = -1
   305  	// AddressFilterVoutInputs specifies that only txs where the address is as input are returned
   306  	AddressFilterVoutInputs = -2
   307  	// AddressFilterVoutOutputs specifies that only txs where the address is as output are returned
   308  	AddressFilterVoutOutputs = -3
   309  	// AddressFilterVoutQueryNotNecessary signals that query for transactions is not necessary as there are no transactions for specified contract filter
   310  	AddressFilterVoutQueryNotNecessary = -4
   311  
   312  	// TokensToReturnNonzeroBalance - return only tokens with nonzero balance
   313  	TokensToReturnNonzeroBalance TokensToReturn = 0
   314  	// TokensToReturnUsed - return tokens with some transfers (even if they have zero balance now)
   315  	TokensToReturnUsed TokensToReturn = 1
   316  	// TokensToReturnDerived - return all derived tokens
   317  	TokensToReturnDerived TokensToReturn = 2
   318  )
   319  
   320  // AddressFilter is used to filter data returned from GetAddress api method
   321  type AddressFilter struct {
   322  	Vout           int
   323  	Contract       string
   324  	FromHeight     uint32
   325  	ToHeight       uint32
   326  	TokensToReturn TokensToReturn
   327  	// OnlyConfirmed set to true will ignore mempool transactions; mempool is also ignored if FromHeight/ToHeight filter is specified
   328  	OnlyConfirmed bool
   329  }
   330  
   331  // Address holds information about address and its transactions
   332  type Address struct {
   333  	Paging
   334  	AddrStr               string               `json:"address"`
   335  	BalanceSat            *Amount              `json:"balance"`
   336  	TotalReceivedSat      *Amount              `json:"totalReceived,omitempty"`
   337  	TotalSentSat          *Amount              `json:"totalSent,omitempty"`
   338  	UnconfirmedBalanceSat *Amount              `json:"unconfirmedBalance"`
   339  	UnconfirmedTxs        int                  `json:"unconfirmedTxs"`
   340  	Txs                   int                  `json:"txs"`
   341  	AddrTxCount           int                  `json:"addrTxCount,omitempty"`
   342  	NonTokenTxs           int                  `json:"nonTokenTxs,omitempty"`
   343  	InternalTxs           int                  `json:"internalTxs,omitempty"`
   344  	Transactions          []*Tx                `json:"transactions,omitempty"`
   345  	Txids                 []string             `json:"txids,omitempty"`
   346  	Nonce                 string               `json:"nonce,omitempty"`
   347  	UsedTokens            int                  `json:"usedTokens,omitempty"`
   348  	Tokens                Tokens               `json:"tokens,omitempty"`
   349  	SecondaryValue        float64              `json:"secondaryValue,omitempty"` // address value in secondary currency
   350  	TokensBaseValue       float64              `json:"tokensBaseValue,omitempty"`
   351  	TokensSecondaryValue  float64              `json:"tokensSecondaryValue,omitempty"`
   352  	TotalBaseValue        float64              `json:"totalBaseValue,omitempty"`      // value including tokens in base currency
   353  	TotalSecondaryValue   float64              `json:"totalSecondaryValue,omitempty"` // value including tokens in secondary currency
   354  	ContractInfo          *bchain.ContractInfo `json:"contractInfo,omitempty"`
   355  	Erc20Contract         *bchain.ContractInfo `json:"erc20Contract,omitempty"` // deprecated
   356  	AddressAliases        AddressAliasesMap    `json:"addressAliases,omitempty"`
   357  	// helpers for explorer
   358  	Filter        string              `json:"-"`
   359  	XPubAddresses map[string]struct{} `json:"-"`
   360  }
   361  
   362  // Utxo is one unspent transaction output
   363  type Utxo struct {
   364  	Txid          string  `json:"txid"`
   365  	Vout          int32   `json:"vout"`
   366  	AmountSat     *Amount `json:"value"`
   367  	Height        int     `json:"height,omitempty"`
   368  	Confirmations int     `json:"confirmations"`
   369  	Address       string  `json:"address,omitempty"`
   370  	Path          string  `json:"path,omitempty"`
   371  	Locktime      uint32  `json:"lockTime,omitempty"`
   372  	Coinbase      bool    `json:"coinbase,omitempty"`
   373  }
   374  
   375  // Utxos is array of Utxo
   376  type Utxos []Utxo
   377  
   378  func (a Utxos) Len() int      { return len(a) }
   379  func (a Utxos) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
   380  func (a Utxos) Less(i, j int) bool {
   381  	// sort in reverse order, unconfirmed (height==0) utxos on top
   382  	hi := a[i].Height
   383  	hj := a[j].Height
   384  	if hi == 0 {
   385  		hi = maxInt
   386  	}
   387  	if hj == 0 {
   388  		hj = maxInt
   389  	}
   390  	return hi >= hj
   391  }
   392  
   393  // BalanceHistory contains info about one point in time of balance history
   394  type BalanceHistory struct {
   395  	Time          uint32             `json:"time"`
   396  	Txs           uint32             `json:"txs"`
   397  	ReceivedSat   *Amount            `json:"received"`
   398  	SentSat       *Amount            `json:"sent"`
   399  	SentToSelfSat *Amount            `json:"sentToSelf"`
   400  	FiatRates     map[string]float32 `json:"rates,omitempty"`
   401  	Txid          string             `json:"txid,omitempty"`
   402  }
   403  
   404  // BalanceHistories is array of BalanceHistory
   405  type BalanceHistories []BalanceHistory
   406  
   407  func (a BalanceHistories) Len() int      { return len(a) }
   408  func (a BalanceHistories) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
   409  func (a BalanceHistories) Less(i, j int) bool {
   410  	ti := a[i].Time
   411  	tj := a[j].Time
   412  	if ti == tj {
   413  		return a[i].Txid < a[j].Txid
   414  	}
   415  	return ti < tj
   416  }
   417  
   418  // SortAndAggregate sums BalanceHistories to groups defined by parameter groupByTime
   419  func (a BalanceHistories) SortAndAggregate(groupByTime uint32) BalanceHistories {
   420  	bhs := make(BalanceHistories, 0)
   421  	if len(a) > 0 {
   422  		bha := BalanceHistory{
   423  			ReceivedSat:   &Amount{},
   424  			SentSat:       &Amount{},
   425  			SentToSelfSat: &Amount{},
   426  		}
   427  		sort.Sort(a)
   428  		for i := range a {
   429  			bh := &a[i]
   430  			time := bh.Time - bh.Time%groupByTime
   431  			if bha.Time != time {
   432  				if bha.Time != 0 {
   433  					// in aggregate, do not return txid as it could multiple of them
   434  					bha.Txid = ""
   435  					bhs = append(bhs, bha)
   436  				}
   437  				bha = BalanceHistory{
   438  					Time:          time,
   439  					ReceivedSat:   &Amount{},
   440  					SentSat:       &Amount{},
   441  					SentToSelfSat: &Amount{},
   442  				}
   443  			}
   444  			if bha.Txid != bh.Txid {
   445  				bha.Txs += bh.Txs
   446  				bha.Txid = bh.Txid
   447  			}
   448  			(*big.Int)(bha.ReceivedSat).Add((*big.Int)(bha.ReceivedSat), (*big.Int)(bh.ReceivedSat))
   449  			(*big.Int)(bha.SentSat).Add((*big.Int)(bha.SentSat), (*big.Int)(bh.SentSat))
   450  			(*big.Int)(bha.SentToSelfSat).Add((*big.Int)(bha.SentToSelfSat), (*big.Int)(bh.SentToSelfSat))
   451  		}
   452  		if bha.Txs > 0 {
   453  			bha.Txid = ""
   454  			bhs = append(bhs, bha)
   455  		}
   456  	}
   457  	return bhs
   458  }
   459  
   460  // Blocks is list of blocks with paging information
   461  type Blocks struct {
   462  	Paging
   463  	Blocks []db.BlockInfo `json:"blocks"`
   464  }
   465  
   466  // BlockInfo contains extended block header data and a list of block txids
   467  type BlockInfo struct {
   468  	Hash          string            `json:"hash"`
   469  	Prev          string            `json:"previousBlockHash,omitempty"`
   470  	Next          string            `json:"nextBlockHash,omitempty"`
   471  	Height        uint32            `json:"height"`
   472  	Confirmations int               `json:"confirmations"`
   473  	Size          int               `json:"size"`
   474  	Time          int64             `json:"time,omitempty"`
   475  	Version       common.JSONNumber `json:"version"`
   476  	MerkleRoot    string            `json:"merkleRoot"`
   477  	Nonce         string            `json:"nonce"`
   478  	Bits          string            `json:"bits"`
   479  	Difficulty    string            `json:"difficulty"`
   480  	Txids         []string          `json:"tx,omitempty"`
   481  }
   482  
   483  // Block contains information about block
   484  type Block struct {
   485  	Paging
   486  	BlockInfo
   487  	TxCount        int               `json:"txCount"`
   488  	Transactions   []*Tx             `json:"txs,omitempty"`
   489  	AddressAliases AddressAliasesMap `json:"addressAliases,omitempty"`
   490  }
   491  
   492  // BlockRaw contains raw block in hex
   493  type BlockRaw struct {
   494  	Hex string `json:"hex"`
   495  }
   496  
   497  // BlockbookInfo contains information about the running blockbook instance
   498  type BlockbookInfo struct {
   499  	Coin                         string                       `json:"coin"`
   500  	Host                         string                       `json:"host"`
   501  	Version                      string                       `json:"version"`
   502  	GitCommit                    string                       `json:"gitCommit"`
   503  	BuildTime                    string                       `json:"buildTime"`
   504  	SyncMode                     bool                         `json:"syncMode"`
   505  	InitialSync                  bool                         `json:"initialSync"`
   506  	InSync                       bool                         `json:"inSync"`
   507  	BestHeight                   uint32                       `json:"bestHeight"`
   508  	LastBlockTime                time.Time                    `json:"lastBlockTime"`
   509  	InSyncMempool                bool                         `json:"inSyncMempool"`
   510  	LastMempoolTime              time.Time                    `json:"lastMempoolTime"`
   511  	MempoolSize                  int                          `json:"mempoolSize"`
   512  	Decimals                     int                          `json:"decimals"`
   513  	DbSize                       int64                        `json:"dbSize"`
   514  	HasFiatRates                 bool                         `json:"hasFiatRates,omitempty"`
   515  	HasTokenFiatRates            bool                         `json:"hasTokenFiatRates,omitempty"`
   516  	CurrentFiatRatesTime         *time.Time                   `json:"currentFiatRatesTime,omitempty"`
   517  	HistoricalFiatRatesTime      *time.Time                   `json:"historicalFiatRatesTime,omitempty"`
   518  	HistoricalTokenFiatRatesTime *time.Time                   `json:"historicalTokenFiatRatesTime,omitempty"`
   519  	DbSizeFromColumns            int64                        `json:"dbSizeFromColumns,omitempty"`
   520  	DbColumns                    []common.InternalStateColumn `json:"dbColumns,omitempty"`
   521  	About                        string                       `json:"about"`
   522  }
   523  
   524  // SystemInfo contains information about the running blockbook and backend instance
   525  type SystemInfo struct {
   526  	Blockbook *BlockbookInfo      `json:"blockbook"`
   527  	Backend   *common.BackendInfo `json:"backend"`
   528  }
   529  
   530  // MempoolTxid contains information about a transaction in mempool
   531  type MempoolTxid struct {
   532  	Time int64  `json:"time"`
   533  	Txid string `json:"txid"`
   534  }
   535  
   536  // MempoolTxids contains a list of mempool txids with paging information
   537  type MempoolTxids struct {
   538  	Paging
   539  	Mempool     []MempoolTxid `json:"mempool"`
   540  	MempoolSize int           `json:"mempoolSize"`
   541  }
   542  
   543  // FiatTicker contains formatted CurrencyRatesTicker data
   544  type FiatTicker struct {
   545  	Timestamp int64              `json:"ts,omitempty"`
   546  	Rates     map[string]float32 `json:"rates"`
   547  	Error     string             `json:"error,omitempty"`
   548  }
   549  
   550  // FiatTickers contains a formatted CurrencyRatesTicker list
   551  type FiatTickers struct {
   552  	Tickers []FiatTicker `json:"tickers"`
   553  }
   554  
   555  // AvailableVsCurrencies contains formatted data about available versus currencies for exchange rates
   556  type AvailableVsCurrencies struct {
   557  	Timestamp int64    `json:"ts,omitempty"`
   558  	Tickers   []string `json:"available_currencies"`
   559  	Error     string   `json:"error,omitempty"`
   560  }