Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
main.cpp File Reference
Include dependency graph for main.cpp:

Go to the source code of this file.

Macros

#define OT_OPTIONS_FILE_DEFAULT   "command-line-ot.opt"
 
#define CLIENT_PATH_DEFAULT   "client_data"
 
#define CA_FILE   "certs/special/ca.crt"
 
#define KEY_FILE   "certs/special/client.pem"
 

Functions

void HandleCommandLineArguments (int32_t argc, char *argv[], AnyOption *opt)
 
bool SetupPointersForWalletMyNymAndServerContract (std::string &str_ServerID, std::string &str_MyNym, OTPseudonym *&pMyNym, OTWallet *&pWallet, OTServerContract *&pServerContract)
 
void CollectDefaultedCLValues (AnyOption *opt, std::string &str_ServerID, std::string &str_MyAcct, std::string &str_MyNym, std::string &str_MyPurse, std::string &str_HisAcct, std::string &str_HisNym, std::string &str_HisPurse)
 
int32_t main (int32_t argc, char *argv[])
 

Macro Definition Documentation

#define CA_FILE   "certs/special/ca.crt"

Definition at line 171 of file main.cpp.

#define CLIENT_PATH_DEFAULT   "client_data"

Definition at line 169 of file main.cpp.

#define KEY_FILE   "certs/special/client.pem"

Definition at line 172 of file main.cpp.

#define OT_OPTIONS_FILE_DEFAULT   "command-line-ot.opt"

Definition at line 168 of file main.cpp.

Function Documentation

void CollectDefaultedCLValues ( AnyOption *  opt,
std::string &  str_ServerID,
std::string &  str_MyAcct,
std::string &  str_MyNym,
std::string &  str_MyPurse,
std::string &  str_HisAcct,
std::string &  str_HisNym,
std::string &  str_HisPurse 
)

Definition at line 499 of file main.cpp.

504 {
505  OT_ASSERT(nullptr != opt);
506 
507  OTAPI_Wrap::Output(1, "\n");
508 
509  // First we pre-set all the values based on the defaults from the options
510  // file.
511  //
512  if (opt->getValue("defaultserver") != nullptr) {
513  // cerr << "Server default: " << (str_ServerID = opt->getValue(
514  // "defaultserver" )) << endl;
515  str_ServerID = opt->getValue("defaultserver");
516  otWarn << "Server default: " << str_ServerID << " \n";
517  }
518 
519  if (opt->getValue("defaultmyacct") != nullptr) {
520  // cerr << "MyAcct default: " << (str_MyAcct = opt->getValue(
521  // "defaultmyacct" )) << endl;
522  str_MyAcct = opt->getValue("defaultmyacct");
523  otWarn << "MyAcct default: " << str_MyAcct << " \n";
524  }
525  if (opt->getValue("defaultmynym") != nullptr) {
526  // cerr << "MyNym default: " << (str_MyNym = opt->getValue(
527  // "defaultmynym" )) << endl;
528  str_MyNym = opt->getValue("defaultmynym");
529  otWarn << "MyNym default: " << str_MyNym << " \n";
530  }
531  if (opt->getValue("defaultmypurse") != nullptr) {
532  // cerr << "MyPurse default: " << (str_MyPurse = opt->getValue(
533  // "defaultmypurse" )) << endl;
534  str_MyPurse = opt->getValue("defaultmypurse");
535  otWarn << "MyPurse default: " << str_MyPurse << " \n";
536  }
537 
538  if (opt->getValue("defaulthisacct") != nullptr) {
539  // cerr << "HisAcct default: " << (str_HisAcct = opt->getValue(
540  // "defaulthisacct" )) << endl;
541  str_HisAcct = opt->getValue("defaulthisacct");
542  otWarn << "HisAcct default: " << str_HisAcct << " \n";
543  }
544  if (opt->getValue("defaulthisnym") != nullptr) {
545  // cerr << "HisNym default: " << (str_HisNym = opt->getValue(
546  // "defaulthisnym" )) << endl;
547  str_HisNym = opt->getValue("defaulthisnym");
548  otWarn << "HisNym default: " << str_HisNym << " \n";
549  }
550  if (opt->getValue("defaulthispurse") != nullptr) {
551  // cerr << "HisPurse default: " << (str_HisPurse = opt->getValue(
552  // "defaulthispurse" )) << endl;
553  str_HisPurse = opt->getValue("defaulthispurse");
554  otWarn << "HisPurse default: " << str_HisPurse << " \n";
555  }
556 
557  // Next, we overwrite those with any that were passed in on the command
558  // line.
559 
560  if (opt->getValue("server") != nullptr) {
561  // cerr << "Server from command-line: " << (str_ServerID =
562  // opt->getValue( "server" )) << endl;
563  str_ServerID = opt->getValue("server");
564  otWarn << "Server from command-line: " << str_ServerID << " \n";
565  }
566 
567  if (opt->getValue("myacct") != nullptr) {
568  // cerr << "MyAcct from command-line: " << (str_MyAcct =
569  // opt->getValue(
570  // "myacct" )) << endl;
571  str_MyAcct = opt->getValue("myacct");
572  otWarn << "MyAcct from command-line: " << str_MyAcct << " \n";
573  }
574  if (opt->getValue("mynym") != nullptr) {
575  // cerr << "MyNym from command-line: " << (str_MyNym =
576  // opt->getValue(
577  // "mynym" )) << endl;
578  str_MyNym = opt->getValue("mynym");
579  otWarn << "MyNym from command-line: " << str_MyNym << " \n";
580  }
581  if (opt->getValue("mypurse") != nullptr) {
582  // cerr << "MyPurse from command-line: " << (str_MyPurse =
583  // opt->getValue( "mypurse" )) << endl;
584  str_MyPurse = opt->getValue("mypurse");
585  otWarn << "MyPurse from command-line: " << str_MyPurse << " \n";
586  }
587 
588  if (opt->getValue("hisacct") != nullptr) {
589  // cerr << "HisAcct from command-line: " << (str_HisAcct =
590  // opt->getValue( "hisacct" )) << endl;
591  str_HisAcct = opt->getValue("hisacct");
592  otWarn << "HisAcct from command-line: " << str_HisAcct << " \n";
593  }
594  if (opt->getValue("hisnym") != nullptr) {
595  // cerr << "HisNym from command-line: " << (str_HisNym =
596  // opt->getValue(
597  // "hisnym" )) << endl;
598  str_HisNym = opt->getValue("hisnym");
599  otWarn << "HisNym from command-line: " << str_HisNym << " \n";
600  }
601  if (opt->getValue("hispurse") != nullptr) {
602  // cerr << "HisPurse from command-line: " << (str_HisPurse =
603  // opt->getValue( "hispurse" )) << endl;
604  str_HisPurse = opt->getValue("hispurse");
605  otWarn << "HisPurse from command-line: " << str_HisPurse << " \n";
606  }
607 }
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otWarn
void HandleCommandLineArguments ( int32_t  argc,
char *  argv[],
AnyOption *  opt 
)

Definition at line 286 of file main.cpp.

287 {
288  if (nullptr == opt) return;
289 
290  OTString strConfigPath(OTPaths::AppDataFolder());
291  {
292  bool GetConfigPathSuccess =
293  strConfigPath.Exists() && 3 < strConfigPath.GetLength();
295  GetConfigPathSuccess,
296  "HandleCommandLineArguments: Must Set Conifg Path First!");
297  }
298 
299  /* 1. CREATE AN OBJECT */
300  // AnyOption *opt = new AnyOption();
301  // OT_ASSERT(nullptr != opt);
302  // std::unique_ptr<AnyOption> theOptionAngel(opt);
303 
304  /* 2. SET PREFERENCES */
305  // opt->noPOSIX(); /* do not check for POSIX style character options */
306  // opt->setVerbose(); /* print warnings about unknown options */
307  // opt->autoUsagePrint(true); /* print usage for bad options */
308 
309  /* 3. SET THE USAGE/HELP */
310  opt->addUsage("");
311  opt->addUsage(" **** NOTE: DO NOT USE 'ot' !! Use 'opentxs help' instead! "
312  "*** OT CLI Usage: ");
313  opt->addUsage("");
314  opt->addUsage(
315  "ot --stat (Prints the wallet contents) ot --prompt (Enter "
316  "the OT prompt)");
317  opt->addUsage("ot [-h|-?|--help] (Prints this help) ot --script "
318  "<filename> [--args \"key value ...\"]");
319  opt->addUsage(
320  "The '|' symbol means use --balance or -b, use --withdraw or -w, etc.");
321  opt->addUsage(
322  "The brackets '[]' show required arguments, where default values are");
323  opt->addUsage(
324  "normally expected to be found in: ~/.ot/command-line-ot.opt");
325  opt->addUsage(
326  "ot --balance | -b [--myacct <acct_id>] (Display "
327  "account balance)");
328  opt->addUsage("ot --withdraw | -w <amount> [--myacct <acct_id>] "
329  "(Withdraw as CASH)");
330  opt->addUsage(
331  "ot --transfer | -t <amount> [--myacct <acct_id>] [--hisacct "
332  "<acct_id>]");
333  opt->addUsage(
334  "ot --cheque | -c <amount> [--myacct <acct_id>] [--hisnym "
335  "<nym_id> ]");
336  opt->addUsage(
337  "ot --voucher | -v <amount> [--myacct <acct_id>] [--hisnym "
338  "<nym_id> ]");
339  opt->addUsage(
340  "ot --depositcheque [--myacct <acct_id>] (Deposit a cheque.)");
341  opt->addUsage(
342  "ot --depositpurse [--myacct <acct_id>] (Deposit a cash purse.)");
343  opt->addUsage("ot --deposittokens [--myacct <acct_id>] (Deposit "
344  "individual cash tokens.)");
345  opt->addUsage(
346  "ot --inbox | -i [--myacct <acct_id>] (Display the inbox.)");
347  opt->addUsage(
348  "ot --sign | -s [--mynym <nym_id> ] (Sign a contract.)");
349  opt->addUsage(
350  "ot --verify [--mynym <nym_id> ] (Verify a signature.)");
351  opt->addUsage(
352  "ot --purse | -p <arguments> (Display a purse.)");
353  opt->addUsage(
354  " Arguments: [--mynym <nym_id> ] [--mypurse <asset_type_id>]");
355  opt->addUsage("ot --refresh | -r [--myacct <acct_id>] (Download "
356  "account files from server.)");
357  opt->addUsage("ot --refreshnym [--mynym <nym_id> ] (Download nym "
358  "files from server.)");
359  opt->addUsage(
360  "ot --marketoffer [--mynym <nym_id> ] (Place an offer "
361  "on a market.)");
362  opt->addUsage(
363  "Also, [--server <server_id>] will work with all of the above.");
364  opt->addUsage("");
365  opt->addUsage("Recurring payments:");
366  opt->addUsage("ot --proposeplan <arguments> (Merchant)");
367  opt->addUsage(" Arguments: [--mynym <nym_id> ] [--myacct <acct_id>] "
368  "(continued.)");
369  opt->addUsage(" Continued: [--hisnym <nym_id> ] [--hisacct <acct_id> ]");
370  opt->addUsage("ot --confirmplan <arguments> (Customer)");
371  opt->addUsage("ot --activateplan <arguments> (Customer again)");
372  opt->addUsage(" Arguments: [--mynym <nym_id> ] [--myacct <acct_id>]");
373  opt->addUsage(
374  " **** NOTE: DO NOT USE 'ot' !! Use 'opentxs help' instead! ***");
375 
376  /* 4. SET THE OPTION STRINGS/CHARACTERS */
377  //
378  // COMMAND LINE *AND* RESOURCE FILE
379 
380  // opt->setOption( "server" ); /* an option (takes an argument),
381  // supporting only int64_t form */
382 
383  /* 4. SET THE OPTION STRINGS/CHARACTERS */
384  //
385  // COMMAND LINE *AND* RESOURCE FILE
386 
387  // opt->setOption( "server" ); /* an option (takes an argument),
388  // supporting only int64_t form */
389 
390  // COMMAND LINE ONLY
391  /* for options that will be checked only on the command and line not in
392  * option/resource file */
393  // opt->setCommandFlag( "zip" , 'z'); /* a flag (takes no argument),
394  // supporting int64_t and short form */
395  opt->setCommandOption("withdraw",
396  'w'); // withdraw from acct to purse, myacct, topurse
397  opt->setCommandOption("transfer",
398  't'); // transfer acct-to-acct, myacct, toacct
399  opt->setCommandOption("cheque", 'c'); // write a cheque myacct, tonym
400  opt->setCommandOption("voucher", 'v'); // withdraw voucher myacct, tonym
401  opt->setCommandFlag("marketoffer"); // add an offer to the market.
402  opt->setCommandFlag("balance", 'b'); // Display account balance
403  opt->setCommandFlag("depositcheque"); // deposit a cheque to myacct
404  opt->setCommandFlag("depositpurse"); // deposit cash purse to myacct
405  opt->setCommandFlag(
406  "deposittokens"); // deposit individual cash tokens to myacct
407  opt->setCommandFlag("proposeplan"); // Merchant proposes a payment plan.
408  opt->setCommandFlag("confirmplan"); // Customer confirms a payment plan.
409  opt->setCommandFlag("activateplan"); // Customer activates a payment plan.
410  opt->setCommandFlag("inbox", 'i'); // displays inbox (for ACCT_ID...)
411  opt->setCommandFlag("sign", 's'); // sign a contract mynym
412  opt->setCommandFlag("verify"); // verify a signature
413  opt->setCommandFlag("purse", 'p'); // display purse contents.
414  opt->setCommandFlag("refresh", 'r'); // refresh intermediary files from
415  // server + verify against last receipt.
416  opt->setCommandFlag("refreshnym"); // refresh intermediary files from server
417  // + verify against last receipt.
418  opt->setCommandFlag("stat"); // print out the wallet contents.
419  opt->setCommandFlag("prompt"); // Enter the OT prompt.
420  opt->setCommandOption(
421  "script"); // Process a script from out of a scriptfile
422  opt->setCommandOption(
423  "args"); // Pass custom arguments from command line: --args "key1 value1
424  // key2 \"here is value2\" key3 value3"
425 
426  opt->setCommandFlag("help", 'h'); // the Help screen.
427  opt->setCommandFlag('?'); // the Help screen.
428 
429  /*
430  --myacct (ACCT ID)
431  --mynym (NYM ID)
432  --mypurse (ASSET TYPE ID)
433 
434  --toacct (ACCT ID)
435  --tonym (NYM ID)
436  --topurse (ASSET TYPE ID)
437  */
438  opt->setCommandOption("server");
439 
440  opt->setCommandOption("myacct");
441  opt->setCommandOption("mynym");
442  opt->setCommandOption("mypurse");
443  opt->setCommandOption("hisacct");
444  opt->setCommandOption("hisnym");
445  opt->setCommandOption("hispurse");
446 
447  // NOTE: Above and Below me are IDs. This interface should allow PARTIAL
448  // IDs.
449 
450  // RESOURCE FILE ONLY
451  /* for options that will be checked only from the option/resource file */
452  opt->setFileOption("defaultserver");
453  /* an option (takes an argument), supporting only int64_t form */
454 
455  opt->setFileOption("defaultmyacct");
456  /* an option (takes an argument), supporting only int64_t form */
457  opt->setFileOption("defaultmynym");
458  /* an option (takes an argument), supporting only int64_t form */
459  opt->setFileOption("defaultmypurse");
460  /* an option (takes an argument), supporting only int64_t form */
461  opt->setFileOption("defaulthisacct");
462  /* an option (takes an argument), supporting only int64_t form */
463  opt->setFileOption("defaulthisnym");
464  /* an option (takes an argument), supporting only int64_t form */
465  opt->setFileOption("defaulthispurse");
466  /* an option (takes an argument), supporting only int64_t form */
467  /*
468  --defaultmyacct (ACCT ID)
469  --defaultmynym (NYM ID)
470  --defaultmypurse (ASSET TYPE ID)
471 
472  --defaulttoacct (ACCT ID)
473  --defaulttonym (NYM ID)
474  --defaulttopurse (ASSET TYPE ID)
475  */
476 
477  /* 5. PROCESS THE COMMANDLINE AND RESOURCE FILE */
478 
479  /* read options from a option/resource file with ':' separated options or
480  * flags, one per line */
481 
482  OTString strOptionsFile(OT_OPTIONS_FILE_DEFAULT), strIniFileExact;
483  {
484  bool bBuildFullPathSuccess = OTPaths::RelativeToCanonical(
485  strIniFileExact, strConfigPath, strOptionsFile);
486  OT_ASSERT_MSG(bBuildFullPathSuccess, "Unalbe to set Full Path");
487  }
488 
489  opt->processFile(strIniFileExact.Get());
490  opt->processCommandArgs(argc, argv);
491 }
#define OT_OPTIONS_FILE_DEFAULT
Definition: main.cpp:168
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
EXPORT const char * Get() const
Definition: OTString.cpp:1045
int32_t main ( int32_t  argc,
char *  argv[] 
)

