Пример #1
0
// GetRawTx get raw tx by txid.
// mode: GET
// url: /api/v1/rawtx?coin_type=[:coin_type]&txid=[:txid]
func GetRawTx(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		var rlt *pp.EmptyRes
		for {
			// get coin type
			cp := r.FormValue("coin_type")
			if cp == "" {
				logger.Error("no coin type")
				rlt = pp.MakeErrRes(errors.New("no coin type"))
				break
			}
			// get txid
			txid := r.FormValue("txid")
			if txid == "" {
				logger.Error("no txid")
				rlt = pp.MakeErrRes(errors.New("no txid"))
				break
			}
			req := pp.GetRawTxReq{
				CoinType: pp.PtrString(cp),
				Txid:     pp.PtrString(txid),
			}
			var res pp.GetRawTxRes
			if err := sknet.EncryGet(se.GetServAddr(), "/get/rawtx", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #2
0
func TestGetOutput(t *testing.T) {
	type args struct {
		hash string
	}
	tests := []struct {
		name    string
		args    args
		want    *pp.Output
		wantErr error
	}{
		// TODO: Add test cases.
		{
			"normal",
			args{
				"a57c038591f862b8fada57e496ef948183b153348d7932921f865a8541a477c5",
			},
			&pp.Output{
				Time:          pp.PtrUint64(1477037552),
				SrcBlockSeq:   pp.PtrUint64(443),
				SrcTx:         pp.PtrString("b8ca61c0788bd711c89563f9bc60add172ee01b543ea5dcb1955c51bbfcbbaa2"),
				OwnerAddress:  pp.PtrString("cBnu9sUvv12dovBmjQKTtfE4rbjMmf3fzW"),
				Coins:         pp.PtrUint64(1000000),
				Hours:         pp.PtrUint64(7),
				SpentBlockSeq: pp.PtrUint64(450),
				SpentTx:       pp.PtrString("b1481d614ffcc27408fe2131198d9d2821c78601a0aa23d8e9965b2a5196edc0"),
			},
			nil,
		},
		{
			"invalid uxhash len",
			args{
				"123",
			},
			nil,
			errors.New("invalid output hash, encoding/hex: odd length hex string"),
		},
		{
			"invalid uxhash ",
			args{
				"a57c038591f862b8fada57e496ef948183b153348d7932921f865a8541a477c7",
			},
			nil,
			errors.New("not found\n"),
		},
	}
	for _, tt := range tests {
		got, err := GetOutput("127.0.0.1:6420", tt.args.hash)
		if !reflect.DeepEqual(err, tt.wantErr) {
			t.Errorf("%q. GetOutput() error = %v, wantErr %v", tt.name, err, tt.wantErr)
			continue
		}
		if !reflect.DeepEqual(got, tt.want) {
			t.Errorf("%q. GetOutput() = %v, want %v", tt.name, got, tt.want)
		}
	}
}
Пример #3
0
// GetWalletBalance get local wallet balance.
// mode: GET
// url: /api/v1/wallet/balance?id=[:id]
// params:
// 		id: wallet id.
func GetWalletBalance(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		var rlt *pp.EmptyRes
		for {
			id := r.FormValue("id")
			if id == "" {
				err := errors.New("id is empty")
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}
			// get addresses in wallet.
			addrs, err := wallet.GetAddresses(id)
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			if len(addrs) == 0 {
				res := pp.GetAddrBalanceRes{
					Result: pp.MakeResult(pp.ErrCode_NotExits, "wallet have no address"),
				}
				sendJSON(w, &res)
				return
			}

			cp := strings.Split(id, "_")[0]

			// get address balance.
			req := pp.GetAddrBalanceReq{
				CoinType: pp.PtrString(cp),
				Addrs:    pp.PtrString(strings.Join(addrs, ",")),
			}

			var res pp.GetAddrBalanceRes
			if err := sknet.EncryGet(se.GetServAddr(), "/get/address/balance", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #4
0
func (bn bitcoinCli) BroadcastTx(rawtx string) (string, error) {
	req := pp.InjectTxnReq{
		CoinType: pp.PtrString("bitcoin"),
		Tx:       pp.PtrString(rawtx),
	}
	res := pp.InjectTxnRes{}
	if err := sknet.EncryGet(bn.NodeAddr, "/inject/tx", req, &res); err != nil {
		return "", err
	}

	if !res.Result.GetSuccess() {
		return "", fmt.Errorf("broadcast tx failed: %v", res.Result.GetReason())
	}

	return res.GetTxid(), nil
}
Пример #5
0
// CreateOrder create order through exchange server.
// mode: POST
// url: /api/v1/account/order?coin_pair=[:coin_pair]&type=[:type]&price=[:price]&amt=[:amt]
// params:
// 		coin_pair: order coin pair.
// 		type: order type, can be bid or ask.
// 		price: price.
// 		amt: amount.
func CreateOrder(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		rlt := &pp.EmptyRes{}
		for {
			req, err := makeOrderReq(r)
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			a, err := account.GetActive()
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			req.Pubkey = pp.PtrString(a.Pubkey)
			var res pp.OrderRes
			if err := sknet.EncryGet(se.GetServAddr(), "/create/order", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #6
0
// GetRawTx return rawtx of specifc tx.
func GetRawTx(egn engine.Exchange) sknet.HandlerFunc {
	return func(c *sknet.Context) error {
		var rlt *pp.EmptyRes
		for {
			req := pp.GetRawTxReq{}
			if err := c.BindJSON(&req); err != nil {
				rlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			coin, err := egn.GetCoin(req.GetCoinType())
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}
			rawtx, err := coin.GetRawTx(req.GetTxid())
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			res := pp.GetRawTxRes{
				Result:   pp.MakeResultWithCode(pp.ErrCode_Success),
				CoinType: req.CoinType,
				Rawtx:    pp.PtrString(rawtx),
			}
			return c.SendJSON(&res)
		}
		return c.Error(rlt)
	}
}
Пример #7
0
// GetCoins get supported coins from exchange server.
func GetCoins(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		rlt := &pp.EmptyRes{}
		for {
			a, err := account.GetActive()
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}
			req := pp.GetCoinsReq{
				Pubkey: pp.PtrString(a.Pubkey),
			}

			var res pp.CoinsRes
			if err := sknet.EncryGet(se.GetServAddr(), "/get/coins", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #8
0
// GetTransactionByID gets transaction verbose info by id
func (cn coinEx) GetTransactionByID(txid string) (string, error) {
	req := pp.GetTxReq{
		CoinType: pp.PtrString(cn.Name),
		Txid:     pp.PtrString(txid),
	}
	res := pp.GetTxRes{}
	if err := sknet.EncryGet(cn.NodeAddr, "/get/tx", req, &res); err != nil {
		return "", err
	}

	if !res.Result.GetSuccess() {
		return "", fmt.Errorf("get %s transaction by id failed: %v", cn.Name, res.Result.GetReason())
	}
	d, err := json.Marshal(res.GetTx())
	if err != nil {
		return "", err
	}
	return string(d), nil
}
Пример #9
0
func makeOrderReq(r *http.Request) (*pp.OrderReq, error) {
	// get coin_pair
	cp := r.FormValue("coin_pair")
	if cp == "" {
		return nil, errors.New("coin_pair is empty")
	}

	// get order type
	tp := r.FormValue("type")
	if tp == "" {
		return nil, errors.New("type is empty")
	}

	// get price
	pc := r.FormValue("price")
	if pc == "" {
		return nil, errors.New("price is empty")
	}
	price, err := strconv.ParseUint(pc, 10, 64)
	if err != nil {
		return nil, err
	}

	// get amount
	amt := r.FormValue("amt")
	if amt == "" {
		return nil, errors.New("amt is empty")
	}
	amount, err := strconv.ParseUint(amt, 10, 64)
	if err != nil {
		return nil, err
	}

	return &pp.OrderReq{
		CoinPair: pp.PtrString(cp),
		Type:     pp.PtrString(tp),
		Price:    pp.PtrUint64(price),
		Amount:   pp.PtrUint64(amount),
	}, nil
}
Пример #10
0
// GetUtxos gets bitcoin utxos of specific addresses.
func (btc *Bitcoin) GetUtxos(addrs []string) (interface{}, error) {
	utxos, err := GetUnspentOutputs(addrs)
	if err != nil {
		return nil, err
	}
	btcUxs := make([]*pp.BtcUtxo, len(utxos))
	for i, u := range utxos {
		btcUxs[i] = &pp.BtcUtxo{
			Address: pp.PtrString(u.GetAddress()),
			Txid:    pp.PtrString(u.GetTxid()),
			Vout:    pp.PtrUint32(u.GetVout()),
			Amount:  pp.PtrUint64(u.GetAmount()),
		}
	}

	var res = pp.GetUtxoRes{
		Result:   pp.MakeResultWithCode(pp.ErrCode_Success),
		BtcUtxos: btcUxs,
	}

	return res, nil
}
Пример #11
0
// MakeRequest creates request
func MakeRequest(path string, data interface{}) (*Request, error) {
	r := &Request{}
	r.Path = pp.PtrString(path)
	if data == nil {
		return r, nil
	}
	d, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}
	r.Data = d[:]
	return r, nil
}
Пример #12
0
// InjectTx broadcast transaction.
// mode: POST
// url: /api/v1/inject_rawtx?rawtx=[:rawtx]&coin_type=[:coin_type]
// params:
// 		rawtx: raw tx that's going to be injected.
// 		coin_type: skycoin or bitcoin.
func InjectTx(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		var rlt *pp.EmptyRes
		for {
			// get tx
			rawtx := r.FormValue("rawtx")
			if rawtx == "" {
				err := errors.New("rawtx is empty")
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			// get coin type
			cp := r.FormValue("coin_type")
			if cp == "" {
				logger.Error("empty coin type")
				rlt = pp.MakeErrRes(errors.New("empty coin type"))
				break
			}

			req := pp.InjectTxnReq{
				CoinType: pp.PtrString(cp),
				Tx:       pp.PtrString(rawtx),
			}

			var res pp.InjectTxnRes
			if err := sknet.EncryGet(se.GetServAddr(), "/inject/tx", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #13
0
// GetDepositAddress get deposit address from exchange server.
func GetDepositAddress(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		rlt := &pp.EmptyRes{}
		for {
			a, err := account.GetActive()
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			cp := r.FormValue("coin_type")
			if cp == "" {
				err := errors.New("coin type empty")
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			req := pp.GetDepositAddrReq{
				Pubkey:   pp.PtrString(a.Pubkey),
				CoinType: pp.PtrString(cp),
			}

			var res pp.GetDepositAddrRes

			if err := sknet.EncryGet(se.GetServAddr(), "/create/deposit_address", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #14
0
func (bn bitcoinCli) getOutputs(addrs []string) ([]*pp.BtcUtxo, error) {
	req := pp.GetUtxoReq{
		CoinType:  pp.PtrString("bitcoin"),
		Addresses: addrs,
	}
	res := pp.GetUtxoRes{}
	if err := sknet.EncryGet(bn.NodeAddr, "/get/utxos", req, &res); err != nil {
		return nil, err
	}

	if !res.Result.GetSuccess() {
		return nil, fmt.Errorf("get utxos failed: %v", res.Result.GetReason())
	}

	return res.BtcUtxos, nil
}
Пример #15
0
func (bn bitcoinCli) GetBalance(addrs []string) (uint64, error) {
	req := pp.GetUtxoReq{
		CoinType:  pp.PtrString("bitcoin"),
		Addresses: addrs,
	}
	res := pp.GetUtxoRes{}
	if err := sknet.EncryGet(bn.NodeAddr, "/get/utxos", req, &res); err != nil {
		return 0, err
	}
	var bal uint64
	for _, u := range res.BtcUtxos {
		bal += u.GetAmount()
	}

	return bal, nil
}
Пример #16
0
func getOrders(se Servicer, tp string) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		rlt := &pp.EmptyRes{}
		for {
			cp := r.FormValue("coin_pair")
			st := r.FormValue("start")
			ed := r.FormValue("end")
			if cp == "" || st == "" || ed == "" || tp == "" {
				rlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			start, err := strconv.ParseInt(st, 10, 64)
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			end, err := strconv.ParseInt(ed, 10, 64)
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			req := pp.GetOrderReq{
				CoinPair: &cp,
				Type:     pp.PtrString(tp),
				Start:    &start,
				End:      &end,
			}

			var res pp.GetOrderRes
			if err := sknet.EncryGet(se.GetServAddr(), "/get/orders", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #17
0
func encrypt(r interface{}, pubkey string, seckey string) (*pp.EncryptReq, error) {
	encData, nonce, err := pp.Encrypt(r, pubkey, seckey)
	if err != nil {
		return nil, err
	}

	s, err := cipher.SecKeyFromHex(seckey)
	if err != nil {
		return nil, err
	}

	p := cipher.PubKeyFromSecKey(s)
	return &pp.EncryptReq{
		Pubkey:      pp.PtrString(p.Hex()),
		Nonce:       nonce,
		Encryptdata: encData,
	}, nil
}
Пример #18
0
// GetUtxos get utxos through exchange server.
func GetUtxos(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		var rlt *pp.EmptyRes
		for {
			cp := r.FormValue("coin_type")
			if cp == "" {
				logger.Error("coin type empty")
				rlt = pp.MakeErrRes(errors.New("coin type empty"))
				break
			}

			addrs := r.FormValue("addrs")
			if addrs == "" {
				logger.Error("addrs empty")
				rlt = pp.MakeErrRes(errors.New("addrs empty"))
				break
			}
			addrArray := strings.Split(addrs, ",")
			for i, addr := range addrArray {
				addrArray[i] = strings.Trim(addr, " ")
			}

			req := pp.GetUtxoReq{
				CoinType:  pp.PtrString(cp),
				Addresses: addrArray,
			}

			var res pp.GetUtxoRes
			if err := sknet.EncryGet(se.GetServAddr(), "/get/utxos", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}
Пример #19
0
// CreateAccount handle the request of creating account.
func CreateAccount(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		// generate account pubkey/privkey pair, pubkey is the account id.
		errRlt := &pp.EmptyRes{}
		for {
			a := account.New()
			r := pp.CreateAccountReq{
				Pubkey: pp.PtrString(a.Pubkey),
			}
			res := pp.CreateAccountRes{}
			if err := sknet.EncryGet(se.GetServAddr(), "/create/account", r, &res); err != nil {
				logger.Error(err.Error())
				errRlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			// acntRes := res.(*pp.CreateAccountRes)
			if !res.GetResult().GetSuccess() {
				sendJSON(w, res)
			} else {
				ret := struct {
					Result    pp.Result `json:"result"`
					Pubkey    string    `json:"pubkey"`
					CreatedAt int64     `json:"created_at"`
				}{
					Result:    *res.Result,
					Pubkey:    a.Pubkey,
					CreatedAt: res.GetCreatedAt(),
				}
				account.Set(a)
				sendJSON(w, &ret)
			}
			return
		}
		sendJSON(w, errRlt)
	}
}
Пример #20
0
// InjectTx inject transaction.
func InjectTx(egn engine.Exchange) sknet.HandlerFunc {
	return func(c *sknet.Context) error {
		var rlt *pp.EmptyRes
		for {
			req := pp.InjectTxnReq{}
			if err := c.BindJSON(&req); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_WrongRequest)
				break
			}

			// get coin gateway
			coin, err := egn.GetCoin(req.GetCoinType())
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			// inject tx.
			txid, err := coin.InjectTx(req.GetTx())
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			res := pp.InjectTxnRes{
				Result: pp.MakeResultWithCode(pp.ErrCode_Success),
				Txid:   pp.PtrString(txid),
			}
			return c.SendJSON(&res)
		}
		return c.Error(rlt)
	}
}
Пример #21
0
// AdminUpdateBalance update balance of specific account
// mode: PUT
// url: /api/v1/admin/account/balance?dst=[:dst]&coin_type=[:coin_type]&amt=[:amt]
// params:
//      dst: the dst account pubkey, whose balance will be updated.
//      coin_type: skycoin or bitcoin, the coin you want to credit.
//      amt: balance that will be updated.
func AdminUpdateBalance(se Servicer) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		var rlt *pp.EmptyRes
		for {
			// get dst_pubkey
			dstPk := r.FormValue("dst")
			if dstPk == "" {
				err := errors.New("dst pubkey is empty")
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			// validate the dst_pubkey
			if _, err := cipher.PubKeyFromHex(dstPk); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(errors.New("invalid dst pubkey"))
				break
			}

			// get coin type.
			cp := r.FormValue("coin_type")
			if cp == "" {
				err := errors.New("coin_type is empty")
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			// get amt
			amt := r.FormValue("amt")
			if amt == "" {
				err := errors.New("amt is empty")
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}
			amount, err := strconv.ParseUint(amt, 10, 64)
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}

			a, err := account.GetActive()
			if err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrRes(err)
				break
			}
			req := pp.UpdateCreditReq{
				Pubkey:   pp.PtrString(a.Pubkey),
				CoinType: pp.PtrString(cp),
				Amount:   pp.PtrUint64(amount),
				Dst:      pp.PtrString(dstPk),
			}

			res := pp.UpdateCreditRes{}
			if err := sknet.EncryGet(se.GetServAddr(), "/admin/update/credit", req, &res); err != nil {
				logger.Error(err.Error())
				rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError)
				break
			}

			sendJSON(w, res)
			return
		}
		sendJSON(w, rlt)
	}
}