"github.com/vapor/protocol/vm/vmutil"
)
-// POST /create-account
-func (a *API) createAccount(ctx context.Context, ins struct {
+type CreateAccountReq struct {
RootXPubs []chainkd.XPub `json:"root_xpubs"`
Quorum int `json:"quorum"`
Alias string `json:"alias"`
-}) Response {
+}
+
+// POST /create-account
+func (a *API) createAccount(ctx context.Context, ins CreateAccountReq) Response {
acc, err := a.wallet.AccountMgr.Create(ins.RootXPubs, ins.Quorum, ins.Alias, signers.BIP0044)
if err != nil {
return NewErrorResponse(err)
}
// POST /delete-account
-func (a *API) deleteAccount(ctx context.Context, filter struct {
- AccountID string `json:"account_id"`
- AccountAlias string `json:"account_alias"`
-}) Response {
+func (a *API) deleteAccount(ctx context.Context, filter AccountFilter) Response {
accountID := filter.AccountID
if filter.AccountAlias != "" {
acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias)
return NewSuccessResponse(resp)
}
-type addressResp struct {
+type AddressReq struct {
+ AccountID string `json:"account_id"`
+ AccountAlias string `json:"account_alias"`
+ From uint `json:"from"`
+ Count uint `json:"count"`
+}
+
+type AddressResp struct {
AccountAlias string `json:"account_alias"`
AccountID string `json:"account_id"`
Address string `json:"address"`
}
// SortByIndex implements sort.Interface for addressResp slices
-type SortByIndex []addressResp
+type SortByIndex []AddressResp
func (a SortByIndex) Len() int { return len(a) }
func (a SortByIndex) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortByIndex) Less(i, j int) bool { return a[i].KeyIndex < a[j].KeyIndex }
-func (a *API) listAddresses(ctx context.Context, ins struct {
- AccountID string `json:"account_id"`
- AccountAlias string `json:"account_alias"`
- From uint `json:"from"`
- Count uint `json:"count"`
-}) Response {
+func (a *API) listAddresses(ctx context.Context, ins AddressReq) Response {
accountID := ins.AccountID
var target *account.Account
if ins.AccountAlias != "" {
return NewErrorResponse(err)
}
- addresses := []addressResp{}
+ addresses := []AddressResp{}
for _, cp := range cps {
if cp.Address == "" || cp.AccountID != target.ID {
continue
}
- addresses = append(addresses, addressResp{
+ addresses = append(addresses, AddressResp{
AccountAlias: target.Alias,
AccountID: cp.AccountID,
Address: cp.Address,
"github.com/vapor/crypto/ed25519/chainkd"
)
-type createKeyResp struct {
+type CreateKeyReq struct {
+ Alias string `json:"alias"`
+ Password string `json:"password"`
+ Mnemonic string `json:"mnemonic"`
+ Language string `json:"language"`
+}
+
+type CreateKeyResp struct {
Alias string `json:"alias"`
XPub chainkd.XPub `json:"xpub"`
File string `json:"file"`
Mnemonic string `json:"mnemonic,omitempty"`
}
-func (a *API) pseudohsmCreateKey(ctx context.Context, in struct {
- Alias string `json:"alias"`
- Password string `json:"password"`
- Mnemonic string `json:"mnemonic"`
- Language string `json:"language"`
-}) Response {
+func (a *API) pseudohsmCreateKey(ctx context.Context, in CreateKeyReq) Response {
if in.Language == "" {
in.Language = "en"
}
if err != nil {
return NewErrorResponse(err)
}
- return NewSuccessResponse(&createKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File})
+ return NewSuccessResponse(&CreateKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File})
}
xpub, mnemonic, err := a.wallet.Hsm.XCreate(in.Alias, in.Password, in.Language)
if err != nil {
return NewErrorResponse(err)
}
- return NewSuccessResponse(&createKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File, Mnemonic: *mnemonic})
+ return NewSuccessResponse(&CreateKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File, Mnemonic: *mnemonic})
}
func (a *API) pseudohsmUpdateKeyAlias(ctx context.Context, in struct {
return NewSuccessResponse(tx)
}
-// POST /list-unspent-outputs
-func (a *API) listUnspentOutputs(ctx context.Context, filter struct {
+type ListUtxosReq struct {
AccountID string `json:"account_id"`
AccountAlias string `json:"account_alias"`
ID string `json:"id"`
SmartContract bool `json:"smart_contract"`
From uint `json:"from"`
Count uint `json:"count"`
-}) Response {
+}
+
+// POST /list-unspent-outputs
+func (a *API) listUnspentOutputs(ctx context.Context, filter ListUtxosReq) Response {
accountID := filter.AccountID
if filter.AccountAlias != "" {
acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias)
"github.com/vapor/blockchain/txbuilder"
)
-func (a *API) createAccountReceiver(ctx context.Context, ins struct {
+type AccountFilter struct {
AccountID string `json:"account_id"`
AccountAlias string `json:"account_alias"`
-}) Response {
+}
+
+func (a *API) createAccountReceiver(ctx context.Context, ins AccountFilter) Response {
accountID := ins.AccountID
if ins.AccountAlias != "" {
account, err := a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
--- /dev/null
+package apinode
+
+import (
+ "encoding/json"
+
+ "github.com/vapor/api"
+ "github.com/vapor/blockchain/pseudohsm"
+ "github.com/vapor/blockchain/query"
+ "github.com/vapor/blockchain/txbuilder"
+ "github.com/vapor/crypto/ed25519/chainkd"
+ "github.com/vapor/errors"
+)
+
+func (n *Node) CreateKey(alias, password string) (*api.CreateKeyResp, error) {
+ url := "/create-key"
+ payload, err := json.Marshal(api.CreateKeyReq{Alias: alias, Password: password})
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &api.CreateKeyResp{}
+ return res, n.request(url, payload, res)
+}
+
+func (n *Node) ListKeys() (*[]pseudohsm.XPub, error) {
+ url := "/list-keys"
+ res := &[]pseudohsm.XPub{}
+ return res, n.request(url, nil, res)
+}
+
+//默认创建单签账户
+func (n *Node) CreateAccount(keyAlias, accountAlias string) (*query.AnnotatedAccount, error) {
+ xPub, err := n.ListKeys()
+ if err != nil {
+ return nil, err
+ }
+
+ var rootXPub *chainkd.XPub
+ for _, x := range *xPub {
+ if x.Alias == keyAlias {
+ rootXPub = &x.XPub
+ break
+ }
+ }
+
+ if rootXPub == nil {
+ return nil, errors.New("keyAlias not found!")
+ }
+
+ return n.postCreateAccount(accountAlias, 1, []chainkd.XPub{*rootXPub})
+}
+
+//多签账户
+func (n *Node) CreateMultiSignAccount(alias string, quorum int, rootXPubs []chainkd.XPub) (*query.AnnotatedAccount, error) {
+ return n.postCreateAccount(alias, quorum, rootXPubs)
+}
+
+func (n *Node) postCreateAccount(alias string, quorum int, rootXPubs []chainkd.XPub) (*query.AnnotatedAccount, error) {
+ url := "/create-account"
+ payload, err := json.Marshal(api.CreateAccountReq{
+ Alias: alias,
+ Quorum: quorum,
+ RootXPubs: rootXPubs,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &query.AnnotatedAccount{}
+ return res, n.request(url, payload, res)
+}
+
+func (n *Node) ListAccounts() (*[]query.AnnotatedAccount, error) {
+ url := "/list-accounts"
+ payload, err := json.Marshal(struct{}{})
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &[]query.AnnotatedAccount{}
+ return res, n.request(url, payload, res)
+}
+
+func (n *Node) CreateAccountReceiver(alias string) (*txbuilder.Receiver, error) {
+ url := "/create-account-receiver"
+ payload, err := json.Marshal(api.AccountFilter{
+ AccountAlias: alias,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &txbuilder.Receiver{}
+ return res, n.request(url, payload, res)
+}
--- /dev/null
+//+build apinode
+
+package apinode
+
+import (
+ "fmt"
+ "testing"
+)
+
+var n *Node
+
+func TestMain(m *testing.M) {
+ n = NewNode("http://127.0.0.1:9889")
+ m.Run()
+}
+
+func TestNodeCreateKey(t *testing.T) {
+ res, err := n.CreateKey("test10", "123456")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ fmt.Println(res)
+}
+
+func TestNodeCreateAccount(t *testing.T) {
+ res, err := n.CreateAccount("test10", "test11")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ fmt.Println(res)
+}
+
+func TestNodeCreateAccountReceiver(t *testing.T) {
+ res, err := n.CreateAccountReceiver("test10")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ fmt.Println(res)
+}
+
+func TestNodeListAccounts(t *testing.T) {
+ res, err := n.ListAccounts()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ fmt.Println(res)
+}
"encoding/json"
"github.com/vapor/errors"
+ "github.com/vapor/netsync/peers"
"github.com/vapor/toolbar/common"
)
return errors.New(resp.ErrDetail)
}
+ if resp.Data == nil {
+ return nil
+ }
+
return json.Unmarshal(resp.Data, respData)
}
+
+func (n *Node) DisconnectPeer(peerID string) error {
+ url := "/disconnect-peer"
+ payload, err := json.Marshal(struct {
+ PeerID string `json:"peer_id"`
+ }{
+ PeerID: peerID,
+ })
+ if err != nil {
+ return err
+ }
+
+ return n.request(url, payload, nil)
+
+}
+
+func (n *Node) ConnectPeer(ip string, port uint16) (*peers.Peer, error) {
+ url := "/connect-peer"
+ payload, err := json.Marshal(struct {
+ Ip string `json:"ip"`
+ Port uint16 `json:"port"`
+ }{
+ Ip: ip,
+ Port: port,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &peers.Peer{}
+ return res, n.request(url, payload, res)
+}
--- /dev/null
+package apinode
+
+import (
+ "encoding/json"
+
+ "github.com/vapor/api"
+ "github.com/vapor/blockchain/query"
+ "github.com/vapor/errors"
+ "github.com/vapor/netsync/peers"
+ "github.com/vapor/wallet"
+)
+
+func (n *Node) ListAddresses(accountAlias string, from, count uint) (*[]api.AddressResp, error) {
+ url := "/list-addresses"
+ payload, err := json.Marshal(api.AddressReq{
+ AccountAlias: accountAlias,
+ From: from,
+ Count: count,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &[]api.AddressResp{}
+ return res, n.request(url, payload, res)
+}
+
+func (n *Node) ListBalances(accountAlias string) (*[]wallet.AccountBalance, error) {
+ url := "/list-balances"
+ payload, err := json.Marshal(api.AccountFilter{
+ AccountAlias: accountAlias,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &[]wallet.AccountBalance{}
+ return res, n.request(url, payload, res)
+}
+
+func (n *Node) ListUtxos(accountAlias string,from, count uint) (*[]query.AnnotatedUTXO, error) {
+ url := "/list-unspent-outputs"
+ payload, err := json.Marshal(api.ListUtxosReq{
+ AccountAlias: accountAlias,
+ From: from,
+ Count: count,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "json marshal")
+ }
+
+ res := &[]query.AnnotatedUTXO{}
+ return res, n.request(url, payload, res)
+}
+
+func (n *Node) WalletInfo() (*api.WalletInfo, error) {
+ url := "/wallet-info"
+ res := &api.WalletInfo{}
+ return res, n.request(url, nil, res)
+}
+
+func (n *Node) NetInfo() (*api.NetInfo, error) {
+ url := "/net-info"
+ res := &api.NetInfo{}
+ return res, n.request(url, nil, res)
+}
+
+func (n *Node) ListPeers() (*[]*peers.PeerInfo, error) {
+ url := "/list-peers"
+ res := &[]*peers.PeerInfo{}
+ return res, n.request(url, nil, res)
+}
--- /dev/null
+//+build apinode
+
+package apinode
+
+import (
+ "fmt"
+ "testing"
+)
+
+func TestNodeListAddresses(t *testing.T) {
+ res, err := n.ListAddresses("test10", 0, 10)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(res)
+}
+
+func TestNodeListBalances(t *testing.T) {
+ res, err := n.ListBalances("test10")
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(res)
+}
+
+func TestNodeListUtxos(t *testing.T) {
+ res, err := n.ListUtxos("test10", 0, 10)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(res)
+}
+
+func TestNodeWalletInfo(t *testing.T) {
+ res, err := n.WalletInfo()
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(res)
+}
+
+func TestNodeNetInfo(t *testing.T) {
+ res, err := n.NetInfo()
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(res)
+}
+
+func TestNodeListPeers(t *testing.T) {
+ res, err := n.ListPeers()
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(res)
+}