Definition at line 614 of file main.cpp.

615 {
616  class __OTclient_RAII
617  {
618  public:
619  __OTclient_RAII()
620  {
621  // OT_API class exists only on the client side.
622 
623  OTAPI_Wrap::AppInit(); // SSL gets initialized in here, before any
624  // keys
625  // are loaded.
626  }
627  ~__OTclient_RAII()
628  {
629  OTAPI_Wrap::AppCleanup();
630  }
631  };
632  //
633  // This makes SURE that AppCleanup() gets called before main() exits
634  // (without
635  // any
636  // twisted logic being necessary below, for that to happen.)
637  //
638  __OTclient_RAII the_client_cleanup;
639  //
640 
641  if (nullptr == OTAPI_Wrap::OTAPI())
642  return -1; // error out if we don't have the API.
643 
644  OTString strConfigPath(OTPaths::AppDataFolder());
645  bool bConfigPathFound =
646  strConfigPath.Exists() && 3 < strConfigPath.GetLength();
647 
648  OT_ASSERT_MSG(bConfigPathFound,
649  "RegisterAPIWithScript: Must set Config Path first!\n");
650 
651  otWarn << "Using configuration path: " << strConfigPath << "\n";
652 
653  // otOut << "Prefix Path: " << OTPaths::PrefixFolder() << "\n";
654  // otOut << "Scripts Path: " << OTPaths::ScriptsFolder() << "\n";
655  //
656  // OTString out_strHomeFolder;
657  // OTPaths::GetHomeFromSystem(out_strHomeFolder);
658  // otOut << "Home from System: " << out_strHomeFolder << "\n";
659 
660  // COMMAND-LINE OPTIONS (and default values from files.)
661  //
662  AnyOption* opt = new AnyOption();
663  OT_ASSERT(nullptr != opt);
664  std::unique_ptr<AnyOption> theOptionAngel(opt);
665 
666  // Process the command line args
667  //
668  HandleCommandLineArguments(argc, argv, opt);
669 
670  // command line values such as account ID, Nym ID, etc.
671  // Also available as defaults in a config file in the ~/.ot folder
672  //
673  std::string str_ServerID;
674 
675  std::string str_MyAcct;
676  std::string str_MyNym;
677  std::string str_MyPurse;
678 
679  std::string str_HisAcct;
680  std::string str_HisNym;
681  std::string str_HisPurse;
682 
683  CollectDefaultedCLValues(opt, str_ServerID, str_MyAcct, str_MyNym,
684  str_MyPurse, str_HisAcct, str_HisNym,
685  str_HisPurse);
686  // Users can put --args "key value key value key value etc"
687  // Then they can access those values from within their scripts.
688 
689  std::string str_Args;
690 
691  if (opt->getValue("args") != nullptr)
692  cerr << "User-defined arguments aka: --args "
693  << (str_Args = opt->getValue("args")) << endl;
694 
695  /* USAGE SCREEN (HELP) */
696  //
697  if (opt->getFlag("help") || opt->getFlag('h') || opt->getFlag('?')) {
698  opt->printUsage();
699 
700  return 0;
701  }
702 
703  bool bIsCommandProvided = false;
704 
705  // See if there's a COMMAND chosen at command line.
706  //
707  if (opt->hasOptions()) {
708  // Below are COMMANDS (only one of them can be true...)
709  //
710 
711  if (opt->getValue('w') != nullptr ||
712  opt->getValue("withdraw") != nullptr) {
713  bIsCommandProvided = true;
714  cerr << "withdraw amount = " << opt->getValue('w') << endl;
715  }
716  else if (opt->getValue('t') != nullptr ||
717  opt->getValue("transfer") != nullptr) {
718  bIsCommandProvided = true;
719  cerr << "transfer amount = " << opt->getValue('t') << endl;
720  }
721  else if (opt->getValue('c') != nullptr ||
722  opt->getValue("cheque") != nullptr) {
723  bIsCommandProvided = true;
724  cerr << "cheque amount = " << opt->getValue('c') << endl;
725  }
726  else if (opt->getFlag("marketoffer") == true) {
727  bIsCommandProvided = true;
728  cerr << "marketoffer flag set " << endl;
729  }
730  else if (opt->getValue('v') != nullptr ||
731  opt->getValue("voucher") != nullptr) {
732  bIsCommandProvided = true;
733  cerr << "voucher amount = " << opt->getValue('v') << endl;
734  }
735  else if (opt->getFlag("depositcheque")) {
736  bIsCommandProvided = true;
737  cerr << "deposit cheque flag set " << endl;
738  }
739  else if (opt->getFlag("depositpurse")) {
740  bIsCommandProvided = true;
741  cerr << "deposit purse flag set " << endl;
742  }
743  else if (opt->getFlag("deposittokens")) {
744  bIsCommandProvided = true;
745  cerr << "deposit tokens flag set " << endl;
746  }
747  else if (opt->getFlag("proposepaymentplan")) {
748  bIsCommandProvided = true;
749  cerr << "proposepaymentplan flag set " << endl;
750  }
751  else if (opt->getFlag("confirmpaymentplan")) {
752  bIsCommandProvided = true;
753  cerr << "confirm payment plan flag set " << endl;
754  }
755  else if (opt->getFlag("activatepaymentplan")) {
756  bIsCommandProvided = true;
757  cerr << "activate payment plan flag set " << endl;
758  }
759  else if (opt->getFlag('b') || opt->getFlag("balance")) {
760  bIsCommandProvided = true;
761  cerr << "balance flag set " << endl;
762  }
763  else if (opt->getFlag('i') || opt->getFlag("inbox")) {
764  bIsCommandProvided = true;
765  cerr << "inbox flag set " << endl;
766  }
767  else if (opt->getFlag('p') || opt->getFlag("purse")) {
768  bIsCommandProvided = true;
769  cerr << "purse flag set " << endl;
770  }
771  else if (opt->getFlag('s') || opt->getFlag("sign")) {
772  bIsCommandProvided = true;
773  cerr << "sign flag set " << endl;
774  }
775  else if (opt->getFlag("verify")) {
776  bIsCommandProvided = true;
777  cerr << "verify flag set " << endl;
778  }
779  else if (opt->getFlag("stat")) {
780  bIsCommandProvided = true;
781  cerr << "stat flag set " << endl;
782  }
783  else if (opt->getFlag("prompt")) {
784  bIsCommandProvided = true;
785  cerr << "prompt flag set " << endl;
786  }
787  else if (opt->getValue("script") != nullptr) {
788  bIsCommandProvided = true;
789  cerr << "script filename: " << opt->getValue("script") << endl;
790  }
791  else if (opt->getFlag('r') || opt->getFlag("refresh")) {
792  bIsCommandProvided = true;
793  cerr << "refresh flag set " << endl;
794  }
795  else if (opt->getFlag("refreshnym")) {
796  bIsCommandProvided = true;
797  cerr << "refreshnym flag set " << endl;
798  }
799 
800  cerr << endl;
801  }
802  else
803  bIsCommandProvided = false;
804 
805  //
806  if (!(opt->getArgc() > 0) && (false == bIsCommandProvided)) // If no command
807  // was provided
808  // (though other
809  // command-line options may have been...)
810  { // then we expect a script to come in through stdin, and we run it
811  // through the script interpreter!
812  otOut << "\n\nYou probably don't want to do this... Use CTRL-C, "
813  "and try \"ot --help\" for instructions.\n\n "
814  "==> Expecting ot script from standard input. (Terminate "
815  "with CTRL-D):\n\n";
816 
817  // don't skip the whitespace while reading
818  std::cin >> std::noskipws;
819 
820  // use stream iterators to copy the stream to a string
821  std::istream_iterator<char> it(std::cin);
822  std::istream_iterator<char> end;
823  std::string results(it, end);
824 
825  OT_ME madeEasy;
827  madeEasy.ExecuteScript_ReturnVoid(results, ("stdin"));
828 
829  return 0;
830  }
831 
832  // Otherwise a command WAS provided at the command line, so we execute a
833  // single time, once just for that command.
834  {
835  OTWallet* pWallet = nullptr;
836  OTServerContract* pServerContract = nullptr;
837  OTPseudonym* pMyNym = nullptr;
838 
839  // This does LoadWallet, andif Nym or Server IDs were provided, loads
840  // those
841  // up as well.
842  // (They may still be nullptr after this call, however.)
843  //
844  bool bMainPointersSetupSuccessful =
846  str_ServerID, str_MyNym, pMyNym, pWallet, pServerContract);
847 
849  bMainPointersSetupSuccessful,
850  "main: SetupPointersForWalletMyNymAndServerContract failed "
851  "to return true");
852 
853  // Below this point, pWallet is available :-)
854  // Later I can split the below commands into "those that need a server
855  // contract"
856  // and "those that don't need a server contract", and put this code
857  // between
858  // them.
859  // That's what the OT Prompt loop does. For now I'm making things easy
860  // here
861  // by just
862  // making it a blanket requirement.
863  //
864  if (nullptr == pServerContract) {
865  otOut << "Unable to find a server contract to use. Please use "
866  "the option: --server SERVER_ID\n"
867  "(Where SERVER_ID is the Server's ID. Partial matches "
868  "ARE accepted.)\n";
869  // return 0;
870  }
871 
872  OTIdentifier theServerID;
873  OTString strServerID;
874 
875  if (nullptr != pServerContract) {
876  pServerContract->GetIdentifier(theServerID);
877  theServerID.GetString(strServerID);
878  }
879  // int32_t nServerPort = 0;
880  // OTString strServerHostname;
881  // You can't just connect to any hostname and port.
882  // Instead, you give me the Server Contract, and *I'll* look up all that
883  // stuff FOR you...
884  // (We verify this up here, but use it at the bottom of the function
885  // once
886  // the message is set up.)
887  //
888 
889  // if (!pServerContract->GetConnectInfo(strServerHostname,
890  // nServerPort))
891  // {
892  // otErr << "Failed retrieving connection info from server "
893  // "contract: " << strServerID << "\n";
894  // return 0;
895  // }
896 
897  // Below this point, pWallet and pServerContract are both available.
898  // UPDATE: Not necessarily... (pServerContract may be nullptr...)
899  //
900 
901  OTAccount* pMyAccount = nullptr;
902  OTAccount* pHisAccount = nullptr;
903 
904  if (str_MyAcct.size() > 0) {
905  const OTIdentifier MY_ACCOUNT_ID(str_MyAcct.c_str());
906 
907  pMyAccount = pWallet->GetAccount(MY_ACCOUNT_ID);
908 
909  // If failure, then we try PARTIAL match.
910  if (nullptr == pMyAccount)
911  pMyAccount = pWallet->GetAccountPartialMatch(str_MyAcct);
912 
913  if (nullptr != pMyAccount) {
914  OTString strTemp;
915  pMyAccount->GetPurportedAccountID().GetString(strTemp);
916 
917  str_MyAcct = strTemp.Get();
918  otOut << "Using as myacct: " << str_MyAcct << "\n";
919  }
920  else // Execution aborts if we cannot find MyAcct when one was
921  // provided.
922  {
923  otOut << "Aborting: Unable to find specified myacct: "
924  << str_MyAcct << "\n";
925  return 0;
926  }
927  }
928  // TODO: I wouldn't have HIS account in MY wallet -- I'd only have his
929  // account ID.
930  // Therefore need to be able to retrieve this info from the ADDRESS BOOK
931  // (in
932  // order
933  // to be able to do PARTIAL MATCHES...)
934  //
935  if (str_HisAcct.size() > 0) {
936  const OTIdentifier HIS_ACCOUNT_ID(str_HisAcct.c_str());
937 
938  pHisAccount = pWallet->GetAccount(HIS_ACCOUNT_ID);
939 
940  // If failure, then we try PARTIAL match.
941  if (nullptr == pHisAccount)
942  pHisAccount = pWallet->GetAccountPartialMatch(str_HisAcct);
943  if (nullptr != pHisAccount) {
944  OTString strTemp;
945  pHisAccount->GetPurportedAccountID().GetString(strTemp);
946 
947  str_HisAcct = strTemp.Get();
948  otOut << "Using as hisacct: " << str_HisAcct << "\n";
949  }
950 
951  // Execution continues, even if we fail to find his account.
952  // (Only my accounts will be in my wallet. Anyone else's account
953  // will exist on the server, even if it's not in my wallet.
954  // Therefore
955  // we still allow users to use HisAcctID since their server messages
956  // will usually actually work.)
957  //
958  // Again: Just because account lkjsf09234lkjafkljasd098q345lkjasdf
959  // doesn't
960  // appear in my wallet, doesn't mean the account doesn't exist on
961  // the
962  // server
963  // and in reality. Therefore I must assume, if I didn't find it by
964  // abbreviation,
965  // that it exists exactly as entered. The server message will just
966  // fail,
967  // if it
968  // doesn't exist. (But then that's the user's fault...)
969  //
970  // We can still keep account IDs in the address book, even if they
971  // aren't
972  // in the wallet (since they're owned by someone else...)
973  //
974  }
975 
976  // I put this here too since I think it's required in all cases.
977  // Update: commented out the return in order to allow for empty wallets.
978  //
979  if (nullptr ==
980  pMyNym) // Todo maybe move this check to the commands below
981  // (ONLY the ones that use a nym.)
982  {
983  otOut << "Unable to find My Nym. Please use the option: --mynym "
984  "USER_ID\n"
985  "(Where USER_ID is the Nym's ID. Partial matches and "
986  "names are "
987  "accepted.)\n";
988  // return 0;
989  }
990 
991  OTIdentifier MY_NYM_ID;
992 
993  if (nullptr != pMyNym) pMyNym->GetIdentifier(MY_NYM_ID);
994  OTPseudonym* pHisNym = nullptr;
995 
996  if (str_HisNym.size() > 0) {
997  const OTIdentifier HIS_NYM_ID(str_HisNym.c_str());
998 
999  pHisNym = pWallet->GetNymByID(HIS_NYM_ID);
1000  // If failure, then we try PARTIAL match.
1001  if (nullptr == pHisNym)
1002  pHisNym = pWallet->GetNymByIDPartialMatch(str_HisNym);
1003  if (nullptr != pHisNym) {
1004  OTString strTemp;
1005  pHisNym->GetIdentifier(strTemp);
1006 
1007  str_HisNym = strTemp.Get();
1008  otOut << "Using as hisnym: " << str_HisNym << "\n";
1009  }
1010  }
1011 
1012  // Below this point, if Nyms or Accounts were specified, they are now
1013  // available.
1014  // (Pointers might be null, though currently My Nym is required to be
1015  // there.)
1016  //
1017  // Execution continues, even if we fail to find his nym.
1018  // This is so the script has the opportunity to "check nym" (Download
1019  // it)
1020  // based on the ID that the user has entered here.
1021 
1022  OTIdentifier thePurseAssetTypeID;
1023  OTAssetContract* pMyAssetContract = nullptr;
1024 
1025  if (str_MyPurse.size() > 0) {
1026  const OTIdentifier MY_ASSET_TYPE_ID(str_MyPurse.c_str());
1027  pMyAssetContract = pWallet->GetAssetContract(MY_ASSET_TYPE_ID);
1028 
1029  // If failure, then we try PARTIAL match.
1030  if (nullptr == pMyAssetContract)
1031  pMyAssetContract =
1032  pWallet->GetAssetContractPartialMatch(str_MyPurse);
1033 
1034  if (nullptr != pMyAssetContract) {
1035  OTString strTemp;
1036  pMyAssetContract->GetIdentifier(strTemp);
1037 
1038  str_MyPurse = strTemp.Get();
1039  otOut << "Using as mypurse: " << str_MyPurse << "\n";
1040 
1041  pMyAssetContract->GetIdentifier(thePurseAssetTypeID);
1042  }
1043  // Execution continues here, so the script has the option to
1044  // download
1045  // any asset contract, if it can't find it in the wallet.
1046  }
1047  // if no purse (asset type) ID was provided, but MyAccount WAS provided,
1048  // then
1049  // use the asset type for the account instead.
1050  else if (nullptr != pMyAccount)
1051  thePurseAssetTypeID = pMyAccount->GetAssetTypeID();
1052  if (!thePurseAssetTypeID.IsEmpty()) {
1053  OTString strTempAssetType(thePurseAssetTypeID);
1054  str_MyPurse = strTempAssetType.Get();
1055  }
1056  // BELOW THIS POINT, pMyAssetContract MIGHT be nullptr, or MIGHT be an
1057  // asset
1058  // type specified by the user.
1059  // There's no guarantee that it's available, but if it IS, then it WILL
1060  // be
1061  // available below this point.
1062  OTIdentifier hisPurseAssetTypeID;
1063 
1064  if (str_HisPurse.size() > 0) {
1065  const OTIdentifier HIS_ASSET_TYPE_ID(str_HisPurse.c_str());
1066  OTAssetContract* pHisAssetContract =
1067  pWallet->GetAssetContract(HIS_ASSET_TYPE_ID);
1068 
1069  // If failure, then we try PARTIAL match.
1070  if (nullptr == pHisAssetContract)
1071  pHisAssetContract =
1072  pWallet->GetAssetContractPartialMatch(str_HisPurse);
1073 
1074  if (nullptr != pHisAssetContract) {
1075  OTString strTemp;
1076  pHisAssetContract->GetIdentifier(strTemp);
1077 
1078  str_HisPurse = strTemp.Get();
1079  otOut << "Using as hispurse: " << str_HisPurse << "\n";
1080 
1081  pHisAssetContract->GetIdentifier(hisPurseAssetTypeID);
1082  }
1083  }
1084  // If no "HisPurse" was provided, but HisAcct WAS, then we use the
1085  // asset type of HisAcct as HisPurse.
1086  else if (nullptr != pHisAccount)
1087  hisPurseAssetTypeID = pHisAccount->GetAssetTypeID();
1088  if (!hisPurseAssetTypeID.IsEmpty()) {
1089  OTString strTempAssetType(hisPurseAssetTypeID);
1090  str_HisPurse = strTempAssetType.Get();
1091  }
1092 
1093  otOut << "\n";
1094 
1095  // Also, pAccount and pMyAssetContract have not be validated AGAINST
1096  // EACH
1097  // OTHER (yet)...
1098  // Also, pHisAccount and pHisAssetContract have not be validated AGAINST
1099  // EACH OTHER (yet)...
1100 
1101  /* GET THE ACTUAL ARGUMENTS AFTER THE OPTIONS */
1102  //
1103  // for( int32_t i = 0 ; i < opt->getArgc() ; i++ )
1104  // {
1105  // cerr << "arg = " << opt->getArgv( i ) << endl ;
1106  // }
1107 
1108  bool bSendCommand = false; // Determines whether to actually send a
1109  // message to the server.
1110 
1111  OTMessage theMessage;
1112 
1113  // If we can match the user's request to a client command,
1114  // AND theClient object is able to process that request into
1115  // theMessage, then we send it down the pipe.
1116 
1117  // In lieu of maintaining a constant connection to the server, in ZMQ
1118  // mode,
1119  // the
1120  // client updates its internal "connection" object to make sure the
1121  // right
1122  // pointers
1123  // are in place (since in ZMQ mode, each message could be from a
1124  // different
1125  // nym
1126  // and to a different server.)
1127  //
1128  if ((nullptr != pServerContract) && (nullptr != pMyNym))
1129  OTAPI_Wrap::OTAPI()->GetClient()->SetFocusToServerAndNym(
1130  *pServerContract, *pMyNym,
1131  OTAPI_Wrap::OTAPI()->GetTransportCallback());
1132  // NOTE -- This MAY be unnecessary for ProcessUserCommand (since these
1133  // args
1134  // are passed
1135  // in there already) but it's definitely necessary soon after for
1136  // ProcessServerReply()
1137  // (which comes next.)
1138 
1139  // (OTClient::OT_CLIENT_CMD_TYPE requestedCommand,
1140  // OTMessage & theMessage,
1141  // OTPseudonym & theNym,
1142  // OTServerContract & theServer,
1143  // OTAccount * pAccount,
1144  // lAmount
1145  // OTAssetContract * pMyAssetType,
1146  // OTAccount * pHisAcct,
1147  // OTPseudonym * pHisNym)
1148 
1149  // COMMANDS
1150 
1151  if ((opt->getValue("script") != nullptr) || (opt->getArgc() > 0)) {
1152  OTAPI_Wrap::OTAPI()->GetClient()->SetRunningAsScript(); // This way
1153  // it won't
1154  // go firing
1155  // off
1156  // messages
1157  // automatically based on receiving certain
1158  // server replies to previous requests.
1159  // Todo: Research whether the above call is still necessary. (OTAPI
1160  // no
1161  // longer fires off ANY auto messages based on server replies. API
1162  // CLIENT
1163  // MUST do those things itself now.)
1164 
1165  std::string strFilename;
1166 
1167  // If a filename is provided as a normal argument (like this: ot
1168  // <filename>)
1169  // then it will work...
1170  //
1171  if (opt->getArgc() > 0) {
1172  strFilename = opt->getArgv(0);
1173  }
1174 
1175  // the --script option will ALSO work for the filename, and will
1176  // override
1177  // the above.
1178  // so: ot --script <filename>
1179  // also: ot --script <actual_filename> <ignored_filename>
1180  //
1181  // In this above example, ignored_filename WOULD have been used, but
1182  // then
1183  // it got
1184  // overridden by the --script actual_filename.
1185 
1186  if (nullptr != opt->getValue("script")) {
1187  strFilename = opt->getValue("script");
1188  }
1189 
1190  std::ifstream t(strFilename.c_str(),
1191  std::ios::in | std::ios::binary);
1192  std::stringstream buffer;
1193  buffer << t.rdbuf();
1194  std::string results = buffer.str();
1195  OT_ME madeEasy;
1196 
1197  std::unique_ptr<OTVariable> angelArgs;
1198 
1199  std::unique_ptr<OTVariable> angelMyNymVar;
1200  std::unique_ptr<OTVariable> angelHisNymVar;
1201  std::unique_ptr<OTVariable> angelServer;
1202  std::unique_ptr<OTVariable> angelMyAcct;
1203  std::unique_ptr<OTVariable> angelHisAcct;
1204  std::unique_ptr<OTVariable> angelMyPurse;
1205  std::unique_ptr<OTVariable> angelHisPurse;
1206 
1207  if ((str_Args.size() > 0) || (opt->getArgc() > 1)) {
1208  const std::string str_var_name("Args");
1209  std::string str_var_value, str_command;
1210 
1211  if (str_Args.size() > 0) str_var_value += str_Args;
1212 
1213  if (opt->getArgc() > 1) {
1214  if (str_Args.size() > 0) str_var_value += " ";
1215 
1216  str_command = opt->getArgv(1);
1217  str_var_value += "ot_cli_command ";
1218  str_var_value += str_command;
1219  }
1220 
1221  otWarn << "Adding user-defined command line arguments as '"
1222  << str_var_name << "' "
1223  "containing value: " << str_var_value
1224  << "\n";
1225 
1226  OTVariable* pVar =
1227  new OTVariable(str_var_name, // "Args"
1228  str_var_value, // "key1 value1 key2 value2
1229  // key3 value3 key4 value4"
1230  OTVariable::Var_Constant); // constant,
1231  // persistent, or
1232  // important.
1233  angelArgs.reset(pVar);
1234  OT_ASSERT(nullptr != pVar);
1235  madeEasy.AddVariable(str_var_name, *pVar);
1236  }
1237  else {
1238  otInfo << "Args variable (optional user-defined "
1239  "arguments) isn't set...\n";
1240  }
1241 
1242  if (str_ServerID.size() > 0) {
1243  const std::string str_var_name("Server");
1244  const std::string str_var_value(str_ServerID);
1245 
1246  otWarn << "Adding constant with name " << str_var_name
1247  << " and value: " << str_var_value << " ...\n";
1248 
1249  OTVariable* pVar = new OTVariable(
1250  str_var_name, // "Server"
1251  str_var_value, // "lkjsdf09834lk5j34lidf09" (Whatever)
1252  OTVariable::Var_Constant); // constant, persistent, or
1253  // important.
1254  angelServer.reset(pVar);
1255  OT_ASSERT(nullptr != pVar);
1256  madeEasy.AddVariable(str_var_name, *pVar);
1257  }
1258  else {
1259  otInfo << "Server variable isn't set...\n";
1260  }
1261 
1262  if (nullptr != pMyNym) {
1263  const std::string str_party_name("MyNym");
1264 
1265  otWarn << "Adding constant with name " << str_party_name
1266  << " and value: " << str_MyNym << " ...\n";
1267 
1268  OTVariable* pVar = new OTVariable(
1269  str_party_name, // "MyNym"
1270  str_MyNym, // "lkjsdf09834lk5j34lidf09" (Whatever)
1271  OTVariable::Var_Constant); // constant, persistent, or
1272  // important.
1273  angelMyNymVar.reset(pVar);
1274  OT_ASSERT(nullptr != pVar);
1275  madeEasy.AddVariable(str_party_name, *pVar);
1276  }
1277  else {
1278  otInfo << "MyNym variable isn't set...\n";
1279  }
1280 
1281  if ((nullptr != pHisNym) || (str_HisNym.size() > 0)) // Even if we
1282  // didn't find
1283  // him, we still
1284  // let
1285  // the ID through, if there is one.
1286  {
1287  const std::string str_party_name("HisNym");
1288 
1289  otWarn << "Adding constant with name " << str_party_name
1290  << " and value: " << str_HisNym << " ...\n";
1291 
1292  OTVariable* pVar = new OTVariable(
1293  str_party_name, // "HisNym"
1294  str_HisNym, // "lkjsdf09834lk5j34lidf09" (Whatever)
1295  OTVariable::Var_Constant); // constant, persistent, or
1296  // important.
1297  angelHisNymVar.reset(pVar);
1298  OT_ASSERT(nullptr != pVar);
1299  madeEasy.AddVariable(str_party_name, *pVar);
1300  }
1301  else {
1302  otInfo << "HisNym variable isn't set...\n";
1303  }
1304  // WE NO LONGER PASS THE PARTY DIRECTLY TO THE SCRIPT,
1305  // BUT INSTEAD, ONLY THE PARTY'S NAME.
1306  //
1307  // (Because often, "HisNym" isn't in my wallet and wouldn't be found
1308  // anyway,
1309  // even though it ends up to contain a perfectly legitimate Nym
1310  // ID.)
1311  /*
1312  if (nullptr != pMyNym)
1313  {
1314  const std::string str_party_name("MyNym"),
1315  str_agent_name("mynym"), str_acct_name("myacct");
1316 
1317  pPartyMyNym = new OTParty (str_party_name, *pMyNym,
1318  str_agent_name, pMyAccount, &str_acct_name);
1319  angelMyNym.reset(pPartyMyNym);
1320  OT_ASSERT(nullptr != pPartyMyNym);
1321  pScript-> AddParty("MyNym", *pPartyMyNym);
1322  }
1323  else
1324  {
1325  otErr << "MyNym variable isn't set...\n";
1326  }
1327  if (nullptr != pHisNym)
1328  {
1329  const std::string str_party_name("HisNym"),
1330  str_agent_name("hisnym"), str_acct_name("hisacct");
1331 
1332  pPartyHisNym = new OTParty (str_party_name, *pHisNym,
1333  str_agent_name, pHisAccount, &str_acct_name);
1334  angelHisNym.reset(pPartyHisNym);
1335  OT_ASSERT(nullptr != pPartyHisNym);
1336  pScript-> AddParty("HisNym", *pPartyHisNym);
1337  }
1338  else
1339  {
1340  otErr << "HisNym variable isn't set...\n";
1341  }
1342  */
1343 
1344  if (str_MyAcct.size() > 0) {
1345  const std::string str_var_name("MyAcct");
1346  const std::string str_var_value(str_MyAcct);
1347 
1348  otWarn << "Adding variable with name " << str_var_name
1349  << " and value: " << str_var_value << " ...\n";
1350 
1351  OTVariable* pVar = new OTVariable(
1352  str_var_name, // "MyAcct"
1353  str_var_value, // "lkjsdf09834lk5j34lidf09" (Whatever)
1354  OTVariable::Var_Constant); // constant, persistent, or
1355  // important.
1356  angelMyAcct.reset(pVar);
1357  OT_ASSERT(nullptr != pVar);
1358  madeEasy.AddVariable(str_var_name, *pVar);
1359  }
1360  else {
1361  otInfo << "MyAcct variable isn't set...\n";
1362  }
1363 
1364  if (str_MyPurse.size() > 0) {
1365  const std::string str_var_name("MyPurse");
1366  const std::string str_var_value(str_MyPurse);
1367 
1368  otWarn << "Adding variable with name " << str_var_name
1369  << " and value: " << str_var_value << " ...\n";
1370 
1371  OTVariable* pVar = new OTVariable(
1372  str_var_name, // "MyPurse"
1373  str_var_value, // "lkjsdf09834lk5j34lidf09" (Whatever)
1374  OTVariable::Var_Constant); // constant, persistent, or
1375  // important.
1376  angelMyPurse.reset(pVar);
1377  OT_ASSERT(nullptr != pVar);
1378  madeEasy.AddVariable(str_var_name, *pVar);
1379  }
1380  else {
1381  otInfo << "MyPurse variable isn't set...\n";
1382  }
1383 
1384  if (str_HisAcct.size() > 0) {
1385  const std::string str_var_name("HisAcct");
1386  const std::string str_var_value(str_HisAcct);
1387 
1388  otWarn << "Adding variable with name " << str_var_name
1389  << " and value: " << str_var_value << " ...\n";
1390 
1391  OTVariable* pVar = new OTVariable(
1392  str_var_name, // "HisAcct"
1393  str_var_value, // "lkjsdf09834lk5j34lidf09" (Whatever)
1394  OTVariable::Var_Constant); // constant, persistent, or
1395  // important.
1396  angelHisAcct.reset(pVar);
1397  OT_ASSERT(nullptr != pVar);
1398  madeEasy.AddVariable(str_var_name, *pVar);
1399  }
1400  else {
1401  otInfo << "HisAcct variable isn't set...\n";
1402  }
1403 
1404  if (str_HisPurse.size() > 0) {
1405  const std::string str_var_name("HisPurse");
1406  const std::string str_var_value(str_HisPurse);
1407 
1408  otWarn << "Adding variable with name " << str_var_name
1409  << " and value: " << str_var_value << " ...\n";
1410 
1411  OTVariable* pVar = new OTVariable(
1412  str_var_name, // "HisPurse"
1413  str_var_value, // "lkjsdf09834lk5j34lidf09" (Whatever)
1414  OTVariable::Var_Constant); // constant, persistent, or
1415  // important.
1416  angelHisPurse.reset(pVar);
1417  OT_ASSERT(nullptr != pVar);
1418  madeEasy.AddVariable(str_var_name, *pVar);
1419  }
1420  else {
1421  otInfo << "MyPurse variable isn't set...\n";
1422  }
1423 
1425 
1426  otWarn << "Script output:\n\n";
1427 
1428  return madeEasy.ExecuteScript_ReturnInt(results, strFilename);
1429  }
1430  // OT SCRIPT ABOVE.
1431 
1432  if ((nullptr == pServerContract) || (nullptr == pMyNym)) {
1433  otErr << "Unexpected nullptr: "
1434  << ((nullptr == pServerContract) ? "pServerContract" : "")
1435  << " " << ((nullptr == pMyNym) ? "pMyNym" : "") << "\n";
1436  }
1437  else if (opt->getValue('w') != nullptr ||
1438  opt->getValue("withdraw") != nullptr) {
1439  const int64_t lAmount = atol(opt->getValue('w'));
1440 
1441  otOut << "(User has instructed to withdraw cash...)\n";
1442 
1443  // if successful setting up the command payload...
1444 
1445  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1446  OTClient::notarizeWithdrawal, theMessage, *pMyNym,
1447  *pServerContract, pMyAccount, lAmount)) {
1448  bSendCommand = true;
1449  }
1450  else
1451  otErr
1452  << "Error processing withdraw command in ProcessMessage.\n";
1453  }
1454  else if (opt->getValue('t') != nullptr ||
1455  opt->getValue("transfer") != nullptr) {
1456  const int64_t lAmount = atol(opt->getValue('t'));
1457 
1458  OTIdentifier HIS_ACCT_ID(
1459  (str_HisAcct.size() > 0) ? str_HisAcct.c_str() : "aaaaaaaa");
1460 
1461  otOut << "User has instructed to send a Transfer command "
1462  "(Notarize Transactions)...\n";
1463 
1464  // if successful setting up the command payload...
1465 
1466  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1467  OTClient::notarizeTransfer, theMessage, *pMyNym,
1468  *pServerContract, pMyAccount, lAmount,
1469  nullptr, // asset contract
1470  nullptr, // his Nym
1471  (str_HisAcct.size() > 0) ? &HIS_ACCT_ID
1472  : nullptr)) // his acct
1473  {
1474  bSendCommand = true;
1475  }
1476  else
1477  otErr << "Error processing notarizeTransactions (transfer) "
1478  "command "
1479  "in ProcessMessage.\n";
1480  }
1481  else if (opt->getValue('c') != nullptr ||
1482  opt->getValue("cheque") != nullptr) {
1483  otOut << "(User has instructed to write a cheque...)\n";
1484 
1485  const int64_t lAmount = atol(opt->getValue('c'));
1486 
1487  OTIdentifier HIS_NYM_ID((str_HisNym.size() > 0)
1488  ? str_HisNym.c_str()
1489  : "aaaaaaaa"); // todo hardcoding
1490 
1491  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1492  OTClient::writeCheque, theMessage, *pMyNym, *pServerContract,
1493  pMyAccount, lAmount, nullptr, // asset contract
1494  (str_HisNym.size() > 0) ? &HIS_NYM_ID : nullptr);
1495  }
1496  else if (opt->getValue('v') != nullptr ||
1497  opt->getValue("voucher") != nullptr) {
1498  otOut << "(User has instructed to withdraw a voucher...)\n";
1499 
1500  const int64_t lAmount = atol(opt->getValue('v'));
1501 
1502  OTIdentifier HIS_NYM_ID((str_HisNym.size() > 0) ? str_HisNym.c_str()
1503  : "aaaaaaaa");
1504 
1505  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1506  OTClient::withdrawVoucher, theMessage, *pMyNym,
1507  *pServerContract, pMyAccount, lAmount,
1508  nullptr, // asset contract
1509  (str_HisNym.size() > 0) ? &HIS_NYM_ID : nullptr)) {
1510  bSendCommand = true;
1511  }
1512  else
1513  otErr << "Error processing withdraw voucher command in "
1514  "ProcessMessage.\n";
1515 
1516  }
1517 
1518  // make an offer and put it onto a market.
1519  else if (opt->getValue("marketoffer") != nullptr) {
1520  otOut << "(User has instructed to send a marketOffer command to "
1521  "the server...)\n";
1522 
1523  // if successful setting up the command payload...
1524 
1525  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1526  OTClient::marketOffer, theMessage, *pMyNym,
1527  *pServerContract,
1528  nullptr)) // for now, keeping it simple.
1529  // Can add options later.
1530  {
1531  bSendCommand = true;
1532  }
1533  else
1534  otErr << "Error processing marketOffer command in "
1535  "ProcessMessage.\n";
1536  }
1537 
1538  /*
1539  bool ProcessUserCommand(OT_CLIENT_CMD_TYPE requestedCommand,
1540  OTMessage & theMessage,
1541  OTPseudonym & theNym,
1542  // OTAssetContract & theContract,
1543  OTServerContract & theServer,
1544  OTAccount * pAccount=nullptr,
1545  int64_t lTransactionAmount = 0,
1546  OTAssetContract * pMyAssetType=nullptr,
1547  OTIdentifier * pHisAcctID=nullptr,
1548  OTIdentifier * pHisNymID=nullptr);
1549  */
1550  else if (opt->getFlag("proposepaymentplan")) {
1551  otOut << "(User has instructed to propose a payment plan...)\n";
1552 
1553  OTIdentifier HIS_NYM_ID((str_HisNym.size() > 0) ? str_HisNym.c_str()
1554  : "aaaaaaaa");
1555  OTIdentifier HIS_ACCT_ID(
1556  (str_HisAcct.size() > 0) ? str_HisAcct.c_str() : "aaaaaaaa");
1557 
1558  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1559  OTClient::proposePaymentPlan, theMessage, *pMyNym,
1560  *pServerContract, pMyAccount, 0, pMyAssetContract,
1561  (str_HisNym.size() > 0) ? &HIS_NYM_ID : nullptr,
1562  (str_HisAcct.size() > 0) ? &HIS_ACCT_ID : nullptr);
1563  }
1564  else if (opt->getFlag("confirmpaymentplan")) {
1565  otOut << "(User has instructed to confirm a payment plan...)\n";
1566 
1567  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1568  OTClient::confirmPaymentPlan, theMessage, *pMyNym,
1569  *pServerContract,
1570  nullptr); // the account info is already on the plan, right?
1571  }
1572  else if (opt->getFlag("activatepaymentplan")) {
1573  otOut << "(User has instructed to activate a payment plan...)\n";
1574 
1575  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1576  OTClient::paymentPlan, theMessage, *pMyNym,
1577  *pServerContract, pMyAccount)) // if user DOES specify
1578  // an account
1579  // (unnecessary)
1580  { // then OT will verify that they match, and error otherwise.
1581  bSendCommand = true;
1582  }
1583  else
1584  otErr << "Error processing activate payment plan command in "
1585  "ProcessMessage.\n";
1586  }
1587  else if (opt->getFlag("depositcheque")) {
1588  otOut << "(User has instructed to deposit a cheque...)\n";
1589 
1590  // if successful setting up the command payload...
1591 
1592  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1593  OTClient::notarizeCheque, theMessage, *pMyNym,
1594  *pServerContract, pMyAccount)) {
1595  bSendCommand = true;
1596  }
1597  else
1598  otErr << "Error processing deposit cheque command in "
1599  "ProcessMessage.\n";
1600  }
1601  else if (opt->getFlag("depositpurse")) {
1602  otOut << "(User has instructed to deposit a cash purse...)\n";
1603 
1604  // if successful setting up the command payload...
1605 
1606  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1607  OTClient::notarizePurse, theMessage, *pMyNym,
1608  *pServerContract, pMyAccount, 0, // amount (unused here)
1609  pMyAssetContract)) {
1610  bSendCommand = true;
1611  }
1612  else
1613  otErr << "Error processing deposit purse command in "
1614  "ProcessMessage.\n";
1615  }
1616  else if (opt->getFlag("deposittokens")) {
1617  otOut << "(User has instructed to deposit individual cash "
1618  "tokens...)\n";
1619 
1620  // if successful setting up the command payload...
1621 
1622  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1623  OTClient::notarizeDeposit, theMessage, *pMyNym,
1624  *pServerContract, pMyAccount)) {
1625  bSendCommand = true;
1626  }
1627  else
1628  otErr << "Error processing deposit cash tokens command in "
1629  "ProcessMessage.\n";
1630  }
1631  else if (opt->getFlag('i') || opt->getFlag("inbox")) {
1632  cerr << "DISPLAY INBOX CONTENTS HERE... (When I code this. What "
1633  "can I "
1634  "say? Use the GUI.)" << endl;
1635  }
1636  else if (opt->getFlag('s') || opt->getFlag("sign")) {
1637  otOut << "(User has instructed to sign a contract...)\n";
1638 
1639  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1640  OTClient::signContract, theMessage, *pMyNym, *pServerContract,
1641  nullptr);
1642  }
1643  else if (opt->getFlag('p') || opt->getFlag("purse")) {
1644  cerr << "User wants to display purse contents (not coded yet here.)"
1645  << endl;
1646  }
1647  else if (opt->getFlag("verify")) {
1648  cerr << "User wants to verify a signature on a contract (not coded "
1649  "yet "
1650  "here) " << endl;
1651  }
1652  else if (opt->getFlag("stat")) {
1653  otOut << "User has instructed to display wallet contents...\n";
1654 
1655  OTString strStat;
1656  pWallet->DisplayStatistics(strStat);
1657  otOut << strStat << "\n";
1658  }
1659  else if (opt->getFlag("prompt")) {
1660  otOut << "User has instructed to enter the OT prompt...\n";
1661  }
1662  else if (opt->getFlag('b') || opt->getFlag("balance")) {
1663  otOut << "\n ACCT BALANCE (server-side): "
1664  << pMyAccount->GetBalance() << "\n\n";
1665 
1666  Purse* pPurse = OTAPI_Wrap::OTAPI()->LoadPurse(
1667  theServerID, thePurseAssetTypeID, MY_NYM_ID);
1668  std::unique_ptr<Purse> thePurseAngel(pPurse);
1669  if (nullptr != pPurse)
1670  otOut << " CASH PURSE (client-side): "
1671  << pPurse->GetTotalValue() << "\n";
1672  }
1673  else if (opt->getFlag('r') || opt->getFlag("refresh")) {
1674  otOut << "(User has instructed to download intermediary files "
1675  "for an asset account...)\n";
1676 
1677  // if successful setting up the command payload...
1678 
1679  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1680  OTClient::getAccount, theMessage, *pMyNym,
1681  *pServerContract, pMyAccount)) {
1682  bSendCommand = true;
1683  }
1684  else
1685  otErr << "Error processing getAccount command in "
1686  "ProcessMessage.\n";
1687  }
1688  else if (opt->getFlag("refreshnym")) {
1689  otOut << "(User has instructed to download intermediary files "
1690  "for a Nym...)\n";
1691 
1692  // if successful setting up the command payload...
1693 
1694  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
1695  OTClient::getNymbox, theMessage, *pMyNym,
1696  *pServerContract, nullptr)) {
1697  bSendCommand = true;
1698  }
1699  else
1700  otErr << "Error processing getNymbox command in "
1701  "ProcessMessage.\n";
1702  }
1703 
1704  //
1705  const OTPseudonym* pServerNym = pServerContract->GetContractPublicNym();
1706 
1707  if ((nullptr == pServerNym) ||
1708  (false == pServerNym->VerifyPseudonym())) {
1709  otOut << "The server Nym was nullptr or failed to verify on server "
1710  "contract: " << strServerID << "\n";
1711  return 0;
1712  }
1713  //
1714 
1715  if (bSendCommand && pServerNym->VerifyPseudonym()) {
1716  OTString strEnvelopeContents(theMessage);
1717  OTEnvelope theEnvelope; // Seal the string up into an encrypted
1718  // Envelope
1719  theEnvelope.Seal(*pServerNym, strEnvelopeContents);
1720 
1721  OTAPI_Wrap::OTAPI()->GetTransportCallback()->operator()(
1722  *pServerContract, theEnvelope);
1723 
1724  } // if bSendCommand
1725 
1726  if (!opt->getFlag("prompt")) // If the user selected to enter the OT
1727  // prompt, then we
1728  // drop down below... (otherwise return.)
1729  {
1730  return 0;
1731  }
1732  } // Command line interface (versus below, which is the PROMPT interface.)
1733 
1734  otOut << "\nLOOKING FOR INSTRUCTIONS for the OT COMMAND LINE?\n"
1735  "Try: quit\n"
1736  "Followed by: ot -?\n"
1737  "or: ot -h\n"
1738  "or: ot --help\n"
1739  "\n"
1740  "(NOW ENTERING OT PROMPT) \n"
1741  "See docs/CLIENT-COMMANDS.txt\n\n";
1742 
1743  //
1744  // THE OPEN-TRANSACTIONS PROMPT
1745  //
1746  // OT>
1747  //
1748  // Basically, loop:
1749  //
1750  // 1) Present a prompt, and get a user string of input. Wait for that.
1751  //
1752  // 2) Process it out as an OTMessage to the server. It goes down the pipe.
1753  //
1754  // 3) Sleep for 1 second.
1755  //
1756  // 4) Awake and check for messages to be read in response from the server.
1757  // Loop. As long as there are any responses there, then process and
1758  // handle
1759  // them all.
1760  // Then continue back up to the prompt at step (1).
1761 
1762  OTPseudonym* pMyNym = nullptr;
1763  OTWallet* pWallet = nullptr;
1764  OTServerContract* pServerContract = nullptr;
1765 
1766  // If we got down here, that means there were no commands on the command
1767  // line
1768  // (That's why we dropped into the OT prompt.)
1769  // However, there still may have been OPTIONS -- and if so, we'll go ahead
1770  // and
1771  // load the wallet. (If there were NOT ANY OPTIONS, then we do NOT load the
1772  // wallet,
1773  // although there is a COMMAND for doing that.)
1774  //
1775  if ((str_ServerID.size() > 0) || (str_MyNym.size() > 0)) {
1776  if (false ==
1778  str_ServerID, str_MyNym, pMyNym, pWallet, pServerContract)) {
1779  return 0;
1780  }
1781  }
1782  else
1783  otOut << "\nYou may wish to 'load' then 'stat'.\n"
1784  "(FYI, --server SERVER_ID and --mynym NYM_ID were both "
1785  "valid options.)\n"
1786  "Also, see: ~/.ot/command-line-ot.opt for defaults.\n";
1787 
1788  // Below this point, pWallet is available and loaded, IF opt->HasOptions().
1789  // Otherwise, pWallet is NOT loaded, and we're waiting for the Load command.
1790 
1791  // Below this point, pMyNym MIGHT be a valid pointer (if it was specified),
1792  // or MIGHT be nullptr. Same with pServerContract. (MIGHT be there.)
1793  //
1794 
1795  char buf[200] = "";
1796 
1797  otLog4 << "Starting client loop.\n";
1798 
1799 // Set the logging level for the network transport code.
1800 #ifndef _WIN32
1801 // XmlRpc::setVerbosity(1);
1802 #endif
1803 
1804  for (;;) {
1805  buf[0] = 0; // Making it fresh again.
1806 
1807  // 1) Present a prompt, and get a user string of input. Wait for that.
1808  otOut << "\nOT -- WARNING: This prompt is too low-level for you.\nType "
1809  "'quit', and then try 'opentxs help' and 'opentxs "
1810  "list'.\n\nOT> ";
1811 
1812  if (nullptr ==
1813  fgets(buf, 190, stdin)) // Leaving myself 10 extra bytes at the
1814  // end for safety's sake.
1815  break;
1816 
1817  otOut << ".\n..\n...\n....\n.....\n......\n.......\n........\n........."
1818  "\n..........\n...........\n............\n.............\n";
1819 
1820  // so we can process the user input
1821  std::string strLine = buf;
1822 
1823  // Load wallet.xml
1824  if (strLine.compare(0, 4, "load") == 0) {
1825  otOut << "User has instructed to load wallet.xml...\n";
1826 
1828  str_ServerID, str_MyNym, pMyNym, pWallet,
1829  pServerContract)) {
1830  return 0;
1831  }
1832 
1833  continue;
1834  }
1835  else if ('\0' == buf[0]) {
1836  continue;
1837  }
1838  else if (strLine.compare(0, 4, "test") == 0) {
1839  std::string strScript = "print(\"Hello, world\")";
1840  OT_ME madeEasy;
1842  madeEasy.ExecuteScript_ReturnVoid(strScript, "hardcoded");
1843 
1844  /*
1845  // TODO: Make sure there's no issues with a known
1846  plaintext attack.
1847  // (Not here, but I am doing a similar thing in
1848  OTASCIIArmor to maintain a
1849  minimum size,
1850  // due to a bug in some other library that I can't
1851  recall at this time.)
1852  //
1853  const char * szBlah = "Transaction processor
1854  featuring Untraceable Digital
1855  Cash, "
1856  "Anonymous Numbered Accounts, Triple-Signed
1857  Receipts, Basket Currencies,
1858  and Signed "
1859  "XML Contracts. Also supports cheques, invoices,
1860  payment plans, markets
1861  with trades, "
1862  "and other instruments... it's like PGP for
1863  Money.... Uses OpenSSL and
1864  Lucre blinded tokens.\n";
1865 
1866  OTASCIIArmor theArmoredText(szBlah);
1867  otOut << "Armored text:\n" << theArmoredText << "\n";
1868 
1869  OTString theFixedText(theArmoredText);
1870  otOut << "Uncompressed, etc text:\n" << theFixedText << "\n";
1871  */
1872 
1873  continue;
1874  }
1875  else if (strLine.compare(0, 8, "clearreq") ==
1876  0) // clear request numbers
1877  {
1878  if (nullptr == pMyNym) {
1879  otOut << "No Nym yet available. Try 'load'.\n";
1880  continue;
1881  }
1882 
1883  OTString strServerID;
1884  pServerContract->GetIdentifier(strServerID);
1885 
1886  otOut << "You are trying to mess around with your (clear your) "
1887  "request numbers.\n"
1888  "Enter the relevant server ID [" << strServerID << "]: ";
1889 
1890  std::string str_ServerID = OT_CLI_ReadLine();
1891 
1892  const OTString strReqNumServerID((str_ServerID.size() > 0)
1893  ? str_ServerID.c_str()
1894  : strServerID.Get());
1895 
1896  pMyNym->RemoveReqNumbers(&strReqNumServerID);
1897 
1898  pMyNym->SaveSignedNymfile(*pMyNym);
1899 
1900  otOut << "Successfully removed request number for server "
1901  << strReqNumServerID << ". Saving nym...\n";
1902  continue;
1903  }
1904  else if (strLine.compare(0, 5, "clear") == 0) {
1905  if (nullptr == pMyNym) {
1906  otOut << "No Nym yet available. Try 'load'.\n";
1907  continue;
1908  }
1909 
1910  OTString strServerID;
1911  pServerContract->GetIdentifier(strServerID);
1912 
1913  otOut << "You are trying to mess around with your (clear your) "
1914  "transaction numbers.\n"
1915  "Enter the relevant server ID [" << strServerID << "]: ";
1916 
1917  std::string str_ServerID = OT_CLI_ReadLine();
1918 
1919  const OTString strTransNumServerID((str_ServerID.size() > 0)
1920  ? str_ServerID.c_str()
1921  : strServerID.Get());
1922 
1923  pMyNym->RemoveAllNumbers(&strTransNumServerID,
1924  true); // bRemoveHighestNum = true.
1925  pMyNym->SaveSignedNymfile(*pMyNym);
1926 
1927  otOut << "Successfully removed all issued and transaction "
1928  "numbers for server " << strTransNumServerID
1929  << ". Saving nym...\n";
1930  continue;
1931  }
1932  else if (strLine.compare(0, 7, "decrypt") == 0) {
1933  if (nullptr == pMyNym) {
1934  otOut << "No Nym yet available to decrypt with.\n";
1935  continue;
1936  }
1937 
1938  otOut << "Enter text to be decrypted:\n> ";
1939 
1940  OTASCIIArmor theArmoredText;
1941  char decode_buffer[200]; // Safe since we only read sizeof - 1
1942 
1943  do {
1944  decode_buffer[0] = 0;
1945  if (nullptr !=
1946  fgets(decode_buffer, sizeof(decode_buffer) - 1, stdin)) {
1947  theArmoredText.Concatenate("%s\n", decode_buffer);
1948  otOut << "> ";
1949  }
1950  else {
1951  break;
1952  }
1953  } while (strlen(decode_buffer) > 1);
1954 
1955  OTEnvelope theEnvelope(theArmoredText);
1956  OTString strDecodedText;
1957 
1958  theEnvelope.Open(*pMyNym, strDecodedText);
1959 
1960  otOut << "\n\nDECRYPTED TEXT:\n\n" << strDecodedText << "\n\n";
1961 
1962  continue;
1963  }
1964  else if (strLine.compare(0, 6, "decode") == 0) {
1965  otOut << "Enter text to be decoded:\n> ";
1966 
1967  OTASCIIArmor theArmoredText;
1968  char decode_buffer[200]; // Safe since we only read sizeof - 1.
1969 
1970  do {
1971  decode_buffer[0] = 0;
1972  if (nullptr !=
1973  fgets(decode_buffer, sizeof(decode_buffer) - 1, stdin)) {
1974  theArmoredText.Concatenate("%s\n", decode_buffer);
1975  otOut << "> ";
1976  }
1977  else {
1978  break;
1979  }
1980 
1981  } while (strlen(decode_buffer) > 1);
1982 
1983  OTString strDecodedText(theArmoredText);
1984 
1985  otOut << "\n\nDECODED TEXT:\n\n" << strDecodedText << "\n\n";
1986 
1987  continue;
1988  }
1989  else if (strLine.compare(0, 6, "encode") == 0) {
1990  otOut << "Enter text to be ascii-encoded (terminate with ~ on a "
1991  "new line):\n> ";
1992 
1993  OTString strDecodedText;
1994  char decode_buffer[200]; // Safe since we only read sizeof - 1.
1995 
1996  do {
1997  decode_buffer[0] = 0;
1998 
1999  if ((nullptr !=
2000  fgets(decode_buffer, sizeof(decode_buffer) - 1, stdin)) &&
2001  (decode_buffer[0] != '~')) {
2002  strDecodedText.Concatenate("%s", decode_buffer);
2003  otOut << "> ";
2004  }
2005  else {
2006  break;
2007  }
2008 
2009  } while (decode_buffer[0] != '~');
2010 
2011  OTASCIIArmor theArmoredText(strDecodedText);
2012 
2013  otOut << "\n\nENCODED TEXT:\n\n" << theArmoredText << "\n\n";
2014 
2015  continue;
2016  }
2017  else if (strLine.compare(0, 4, "hash") == 0) {
2018  otOut << "Enter text to be hashed (terminate with ~ on a "
2019  "new line):\n> ";
2020 
2021  OTString strDecodedText;
2022  char decode_buffer[200]; // Safe since we only read sizeof - 1.
2023 
2024  do {
2025  decode_buffer[0] = 0;
2026 
2027  if ((nullptr !=
2028  fgets(decode_buffer, sizeof(decode_buffer) - 1, stdin)) &&
2029  (decode_buffer[0] != '~')) {
2030  strDecodedText.Concatenate("%s\n", decode_buffer);
2031  otOut << "> ";
2032  }
2033  else {
2034  break;
2035  }
2036 
2037  } while (decode_buffer[0] != '~');
2038 
2039  std::string str_Trim(strDecodedText.Get());
2040  std::string str_Trim2 = OTString::trim(str_Trim);
2041  strDecodedText.Set(str_Trim2.c_str());
2042 
2043  OTIdentifier theIdentifier;
2044  theIdentifier.CalculateDigest(strDecodedText);
2045 
2046  OTString strHash(theIdentifier);
2047 
2048  otOut << "\n\nMESSAGE DIGEST:\n\n" << strHash << "\n\n";
2049 
2050  continue;
2051  }
2052  else if (strLine.compare(0, 4, "stat") == 0) {
2053  otOut << "User has instructed to display wallet contents...\n";
2054 
2055  if (pWallet) {
2056  OTString strStat;
2057  pWallet->DisplayStatistics(strStat);
2058  otOut << strStat << "\n";
2059  }
2060  else
2061  otOut << "No wallet is loaded...\n";
2062 
2063  continue;
2064  }
2065  else if (strLine.compare(0, 4, "help") == 0) {
2066  otOut << "User has instructed to display the help file...\nPlease "
2067  "see this file: docs/CLIENT_COMMANDS.txt\n";
2068 
2069  continue;
2070  }
2071  else if (strLine.compare(0, 4, "quit") == 0) {
2072  otOut << "User has instructed to exit the wallet...\n";
2073 
2074  break;
2075  }
2076 
2077  /*
2078  --myacct (ACCT ID)
2079  --mynym (NYM ID)
2080  --mypurse (ASSET TYPE ID)
2081 
2082  --toacct (ACCT ID)
2083  --tonym (NYM ID)
2084  --topurse (ASSET TYPE ID)
2085 
2086  OTPseudonym * GetNymByIDPartialMatch(const
2087  std::string PARTIAL_ID);
2088  OTServerContract * GetServerContractPartialMatch(const
2089  std::string
2090  PARTIAL_ID);
2091  OTAssetContract * GetAssetContractPartialMatch(const
2092  std::string
2093  PARTIAL_ID);
2094  OTAccount * GetAccountPartialMatch(const std::string
2095  PARTIAL_ID);
2096  */
2097 
2098  if (nullptr == pServerContract) {
2099  otOut << "Unable to find a server contract. Please restart using "
2100  "the option: --server SERVER_ID\n"
2101  "(Where SERVER_ID is the server ID. Partial matches ARE "
2102  "accepted.)\n";
2103  continue;
2104  }
2105 
2106  // You can't just connect to any hostname and port.
2107  // Instead, you give me the Server Contract, and *I'll* look up all that
2108  // stuff FOR you...
2109  // (We verify this up here, but use it at the bottom of the function
2110  // once
2111  // the message is set up.)
2112  //
2113  // int32_t nServerPort = 0;
2114  // OTString strServerHostname;
2115  // if (!pServerContract->GetConnectInfo(strServerHostname,
2116  // nServerPort))
2117  // {
2118  // otErr << "Failed retrieving connection info from"
2119  // "server contract.\n";
2120  // continue;
2121  // }
2122 
2123  // I put this here too since I think it's required in all cases below.
2124  //
2125  if (nullptr ==
2126  pMyNym) // Todo maybe move this check to the commands below
2127  // (ONLY the ones that use a nym.)
2128  {
2129  otOut
2130  << "Unable to find My Nym. Please restart and use the option:\n"
2131  " --mynym USER_ID\n"
2132  "(Where USER_ID is the Nym's ID. Partial matches ARE "
2133  "accepted.)\n";
2134  continue;
2135  }
2136 
2137  bool bSendCommand = false; // Determines whether to actually send a
2138  // message to the server.
2139 
2140  OTMessage theMessage;
2141 
2142  // If we can match the user's request to a client command,
2143  // AND theClient object is able to process that request into
2144  // theMessage, then we send it down the pipe.
2145 
2146  // In lieu of maintaining a constant connection to the server, in RPC
2147  // mode,
2148  // the
2149  // client updates its internal "connection" object to make sure the
2150  // right
2151  // pointers
2152  // are in place (since in RPC mode, each message could be from a
2153  // different
2154  // nym
2155  // and to a different server.)
2156  //
2157  OTAPI_Wrap::OTAPI()->GetClient()->SetFocusToServerAndNym(
2158  *pServerContract, *pMyNym,
2159  OTAPI_Wrap::OTAPI()->GetTransportCallback());
2160  // NOTE -- This MAY be unnecessary for ProcessUserCommand (since these
2161  // args
2162  // are passed
2163  // in there already) but it's definitely necessary soon after for
2164  // ProcessServerReply()
2165  // (which comes next.)
2166 
2167  // 'check server ID' command
2168  if (buf[0] == 'c') {
2169  otOut << "(User has instructed to send a checkServerID command "
2170  "to the server...)\n";
2171 
2172  // if successful setting up the command payload...
2173 
2174  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2175  OTClient::checkServerID, theMessage, *pMyNym,
2176  *pServerContract,
2177  nullptr)) // nullptr pAccount on this command (so far).
2178  {
2179  bSendCommand = true;
2180  }
2181  else
2182  otErr << "Error processing checkServerID command in "
2183  "ProcessMessage: " << buf[0] << "\n";
2184 
2185  }
2186 
2187  // register new user account
2188  else if (buf[0] == 'r') {
2189  otOut << "(User has instructed to send a createUserAccount "
2190  "command to the server...)\n";
2191 
2192  // if successful setting up the command payload...
2193 
2194  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2195  OTClient::createUserAccount, theMessage, *pMyNym,
2196  *pServerContract,
2197  nullptr)) // nullptr pAccount on this command.
2198  {
2199  bSendCommand = true;
2200  }
2201  else
2202  otErr << "Error processing createUserAccount command in "
2203  "ProcessMessage: " << buf[0] << "\n";
2204 
2205  }
2206 
2207  // ALL MESSAGES BELOW THIS POINT SHOULD ATTACH A REQUEST NUMBER IF THEY
2208  // EXPECT THE SERVER TO PROCESS THEM.
2209  // (Handled inside ProcessUserCommand)
2210 
2211  // checkUser
2212  else if (buf[0] == 'u') {
2213  otOut << "(User has instructed to send a checkUser command to "
2214  "the server...)\n";
2215 
2216  // if successful setting up the command payload...
2217 
2218  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2219  OTClient::checkUser, theMessage, *pMyNym,
2220  *pServerContract,
2221  nullptr)) // nullptr pAccount on this command.
2222  {
2223  bSendCommand = true;
2224  }
2225  else
2226  otErr << "Error processing checkUser command in "
2227  "ProcessMessage: " << buf[0] << "\n";
2228 
2229  }
2230 
2231  // register new asset account
2232  else if (buf[0] == 'a') {
2233  otOut << "(User has instructed to send a createAccount command "
2234  "to the server...)\n";
2235 
2236  // if successful setting up the command payload...
2237 
2238  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2239  OTClient::createAccount, theMessage, *pMyNym,
2240  *pServerContract,
2241  nullptr)) // nullptr pAccount on this command.
2242  {
2243  bSendCommand = true;
2244  }
2245  else
2246  otErr << "Error processing createAccount command in "
2247  "ProcessMessage: " << buf[0] << "\n";
2248 
2249  }
2250 
2251  // issue a new asset type
2252  else if (!strcmp(buf, "issue\n")) {
2253  otOut << "(User has instructed to send an issueAssetType command "
2254  "to the server...)\n";
2255 
2256  // if successful setting up the command payload...
2257 
2258  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2259  OTClient::issueAssetType, theMessage, *pMyNym,
2260  *pServerContract,
2261  nullptr)) // nullptr pAccount on this command.
2262  {
2263  bSendCommand = true;
2264  }
2265  else
2266  otErr << "Error processing issueAssetType command in "
2267  "ProcessMessage: " << buf << "\n";
2268 
2269  }
2270 
2271  // issue a new basket asset type
2272  else if (!strcmp(buf, "basket\n")) {
2273  otOut << "(User has instructed to send an issueBasket command to "
2274  "the server...)\n";
2275 
2276  // if successful setting up the command payload...
2277 
2278  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2279  OTClient::issueBasket, theMessage, *pMyNym,
2280  *pServerContract,
2281  nullptr)) // nullptr pAccount on this command.
2282  {
2283  bSendCommand = true;
2284  }
2285  else
2286  otErr << "Error processing issueBasket command in "
2287  "ProcessMessage: " << buf << "\n";
2288 
2289  }
2290 
2291  // exchange in/out of a basket currency
2292  else if (!strcmp(buf, "exchange\n")) {
2293  otOut << "(User has instructed to send an exchangeBasket command "
2294  "to the server...)\n";
2295 
2296  // if successful setting up the command payload...
2297 
2298  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2299  OTClient::exchangeBasket, theMessage, *pMyNym,
2300  *pServerContract,
2301  nullptr)) // nullptr pAccount on this command.
2302  {
2303  bSendCommand = true;
2304  }
2305  else
2306  otErr << "Error processing exchangeBasket command in "
2307  "ProcessMessage: " << buf << "\n";
2308 
2309  }
2310 
2311  // make an offer and put it onto a market.
2312  else if (!strcmp(buf, "offer\n")) {
2313  otOut << "(User has instructed to send a marketOffer command to "
2314  "the server...)\n";
2315 
2316  // if successful setting up the command payload...
2317 
2318  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2319  OTClient::marketOffer, theMessage, *pMyNym,
2320  *pServerContract,
2321  nullptr)) // nullptr pAccount on this command.
2322  {
2323  bSendCommand = true;
2324  }
2325  else
2326  otErr << "Error processing marketOffer command in "
2327  "ProcessMessage: " << buf << "\n";
2328 
2329  }
2330 
2331  // Set a Server Contract's client-side name (merely a label.)
2332  else if (!strcmp(buf, "setservername\n")) {
2333  otOut << "(User wants to set a Server Contract's "
2334  "client-side name...)\n";
2335 
2336  // if successful setting up the command payload...
2337 
2338  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2339  OTClient::setServerName, theMessage, *pMyNym,
2340  *pServerContract,
2341  nullptr)) // nullptr pAccount on this command.
2342  {
2343  // bSendCommand = true; //
2344  // No
2345  // message needed. Local data only.
2346  }
2347  }
2348 
2349  // Set an Asset Contract's client-side name (merely a label.)
2350  else if (!strcmp(buf, "setassetname\n")) {
2351  otOut << "(User wants to set an Asset Contract's "
2352  "client-side name...)\n";
2353 
2354  // if successful setting up the command payload...
2355 
2356  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2357  OTClient::setAssetName, theMessage, *pMyNym,
2358  *pServerContract,
2359  nullptr)) // nullptr pAccount on this command.
2360  {
2361  // bSendCommand = true; //
2362  // No
2363  // message needed. Local data only.
2364  }
2365  }
2366 
2367  // Set a Nym's client-side name (merely a label.)
2368  else if (!strcmp(buf, "setnymname\n")) {
2369  otOut << "(User wants to set a Nym's client-side name...)\n";
2370 
2371  // if successful setting up the command payload...
2372 
2373  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2374  OTClient::setNymName, theMessage, *pMyNym,
2375  *pServerContract,
2376  nullptr)) // nullptr pAccount on this command.
2377  {
2378  // bSendCommand = true; //
2379  // No
2380  // message needed. Local data only.
2381  }
2382  }
2383 
2384  // Set an Asset Account's client-side name (merely a label.)
2385  else if (!strcmp(buf, "setaccountname\n")) {
2386  otOut << "(User wants to set an Asset Account's client-side "
2387  "name...)\n";
2388 
2389  // if successful setting up the command payload...
2390 
2391  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2392  OTClient::setAccountName, theMessage, *pMyNym,
2393  *pServerContract,
2394  nullptr)) // nullptr pAccount on this command.
2395  {
2396  // bSendCommand = true; //
2397  // No
2398  // message needed. Local data only.
2399  }
2400 
2401  }
2402 
2403  // sign contract
2404  // This doesn't message the server, but it DOES require the user's Nym
2405  // to be loaded.
2406  else if (!strcmp(buf, "signcontract\n")) {
2407  otOut << "(User has instructed to sign a contract...)\n";
2408 
2409  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2410  OTClient::signContract, theMessage, *pMyNym, *pServerContract,
2411  nullptr);
2412  continue;
2413  }
2414 
2415  // sendUserMessage
2416  else if (buf[0] == 's') {
2417  otOut << "(User has instructed to send a sendUserMessage command "
2418  "to the server...)\n";
2419 
2420  // if successful setting up the command payload...
2421 
2422  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2423  OTClient::sendUserMessage, theMessage, *pMyNym,
2424  *pServerContract,
2425  nullptr)) // nullptr pAccount on this command.
2426  {
2427  bSendCommand = true;
2428  }
2429  else
2430  otErr << "Error processing sendUserMessage command in "
2431  "ProcessMessage: " << buf[0] << "\n";
2432 
2433  }
2434 
2435  // process nymbox
2436  else if (strLine.compare(0, 2, "py") == 0) {
2437  otOut << "(User has instructed to send a processNymbox command "
2438  "to the server...)\n";
2439 
2440  // if successful setting up the command payload...
2441 
2442  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2443  OTClient::processEntireNymbox, theMessage, *pMyNym,
2444  *pServerContract,
2445  nullptr)) // nullptr pAccount on this command.
2446  {
2447  bSendCommand = true;
2448  }
2449  else
2450  otErr << "Error in processNymbox command in ProcessMessage: "
2451  << strLine << "\n";
2452 
2453  }
2454 
2455  // get nymbox
2456  else if (buf[0] == 'y') {
2457  otOut << "(User has instructed to send a getNymbox command to "
2458  "the server...)\n";
2459 
2460  // if successful setting up the command payload...
2461 
2462  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2463  OTClient::getNymbox, theMessage, *pMyNym,
2464  *pServerContract,
2465  nullptr)) // nullptr pAccount on this command.
2466  {
2467  bSendCommand = true;
2468  }
2469  else
2470  otErr << "Error processing getNymbox command in "
2471  "ProcessMessage: " << buf[0] << "\n";
2472 
2473  }
2474 
2475  // Nym, Account, Server ID, Server Contract
2476 
2477  // process inbox
2478  else if (strLine.compare(0, 2, "pi") == 0) {
2479  otOut << "(User has instructed to send a processInbox command to "
2480  "the server...)\n";
2481 
2482  // if successful setting up the command payload...
2483 
2484  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2485  OTClient::processEntireInbox, theMessage, *pMyNym,
2486  *pServerContract, nullptr)) // have to allow this to be
2487  // defaulted at some point...
2488  {
2489  bSendCommand = true;
2490  }
2491  else
2492  otErr << "Error in processInbox command in ProcessMessage: "
2493  << strLine << "\n";
2494 
2495  }
2496 
2497  // get inbox
2498  else if (buf[0] == 'i') {
2499  otOut << "(User has instructed to send a getInbox command to the "
2500  "server...)\n";
2501 
2502  // if successful setting up the command payload...
2503 
2504  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2505  OTClient::getInbox, theMessage, *pMyNym,
2506  *pServerContract, nullptr)) {
2507  bSendCommand = true;
2508  }
2509  else
2510  otErr << "Error processing getInbox command in ProcessMessage: "
2511  << buf[0] << "\n";
2512 
2513  }
2514 
2515  // get outbox
2516  else if (buf[0] == 'o') {
2517  otOut << "(User has instructed to send a getOutbox command to "
2518  "the server...)\n";
2519 
2520  // if successful setting up the command payload...
2521 
2522  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2523  OTClient::getOutbox, theMessage, *pMyNym,
2524  *pServerContract, nullptr)) {
2525  bSendCommand = true;
2526  }
2527  else
2528  otErr << "Error processing getOutbox command in "
2529  "ProcessMessage: " << buf[0] << "\n";
2530 
2531  }
2532 
2533  // deposit cheque
2534  else if (buf[0] == 'q') {
2535  otOut << "User has instructed to deposit a cheque...\n";
2536 
2537  // if successful setting up the command payload...
2538 
2539  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2540  OTClient::notarizeCheque, theMessage, *pMyNym,
2541  *pServerContract, nullptr)) {
2542  bSendCommand = true;
2543  }
2544  else
2545  otErr << "Error processing deposit cheque command in "
2546  "ProcessMessage: " << buf[0] << "\n";
2547 
2548  }
2549 
2550  // deposit purse
2551  else if (buf[0] == 'p') {
2552  otOut << "(User has instructed to deposit a purse "
2553  "containing cash...)\n";
2554 
2555  // if successful setting up the command payload...
2556 
2557  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2558  OTClient::notarizePurse, theMessage, *pMyNym,
2559  *pServerContract, nullptr)) {
2560  bSendCommand = true;
2561  }
2562  else
2563  otErr << "Error processing deposit command in ProcessMessage: "
2564  << buf[0] << "\n";
2565 
2566  }
2567 
2568  // deposit tokens
2569  else if (buf[0] == 'd') {
2570  otOut << "(User has instructed to deposit cash tokens...)\n";
2571 
2572  // if successful setting up the command payload...
2573 
2574  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2575  OTClient::notarizeDeposit, theMessage, *pMyNym,
2576  *pServerContract, nullptr)) {
2577  bSendCommand = true;
2578  }
2579  else
2580  otErr << "Error processing deposit command in ProcessMessage: "
2581  << buf[0] << "\n";
2582 
2583  }
2584 
2585  // withdraw voucher
2586  else if (buf[0] == 'v') {
2587  otOut << "User has instructed to withdraw a voucher (like a "
2588  "cashier's cheque)...\n";
2589 
2590  // if successful setting up the command payload...
2591 
2592  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2593  OTClient::withdrawVoucher, theMessage, *pMyNym,
2594  *pServerContract,
2595  nullptr)) // nullptr pAccount on this command.
2596  {
2597  bSendCommand = true;
2598  }
2599  else
2600  otErr << "Error processing withdraw voucher command in "
2601  "ProcessMessage: " << buf[0] << "\n";
2602 
2603  }
2604 
2605  // withdraw cash
2606  else if (buf[0] == 'w') {
2607  otOut << "(User has instructed to withdraw cash...)\n";
2608 
2609  // if successful setting up the command payload...
2610 
2611  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2612  OTClient::notarizeWithdrawal, theMessage, *pMyNym,
2613  *pServerContract,
2614  nullptr)) // nullptr pAccount on this command.
2615  {
2616  bSendCommand = true;
2617  }
2618  else
2619  otErr << "Error processing withdraw command in ProcessMessage: "
2620  << buf[0] << "\n";
2621 
2622  }
2623 
2624  // activate payment plan
2625  else if (!strcmp(buf, "activate\n")) {
2626  otOut << "User has instructed to activate a payment plan...\n";
2627 
2628  // if successful setting up the command payload...
2629 
2630  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2631  OTClient::paymentPlan, theMessage, *pMyNym,
2632  *pServerContract,
2633  nullptr)) // nullptr pAccount on this command.
2634  {
2635  bSendCommand = true;
2636  }
2637  else
2638  otErr << "Error processing payment plan command in "
2639  "ProcessMessage: " << buf[0] << "\n";
2640 
2641  }
2642 
2643  // get account
2644  else if (!strcmp(buf, "get\n")) {
2645  otOut << "(User has instructed to send a getAccount command to "
2646  "the server...)\n";
2647 
2648  // if successful setting up the command payload...
2649 
2650  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2651  OTClient::getAccount, theMessage, *pMyNym,
2652  *pServerContract,
2653  nullptr)) // nullptr pAccount on this command.
2654  {
2655  bSendCommand = true;
2656  }
2657  else
2658  otErr << "Error processing getAccount command in "
2659  "ProcessMessage: " << buf[0] << "\n";
2660 
2661  }
2662 
2663  // get contract
2664  else if (!strcmp(buf, "getcontract\n")) {
2665  otOut << "(User has instructed to send a getContract command to "
2666  "the server...)\n";
2667 
2668  // if successful setting up the command payload...
2669 
2670  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2671  OTClient::getContract, theMessage, *pMyNym,
2672  *pServerContract,
2673  nullptr)) // nullptr pAccount on this command.
2674  {
2675  bSendCommand = true;
2676  }
2677  else
2678  otErr << "Error processing getContract command in "
2679  "ProcessMessage: " << buf[0] << "\n";
2680 
2681  }
2682  else if (!strcmp(buf, "propose\n")) {
2683  otOut << "(User has instructed to propose a payment plan...)\n";
2684 
2685  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2686  OTClient::proposePaymentPlan, theMessage, *pMyNym,
2687  *pServerContract,
2688  nullptr); // User owns Merchant (recipient) account
2689  continue;
2690  }
2691  else if (!strcmp(buf, "confirm\n")) {
2692  otOut << "(User has instructed to confirm a payment plan...)\n";
2693 
2694  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2695  OTClient::confirmPaymentPlan, theMessage, *pMyNym,
2696  *pServerContract,
2697  nullptr); // the account info is already on the plan, right?
2698  continue;
2699  }
2700  else if (!strcmp(buf, "cheque\n")) {
2701  otOut << "(User has instructed to write a cheque...)\n";
2702 
2703  OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2704  OTClient::writeCheque, theMessage, *pMyNym, *pServerContract,
2705  nullptr); // It will ascertain the account inside the call.
2706  continue;
2707  }
2708 
2709  // get mint
2710  else if (!strcmp(buf, "getmint\n")) {
2711  otOut << "(User has instructed to send a getMint command "
2712  "to the server...)\n";
2713 
2714  // if successful setting up the command payload...
2715 
2716  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2717  OTClient::getMint, theMessage, *pMyNym,
2718  *pServerContract,
2719  nullptr)) // nullptr pAccount on this command.
2720  {
2721  bSendCommand = true;
2722  }
2723  else
2724  otErr << "Error processing getMint command in ProcessMessage: "
2725  << buf[0] << "\n";
2726 
2727  }
2728 
2729  // notarize transfer
2730  else if (buf[0] == 't') {
2731  otOut << "(User has instructed to send a Transfer command "
2732  "(Notarize Transactions) to the server...)\n";
2733 
2734  // if successful setting up the command payload...
2735 
2736  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2737  OTClient::notarizeTransfer, theMessage, *pMyNym,
2738  *pServerContract,
2739  nullptr)) // nullptr pAccount on this command.
2740  {
2741  bSendCommand = true;
2742  }
2743  else
2744  otErr << "Error processing notarizeTransactions command in "
2745  "ProcessMessage: " << buf[0] << "\n";
2746 
2747  }
2748 
2749  // getRequest
2750  else if (buf[0] == 'g') {
2751  otOut << "(User has instructed to send a getRequest command to "
2752  "the server...)\n";
2753 
2754  // if successful setting up the command payload...
2755 
2756  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2757  OTClient::getRequest, theMessage, *pMyNym,
2758  *pServerContract,
2759  nullptr)) // nullptr pAccount on this command.
2760  {
2761  bSendCommand = true;
2762  }
2763  else
2764  otErr << "Error processing getRequest command in "
2765  "ProcessMessage: " << buf[0] << "\n";
2766 
2767  }
2768 
2769  // getTransactionNum
2770  else if (buf[0] == 'n') {
2771  // I just coded (here) for myself a secret option (for testing)...
2772  // Optionally instead of JUST 'n', I can put n <number>, (without
2773  // brackets) and
2774  // this code will add that number to my list of issued and
2775  // transaction
2776  // numbers.
2777  // I already have the ability to clear the list, so now I can add
2778  // numbers
2779  // to it as well.
2780  // (Which adds to both lists.)
2781  // I can also remove a number from the transaction list but LEAVE it
2782  // on
2783  // the issued list,
2784  // for example by writing a cheque and throwing it away.
2785  //
2786  // This code is for testing and allows me to find and patch any
2787  // problems
2788  // without
2789  // having to re-create my data each time -- speeds up debugging.
2790  //
2791  int64_t lTransactionNumber =
2792  ((strlen(buf) > 2) ? atol(&(buf[2])) : 0);
2793 
2794  if (lTransactionNumber > 0) {
2795  OTString strServerID;
2796  pServerContract->GetIdentifier(strServerID);
2797 
2798  otOut << "You are trying to mess around with your (add to "
2799  "your) transaction numbers.\n"
2800  "Enter the relevant server ID [" << strServerID
2801  << "]: ";
2802 
2803  std::string str_ServerID = OT_CLI_ReadLine();
2804 
2805  const OTString strTransNumServerID((str_ServerID.size() > 0)
2806  ? str_ServerID.c_str()
2807  : strServerID.Get());
2808 
2809  pMyNym->AddTransactionNum(*pMyNym, strTransNumServerID,
2810  lTransactionNumber,
2811  true); // bool bSave=true
2812 
2813  otOut << "Transaction number " << lTransactionNumber
2814  << " added to both lists "
2815  "(on client side.)\n";
2816  }
2817  else {
2818  otOut << "(User has instructed to send a getTransactionNum "
2819  "command to the server...)\n";
2820 
2821  // if successful setting up the command payload...
2822 
2823  if (0 < OTAPI_Wrap::OTAPI()->GetClient()->ProcessUserCommand(
2824  OTClient::getTransactionNum, theMessage, *pMyNym,
2825  *pServerContract,
2826  nullptr)) // nullptr pAccount on this command.
2827  {
2828  bSendCommand = true;
2829  }
2830  else
2831  otErr << "Error processing getTransactionNum command in "
2832  "ProcessMessage: " << buf[0] << "\n";
2833  }
2834 
2835  }
2836  else {
2837  {
2838  // gDebugLog.Write("unknown user command in ProcessMessage in
2839  // main.cpp");
2840  otOut << "\n";
2841  // otErr << "unknown user command in ProcessMessage in main.cpp:
2842  // " << buf[0] << "\n";
2843  }
2844  continue;
2845  }
2846 
2847  const OTPseudonym* pServerNym = pServerContract->GetContractPublicNym();
2848 
2849  if (bSendCommand && (nullptr != pServerNym) &&
2850  pServerNym->VerifyPseudonym()) {
2851  OTString strEnvelopeContents(theMessage);
2852  OTEnvelope theEnvelope;
2853  theEnvelope.Seal(*pServerNym, strEnvelopeContents);
2854 
2855  OTAPI_Wrap::OTAPI()->GetTransportCallback()->operator()(
2856  *pServerContract, theEnvelope);
2857 
2858  } // if bSendCommand
2859  } // for
2860 
2861  otOut << "Exiting OT prompt.\n";
2862 
2863  // NOTE: Cleanup is handled via a nested class at the top of this main
2864  // function.
2865 
2866  return 0;
2867 }
OTLOG_IMPORT OTLogStream otLog4
EXPORT bool CalculateDigest(const OTData &dataInput)
EXPORT void ExecuteScript_ReturnVoid(const std::string &str_Code, std::string str_DisplayName="<BLANK>")
Definition: OT_ME.cpp:1202
EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
EXPORT OTAccount * GetAccountPartialMatch(std::string PARTIAL_ID)
Definition: OTWallet.cpp:613
EXPORT static OT_OTAPI_OT void CopyVariables()
EXPORT OTAssetContract * GetAssetContract(const OTIdentifier &theContractID)
Definition: OTWallet.cpp:1203
bool SetupPointersForWalletMyNymAndServerContract(std::string &str_ServerID, std::string &str_MyNym, OTPseudonym *&pMyNym, OTWallet *&pWallet, OTServerContract *&pServerContract)
Definition: main.cpp:192
EXPORT OTPseudonym * GetNymByIDPartialMatch(std::string PARTIAL_ID)
Definition: OTWallet.cpp:291
OTLOG_IMPORT OTLogStream otOut
EXPORT void DisplayStatistics(OTString &strOutput)
Definition: OTWallet.cpp:457
EXPORT bool GetAccount(int32_t iIndex, OTIdentifier &THE_ID, OTString &THE_NAME)
Definition: OTWallet.cpp:431
EXPORT bool Open(const OTPseudonym &theRecipient, OTString &theOutput, const OTPasswordData *pPWData=nullptr)
Definition: OTEnvelope.cpp:581
EXPORT void Concatenate(const char *arg,...)
Definition: OTString.cpp:1334
EXPORT bool Seal(const OTPseudonym &theRecipient, const OTString &theInput)
Definition: OTEnvelope.cpp:521
EXPORT bool VerifyPseudonym() const
EXPORT const OTPseudonym * GetContractPublicNym() const
Definition: OTContract.cpp:413
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
Definition: OTString.cpp:1055
EXPORT bool AddTransactionNum(OTPseudonym &SIGNER_NYM, const OTString &strServerID, int64_t lTransNum, bool bSave)
EXPORT std::string OT_CLI_ReadLine()
Definition: Helpers.hpp:144
EXPORT OTPseudonym * GetNymByID(const OTIdentifier &NYM_ID)
Definition: OTWallet.cpp:275
void HandleCommandLineArguments(int32_t argc, char *argv[], AnyOption *opt)
Definition: main.cpp:286
#define OT_ASSERT(x)
Definition: Assert.hpp:150
int64_t GetTotalValue() const
Definition: Purse.hpp:292
EXPORT OTAssetContract * GetAssetContractPartialMatch(std::string PARTIAL_ID)
Definition: OTWallet.cpp:1218
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
OTLOG_IMPORT OTLogStream otInfo
virtual EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
Definition: OTContract.cpp:317
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
Definition: OTString.cpp:1045
OTLOG_IMPORT OTLogStream otErr
EXPORT int32_t ExecuteScript_ReturnInt(const std::string &str_Code, std::string str_DisplayName="<BLANK>")
Definition: OT_ME.cpp:1185
EXPORT void AddVariable(const std::string &str_var_name, OTVariable &theVar)
Definition: OT_ME.cpp:1131
EXPORT void RemoveReqNumbers(const OTString *pstrServerID=nullptr)
EXPORT void GetString(OTString &theStr) const
EXPORT bool LoadPurse(const char *szServerID=nullptr, const char *szUserID=nullptr, const char *szAssetTypeID=nullptr)
Definition: Purse.cpp:832
EXPORT bool IsEmpty() const
Definition: OTData.cpp:291
EXPORT void RemoveAllNumbers(const OTString *pstrServerID=nullptr, bool bRemoveHighestNum=true)
void CollectDefaultedCLValues(AnyOption *opt, std::string &str_ServerID, std::string &str_MyAcct, std::string &str_MyNym, std::string &str_MyPurse, std::string &str_HisAcct, std::string &str_HisNym, std::string &str_HisPurse)
Definition: main.cpp:499
EXPORT bool SaveSignedNymfile(OTPseudonym &SIGNER_NYM)
bool SetupPointersForWalletMyNymAndServerContract ( std::string &  str_ServerID,
std::string &  str_MyNym,
OTPseudonym *&  pMyNym,
OTWallet *&  pWallet,
OTServerContract *&  pServerContract 
)

