// 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) } }
// 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) } }
// 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) } }
// Withdraw transaction. func Withdraw(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 } amount := r.FormValue("amount") if amount == "" { rlt = pp.MakeErrRes(errors.New("amount empty")) break } toAddr := r.FormValue("toaddr") if toAddr == "" { rlt = pp.MakeErrRes(errors.New("toaddr empty")) break } amt, err := strconv.ParseUint(amount, 10, 64) if err != nil { rlt = pp.MakeErrRes(err) break } req := pp.WithdrawalReq{ Pubkey: &a.Pubkey, CoinType: &cp, Coins: &amt, OutputAddress: &toAddr, } var res pp.WithdrawalRes if err := sknet.EncryGet(se.GetServAddr(), "/withdrawl", req, &res); err != nil { logger.Error(err.Error()) rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError) break } sendJSON(w, res) return } sendJSON(w, rlt) } }
// 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) } }
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 }
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 }
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 }
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) } }
// 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 }
// 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) } }
// 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) } }
// 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) } }
// 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) } }
// 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) } }