github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/cmd/lit-af/dlccmds.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/fatih/color"
    11  	"github.com/mit-dci/lit/litrpc"
    12  	"github.com/mit-dci/lit/lnutil"
    13  	"github.com/mit-dci/lit/logging"
    14  )
    15  
    16  var dlcCommand = &Command{
    17  	Format: fmt.Sprintf("%s%s%s\n", lnutil.White("dlc"),
    18  		lnutil.ReqColor("subcommand"), lnutil.OptColor("parameters...")),
    19  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n",
    20  		"Command for working with discreet log contracts. ",
    21  		"Subcommand can be one of:",
    22  		fmt.Sprintf("%-10s %s",
    23  			lnutil.White("oracle"), "Command to manage oracles"),
    24  		fmt.Sprintf("%-10s %s",
    25  			lnutil.White("contract"), "Command to manage contracts"),
    26  	),
    27  	ShortDescription: "Command for working with Discreet Log Contracts.\n",
    28  }
    29  
    30  var oracleCommand = &Command{
    31  	Format: fmt.Sprintf("%s%s%s\n", lnutil.White("dlc oracle"),
    32  		lnutil.ReqColor("subcommand"), lnutil.OptColor("parameters...")),
    33  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n",
    34  		"Command for managing oracles. Subcommand can be one of:",
    35  		fmt.Sprintf("%-20s %s",
    36  			lnutil.White("add"),
    37  			"Adds a new oracle by manually providing the pubkey"),
    38  		fmt.Sprintf("%-20s %s",
    39  			lnutil.White("import"),
    40  			"Imports a new oracle using a URL to its REST interface"),
    41  		fmt.Sprintf("%-20s %s",
    42  			lnutil.White("ls"),
    43  			"Shows a list of known oracles"),
    44  	),
    45  	ShortDescription: "Manages oracles for the Discreet Log Contracts.\n",
    46  }
    47  
    48  var listOraclesCommand = &Command{
    49  	Format:           fmt.Sprintf("%s\n", lnutil.White("dlc oracle ls")),
    50  	Description:      "Shows a list of known oracles\n",
    51  	ShortDescription: "Shows a list of known oracles\n",
    52  }
    53  
    54  var importOracleCommand = &Command{
    55  	Format: fmt.Sprintf("%s%s%s\n", lnutil.White("dlc oracle import"),
    56  		lnutil.ReqColor("url"), lnutil.ReqColor("name")),
    57  	Description: fmt.Sprintf("%s\n%s\n%s\n",
    58  		"Imports a new oracle using a URL to its REST interface",
    59  		fmt.Sprintf("%-20s %s",
    60  			lnutil.White("url"),
    61  			"URL to the root of the publishes dlcoracle REST interface"),
    62  		fmt.Sprintf("%-20s %s",
    63  			lnutil.White("name"),
    64  			"Name under which to register the oracle in LIT"),
    65  	),
    66  	ShortDescription: "Imports a new oracle into LIT from a REST interface\n",
    67  }
    68  
    69  var addOracleCommand = &Command{
    70  	Format: fmt.Sprintf("%s%s%s\n", lnutil.White("dlc oracle add"),
    71  		lnutil.ReqColor("keys"), lnutil.ReqColor("name")),
    72  	Description: fmt.Sprintf("%s\n%s\n%s\n",
    73  		"Adds a new oracle by entering the pubkeys manually",
    74  		fmt.Sprintf("%-20s %s",
    75  			lnutil.White("keys"),
    76  			"Public key for the oracle (33 bytes in hex)"),
    77  		fmt.Sprintf("%-20s %s",
    78  			lnutil.White("name"),
    79  			"Name under which to register the oracle in LIT"),
    80  	),
    81  	ShortDescription: "Adds a new oracle into LIT\n",
    82  }
    83  
    84  var contractCommand = &Command{
    85  	Format: fmt.Sprintf("%s%s%s\n", lnutil.White("dlc contract"),
    86  		lnutil.ReqColor("subcommand"), lnutil.OptColor("parameters...")),
    87  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n"+
    88  		"%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
    89  		"Command for managing contracts. Subcommand can be one of:",
    90  		fmt.Sprintf("%-20s %s",
    91  			lnutil.White("new"),
    92  			"Adds a new draft contract"),
    93  		fmt.Sprintf("%-20s %s",
    94  			lnutil.White("view"),
    95  			"Views a contract"),
    96  		fmt.Sprintf("%-20s %s",
    97  			lnutil.White("viewpayout"),
    98  			"Views the payout table of a contract"),
    99  		fmt.Sprintf("%-20s %s",
   100  			lnutil.White("setoracle"),
   101  			"Sets a contract to use a particular oracle"),
   102  		fmt.Sprintf("%-20s %s",
   103  			lnutil.White("settime"),
   104  			"Sets the settlement time of a contract"),
   105  		fmt.Sprintf("%-20s %s",
   106  			lnutil.White("setdatafeed"),
   107  			"Sets the data feed to use, will fetch the R point"),
   108  		fmt.Sprintf("%-20s %s",
   109  			lnutil.White("setrpoint"),
   110  			"Sets the R point manually"),
   111  		fmt.Sprintf("%-20s %s",
   112  			lnutil.White("setfunding"),
   113  			"Sets the funding parameters of a contract"),
   114  		fmt.Sprintf("%-20s %s",
   115  			lnutil.White("setdivision"),
   116  			"Sets the settlement division of a contract"),
   117  		fmt.Sprintf("%-20s %s",
   118  			lnutil.White("setcointype"),
   119  			"Sets the cointype of a contract"),
   120  		fmt.Sprintf("%-20s %s",
   121  			lnutil.White("offer"),
   122  			"Offer a draft contract to one of your peers"),
   123  		fmt.Sprintf("%-20s %s",
   124  			lnutil.White("decline"),
   125  			"Decline a contract sent to you"),
   126  		fmt.Sprintf("%-20s %s",
   127  			lnutil.White("settle"),
   128  			"Settles the contract"),
   129  		fmt.Sprintf("%-20s %s",
   130  			lnutil.White("ls"),
   131  			"Shows a list of known contracts"),
   132  	),
   133  	ShortDescription: "Manages oracles for the Discreet Log Contracts.\n",
   134  }
   135  
   136  var listContractsCommand = &Command{
   137  	Format:           fmt.Sprintf("%s\n", lnutil.White("dlc contract ls")),
   138  	Description:      "Shows a list of known contracts\n",
   139  	ShortDescription: "Shows a list of known contracts\n",
   140  }
   141  
   142  var addContractCommand = &Command{
   143  	Format:           fmt.Sprintf("%s\n", lnutil.White("dlc contract add")),
   144  	Description:      "Adds a new draft contract\n",
   145  	ShortDescription: "Adds a new draft contract\n",
   146  }
   147  
   148  var viewContractCommand = &Command{
   149  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract view"),
   150  		lnutil.ReqColor("id")),
   151  	Description: fmt.Sprintf("%s\n%s\n",
   152  		"Views the current status of a contract",
   153  		fmt.Sprintf("%-10s %s",
   154  			lnutil.White("id"),
   155  			"The ID of the contract to view"),
   156  	),
   157  	ShortDescription: "Views the current status of a contract\n",
   158  }
   159  
   160  var viewContractPayoutCommand = &Command{
   161  	Format: fmt.Sprintf("%s%s%s%s%s\n", lnutil.White("dlc contract viewpayout"),
   162  		lnutil.ReqColor("id"), lnutil.ReqColor("start"),
   163  		lnutil.ReqColor("end"), lnutil.ReqColor("increment")),
   164  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n",
   165  		"Views the payout table of a contract",
   166  		fmt.Sprintf("%-10s %s",
   167  			lnutil.White("id"),
   168  			"The ID of the contract to view"),
   169  		fmt.Sprintf("%-10s %s",
   170  			lnutil.White("start"),
   171  			"The start value to print payout data for"),
   172  		fmt.Sprintf("%-10s %s",
   173  			lnutil.White("end"),
   174  			"The end value to print payout data for"),
   175  		fmt.Sprintf("%-10s %s",
   176  			lnutil.White("increment"),
   177  			"Print every X oracle value (1 = all)"),
   178  	),
   179  	ShortDescription: "Views the payout table of a contract\n",
   180  }
   181  
   182  var setContractOracleCommand = &Command{
   183  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract setoracle"),
   184  		lnutil.ReqColor("cid", "oid")),
   185  	Description: fmt.Sprintf("%s\n%s\n%s\n",
   186  		"Configures a contract for using a specific oracle",
   187  		fmt.Sprintf("%-10s %s",
   188  			lnutil.White("cid"),
   189  			"The ID of the contract"),
   190  		fmt.Sprintf("%-10s %s",
   191  			lnutil.White("oid"),
   192  			"The ID of the oracle"),
   193  	),
   194  	ShortDescription: "Configures a contract for using a specific oracle\n",
   195  }
   196  
   197  var setContractDatafeedCommand = &Command{
   198  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract setdatafeed"),
   199  		lnutil.ReqColor("cid", "feed")),
   200  	Description: fmt.Sprintf("%s\n%s\n%s\n",
   201  		"Sets the data feed to use for the contract",
   202  		fmt.Sprintf("%-10s %s",
   203  			lnutil.White("cid"),
   204  			"The ID of the contract"),
   205  		fmt.Sprintf("%-10s %s",
   206  			lnutil.White("feed"),
   207  			"The ID of the data feed (provided by the oracle)"),
   208  	),
   209  	ShortDescription: "Sets the data feed to use for the contract\n",
   210  }
   211  
   212  var setContractRPointCommand = &Command{
   213  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract setrpoint"),
   214  		lnutil.ReqColor("cid", "rpoint")),
   215  	Description: fmt.Sprintf("%s\n%s\n%s\n",
   216  		"Sets the R point to use for the contract",
   217  		fmt.Sprintf("%-10s %s",
   218  			lnutil.White("cid"),
   219  			"The ID of the contract"),
   220  		fmt.Sprintf("%-10s %s",
   221  			lnutil.White("rpoint"),
   222  			"The Rpoint of the publication to use (33 byte in hex)"),
   223  	),
   224  	ShortDescription: "Sets the R point to use for the contract\n",
   225  }
   226  
   227  var setContractSettlementTimeCommand = &Command{
   228  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract settime"),
   229  		lnutil.ReqColor("cid", "time")),
   230  	Description: fmt.Sprintf("%s\n%s\n%s\n",
   231  		"Sets the settlement time for the contract",
   232  		fmt.Sprintf("%-10s %s",
   233  			lnutil.White("cid"),
   234  			"The ID of the contract"),
   235  		fmt.Sprintf("%-10s %s",
   236  			lnutil.White("time"),
   237  			"The settlement time (unix timestamp)"),
   238  	),
   239  	ShortDescription: "Sets the settlement time for the contract\n",
   240  }
   241  var setContractFundingCommand = &Command{
   242  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract setfunding"),
   243  		lnutil.ReqColor("cid", "ourAmount", "theirAmount")),
   244  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n",
   245  		"Sets the amounts both parties in the contract will fund",
   246  		fmt.Sprintf("%-10s %s",
   247  			lnutil.White("cid"),
   248  			"The ID of the contract"),
   249  		fmt.Sprintf("%-10s %s",
   250  			lnutil.White("ourAmount"),
   251  			"The amount we will fund"),
   252  		fmt.Sprintf("%-10s %s",
   253  			lnutil.White("theirAmount"),
   254  			"The amount our peer will fund"),
   255  	),
   256  	ShortDescription: "Sets the amount both parties will fund\n",
   257  }
   258  var setContractDivisionCommand = &Command{
   259  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract setdivision"),
   260  		lnutil.ReqColor("cid", "valueAllForUs", "valueAllForThem")),
   261  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n",
   262  		"Sets the values of the oracle data that will result in the full"+
   263  			"contract funds being paid to either peer",
   264  		fmt.Sprintf("%-10s %s",
   265  			lnutil.White("cid"),
   266  			"The ID of the contract"),
   267  		fmt.Sprintf("%-10s %s",
   268  			lnutil.White("valueAllForUs"),
   269  			"The outcome with which we will be entitled to the full"+
   270  				" contract value"),
   271  		fmt.Sprintf("%-10s %s",
   272  			lnutil.White("valueAllForThem"),
   273  			"The outcome with which our peer will be entitled to the full"+
   274  				" contract value"),
   275  	),
   276  	ShortDescription: "Sets the edge values for dividing the funds\n",
   277  }
   278  var setContractCoinTypeCommand = &Command{
   279  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract setcointype"),
   280  		lnutil.ReqColor("cid", "cointype")),
   281  	Description: fmt.Sprintf("%s\n%s\n%s\n",
   282  		"Sets the coin type to use for the contract",
   283  		fmt.Sprintf("%-10s %s",
   284  			lnutil.White("cid"),
   285  			"The ID of the contract"),
   286  		fmt.Sprintf("%-10s %s",
   287  			lnutil.White("cointype"),
   288  			"The ID of the coin type to use for the contract"),
   289  	),
   290  	ShortDescription: "Sets the coin type to use for the contract\n",
   291  }
   292  var declineContractCommand = &Command{
   293  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract decline"),
   294  		lnutil.ReqColor("cid")),
   295  	Description: fmt.Sprintf("%s\n%s\n",
   296  		"Declines a contract offered to you",
   297  		fmt.Sprintf("%-10s %s",
   298  			lnutil.White("cid"),
   299  			"The ID of the contract to decline"),
   300  	),
   301  	ShortDescription: "Declines a contract offered to you\n",
   302  }
   303  var acceptContractCommand = &Command{
   304  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract accept"),
   305  		lnutil.ReqColor("cid")),
   306  	Description: fmt.Sprintf("%s\n%s\n",
   307  		"Accepts a contract offered to you",
   308  		fmt.Sprintf("%-10s %s",
   309  			lnutil.White("cid"),
   310  			"The ID of the contract to accept"),
   311  	),
   312  	ShortDescription: "Accepts a contract offered to you\n",
   313  }
   314  var offerContractCommand = &Command{
   315  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract offer"),
   316  		lnutil.ReqColor("cid", "peer")),
   317  	Description: fmt.Sprintf("%s\n%s\n%s\n",
   318  		"Offers a contract to one of your peers",
   319  		fmt.Sprintf("%-10s %s",
   320  			lnutil.White("cid"),
   321  			"The ID of the contract"),
   322  		fmt.Sprintf("%-10s %s",
   323  			lnutil.White("cointype"),
   324  			"The ID of the peer to offer the contract to"),
   325  	),
   326  	ShortDescription: "Offers a contract to one of your peers\n",
   327  }
   328  var settleContractCommand = &Command{
   329  	Format: fmt.Sprintf("%s%s\n", lnutil.White("dlc contract settle"),
   330  		lnutil.ReqColor("cid", "oracleValue", "oracleSig")),
   331  	Description: fmt.Sprintf("%s\n%s\n%s\n%s\n",
   332  		"Settles the contract based on a value and signature from the oracle",
   333  		fmt.Sprintf("%-20s %s",
   334  			lnutil.White("cid"),
   335  			"The ID of the contract"),
   336  		fmt.Sprintf("%-20s %s",
   337  			lnutil.White("oracleValue"),
   338  			"The value the oracle published"),
   339  		fmt.Sprintf("%-20s %s",
   340  			lnutil.White("oracleSig"),
   341  			"The signature from the oracle"),
   342  	),
   343  	ShortDescription: "Settles the contract\n",
   344  }
   345  
   346  func (lc *litAfClient) Dlc(textArgs []string) error {
   347  	if len(textArgs) > 0 && textArgs[0] == "-h" {
   348  		fmt.Fprintf(color.Output, dlcCommand.Format)
   349  		fmt.Fprintf(color.Output, dlcCommand.Description)
   350  		return nil
   351  	}
   352  
   353  	if len(textArgs) > 0 && textArgs[0] == "oracle" {
   354  		return lc.DlcOracle(textArgs[1:])
   355  	}
   356  	if len(textArgs) > 0 && textArgs[0] == "contract" {
   357  		return lc.DlcContract(textArgs[1:])
   358  	}
   359  	return fmt.Errorf(dlcCommand.Format)
   360  }
   361  
   362  func (lc *litAfClient) DlcOracle(textArgs []string) error {
   363  	if len(textArgs) > 0 && textArgs[0] == "-h" {
   364  		fmt.Fprintf(color.Output, oracleCommand.Format)
   365  		fmt.Fprintf(color.Output, oracleCommand.Description)
   366  		return nil
   367  	}
   368  
   369  	if len(textArgs) > 0 && textArgs[0] == "ls" {
   370  		return lc.DlcListOracles(textArgs[1:])
   371  	}
   372  
   373  	if len(textArgs) > 0 && textArgs[0] == "add" {
   374  		return lc.DlcAddOracle(textArgs[1:])
   375  	}
   376  
   377  	if len(textArgs) > 0 && textArgs[0] == "import" {
   378  		return lc.DlcImportOracle(textArgs[1:])
   379  	}
   380  
   381  	return fmt.Errorf(oracleCommand.Format)
   382  }
   383  
   384  func (lc *litAfClient) DlcListOracles(textArgs []string) error {
   385  	args := new(litrpc.ListOraclesArgs)
   386  	reply := new(litrpc.ListOraclesReply)
   387  
   388  	err := lc.Call("LitRPC.ListOracles", args, reply)
   389  	if err != nil {
   390  		return err
   391  	}
   392  	if len(reply.Oracles) == 0 {
   393  		logging.Infof("No oracles found")
   394  	}
   395  	for _, o := range reply.Oracles {
   396  		fmt.Fprintf(color.Output, "%04d: [%x...%x...%x]  %s\n",
   397  			o.Idx, o.A[:2], o.A[15:16], o.A[31:], o.Name)
   398  	}
   399  
   400  	return nil
   401  }
   402  
   403  func (lc *litAfClient) DlcImportOracle(textArgs []string) error {
   404  	stopEx, err := CheckHelpCommand(importOracleCommand, textArgs, 2)
   405  	if err != nil || stopEx {
   406  		return err
   407  	}
   408  
   409  	args := new(litrpc.ImportOracleArgs)
   410  	reply := new(litrpc.ImportOracleReply)
   411  
   412  	args.Url = textArgs[0]
   413  	args.Name = textArgs[1]
   414  
   415  	err = lc.Call("LitRPC.ImportOracle", args, reply)
   416  	if err != nil {
   417  		return err
   418  	}
   419  
   420  	fmt.Fprintf(color.Output, "Oracle successfully registered under ID %d\n",
   421  		reply.Oracle.Idx)
   422  	return nil
   423  }
   424  
   425  func (lc *litAfClient) DlcAddOracle(textArgs []string) error {
   426  	stopEx, err := CheckHelpCommand(addOracleCommand, textArgs, 2)
   427  	if err != nil || stopEx {
   428  		return err
   429  	}
   430  
   431  	if err != nil {
   432  		return err
   433  	}
   434  
   435  	args := new(litrpc.AddOracleArgs)
   436  	reply := new(litrpc.AddOracleReply)
   437  
   438  	args.Key = textArgs[0]
   439  	args.Name = textArgs[1]
   440  
   441  	err = lc.Call("LitRPC.AddOracle", args, reply)
   442  	if err != nil {
   443  		return err
   444  	}
   445  
   446  	fmt.Fprintf(color.Output, "Oracle successfully registered under ID %d\n",
   447  		reply.Oracle.Idx)
   448  	return nil
   449  }
   450  
   451  func (lc *litAfClient) DlcContract(textArgs []string) error {
   452  	if len(textArgs) < 1 { // this shouldn't happen?
   453  		return fmt.Errorf("No argument specified")
   454  	}
   455  	cmd := textArgs[0]
   456  	textArgs = textArgs[1:]
   457  	if cmd == "-h" {
   458  		fmt.Fprintf(color.Output, contractCommand.Format)
   459  		fmt.Fprintf(color.Output, contractCommand.Description)
   460  		return nil
   461  	}
   462  
   463  	if cmd == "ls" {
   464  		return lc.DlcListContracts(textArgs)
   465  	}
   466  
   467  	if cmd == "new" {
   468  		return lc.DlcNewContract(textArgs)
   469  	}
   470  
   471  	if cmd == "view" {
   472  		return lc.DlcViewContract(textArgs)
   473  	}
   474  
   475  	if cmd == "viewpayout" {
   476  		return lc.DlcViewContractPayout(textArgs)
   477  	}
   478  
   479  	if cmd == "setoracle" {
   480  		return lc.DlcSetContractOracle(textArgs)
   481  	}
   482  
   483  	if cmd == "setdatafeed" {
   484  		return lc.DlcSetContractDatafeed(textArgs)
   485  	}
   486  
   487  	if cmd == "setrpoint" {
   488  		return lc.DlcSetContractRPoint(textArgs)
   489  	}
   490  
   491  	if cmd == "settime" {
   492  		return lc.DlcSetContractSettlementTime(textArgs)
   493  	}
   494  
   495  	if cmd == "setfunding" {
   496  		return lc.DlcSetContractFunding(textArgs)
   497  	}
   498  
   499  	if cmd == "setdivision" {
   500  		return lc.DlcSetContractDivision(textArgs)
   501  	}
   502  
   503  	if cmd == "setcointype" {
   504  		return lc.DlcSetContractCoinType(textArgs)
   505  	}
   506  
   507  	if cmd == "offer" {
   508  		return lc.DlcOfferContract(textArgs)
   509  	}
   510  
   511  	if cmd == "decline" {
   512  		return lc.DlcDeclineContract(textArgs)
   513  	}
   514  
   515  	if cmd == "accept" {
   516  		return lc.DlcAcceptContract(textArgs)
   517  	}
   518  
   519  	if cmd == "settle" {
   520  		return lc.DlcSettleContract(textArgs)
   521  	}
   522  	return fmt.Errorf(contractCommand.Format)
   523  }
   524  
   525  func (lc *litAfClient) DlcListContracts(textArgs []string) error {
   526  	args := new(litrpc.ListContractsArgs)
   527  	reply := new(litrpc.ListContractsReply)
   528  
   529  	err := lc.Call("LitRPC.ListContracts", args, reply)
   530  	if err != nil {
   531  		return err
   532  	}
   533  
   534  	if len(reply.Contracts) == 0 {
   535  		fmt.Println("No contracts found")
   536  	}
   537  
   538  	for _, c := range reply.Contracts {
   539  		fmt.Fprintf(color.Output, "%04d: \n", c.Idx)
   540  	}
   541  
   542  	return nil
   543  }
   544  
   545  func (lc *litAfClient) DlcNewContract(textArgs []string) error {
   546  	args := new(litrpc.NewContractArgs)
   547  	reply := new(litrpc.NewContractReply)
   548  
   549  	err := lc.Call("LitRPC.NewContract", args, reply)
   550  	if err != nil {
   551  		return err
   552  	}
   553  
   554  	fmt.Fprint(color.Output, "Contract successfully created\n\n")
   555  	PrintContract(reply.Contract)
   556  	return nil
   557  }
   558  
   559  func (lc *litAfClient) DlcViewContract(textArgs []string) error {
   560  	stopEx, err := CheckHelpCommand(viewContractCommand, textArgs, 1)
   561  	if err != nil || stopEx {
   562  		return err
   563  	}
   564  
   565  	args := new(litrpc.GetContractArgs)
   566  	reply := new(litrpc.GetContractReply)
   567  
   568  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   569  	if err != nil {
   570  		return err
   571  	}
   572  	args.Idx = cIdx
   573  
   574  	err = lc.Call("LitRPC.GetContract", args, reply)
   575  	if err != nil {
   576  		return err
   577  	}
   578  
   579  	PrintContract(reply.Contract)
   580  	return nil
   581  }
   582  
   583  func (lc *litAfClient) DlcViewContractPayout(textArgs []string) error {
   584  	stopEx, err := CheckHelpCommand(viewContractPayoutCommand, textArgs, 4)
   585  	if err != nil || stopEx {
   586  		return err
   587  	}
   588  
   589  	args := new(litrpc.GetContractArgs)
   590  	reply := new(litrpc.GetContractReply)
   591  
   592  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   593  	if err != nil {
   594  		return err
   595  	}
   596  	start, err := strconv.ParseInt(textArgs[1], 10, 64)
   597  	if err != nil {
   598  		return err
   599  	}
   600  	end, err := strconv.ParseInt(textArgs[2], 10, 64)
   601  	if err != nil {
   602  		return err
   603  	}
   604  	increment, err := strconv.ParseInt(textArgs[3], 10, 64)
   605  	if err != nil {
   606  		return err
   607  	}
   608  
   609  	args.Idx = cIdx
   610  
   611  	err = lc.Call("LitRPC.GetContract", args, reply)
   612  	if err != nil {
   613  		return err
   614  	}
   615  
   616  	PrintPayout(reply.Contract, start, end, increment)
   617  	return nil
   618  }
   619  
   620  func (lc *litAfClient) DlcSetContractOracle(textArgs []string) error {
   621  	stopEx, err := CheckHelpCommand(setContractOracleCommand, textArgs, 2)
   622  	if err != nil || stopEx {
   623  		return err
   624  	}
   625  
   626  	args := new(litrpc.SetContractOracleArgs)
   627  	reply := new(litrpc.SetContractOracleReply)
   628  
   629  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   630  	if err != nil {
   631  		return err
   632  	}
   633  	oIdx, err := strconv.ParseUint(textArgs[1], 10, 64)
   634  	if err != nil {
   635  		return err
   636  	}
   637  	args.CIdx = cIdx
   638  	args.OIdx = oIdx
   639  
   640  	err = lc.Call("LitRPC.SetContractOracle", args, reply)
   641  	if err != nil {
   642  		return err
   643  	}
   644  
   645  	fmt.Fprint(color.Output, "Oracle set successfully\n")
   646  
   647  	return nil
   648  }
   649  
   650  func (lc *litAfClient) DlcSetContractDatafeed(textArgs []string) error {
   651  	stopEx, err := CheckHelpCommand(setContractDatafeedCommand, textArgs, 2)
   652  	if err != nil || stopEx {
   653  		return err
   654  	}
   655  
   656  	args := new(litrpc.SetContractDatafeedArgs)
   657  	reply := new(litrpc.SetContractDatafeedReply)
   658  
   659  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   660  	if err != nil {
   661  		return err
   662  	}
   663  	feed, err := strconv.ParseUint(textArgs[1], 10, 64)
   664  	if err != nil {
   665  		return err
   666  	}
   667  	args.CIdx = cIdx
   668  	args.Feed = feed
   669  
   670  	err = lc.Call("LitRPC.SetContractDatafeed", args, reply)
   671  	if err != nil {
   672  		return err
   673  	}
   674  
   675  	fmt.Fprint(color.Output, "Datafeed set successfully\n")
   676  
   677  	return nil
   678  }
   679  
   680  func (lc *litAfClient) DlcSetContractRPoint(textArgs []string) error {
   681  	stopEx, err := CheckHelpCommand(setContractRPointCommand, textArgs, 2)
   682  	if err != nil || stopEx {
   683  		return err
   684  	}
   685  
   686  	args := new(litrpc.SetContractRPointArgs)
   687  	reply := new(litrpc.SetContractRPointReply)
   688  
   689  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   690  	if err != nil {
   691  		return err
   692  	}
   693  	rPoint, err := hex.DecodeString(textArgs[1])
   694  	if err != nil {
   695  		return err
   696  	}
   697  	args.CIdx = cIdx
   698  	copy(args.RPoint[:], rPoint[:])
   699  
   700  	err = lc.Call("LitRPC.SetContractRPoint", args, reply)
   701  	if err != nil {
   702  		return err
   703  	}
   704  
   705  	fmt.Fprint(color.Output, "R-point set successfully\n")
   706  
   707  	return nil
   708  }
   709  
   710  func (lc *litAfClient) DlcSetContractSettlementTime(textArgs []string) error {
   711  	stopEx, err := CheckHelpCommand(setContractSettlementTimeCommand, textArgs, 2)
   712  	if err != nil || stopEx {
   713  		return err
   714  	}
   715  
   716  	args := new(litrpc.SetContractSettlementTimeArgs)
   717  	reply := new(litrpc.SetContractSettlementTimeReply)
   718  
   719  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   720  	if err != nil {
   721  		return err
   722  	}
   723  	time, err := strconv.ParseUint(textArgs[1], 10, 64)
   724  	if err != nil {
   725  		return err
   726  	}
   727  	args.CIdx = cIdx
   728  	args.Time = time
   729  
   730  	err = lc.Call("LitRPC.SetContractSettlementTime", args, reply)
   731  	if err != nil {
   732  		return err
   733  	}
   734  
   735  	fmt.Fprint(color.Output, "Settlement time set successfully\n")
   736  
   737  	return nil
   738  }
   739  
   740  func (lc *litAfClient) DlcSetContractFunding(textArgs []string) error {
   741  	stopEx, err := CheckHelpCommand(setContractFundingCommand, textArgs, 3)
   742  	if err != nil || stopEx {
   743  		return err
   744  	}
   745  
   746  	args := new(litrpc.SetContractFundingArgs)
   747  	reply := new(litrpc.SetContractFundingReply)
   748  
   749  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   750  	if err != nil {
   751  		return err
   752  	}
   753  	ourAmount, err := strconv.ParseInt(textArgs[1], 10, 64)
   754  	if err != nil {
   755  		return err
   756  	}
   757  	theirAmount, err := strconv.ParseInt(textArgs[2], 10, 64)
   758  	if err != nil {
   759  		return err
   760  	}
   761  	args.CIdx = cIdx
   762  	args.OurAmount = ourAmount
   763  	args.TheirAmount = theirAmount
   764  
   765  	err = lc.Call("LitRPC.SetContractFunding", args, reply)
   766  	if err != nil {
   767  		return err
   768  	}
   769  
   770  	fmt.Fprint(color.Output, "Funding set successfully\n")
   771  
   772  	return nil
   773  }
   774  
   775  func (lc *litAfClient) DlcSetContractCoinType(textArgs []string) error {
   776  	stopEx, err := CheckHelpCommand(setContractCoinTypeCommand, textArgs, 2)
   777  	if err != nil || stopEx {
   778  		return err
   779  	}
   780  
   781  	args := new(litrpc.SetContractCoinTypeArgs)
   782  	reply := new(litrpc.SetContractCoinTypeReply)
   783  
   784  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   785  	if err != nil {
   786  		return err
   787  	}
   788  	cointype, err := strconv.ParseUint(textArgs[1], 10, 64)
   789  	if err != nil {
   790  		return err
   791  	}
   792  
   793  	args.CIdx = cIdx
   794  	args.CoinType = uint32(cointype)
   795  
   796  	err = lc.Call("LitRPC.SetContractCoinType", args, reply)
   797  	if err != nil {
   798  		return err
   799  	}
   800  
   801  	fmt.Fprint(color.Output, "Cointype set successfully\n")
   802  
   803  	return nil
   804  }
   805  
   806  func (lc *litAfClient) DlcSetContractDivision(textArgs []string) error {
   807  	stopEx, err := CheckHelpCommand(setContractDivisionCommand, textArgs, 3)
   808  	if err != nil || stopEx {
   809  		return err
   810  	}
   811  
   812  	args := new(litrpc.SetContractDivisionArgs)
   813  	reply := new(litrpc.SetContractDivisionReply)
   814  
   815  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   816  	if err != nil {
   817  		return err
   818  	}
   819  	fullyOurs, err := strconv.ParseInt(textArgs[1], 10, 64)
   820  	if err != nil {
   821  		return err
   822  	}
   823  	fullyTheirs, err := strconv.ParseInt(textArgs[2], 10, 64)
   824  	if err != nil {
   825  		return err
   826  	}
   827  	args.CIdx = cIdx
   828  	args.ValueFullyOurs = fullyOurs
   829  	args.ValueFullyTheirs = fullyTheirs
   830  
   831  	err = lc.Call("LitRPC.SetContractDivision", args, reply)
   832  	if err != nil {
   833  		return err
   834  	}
   835  
   836  	fmt.Fprint(color.Output, "Funding set successfully\n")
   837  
   838  	return nil
   839  }
   840  
   841  func (lc *litAfClient) DlcOfferContract(textArgs []string) error {
   842  	stopEx, err := CheckHelpCommand(offerContractCommand, textArgs, 2)
   843  	if err != nil || stopEx {
   844  		return err
   845  	}
   846  
   847  	args := new(litrpc.OfferContractArgs)
   848  	reply := new(litrpc.OfferContractReply)
   849  
   850  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   851  	if err != nil {
   852  		return err
   853  	}
   854  	peerIdx, err := strconv.ParseUint(textArgs[1], 10, 64)
   855  	if err != nil {
   856  		return err
   857  	}
   858  
   859  	args.CIdx = cIdx
   860  	args.PeerIdx = uint32(peerIdx)
   861  
   862  	err = lc.Call("LitRPC.OfferContract", args, reply)
   863  	if err != nil {
   864  		return err
   865  	}
   866  
   867  	fmt.Fprint(color.Output, "Offer sent set successfully\n")
   868  
   869  	return nil
   870  }
   871  
   872  func (lc *litAfClient) dlcContractRespond(textArgs []string, aor bool) error {
   873  	args := new(litrpc.ContractRespondArgs)
   874  	reply := new(litrpc.ContractRespondReply)
   875  
   876  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   877  	if err != nil {
   878  		return err
   879  	}
   880  
   881  	args.CIdx = cIdx
   882  	args.AcceptOrDecline = aor
   883  
   884  	err = lc.Call("LitRPC.ContractRespond", args, reply)
   885  	if err != nil {
   886  		return err
   887  	}
   888  
   889  	if aor {
   890  		fmt.Fprintf(color.Output, "Offer acceptance initiated. Use [dlc contract view %d] to see the status.\n", cIdx)
   891  	} else {
   892  		fmt.Fprint(color.Output, "Offer declined successfully\n")
   893  	}
   894  
   895  	return nil
   896  }
   897  
   898  func (lc *litAfClient) DlcDeclineContract(textArgs []string) error {
   899  	stopEx, err := CheckHelpCommand(declineContractCommand, textArgs, 1)
   900  	if err != nil || stopEx {
   901  		return err
   902  	}
   903  
   904  	return lc.dlcContractRespond(textArgs, false)
   905  }
   906  
   907  func (lc *litAfClient) DlcAcceptContract(textArgs []string) error {
   908  	stopEx, err := CheckHelpCommand(acceptContractCommand, textArgs, 1)
   909  	if err != nil || stopEx {
   910  		return err
   911  	}
   912  
   913  	return lc.dlcContractRespond(textArgs, true)
   914  }
   915  
   916  func (lc *litAfClient) DlcSettleContract(textArgs []string) error {
   917  	stopEx, err := CheckHelpCommand(settleContractCommand, textArgs, 3)
   918  	if err != nil || stopEx {
   919  		return err
   920  	}
   921  
   922  	args := new(litrpc.SettleContractArgs)
   923  	reply := new(litrpc.SettleContractReply)
   924  
   925  	cIdx, err := strconv.ParseUint(textArgs[0], 10, 64)
   926  	if err != nil {
   927  		return err
   928  	}
   929  
   930  	args.CIdx = cIdx
   931  
   932  	oracleValue, err := strconv.ParseInt(textArgs[1], 10, 64)
   933  	if err != nil {
   934  		return err
   935  	}
   936  
   937  	args.OracleValue = oracleValue
   938  	oracleSigBytes, err := hex.DecodeString(textArgs[2])
   939  	if err != nil {
   940  		return err
   941  	}
   942  
   943  	copy(args.OracleSig[:], oracleSigBytes)
   944  
   945  	err = lc.Call("LitRPC.SettleContract", args, reply)
   946  	if err != nil {
   947  		return err
   948  	}
   949  
   950  	fmt.Fprint(color.Output, "Contract settled successfully\n")
   951  
   952  	return nil
   953  }
   954  
   955  func PrintContract(c *lnutil.DlcContract) {
   956  	fmt.Fprintf(color.Output, "%-30s : %d\n", lnutil.White("Index"), c.Idx)
   957  	fmt.Fprintf(color.Output, "%-30s : [%x...%x...%x]\n",
   958  		lnutil.White("Oracle public key"),
   959  		c.OracleA[:2], c.OracleA[15:16], c.OracleA[31:])
   960  	fmt.Fprintf(color.Output, "%-30s : [%x...%x...%x]\n",
   961  		lnutil.White("Oracle R-point"), c.OracleR[:2],
   962  		c.OracleR[15:16], c.OracleR[31:])
   963  	fmt.Fprintf(color.Output, "%-30s : %s\n",
   964  		lnutil.White("Settlement time"),
   965  		time.Unix(int64(c.OracleTimestamp), 0).UTC().Format(time.UnixDate))
   966  	fmt.Fprintf(color.Output, "%-30s : %d\n",
   967  		lnutil.White("Funded by us"), c.OurFundingAmount)
   968  	fmt.Fprintf(color.Output, "%-30s : %d\n",
   969  		lnutil.White("Funded by peer"), c.TheirFundingAmount)
   970  	fmt.Fprintf(color.Output, "%-30s : %d\n",
   971  		lnutil.White("Coin type"), c.CoinType)
   972  
   973  	peer := "None"
   974  	if c.PeerIdx > 0 {
   975  		peer = fmt.Sprintf("Peer %d", c.PeerIdx)
   976  	}
   977  
   978  	fmt.Fprintf(color.Output, "%-30s : %s\n", lnutil.White("Peer"), peer)
   979  
   980  	status := "Draft"
   981  	switch c.Status {
   982  	case lnutil.ContractStatusActive:
   983  		status = "Active"
   984  	case lnutil.ContractStatusClosed:
   985  		status = "Closed"
   986  	case lnutil.ContractStatusOfferedByMe:
   987  		status = "Sent offer, awaiting reply"
   988  	case lnutil.ContractStatusOfferedToMe:
   989  		status = "Received offer, awaiting reply"
   990  	case lnutil.ContractStatusAccepting:
   991  		status = "Accepting"
   992  	case lnutil.ContractStatusAccepted:
   993  		status = "Accepted"
   994  	case lnutil.ContractStatusAcknowledged:
   995  		status = "Acknowledged"
   996  	case lnutil.ContractStatusError:
   997  		status = "Error"
   998  	case lnutil.ContractStatusDeclined:
   999  		status = "Declined"
  1000  	}
  1001  
  1002  	fmt.Fprintf(color.Output, "%-30s : %s\n\n", lnutil.White("Status"), status)
  1003  
  1004  	increment := int64(len(c.Division) / 10)
  1005  	PrintPayout(c, 0, int64(len(c.Division)), increment)
  1006  }
  1007  
  1008  func PrintPayout(c *lnutil.DlcContract, start, end, increment int64) {
  1009  	fmt.Fprintf(color.Output, "Payout division:\n\n")
  1010  	fmt.Fprintf(color.Output, "%-20s | %-20s | %-20s\n",
  1011  		"Oracle value", "Our payout", "Their payout")
  1012  	fmt.Fprintf(color.Output, "%s\n", strings.Repeat("-", 66))
  1013  
  1014  	for i := start; i < end; i += increment {
  1015  		fmt.Fprintf(color.Output, "%20d | %20d | %20d\n",
  1016  			c.Division[i].OracleValue, c.Division[i].ValueOurs,
  1017  			c.OurFundingAmount+c.TheirFundingAmount-c.Division[i].ValueOurs)
  1018  	}
  1019  }