Definition at line 192 of file main.cpp.

195 {
196  // If we got down here, that means there were no commands on the command
197  // line
198  // (That's why we dropped into the OT prompt.)
199  // However, there still may have been OPTIONS -- and if so, we'll go ahead
200  // and
201  // load the wallet. (If there were NOT ANY OPTIONS, then we do NOT load the
202  // wallet,
203  // although there is a COMMAND for doing that.)
204  //
205 
206  OTAPI_Wrap::OTAPI()->LoadWallet();
207 
208  //
209  pWallet = OTAPI_Wrap::OTAPI()->GetWallet();
210 
211  if (nullptr == pWallet) {
212  otOut
213  << "The wallet object is still nullptr, somehow. Please load it.\n";
214  return false;
215  }
216 
217  // Below this point, pWallet is available :-)
218 
219  if (str_ServerID.size() > 0) {
220  const OTIdentifier SERVER_ID(str_ServerID.c_str());
221 
222  pServerContract = pWallet->GetServerContract(SERVER_ID);
223  // If failure, then we try PARTIAL match.
224  if (nullptr == pServerContract)
225  pServerContract =
226  pWallet->GetServerContractPartialMatch(str_ServerID);
227 
228  if (nullptr != pServerContract) {
229  OTString strTemp;
230  pServerContract->GetIdentifier(strTemp);
231 
232  str_ServerID = strTemp.Get();
233  otOut << "Using as server: " << str_ServerID << "\n";
234  }
235  else {
236  otOut
237  << "Unable to find a server contract. Please use the option: "
238  "--server SERVER_ID\n"
239  "(Where SERVER_ID is the server ID. Partial matches are "
240  "accepted "
241  "if the contract is already in the wallet.)\n"
242  "Also, see default values located in "
243  "~/.ot/comand-line-ot.opt \n";
244  // return false;
245  }
246  }
247  // Below this point, pServerContract MAY be available, but also may be
248  // nullptr.
249  //
250 
251  if (str_MyNym.size() > 0) {
252  const OTIdentifier MY_NYM_ID(str_MyNym.c_str());
253 
254  pMyNym = pWallet->GetNymByID(MY_NYM_ID);
255 
256  // If failure, then we try PARTIAL match.
257  if (nullptr == pMyNym)
258  pMyNym = pWallet->GetNymByIDPartialMatch(str_MyNym);
259 
260  if (nullptr != pMyNym) {
261  OTString strTemp;
262  pMyNym->GetIdentifier(strTemp);
263 
264  str_MyNym = strTemp.Get();
265  otOut << "Using as mynym: " << str_MyNym << "\n";
266  }
267  else {
268  otOut << "==> Unable to find My Nym. Please use the option: "
269  "--mynym USER_ID\n"
270  "(Where USER_ID is the Nym's ID. Partial matches are "
271  "accepted "
272  "if the nym is already in the wallet.)\n"
273  "Also, see default values located in "
274  "~/.ot/comand-line-ot.opt\n";
275  // return false;
276  }
277  } // Below this point, pMyNym MIGHT be a valid pointer, or MIGHT be nullptr.
278 
279  // Below THIS point, there's no guarantee of pWallet, though it MIGHT be
280  // there.
281  // Same with pServerContract. (MIGHT be there.)
282 
283  return true;
284 }
EXPORT OTPseudonym * GetNymByIDPartialMatch(std::string PARTIAL_ID)
Definition: OTWallet.cpp:291
OTLOG_IMPORT OTLogStream otOut
EXPORT OTPseudonym * GetNymByID(const OTIdentifier &NYM_ID)
Definition: OTWallet.cpp:275
EXPORT const char * Get() const
Definition: OTString.cpp:1045
EXPORT OTServerContract * GetServerContractPartialMatch(std::string PARTIAL_ID)
Definition: OTWallet.cpp:685
EXPORT OTServerContract * GetServerContract(const OTIdentifier &SERVER_ID)
Definition: OTWallet.cpp:667