github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/cmd/lit-af/walletcmds.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strconv" 6 7 "github.com/fatih/color" 8 "github.com/mit-dci/lit/litrpc" 9 "github.com/mit-dci/lit/lnutil" 10 "github.com/mit-dci/lit/logging" 11 ) 12 13 var sendCommand = &Command{ 14 Format: fmt.Sprintf( 15 "%s%s\n", lnutil.White("send"), lnutil.ReqColor("address", "amount")), 16 Description: "Send the given amount of satoshis to the given address.\n", 17 ShortDescription: "Send the given amount of satoshis to the given address.\n", 18 } 19 20 var addressCommand = &Command{ 21 Format: fmt.Sprintf( 22 "%s%s\n", lnutil.White("adr"), lnutil.ReqColor("?amount", "?cointype")), 23 Description: "Makes new addresses in a specified wallet.\n", 24 ShortDescription: "Makes new addresses.\n", 25 } 26 27 var fanCommand = &Command{ 28 Format: fmt.Sprintf( 29 "%s%s\n", lnutil.White("fan"), lnutil.ReqColor("addr", "howmany", "howmuch")), 30 Description: "\n", 31 ShortDescription: "\n", 32 // TODO: Add description. 33 } 34 35 var sweepCommand = &Command{ 36 Format: fmt.Sprintf( 37 "%s%s%s\n", lnutil.White("sweep"), 38 lnutil.ReqColor("addr", "howmany"), lnutil.OptColor("drop")), 39 Description: "Move UTXOs with many 1-in-1-out txs.\n", 40 // TODO: Make this more clear. 41 ShortDescription: "Move UTXOs with many 1-in-1-out txs.\n", 42 } 43 44 // Send sends coins somewhere 45 func (lc *litAfClient) Send(textArgs []string) error { 46 stopEx, err := CheckHelpCommand(sendCommand, textArgs, 2) 47 if err != nil || stopEx { 48 return err 49 } 50 51 args := new(litrpc.SendArgs) 52 reply := new(litrpc.TxidsReply) 53 54 /* 55 adr, err := btcutil.DecodeAddress(args[0], lc.Param) 56 if err != nil { 57 fmt.Fprintf(color.Output,"error parsing %s as address\t", args[0]) 58 return err 59 } 60 */ 61 amt, err := strconv.Atoi(textArgs[1]) 62 if err != nil { 63 return err 64 } 65 66 fmt.Fprintf(color.Output, "send %d to address: %s \n", amt, textArgs[0]) 67 68 args.DestAddrs = []string{textArgs[0]} 69 args.Amts = []int64{int64(amt)} 70 71 err = lc.Call("LitRPC.Send", args, reply) 72 if err != nil { 73 return err 74 } 75 fmt.Fprintf(color.Output, "sent txid(s):\n") 76 for i, t := range reply.Txids { 77 fmt.Fprintf(color.Output, "\t%d %s\n", i, t) 78 } 79 return nil 80 } 81 82 // Sweep moves utxos with many 1-in-1-out txs 83 func (lc *litAfClient) Sweep(textArgs []string) error { 84 stopEx, err := CheckHelpCommand(sweepCommand, textArgs, 2) 85 if err != nil || stopEx { 86 return err 87 } 88 89 args := new(litrpc.SweepArgs) 90 reply := new(litrpc.TxidsReply) 91 92 args.DestAdr = textArgs[0] 93 numTxs, err := strconv.Atoi(textArgs[1]) 94 if err != nil { 95 return err 96 } 97 args.NumTx = uint32(numTxs) 98 if len(textArgs) > 2 { 99 args.Drop = true 100 } 101 102 err = lc.Call("LitRPC.Sweep", args, reply) 103 if err != nil { 104 return err 105 } 106 fmt.Fprintf(color.Output, "Swept\n") 107 for i, t := range reply.Txids { 108 fmt.Fprintf(color.Output, "%d %s\n", i, t) 109 } 110 111 return nil 112 } 113 114 //// ------------------------- fanout 115 //type FanArgs struct { 116 // DestAdr string 117 // NumOutputs uint32 118 // AmtPerOutput int64 119 //} 120 121 func (lc *litAfClient) Fan(textArgs []string) error { 122 stopEx, err := CheckHelpCommand(fanCommand, textArgs, 3) 123 if err != nil || stopEx { 124 return err 125 } 126 127 args := new(litrpc.FanArgs) 128 reply := new(litrpc.TxidsReply) 129 args.DestAdr = textArgs[0] 130 131 outputs, err := strconv.Atoi(textArgs[1]) 132 if err != nil { 133 return err 134 } 135 args.NumOutputs = uint32(outputs) 136 137 amt, err := strconv.Atoi(textArgs[2]) 138 if err != nil { 139 return err 140 } 141 args.AmtPerOutput = int64(amt) 142 143 err = lc.Call("LitRPC.Fanout", args, reply) 144 if err != nil { 145 return err 146 } 147 148 fmt.Fprintf(color.Output, "Fanout:\n") 149 for i, t := range reply.Txids { 150 fmt.Fprintf(color.Output, "\t%d %s\n", i, t) 151 } 152 return nil 153 } 154 155 // ------------------ get / set fee 156 157 func (lc *litAfClient) Fee(textArgs []string) error { 158 159 reply := new(litrpc.FeeReply) 160 161 SetArgs := new(litrpc.SetFeeArgs) 162 GetArgs := new(litrpc.FeeArgs) 163 164 // whether we are setting the fee or not 165 var set bool 166 // There is an argument. That's the coin type. (coin type 0 means default) 167 if len(textArgs) > 0 { 168 feeint, err := strconv.Atoi(textArgs[0]) 169 if err != nil { 170 logging.Errorf("Can't set fee to %s, querying current fee instead\n", textArgs[0]) 171 } else { 172 set = true 173 SetArgs.Fee = int64(feeint) 174 } 175 } 176 177 if len(textArgs) > 1 { 178 coinint, err := strconv.Atoi(textArgs[1]) 179 if err != nil { 180 return err 181 } 182 SetArgs.CoinType = uint32(coinint) 183 GetArgs.CoinType = uint32(coinint) 184 } 185 186 if set { 187 err := lc.Call("LitRPC.SetFee", SetArgs, reply) 188 if err != nil { 189 return err 190 } 191 } else { 192 err := lc.Call("LitRPC.GetFee", GetArgs, reply) 193 if err != nil { 194 return err 195 } 196 197 } 198 199 fmt.Printf("Current fee rate %d sat / byte\n", reply.CurrentFee) 200 201 return nil 202 } 203 204 // ------------------ set fee 205 206 func (lc *litAfClient) SetFee(textArgs []string) error { 207 208 args := new(litrpc.SetFeeArgs) 209 reply := new(litrpc.FeeReply) 210 211 // there is at least 1 argument; that should be the new fee rate 212 if len(textArgs) > 0 { 213 feeint, err := strconv.Atoi(textArgs[0]) 214 if err != nil { 215 return err 216 } 217 args.Fee = int64(feeint) 218 } 219 // there is another argument. That's the coin type. (coin type 0 means default) 220 if len(textArgs) > 1 { 221 coinint, err := strconv.Atoi(textArgs[1]) 222 if err != nil { 223 return err 224 } 225 args.CoinType = uint32(coinint) 226 } 227 228 fmt.Printf("Current fee rate %d sat / byte\n", reply.CurrentFee) 229 230 return nil 231 } 232 233 // Address makes new addresses 234 func (lc *litAfClient) Address(textArgs []string) error { 235 stopEx, err := CheckHelpCommand(addressCommand, textArgs, 0) 236 if err != nil || stopEx { 237 return err 238 } 239 240 var cointype, numadrs uint32 241 242 // if no arguments given, generate 1 new address. 243 // if no cointype given, assume type 1 (testnet) 244 switch len(textArgs) { 245 default: // meaning 2 or more args. args 3+ are ignored 246 cnum, err := strconv.Atoi(textArgs[1]) 247 if err != nil { 248 return err 249 } 250 cointype = uint32(cnum) 251 fallthrough 252 case 1: 253 num, err := strconv.Atoi(textArgs[0]) 254 if err != nil { 255 return err 256 } 257 numadrs = uint32(num) 258 case 0: 259 // default one new address 260 numadrs = 1 261 } 262 // cointype of 0 means default, not mainnet. 263 // this is ugly but does prevent mainnet use for now. 264 265 reply := new(litrpc.AddressReply) 266 267 args := new(litrpc.AddressArgs) 268 args.CoinType = cointype 269 args.NumToMake = numadrs 270 271 fmt.Printf("args: %v\n", args) 272 err = lc.Call("LitRPC.Address", args, reply) 273 if err != nil { 274 return err 275 } 276 277 fmt.Fprintf(color.Output, "new adr(s): %s\nold: %s\n", 278 lnutil.Address(reply.WitAddresses), lnutil.Address(reply.LegacyAddresses)) 279 return nil 280 281 }