7 log "github.com/sirupsen/logrus"
9 "github.com/bytom/account"
10 "github.com/bytom/blockchain/query"
11 "github.com/bytom/consensus"
12 chainjson "github.com/bytom/encoding/json"
13 "github.com/bytom/protocol/bc"
14 "github.com/bytom/protocol/bc/types"
17 // POST /list-accounts
18 func (a *API) listAccounts(ctx context.Context, filter struct {
21 accounts, err := a.wallet.AccountMgr.ListAccounts(filter.ID)
23 log.Errorf("listAccounts: %v", err)
24 return NewErrorResponse(err)
27 annotatedAccounts := []query.AnnotatedAccount{}
28 for _, acc := range accounts {
29 annotatedAccounts = append(annotatedAccounts, *account.Annotated(acc))
32 return NewSuccessResponse(annotatedAccounts)
36 func (a *API) getAsset(ctx context.Context, filter struct {
39 asset, err := a.wallet.AssetReg.GetAsset(filter.ID)
41 log.Errorf("getAsset: %v", err)
42 return NewErrorResponse(err)
45 return NewSuccessResponse(asset)
49 func (a *API) listAssets(ctx context.Context, filter struct {
52 assets, err := a.wallet.AssetReg.ListAssets(filter.ID)
54 log.Errorf("listAssets: %v", err)
55 return NewErrorResponse(err)
58 return NewSuccessResponse(assets)
61 // POST /list-balances
62 func (a *API) listBalances(ctx context.Context) Response {
63 balances, err := a.wallet.GetAccountBalances("")
65 return NewErrorResponse(err)
67 return NewSuccessResponse(balances)
70 // POST /get-transaction
71 func (a *API) getTransaction(ctx context.Context, txInfo struct {
72 TxID string `json:"tx_id"`
74 var annotatedTx *query.AnnotatedTx
77 annotatedTx, err = a.wallet.GetTransactionByTxID(txInfo.TxID)
79 // transaction not found in blockchain db, search it from unconfirmed db
80 annotatedTx, err = a.wallet.GetUnconfirmedTxByTxID(txInfo.TxID)
82 return NewErrorResponse(err)
86 return NewSuccessResponse(annotatedTx)
89 // POST /list-transactions
90 func (a *API) listTransactions(ctx context.Context, filter struct {
92 AccountID string `json:"account_id"`
93 Detail bool `json:"detail"`
94 Unconfirmed bool `json:"unconfirmed"`
96 transactions := []*query.AnnotatedTx{}
98 var transaction *query.AnnotatedTx
101 transaction, err = a.wallet.GetTransactionByTxID(filter.ID)
102 if err != nil && filter.Unconfirmed {
103 transaction, err = a.wallet.GetUnconfirmedTxByTxID(filter.ID)
105 return NewErrorResponse(err)
108 transactions = []*query.AnnotatedTx{transaction}
110 transactions, err = a.wallet.GetTransactions(filter.AccountID)
112 return NewErrorResponse(err)
115 if filter.Unconfirmed {
116 unconfirmedTxs, err := a.wallet.GetUnconfirmedTxs(filter.AccountID)
118 return NewErrorResponse(err)
120 transactions = append(unconfirmedTxs, transactions...)
124 if filter.Detail == false {
125 txSummary := a.wallet.GetTransactionsSummary(transactions)
126 return NewSuccessResponse(txSummary)
128 return NewSuccessResponse(transactions)
131 // POST /get-unconfirmed-transaction
132 func (a *API) getUnconfirmedTx(ctx context.Context, filter struct {
133 TxID chainjson.HexBytes `json:"tx_id"`
136 copy(tmpTxID[:], filter.TxID[:])
138 txHash := bc.NewHash(tmpTxID)
139 txPool := a.chain.GetTxPool()
140 txDesc, err := txPool.GetTransaction(&txHash)
142 return NewErrorResponse(err)
147 Version: txDesc.Tx.Version,
148 Size: txDesc.Tx.SerializedSize,
149 TimeRange: txDesc.Tx.TimeRange,
150 Inputs: []*query.AnnotatedInput{},
151 Outputs: []*query.AnnotatedOutput{},
155 for i := range txDesc.Tx.Inputs {
156 tx.Inputs = append(tx.Inputs, a.wallet.BuildAnnotatedInput(txDesc.Tx, uint32(i)))
158 for i := range txDesc.Tx.Outputs {
159 tx.Outputs = append(tx.Outputs, a.wallet.BuildAnnotatedOutput(txDesc.Tx, i))
162 return NewSuccessResponse(tx)
165 type unconfirmedTxsResp struct {
166 Total uint64 `json:"total"`
167 TxIDs []bc.Hash `json:"tx_ids"`
170 // POST /list-unconfirmed-transactions
171 func (a *API) listUnconfirmedTxs(ctx context.Context) Response {
174 txPool := a.chain.GetTxPool()
175 txs := txPool.GetTransactions()
176 for _, txDesc := range txs {
177 txIDs = append(txIDs, bc.Hash(txDesc.Tx.ID))
180 return NewSuccessResponse(&unconfirmedTxsResp{
181 Total: uint64(len(txIDs)),
186 // RawTx is the tx struct for getRawTransaction
188 Version uint64 `json:"version"`
189 Size uint64 `json:"size"`
190 TimeRange uint64 `json:"time_range"`
191 Inputs []*query.AnnotatedInput `json:"inputs"`
192 Outputs []*query.AnnotatedOutput `json:"outputs"`
193 Fee int64 `json:"fee"`
196 // POST /decode-raw-transaction
197 func (a *API) decodeRawTransaction(ctx context.Context, ins struct {
198 Tx types.Tx `json:"raw_transaction"`
201 Version: ins.Tx.Version,
202 Size: ins.Tx.SerializedSize,
203 TimeRange: ins.Tx.TimeRange,
204 Inputs: []*query.AnnotatedInput{},
205 Outputs: []*query.AnnotatedOutput{},
208 for i := range ins.Tx.Inputs {
209 tx.Inputs = append(tx.Inputs, a.wallet.BuildAnnotatedInput(&ins.Tx, uint32(i)))
211 for i := range ins.Tx.Outputs {
212 tx.Outputs = append(tx.Outputs, a.wallet.BuildAnnotatedOutput(&ins.Tx, i))
215 totalInputBtm := uint64(0)
216 totalOutputBtm := uint64(0)
217 for _, input := range tx.Inputs {
218 if input.AssetID.String() == consensus.BTMAssetID.String() {
219 totalInputBtm += input.Amount
223 for _, output := range tx.Outputs {
224 if output.AssetID.String() == consensus.BTMAssetID.String() {
225 totalOutputBtm += output.Amount
229 tx.Fee = int64(totalInputBtm) - int64(totalOutputBtm)
230 return NewSuccessResponse(tx)
233 // POST /list-unspent-outputs
234 func (a *API) listUnspentOutputs(ctx context.Context, filter struct {
235 ID string `json:"id"`
237 accountUTXOs := a.wallet.GetAccountUTXOs(filter.ID)
239 UTXOs := []query.AnnotatedUTXO{}
240 for _, utxo := range accountUTXOs {
241 UTXOs = append([]query.AnnotatedUTXO{{
242 AccountID: utxo.AccountID,
243 OutputID: utxo.OutputID.String(),
244 SourceID: utxo.SourceID.String(),
245 AssetID: utxo.AssetID.String(),
247 SourcePos: utxo.SourcePos,
248 Program: fmt.Sprintf("%x", utxo.ControlProgram),
249 ControlProgramIndex: utxo.ControlProgramIndex,
250 Address: utxo.Address,
251 ValidHeight: utxo.ValidHeight,
252 Alias: a.wallet.AccountMgr.GetAliasByID(utxo.AccountID),
253 AssetAlias: a.wallet.AssetReg.GetAliasByID(utxo.AssetID.String()),
258 return NewSuccessResponse(UTXOs)
262 func (a *API) gasRate() Response {
263 gasrate := map[string]int64{"gas_rate": consensus.VMGasRate}
264 return NewSuccessResponse(gasrate)