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  }