//Handler for /nodemanager/stop - stop Node //mode: GET //url: /nodemanager/stop?id=value func nodeStopHandler(nm *nodemanager.NodeManager) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { logger.Info("Stoping Node") nodeID := r.FormValue("id") if nodeID == "" { wh.Error400(w, "Missing Node id") return } i, err := strconv.Atoi(nodeID) if err != nil { wh.Error400(w, "Node id must be integer") return } if len(nm.PubKeyList) < i { wh.Error400(w, "Invalid Node id") return } nm.NodesList[nm.PubKeyList[i]].Close() delete(nm.NodesList, nm.PubKeyList[i]) nm.PubKeyList = append(nm.PubKeyList[:i], nm.PubKeyList[i+1:]...) } }
func getTransactionByID(gate *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } txid := r.FormValue("txid") if txid == "" { wh.Error400(w, "txid is empty") return } h, err := cipher.SHA256FromHex(txid) if err != nil { wh.Error400(w, err.Error()) return } tx, err := gate.V.GetTransaction(h) if err != nil { wh.Error400(w, err.Error()) return } if tx == nil { wh.Error404(w, "not found") return } resTx := visor.TransactionResult{ Transaction: visor.NewReadableTransaction(tx), Status: tx.Status, } wh.SendOr404(w, &resTx) } }
func getAddrUxOuts(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } addr := r.FormValue("address") if addr == "" { wh.Error400(w, "address is empty") return } cipherAddr, err := cipher.DecodeBase58Address(addr) if err != nil { wh.Error400(w, err.Error()) return } uxs, err := gateway.GetAddrUxOuts(cipherAddr) if err != nil { wh.Error400(w, err.Error()) return } wh.SendOr404(w, uxs) } }
func getRawTx(gate *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } txid := r.FormValue("txid") if txid == "" { wh.Error400(w, "txid is empty") return } h, err := cipher.SHA256FromHex(txid) if err != nil { wh.Error400(w, err.Error()) return } tx, err := gate.V.GetTransaction(h) if err != nil { wh.Error400(w, err.Error()) return } d := tx.Txn.Serialize() wh.SendOr404(w, hex.EncodeToString(d)) return } }
// Update wallet label func walletUpdateHandler(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // Update wallet id := r.FormValue("id") if id == "" { wh.Error400(w, "wallet id is empty") return } label := r.FormValue("label") if label == "" { wh.Error400(w, "label is empty") return } wlt := Wg.GetWallet(id) if wlt == nil { wh.Error404(w, fmt.Sprintf("wallet of id: %v does not exist", id)) return } wlt.SetLabel(label) if err := Wg.SaveWallet(wlt.GetID()); err != nil { m := "Failed to save wallet: %v" logger.Critical(m, "Failed to update label of wallet %v", id) wh.Error500(w, "Update wallet failed") return } wh.SendOr404(w, "success") } }
func getUxOutByID(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } uxid := r.FormValue("uxid") if uxid == "" { wh.Error400(w, "uxid is empty") return } id, err := cipher.SHA256FromHex(uxid) if err != nil { wh.Error400(w, err.Error()) return } uxout, err := gateway.GetUxOutByID(id) if err != nil { wh.Error400(w, err.Error()) return } if uxout == nil { wh.Error404(w, "not found") return } wh.SendOr404(w, uxout) } }
func walletNewAddresses(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { wh.Error405(w, "") return } wltID := r.FormValue("id") if wltID == "" { wh.Error400(w, "wallet id not set") return } addrs, err := Wg.NewAddresses(wltID, 1) if err != nil { wh.Error400(w, err.Error()) return } if err := Wg.SaveWallet(wltID); err != nil { wh.Error500(w, "") return } var rlt = struct { Address string `json:"address"` }{ addrs[0].String(), } wh.SendOr404(w, rlt) return } }
// Create a wallet Name is set by creation date func walletCreate(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { logger.Info("API request made to create a wallet") seed := r.FormValue("seed") label := r.FormValue("label") wltName := wallet.NewWalletFilename() var wlt wallet.Wallet var err error // the wallet name may dup, rename it till no conflict. for { wlt, err = Wg.CreateWallet(wltName, wallet.OptSeed(seed), wallet.OptLabel(label)) if err != nil && strings.Contains(err.Error(), "renaming") { wltName = wallet.NewWalletFilename() continue } break } if err := Wg.SaveWallet(wlt.GetID()); err != nil { wh.Error400(w, err.Error()) return } rlt := wallet.NewReadableWallet(wlt) wh.SendOr500(w, rlt) } }
//Handler for /nodemanager/addtransport //mode: POST //url: /nodemanager/addtransport func nodeAddTransportHandler(nm *nodemanager.NodeManager) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { logger.Info("Add transport to Node") var c ConfigWithID err := json.NewDecoder(r.Body).Decode(&c) if err != nil { wh.Error400(w, "Error decoding config for transport") } if len(nm.PubKeyList) < c.NodeID { wh.Error400(w, "Invalid Node id") return } node := nm.GetNodeByIndex(c.NodeID) nodemanager.AddPeersToNode(node, c.Config) } }
//Handler for /nodemanager/removetransport //mode: POST //url: /nodemanager/removetransport func nodeRemoveTransportHandler(nm *nodemanager.NodeManager) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { logger.Info("Remove transport from Node") var c TransportWithID err := json.NewDecoder(r.Body).Decode(&c) if err != nil { wh.Error400(w, "Error decoding config for transport") } if len(nm.PubKeyList) < c.NodeID { wh.Error400(w, "Invalid Node id") return } logger.Info(strconv.Itoa(c.NodeID)) nm.RemoveTransportsFromNode(c.NodeID, c.Transport) } }
// get block by hash or seq // method: GET // url: /block?hash=[:hash] or /block?seq[:seq] // params: hash or seq, should only specify one filter. func getBlock(gate *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } hash := r.FormValue("hash") seq := r.FormValue("seq") var b *coin.Block switch { case hash == "" && seq == "": wh.Error400(w, "should specify one filter, hash or seq") return case hash != "" && seq != "": wh.Error400(w, "should only specify one filter, hash or seq") return case hash != "": h, err := cipher.SHA256FromHex(hash) if err != nil { wh.Error400(w, err.Error()) return } b = gate.V.GetBlockByHash(h) case seq != "": uSeq, err := strconv.ParseUint(seq, 10, 64) if err != nil { wh.Error400(w, err.Error()) return } b = gate.V.GetBlockBySeq(uSeq) } if b == nil { wh.SendOr404(w, nil) return } wh.SendOr404(w, visor.NewReadableBlock(b)) } }
//Implement func injectTransaction(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { wh.Error405(w, "") return } // get the rawtransaction v := struct { Rawtx string `json:"rawtx"` }{} if err := json.NewDecoder(r.Body).Decode(&v); err != nil { logger.Error("bad request: %v", err) wh.Error400(w, err.Error()) return } b, err := hex.DecodeString(v.Rawtx) if err != nil { logger.Error("%v", err) wh.Error400(w, err.Error()) return } txn := coin.TransactionDeserialize(b) if err := visor.VerifyTransactionFee(gateway.D.Visor.Visor.Blockchain, &txn); err != nil { wh.Error400(w, err.Error()) return } t, err := gateway.D.Visor.InjectTransaction(txn, gateway.D.Pool) if err != nil { wh.Error400(w, fmt.Sprintf("inject tx failed:%v", err)) return } wh.SendOr404(w, t.Hash().Hex()) } }
func getBlocks(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } sstart := r.FormValue("start") start, err := strconv.ParseUint(sstart, 10, 64) if err != nil { wh.Error400(w, fmt.Sprintf("Invalid start value \"%s\"", sstart)) return } send := r.FormValue("end") end, err := strconv.ParseUint(send, 10, 64) if err != nil { wh.Error400(w, fmt.Sprintf("Invalid end value \"%s\"", send)) return } wh.SendOr404(w, gateway.GetBlocks(start, end)) } }
// get last N blocks func getLastBlocks(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { wh.Error405(w, "") return } num := r.FormValue("num") if num == "" { wh.Error400(w, "Param: num is empty") return } n, err := strconv.ParseUint(num, 10, 64) if err != nil { wh.Error400(w, err.Error()) return } wh.SendOr404(w, gateway.GetLastBlocks(n)) } }
func testHandler(nm *nodemanager.NodeManager) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { wh.Error400(w, fmt.Sprint("Works!")) if addr := r.FormValue("addr"); addr == "" { wh.Error404(w) } else { //wh.SendOr404(w, nm.GetConnection(addr)) wh.Error404(w) } } }
// Generating secret key, address, public key by given // GET/POST // bc - bool - is bitcoin type (optional) - default: true // n - int - Generation count (optional) - default: 1 // s - bool - is hide secret key (optional) - default: false // seed - string - seed hash func apiCreateAddressHandler(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var seed string = r.FormValue("seed") var err error if seed == "" { wh.Error400(w, "Empty seed") return } isBitcoin, err = strconv.ParseBool(r.FormValue("bc")) if err != nil { isBitcoin = true } genCount, err := strconv.Atoi(r.FormValue("n")) if err != nil { genCount = 1 } hideSecKey, err = strconv.ParseBool(r.FormValue("s")) if err != nil { hideSecKey = false } wallet := Wallet{ Meta: make(map[string]string), //map[string]string Entries: make([]KeyEntry, genCount), } if isBitcoin == false { wallet.Meta = map[string]string{"coin": "skycoin"} } else { wallet.Meta = map[string]string{"coin": "bitcoin"} } wallet.Meta["seed"] = seed seckeys := cipher.GenerateDeterministicKeyPairs([]byte(seed), genCount) for i, sec := range seckeys { pub := cipher.PubKeyFromSecKey(sec) wallet.Entries[i] = getKeyEntry(pub, sec) } ret := wallet wh.SendOr404(w, ret) } }
// Creates and broadcasts a transaction sending money from one of our wallets // to destination address. func walletSpendHandler(gateway *daemon.Gateway) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { //log.Printf("Spend1") if r.FormValue("id") == "" { wh.Error400(w, "Missing wallet_id") return } walletId := r.FormValue("id") if walletId == "" { wh.Error400(w, "Invalid Wallet Id") return } sdst := r.FormValue("dst") if sdst == "" { wh.Error400(w, "Missing destination address \"dst\"") return } dst, err := cipher.DecodeBase58Address(sdst) if err != nil { //Error400(w, "Invalid destination address: %v", err) wh.Error400(w, "Invalid destination address: %v", err.Error()) return } //set fee automatically for now /* sfee := r.FormValue("fee") fee, err := strconv.ParseUint(sfee, 10, 64) if err != nil { Error400(w, "Invalid \"fee\" value") return } */ //var fee uint64 = 0 scoins := r.FormValue("coins") //shours := r.FormValue("hours") coins, err := strconv.ParseUint(scoins, 10, 64) if err != nil { wh.Error400(w, "Invalid \"coins\" value") return } var hours uint64 = 0 var fee uint64 = 0 //doesnt work/do anything right now //MOVE THIS INTO HERE ret := Spend(gateway.D, gateway.D.Visor, Wg, walletId, wallet.NewBalance(coins, hours), fee, dst) if ret.Error != "" { wh.Error400(w, "Spend Failed: %s", ret.Error) } wh.SendOr404(w, ret) } }
//Handler for /nodemanager/gettransports //mode: GET //url: /nodemanager/gettransports?id=value func nodeGetTransportsHandler(nm *nodemanager.NodeManager) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { logger.Info("Get transport from Node") nodeID := r.FormValue("id") if nodeID == "" { wh.Error400(w, "Missing Node id") return } i, err := strconv.Atoi(nodeID) if err != nil { wh.Error400(w, "Node id must be integer") return } if len(nm.PubKeyList) < i { wh.Error400(w, "Invalid Node id") return } wh.SendJSON(w, nm.GetTransportsFromNode(i)) } }