log "github.com/sirupsen/logrus"
- "github.com/bytom/account"
- "github.com/bytom/blockchain/query"
- "github.com/bytom/blockchain/signers"
- "github.com/bytom/consensus"
- "github.com/bytom/crypto/ed25519/chainkd"
- chainjson "github.com/bytom/encoding/json"
- "github.com/bytom/protocol/bc"
- "github.com/bytom/protocol/bc/types"
+ "github.com/bytom/bytom/account"
+ "github.com/bytom/bytom/asset"
+ "github.com/bytom/bytom/blockchain/query"
+ "github.com/bytom/bytom/blockchain/signers"
+ "github.com/bytom/bytom/blockchain/txbuilder"
+ "github.com/bytom/bytom/consensus"
+ "github.com/bytom/bytom/crypto/ed25519"
+ "github.com/bytom/bytom/crypto/ed25519/chainkd"
+ chainjson "github.com/bytom/bytom/encoding/json"
+ "github.com/bytom/bytom/errors"
+ "github.com/bytom/bytom/protocol/bc"
+ "github.com/bytom/bytom/protocol/bc/types"
)
// POST /list-accounts
func (a *API) listAccounts(ctx context.Context, filter struct {
- ID string `json:"id"`
+ ID string `json:"id"`
+ Alias string `json:"alias"`
}) Response {
- accounts, err := a.wallet.AccountMgr.ListAccounts(filter.ID)
+ accountID := filter.ID
+ if filter.Alias != "" {
+ acc, err := a.wallet.AccountMgr.FindByAlias(filter.Alias)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ accountID = acc.ID
+ }
+
+ accounts, err := a.wallet.AccountMgr.ListAccounts(accountID)
if err != nil {
log.Errorf("listAccounts: %v", err)
return NewErrorResponse(err)
func (a *API) getAsset(ctx context.Context, filter struct {
ID string `json:"id"`
}) Response {
- asset, err := a.wallet.AssetReg.GetAsset(filter.ID)
+ ass, err := a.wallet.AssetReg.GetAsset(filter.ID)
if err != nil {
log.Errorf("getAsset: %v", err)
return NewErrorResponse(err)
}
- return NewSuccessResponse(asset)
+ annotatedAsset, err := asset.Annotated(ass)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ return NewSuccessResponse(annotatedAsset)
}
// POST /list-assets
return NewErrorResponse(err)
}
- return NewSuccessResponse(assets)
+ annotatedAssets := []*query.AnnotatedAsset{}
+ for _, ass := range assets {
+ annotatedAsset, err := asset.Annotated(ass)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ annotatedAssets = append(annotatedAssets, annotatedAsset)
+ }
+ return NewSuccessResponse(annotatedAssets)
}
// POST /list-balances
-func (a *API) listBalances(ctx context.Context) Response {
- balances, err := a.wallet.GetAccountBalances("")
+func (a *API) listBalances(ctx context.Context, filter struct {
+ AccountID string `json:"account_id"`
+ AccountAlias string `json:"account_alias"`
+}) Response {
+ accountID := filter.AccountID
+ if filter.AccountAlias != "" {
+ acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ accountID = acc.ID
+ }
+
+ balances, err := a.wallet.GetAccountBalances(accountID, "")
if err != nil {
return NewErrorResponse(err)
}
AccountID string `json:"account_id"`
Detail bool `json:"detail"`
Unconfirmed bool `json:"unconfirmed"`
+ From uint `json:"from"`
+ Count uint `json:"count"`
}) Response {
transactions := []*query.AnnotatedTx{}
var err error
transaction, err = a.wallet.GetTransactionByTxID(filter.ID)
if err != nil && filter.Unconfirmed {
transaction, err = a.wallet.GetUnconfirmedTxByTxID(filter.ID)
- if err != nil {
- return NewErrorResponse(err)
- }
+ }
+
+ if err != nil {
+ return NewErrorResponse(err)
}
transactions = []*query.AnnotatedTx{transaction}
} else {
if filter.Detail == false {
txSummary := a.wallet.GetTransactionsSummary(transactions)
- return NewSuccessResponse(txSummary)
+ start, end := getPageRange(len(txSummary), filter.From, filter.Count)
+ return NewSuccessResponse(txSummary[start:end])
}
- return NewSuccessResponse(transactions)
+ start, end := getPageRange(len(transactions), filter.From, filter.Count)
+ return NewSuccessResponse(transactions[start:end])
}
// POST /get-unconfirmed-transaction
TimeRange: txDesc.Tx.TimeRange,
Inputs: []*query.AnnotatedInput{},
Outputs: []*query.AnnotatedOutput{},
- StatusFail: false,
+ StatusFail: txDesc.StatusFail,
+ }
+
+ resOutID := txDesc.Tx.ResultIds[0]
+ resOut := txDesc.Tx.Entries[*resOutID]
+ switch out := resOut.(type) {
+ case *bc.Output:
+ tx.MuxID = *out.Source.Ref
+ case *bc.Retirement:
+ tx.MuxID = *out.Source.Ref
}
for i := range txDesc.Tx.Inputs {
TimeRange uint64 `json:"time_range"`
Inputs []*query.AnnotatedInput `json:"inputs"`
Outputs []*query.AnnotatedOutput `json:"outputs"`
- Fee int64 `json:"fee"`
+ Fee uint64 `json:"fee"`
}
// POST /decode-raw-transaction
tx.Outputs = append(tx.Outputs, a.wallet.BuildAnnotatedOutput(&ins.Tx, i))
}
- totalInputBtm := uint64(0)
- totalOutputBtm := uint64(0)
- for _, input := range tx.Inputs {
- if input.AssetID.String() == consensus.BTMAssetID.String() {
- totalInputBtm += input.Amount
- }
- }
-
- for _, output := range tx.Outputs {
- if output.AssetID.String() == consensus.BTMAssetID.String() {
- totalOutputBtm += output.Amount
- }
- }
-
- tx.Fee = int64(totalInputBtm) - int64(totalOutputBtm)
+ tx.Fee = txbuilder.CalculateTxFee(&ins.Tx)
return NewSuccessResponse(tx)
}
// POST /list-unspent-outputs
func (a *API) listUnspentOutputs(ctx context.Context, filter struct {
+ AccountID string `json:"account_id"`
+ AccountAlias string `json:"account_alias"`
ID string `json:"id"`
Unconfirmed bool `json:"unconfirmed"`
SmartContract bool `json:"smart_contract"`
+ From uint `json:"from"`
+ Count uint `json:"count"`
}) Response {
- accountUTXOs := a.wallet.GetAccountUtxos(filter.ID, filter.Unconfirmed, filter.SmartContract)
+ accountID := filter.AccountID
+ if filter.AccountAlias != "" {
+ acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ accountID = acc.ID
+ }
+ accountUTXOs := a.wallet.GetAccountUtxos(accountID, filter.ID, filter.Unconfirmed, filter.SmartContract)
UTXOs := []query.AnnotatedUTXO{}
for _, utxo := range accountUTXOs {
Change: utxo.Change,
}}, UTXOs...)
}
-
- return NewSuccessResponse(UTXOs)
+ start, end := getPageRange(len(UTXOs), filter.From, filter.Count)
+ return NewSuccessResponse(UTXOs[start:end])
}
// return gasRate
PubKeyInfos []PubKeyInfo `json:"pubkey_infos"`
}
+func getPubkey(account *account.Account, change bool, index uint64) (*ed25519.PublicKey, []chainjson.HexBytes, error) {
+ rawPath, err := signers.Path(account.Signer, signers.AccountKeySpace, change, index)
+ if err != nil {
+ return nil, nil, err
+ }
+ derivedXPub := account.XPubs[0].Derive(rawPath)
+ pubkey := derivedXPub.PublicKey()
+ var path []chainjson.HexBytes
+ for _, p := range rawPath {
+ path = append(path, chainjson.HexBytes(p))
+ }
+
+ return &pubkey, path, nil
+}
+
// POST /list-pubkeys
func (a *API) listPubKeys(ctx context.Context, ins struct {
- AccountID string `json:"account_id"`
+ AccountID string `json:"account_id"`
+ AccountAlias string `json:"account_alias"`
+ PublicKey string `json:"public_key"`
}) Response {
- account, err := a.wallet.AccountMgr.FindByID(ins.AccountID)
+ var err error
+ account := &account.Account{}
+ if ins.AccountAlias != "" {
+ account, err = a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
+ } else {
+ account, err = a.wallet.AccountMgr.FindByID(ins.AccountID)
+ }
+
if err != nil {
return NewErrorResponse(err)
}
pubKeyInfos := []PubKeyInfo{}
- idx := a.wallet.AccountMgr.GetContractIndex(ins.AccountID)
- for i := uint64(1); i <= idx; i++ {
- rawPath := signers.Path(account.Signer, signers.AccountKeySpace, i)
- derivedXPub := account.XPubs[0].Derive(rawPath)
- pubkey := derivedXPub.PublicKey()
-
- var path []chainjson.HexBytes
- for _, p := range rawPath {
- path = append(path, chainjson.HexBytes(p))
+ if account.DeriveRule == signers.BIP0032 {
+ idx := a.wallet.AccountMgr.GetContractIndex(account.ID)
+ for i := uint64(1); i <= idx; i++ {
+ pubkey, path, err := getPubkey(account, false, i)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ if ins.PublicKey != "" && ins.PublicKey != hex.EncodeToString(*pubkey) {
+ continue
+ }
+ pubKeyInfos = append(pubKeyInfos, PubKeyInfo{
+ Pubkey: hex.EncodeToString(*pubkey),
+ Path: path,
+ })
+ }
+ } else if account.DeriveRule == signers.BIP0044 {
+ idx := a.wallet.AccountMgr.GetBip44ContractIndex(account.ID, true)
+ for i := uint64(1); i <= idx; i++ {
+ pubkey, path, err := getPubkey(account, true, i)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ if ins.PublicKey != "" && ins.PublicKey != hex.EncodeToString(*pubkey) {
+ continue
+ }
+ pubKeyInfos = append(pubKeyInfos, PubKeyInfo{
+ Pubkey: hex.EncodeToString(*pubkey),
+ Path: path,
+ })
+ }
+
+ idx = a.wallet.AccountMgr.GetBip44ContractIndex(account.ID, false)
+ for i := uint64(1); i <= idx; i++ {
+ pubkey, path, err := getPubkey(account, false, i)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
+ if ins.PublicKey != "" && ins.PublicKey != hex.EncodeToString(*pubkey) {
+ continue
+ }
+ pubKeyInfos = append(pubKeyInfos, PubKeyInfo{
+ Pubkey: hex.EncodeToString(*pubkey),
+ Path: path,
+ })
}
+ }
- pubKeyInfos = append([]PubKeyInfo{{
- Pubkey: hex.EncodeToString(pubkey),
- Path: path,
- }}, pubKeyInfos...)
+ if len(pubKeyInfos) == 0 {
+ return NewErrorResponse(errors.New("Not found publickey for the account"))
}
return NewSuccessResponse(&AccountPubkey{