// Withdraw api for handlering withdraw process. func Withdraw(ee engine.Exchange) sknet.HandlerFunc { return func(c *sknet.Context) error { rlt := &pp.EmptyRes{} for { reqParam, err := getWithdrawReqParams(c, ee) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } cp := reqParam.Values["cointype"].(string) a := reqParam.Values["account"].(account.Accounter) amt := reqParam.Values["amt"].(uint64) outAddr := reqParam.Values["outAddr"].(string) // get handler for creating txIns and txOuts base on the coin type. createTxInOut, err := getTxInOutHandler(cp) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } // create txIns and txOuts. inOutSet, err := createTxInOut(ee, a, amt, outAddr) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } var success bool defer func() { if !success { // if not success, invoke the teardown, for putting back utxos, and reset balance. inOutSet.Teardown() } }() // get coin gateway. coin, err := ee.GetCoin(cp) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } // create raw tx rawtx, err := coin.CreateRawTx(inOutSet.TxIns, inOutSet.TxOuts) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } // sign the tx rawtx, err = coin.SignRawTx(rawtx, getAddrPrivKey(ee, cp)) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } // inject the transaction. txid, err := coin.InjectTx(rawtx) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } success = true resp := pp.WithdrawalRes{ Result: pp.MakeResultWithCode(pp.ErrCode_Success), NewTxid: &txid, } return c.SendJSON(&resp) } return c.Error(rlt) } }
// CreateRawTx create raw tx base on some utxos. // mode: POST // url: /api/v1/create_rawtx?coin_type=[:coin_type] // request json: // different in bitcoin and skycoin. func CreateRawTx(se Servicer) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var rlt *pp.EmptyRes loop: for { // get coin type cp := r.FormValue("coin_type") // get request body params := rawTxParams{} if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } coin, err := se.GetCoin(cp) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrResWithCode(pp.ErrCode_ServerError) break } var rawtx string switch cp { case bitcoin.Type: outs := make([]bitcoin.TxOut, len(params.TxOuts)) for i, o := range params.TxOuts { outs[i].Addr = o.Addr outs[i].Value = o.Value } rawtx, err = coin.CreateRawTx(params.TxIns, outs) case skycoin.Type: outs := make([]skycoin.TxOut, len(params.TxOuts)) for i, o := range params.TxOuts { addr, err := cipher.DecodeBase58Address(o.Addr) if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break loop } outs[i].Address = addr outs[i].Coins = o.Value outs[i].Hours = o.Hours } rawtx, err = coin.CreateRawTx(params.TxIns, outs) } if err != nil { logger.Error(err.Error()) rlt = pp.MakeErrRes(err) break } res := struct { Result *pp.Result `json:"result"` Rawtx string `json:"rawtx"` }{ Result: pp.MakeResultWithCode(pp.ErrCode_Success), Rawtx: rawtx, } sendJSON(w, &res) return } sendJSON(w, rlt) } }