// 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) } }
// Creates a Transaction spending coins and hours from our coins func CreateSpendingTransaction(wallet wallet.Wallet, unconfirmed *UnconfirmedTxnPool, unspent *coin.UnspentPool, headTime uint64, amt Balance, fee, burnFactor uint64, dest coin.Address) (coin.Transaction, error) { txn := coin.Transaction{} auxs := unspent.AllForAddresses(wallet.GetAddresses()) // Subtract pending spends from available puxs := unconfirmed.SpendsForAddresses(unspent, wallet.GetAddressSet()) auxs = auxs.Sub(puxs) // Determine which unspents to spend spends, err := createSpends(headTime, auxs.Flatten(), amt, fee, burnFactor) if err != nil { return txn, err } // Add these unspents as tx inputs toSign := make([]coin.SecKey, len(spends)) spending := Balance{0, 0} for i, au := range spends { entry, exists := wallet.GetEntry(au.Body.Address) if !exists { log.Panic("On second thought, the wallet entry does not exist") } txn.PushInput(au.Hash()) toSign[i] = entry.Secret spending.Coins += au.Body.Coins spending.Hours += au.CoinHours(headTime) } // Determine how much change we get back, if any _, changeHours, err := calculateBurnAndChange(spending.Hours, amt.Hours, fee, burnFactor) if err != nil { // This should not occur, else createSpends is broken return txn, err } change := NewBalance(spending.Coins-amt.Coins, changeHours) // TODO -- send change to a new address changeAddr := spends[0].Body.Address if change.Coins == 0 { if change.Hours > 0 { msg := ("Have enough coins, but not enough to send coin hours " + "change back. Would spend %d more hours than requested.") return txn, fmt.Errorf(msg, change.Hours) } } else { txn.PushOutput(changeAddr, change.Coins, change.Hours) } // Finalize the the transaction txn.PushOutput(dest, amt.Coins, amt.Hours) txn.SignInputs(toSign) txn.UpdateHeader() return txn, nil }
func getKeys(wlt *wallet.Wallet, outs []unspentOut) ([]cipher.SecKey, error) { keys := make([]cipher.SecKey, len(outs)) for i, o := range outs { addr, err := cipher.DecodeBase58Address(o.Address) if err != nil { return nil, errAddress } entry, ok := wlt.GetEntry(addr) if !ok { return nil, fmt.Errorf("%v is not in wallet", o.Address) } keys[i] = entry.Secret } return keys, nil }
//Check if any of the outputs are spent func (self *WalletRPC) HasUnconfirmedTransactions(v *visor.Visor, wallet *wallet.Wallet) bool { if wallet == nil { log.Panic("Wallet does not exist") } auxs := v.Blockchain.Unspent.AllForAddresses(wallet.GetAddresses()) puxs := v.Unconfirmed.SpendsForAddresses(&v.Blockchain.Unspent, wallet.GetAddressSet()) _ = auxs _ = puxs //no transactions if len(puxs) == 0 { return true } return false }
//DEPRECATE //deprecate dependency on wallet // Creates a Transaction spending coins and hours from our coins //MOVE SOMEWHERE ELSE //Move to wallet or move to ??? func CreateSpendingTransaction(wlt wallet.Wallet, unconfirmed *UnconfirmedTxnPool, unspent *coin.UnspentPool, headTime uint64, amt wallet.Balance, dest cipher.Address) (coin.Transaction, error) { txn := coin.Transaction{} auxs := unspent.AllForAddresses(wlt.GetAddresses()) // Subtract pending spends from available puxs := unconfirmed.SpendsForAddresses(unspent, wlt.GetAddressSet()) auxs = auxs.Sub(puxs) // Determine which unspents to spend spends, err := createSpends(headTime, auxs.Flatten(), amt) if err != nil { return txn, err } // Add these unspents as tx inputs toSign := make([]cipher.SecKey, len(spends)) spending := wallet.Balance{0, 0} for i, au := range spends { entry, exists := wlt.GetEntry(au.Body.Address) if !exists { log.Panic("On second thought, the wallet entry does not exist") } txn.PushInput(au.Hash()) toSign[i] = entry.Secret spending.Coins += au.Body.Coins spending.Hours += au.CoinHours(headTime) } //keep 1/4th of hours as change //send half to each address var changeHours uint64 = spending.Hours / 4 if amt.Coins == spending.Coins { txn.PushOutput(dest, amt.Coins, changeHours/2) txn.SignInputs(toSign) txn.UpdateHeader() return txn, nil } change := wallet.NewBalance(spending.Coins-amt.Coins, changeHours/2) // TODO -- send change to a new address changeAddr := spends[0].Body.Address //create transaction txn.PushOutput(changeAddr, change.Coins, change.Hours) txn.PushOutput(dest, amt.Coins, changeHours/2) txn.SignInputs(toSign) txn.UpdateHeader() return txn, nil }