Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ot_otapi_ot.cpp
Go to the documentation of this file.
1 /************************************************************
2 *
3 * ot_otapi_ot.cpp
4 *
5 */
6 
7 /************************************************************
8  -----BEGIN PGP SIGNED MESSAGE-----
9  Hash: SHA1
10 
11  * OPEN TRANSACTIONS
12  *
13  * Financial Cryptography and Digital Cash
14  * Library, Protocol, API, Server, CLI, GUI
15  *
16  * -- Anonymous Numbered Accounts.
17  * -- Untraceable Digital Cash.
18  * -- Triple-Signed Receipts.
19  * -- Cheques, Vouchers, Transfers, Inboxes.
20  * -- Basket Currencies, Markets, Payment Plans.
21  * -- Signed, XML, Ricardian-style Contracts.
22  * -- Scripted smart contracts.
23  *
24  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
25  *
26  * EMAIL:
28  *
29  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
30  *
31  * KEY FINGERPRINT (PGP Key in license file):
32  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
33  *
34  * OFFICIAL PROJECT WIKI(s):
35  * https://github.com/FellowTraveler/Moneychanger
36  * https://github.com/FellowTraveler/Open-Transactions/wiki
37  *
38  * WEBSITE:
39  * http://www.OpenTransactions.org/
40  *
41  * Components and licensing:
42  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
43  * -- otlib.........A class library.......LICENSE:...LAGPLv3
44  * -- otapi.........A client API..........LICENSE:...LAGPLv3
45  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
46  * -- otserver......Server Application....LICENSE:....AGPLv3
47  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
48  *
49  * All of the above OT components were designed and written by
50  * Fellow Traveler, with the exception of Moneychanger, which
51  * was contracted out to Vicky C ([email protected]).
52  * The open-source community has since actively contributed.
53  *
54  * -----------------------------------------------------
55  *
56  * LICENSE:
57  * This program is free software: you can redistribute it
58  * and/or modify it under the terms of the GNU Affero
59  * General Public License as published by the Free Software
60  * Foundation, either version 3 of the License, or (at your
61  * option) any later version.
62  *
63  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
64  * section 7: (This paragraph applies only to the LAGPLv3
65  * components listed above.) If you modify this Program, or
66  * any covered work, by linking or combining it with other
67  * code, such other code is not for that reason alone subject
68  * to any of the requirements of the GNU Affero GPL version 3.
69  * (==> This means if you are only using the OT API, then you
70  * don't have to open-source your code--only your changes to
71  * Open-Transactions itself must be open source. Similar to
72  * LGPLv3, except it applies to software-as-a-service, not
73  * just to distributing binaries.)
74  *
75  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
76  * used by Open Transactions: This program is released under
77  * the AGPL with the additional exemption that compiling,
78  * linking, and/or using OpenSSL is allowed. The same is true
79  * for any other open source libraries included in this
80  * project: complete waiver from the AGPL is hereby granted to
81  * compile, link, and/or use them with Open-Transactions,
82  * according to their own terms, as long as the rest of the
83  * Open-Transactions terms remain respected, with regard to
84  * the Open-Transactions code itself.
85  *
86  * Lucre License:
87  * This code is also "dual-license", meaning that Ben Lau-
88  * rie's license must also be included and respected, since
89  * the code for Lucre is also included with Open Transactions.
90  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
91  * The Laurie requirements are light, but if there is any
92  * problem with his license, simply remove the Lucre code.
93  * Although there are no other blind token algorithms in Open
94  * Transactions (yet. credlib is coming), the other functions
95  * will continue to operate.
96  * See Lucre on Github: https://github.com/benlaurie/lucre
97  * -----------------------------------------------------
98  * You should have received a copy of the GNU Affero General
99  * Public License along with this program. If not, see:
100  * http://www.gnu.org/licenses/
101  *
102  * If you would like to use this software outside of the free
103  * software license, please contact FellowTraveler.
104  * (Unfortunately many will run anonymously and untraceably,
105  * so who could really stop them?)
106  *
107  * DISCLAIMER:
108  * This program is distributed in the hope that it will be
109  * useful, but WITHOUT ANY WARRANTY; without even the implied
110  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
111  * PURPOSE. See the GNU Affero General Public License for
112  * more details.
113 
114  -----BEGIN PGP SIGNATURE-----
115  Version: GnuPG v1.4.9 (Darwin)
116 
117  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
118  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
119  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
120  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
121  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
122  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
123  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
124  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
125  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
126  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
127  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
128  kamH0Y/n11lCvo1oQxM+
129  =uSzz
130  -----END PGP SIGNATURE-----
131  **************************************************************/
132 
133 #include "ot_otapi_ot.hpp"
134 #include "ot_utility_ot.hpp"
135 #include "../core/script/OTVariable.hpp"
136 #include "../core/OTLog.hpp"
137 
138 using namespace opentxs;
139 using namespace std;
140 
141 string Args;
142 string HisAcct;
143 string HisNym;
144 string HisPurse;
145 string MyAcct;
146 string MyNym;
147 string MyPurse;
148 string Server;
149 
150 /*
151 * FT: I noticed a lot of code duplication, when sending messages and transaction
152 * requests. I could basically remove all that duplication, except there are a
153 * couple of OT_API calls inside each one, that are different, and that take
154 * different parameters.
155 * Best way to get around that, is to just make an object that will do the
156 * appropriate API call, and store the necessary parameters inside. (A "functor"
157 * aka function object.) Then pass it in as a parameter and trigger it at the
158 * appropriate time. (That's what this is.)
159 */
160 
161 string GetVariable(const char* name)
162 {
163  OTVariable* pVar = OT_ME::FindVariable2(name);
164  return pVar == nullptr ? "" : pVar->GetValueString();
165 }
166 
168 {
169  Args = GetVariable("Args");
170  HisAcct = GetVariable("HisAcct");
171  HisNym = GetVariable("HisNym");
172  HisPurse = GetVariable("HisPurse");
173  MyAcct = GetVariable("MyAcct");
174  MyNym = GetVariable("MyNym");
175  MyPurse = GetVariable("MyPurse");
176  Server = GetVariable("Server");
177 }
178 
180 {
181  bBool = false;
182  nData = 0;
183  lData = 0;
184  tData = OT_TIME_ZERO;
185  nTransNumsNeeded = 0;
186  nRequestNum = -1;
187  funcType = NO_FUNC;
188 }
189 
191 {
192  // otOut << "(Version of OTAPI_Func with 0 arguments.)\n";
193 
194  InitCustom();
195 }
196 
198 {
199 }
200 
201 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
202  const string& p_nymID)
203 {
204  // otOut << "(Version of OTAPI_Func with 3 arguments.)\n";
205 
206  InitCustom();
207 
208  string strError =
209  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
210  if (!VerifyStringVal(p_serverID)) {
211  otOut << strError << "p_serverID";
212  }
213  if (!VerifyStringVal(p_nymID)) {
214  otOut << strError << "p_nymID";
215  }
216 
217  funcType = theType;
218  serverID = p_serverID;
219  nymID = p_nymID;
220  nTransNumsNeeded = 1;
221  bBool = false;
222 }
223 
224 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
225  const string& p_nymID, const string& p_strParam)
226 {
227  // otOut << "(Version of OTAPI_Func with 4 arguments.)\n";
228 
229  InitCustom();
230 
231  string strError =
232  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
233  if (!VerifyStringVal(p_serverID)) {
234  otOut << strError << "p_serverID";
235  }
236  if (!VerifyStringVal(p_nymID)) {
237  otOut << strError << "p_nymID";
238  }
239  if (!VerifyStringVal(p_strParam)) {
240  otOut << strError << "p_strParam";
241  }
242 
243  funcType = theType;
244  serverID = p_serverID;
245  nymID = p_nymID;
246  nTransNumsNeeded = 1;
247  bBool = false;
248 
249  if (theType == ISSUE_BASKET) {
250  basket = p_strParam;
251  }
252  else if ((theType == GET_MINT) || (theType == GET_CONTRACT) ||
253  (theType == CREATE_ASSET_ACCT)) {
254  assetID = p_strParam;
255  }
256  else if (theType == CHECK_USER) {
257  nymID2 = p_strParam;
258  }
259  else if (theType == DELETE_ASSET_ACCT) {
260  accountID = p_strParam;
261  }
262  else if ((theType == ISSUE_ASSET_TYPE) ||
263  (theType == GET_MARKET_RECENT_TRADES) ||
264  (theType == QUERY_ASSET_TYPES)) {
265  strData = p_strParam;
266  }
267  else {
268  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func()\n";
269  }
270 }
271 
272 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
273  const string& p_nymID, const string& p_strParam,
274  const string& p_strData)
275 {
276  // otOut << "(Version of OTAPI_Func with 5 arguments.)\n";
277 
278  InitCustom();
279 
280  string strError =
281  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
282  if (!VerifyStringVal(p_serverID)) {
283  otOut << strError << "p_serverID \n";
284  }
285  if (!VerifyStringVal(p_nymID)) {
286  otOut << strError << "p_nymID \n";
287  }
288 
289  if (!VerifyStringVal(p_strParam)) {
290  otOut << strError << "p_strParam \n";
291  }
292 
293  if (!VerifyStringVal(p_strData)) {
294  otOut << strError << "p_strData \n";
295  }
296 
297  funcType = theType;
298  serverID = p_serverID;
299  nymID = p_nymID;
300  nTransNumsNeeded = 1;
301  bBool = false;
302 
303  if ((theType == KILL_MARKET_OFFER) || (theType == KILL_PAYMENT_PLAN) ||
304  (theType == PROCESS_INBOX) || (theType == DEPOSIT_CASH) ||
305  (theType == DEPOSIT_CHEQUE) || (theType == DEPOSIT_PAYMENT_PLAN)) {
306  accountID = p_strParam;
307  strData = p_strData;
308  }
309  else if (theType == ADJUST_USAGE_CREDITS) {
310  nymID2 = p_strParam; // target nym ID
311  strData = p_strData; // adjustment (up or down.)
312  }
313  else if (theType == EXCHANGE_CASH) {
314  assetID = p_strParam;
315  strData = p_strData;
316  }
317  else {
318  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func()\n";
319  }
320 }
321 
322 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
323  const string& p_nymID, const string& p_strParam,
324  int64_t p_lData)
325 {
326  // otOut << "(Version of OTAPI_Func with 5 arguments.)\n";
327 
328  InitCustom();
329 
330  string strError =
331  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
332  if (!VerifyStringVal(p_serverID)) {
333  otOut << strError << "p_serverID \n";
334  }
335  if (!VerifyStringVal(p_nymID)) {
336  otOut << strError << "p_nymID \n";
337  }
338 
339  if (!VerifyStringVal(p_strParam)) {
340  otOut << strError << "p_strParam \n";
341  }
342 
343  funcType = theType;
344  serverID = p_serverID;
345  nymID = p_nymID;
346  nTransNumsNeeded = 1;
347  bBool = false;
348 
349  if (theType == WITHDRAW_CASH) {
350  accountID = p_strParam;
351  lData = p_lData;
352  }
353  else if (theType == GET_MARKET_OFFERS) {
354  strData = p_strParam;
355  lData = p_lData;
356  }
357  else {
358  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func()\n";
359  }
360 }
361 
362 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
363  const string& p_nymID, const string& p_nymID2,
364  const string& p_strData, const string& p_strData2)
365 {
366  // otOut << "(Version of OTAPI_Func with 6 arguments.)\n";
367  InitCustom();
368 
369  string strError =
370  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
371  if (!VerifyStringVal(p_serverID)) {
372  otOut << strError << "p_serverID";
373  }
374  if (!VerifyStringVal(p_nymID)) {
375  otOut << strError << "p_nymID";
376  }
377  if (!VerifyStringVal(p_nymID2)) {
378  otOut << strError << "p_nymID2";
379  }
380  if (!VerifyStringVal(p_strData)) {
381  otOut << strError << "p_strData";
382  }
383  if (!VerifyStringVal(p_strData2)) {
384  otOut << strError << "p_strData2";
385  }
386 
387  funcType = theType;
388  serverID = p_serverID;
389  nymID = p_nymID;
390  nTransNumsNeeded = 1;
391  bBool = false;
392 
393  if ((theType == SEND_USER_MESSAGE) || (theType == SEND_USER_INSTRUMENT)) {
394  nymID2 = p_nymID2;
395  strData = p_strData;
396  strData2 = p_strData2;
397  }
398  else if (theType == TRIGGER_CLAUSE) {
399  strData = p_nymID2;
400  strData2 = p_strData;
401  strData3 = p_strData2;
402  }
403  else if (theType == ACTIVATE_SMART_CONTRACT) {
404 
405  accountID = p_nymID2; // the "official" asset account of the party
406  // activating the contract.;
407  strData = p_strData; // the agent's name for that party, as listed on
408  // the contract.;
409  strData2 = p_strData2; // the smart contract itself.;
410 
411  int32_t nNumsNeeded =
412  OTAPI_Wrap::SmartContract_CountNumsNeeded(p_strData2, p_strData);
413 
414  if (nNumsNeeded > 0) {
415  nTransNumsNeeded = nNumsNeeded;
416  }
417  }
418  else if (theType == GET_BOX_RECEIPT) {
419  accountID = p_nymID2; // accountID (inbox/outbox) or NymID (nymbox) is
420  // passed here.;
421  nData = stol(p_strData);
422  strData = p_strData2; // transaction number passed here as string;
423  }
424  else {
425  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func() "
426  "ERROR!!!!!!\n";
427  }
428 }
429 
430 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
431  const string& p_nymID, const string& p_accountID,
432  const string& p_strParam, int64_t p_lData,
433  const string& p_strData2)
434 {
435  // otOut << "(Version of OTAPI_Func with 7 arguments.)\n";
436 
437  InitCustom();
438 
439  string strError =
440  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
441  if (!VerifyStringVal(p_serverID)) {
442  otOut << strError << "p_serverID";
443  }
444  if (!VerifyStringVal(p_nymID)) {
445  otOut << strError << "p_nymID";
446  }
447  if (!VerifyStringVal(p_accountID)) {
448  otOut << strError << "p_accountID";
449  }
450  if (!VerifyStringVal(p_strParam)) {
451  otOut << strError << "p_strParam";
452  }
453 
454  funcType = theType;
455  serverID = p_serverID;
456  nymID = p_nymID;
457  nTransNumsNeeded = 1;
458  bBool = false;
459  accountID = p_accountID;
460 
461  if (theType == SEND_TRANSFER) {
462  if (!VerifyStringVal(p_strData2)) {
463  otOut << strError << "p_strData2";
464  }
465  accountID2 = p_strParam;
466  lData = p_lData; // int64_t Amount;
467  strData = p_strData2; // str Note;
468  }
469  else {
470  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func() "
471  "ERROR!!!!!!\n";
472  }
473 }
474 
475 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
476  const string& p_nymID, const string& p_accountID,
477  const string& p_strParam, const string& p_strData,
478  int64_t p_lData2)
479 {
480  // otOut << "(Version of OTAPI_Func with 7 arguments.)\n";
481 
482  InitCustom();
483 
484  string strError =
485  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
486  if (!VerifyStringVal(p_serverID)) {
487  otOut << strError << "p_serverID";
488  }
489  if (!VerifyStringVal(p_nymID)) {
490  otOut << strError << "p_nymID";
491  }
492  if (!VerifyStringVal(p_accountID)) {
493  otOut << strError << "p_accountID";
494  }
495  if (!VerifyStringVal(p_strParam)) {
496  otOut << strError << "p_strParam";
497  }
498 
499  funcType = theType;
500  serverID = p_serverID;
501  nymID = p_nymID;
502  nTransNumsNeeded = 1;
503  bBool = false;
504  accountID = p_accountID;
505 
506  if (theType == WITHDRAW_VOUCHER) {
507  if (!VerifyStringVal(p_strData)) {
508  otOut << strError << "p_strData";
509  }
510  nymID2 = p_strParam; // str Recipient Nym ID;
511  strData = p_strData; // str Memo;
512  lData = p_lData2; // int64_t Amount;
513  }
514  else if (theType == PAY_DIVIDEND) {
515  if (!VerifyStringVal(p_strData)) {
516  otOut << strError << "p_strData";
517  }
518  assetID = p_strParam; // str Shares Asset ID;
519  strData = p_strData; // str Memo;
520  lData = p_lData2; // int64_t Amount Per Share;
521  }
522  else {
523  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func() "
524  "ERROR!!!!!!\n";
525  }
526 }
527 
528 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
529  const string& p_nymID, const string& p_accountID,
530  const string& p_strParam, const string& p_strData,
531  const string& p_strData2)
532 {
533  // otOut << "(Version of OTAPI_Func with 7 arguments.)\n";
534 
535  InitCustom();
536 
537  string strError =
538  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
539  if (!VerifyStringVal(p_serverID)) {
540  otOut << strError << "p_serverID";
541  }
542  if (!VerifyStringVal(p_nymID)) {
543  otOut << strError << "p_nymID";
544  }
545  if (!VerifyStringVal(p_accountID)) {
546  otOut << strError << "p_accountID";
547  }
548  if (!VerifyStringVal(p_strParam)) {
549  otOut << strError << "p_strParam";
550  }
551 
552  funcType = theType;
553  serverID = p_serverID;
554  nymID = p_nymID;
555  nTransNumsNeeded = 1;
556  bBool = false;
557  accountID = p_accountID;
558 
559  if (theType == SEND_USER_INSTRUMENT) {
560  if (!VerifyStringVal(p_accountID)) {
561  otOut << strError << "p_accountID";
562  }
563  if (!VerifyStringVal(p_strParam)) {
564  otOut << strError << "p_strParam";
565  }
566  if (!VerifyStringVal(p_strData)) {
567  otOut << strError << "p_strData";
568  }
569  nymID2 = p_accountID; // Recipient Nym;
570  strData = p_strParam; // Recipient pubkey;
571  strData2 = p_strData; // Instrument for recipient.;
572  accountID =
573  p_strData2; // sender_instrument is attached here. (Optional.);
574  }
575  else {
576  otOut << "ERROR! WRONG TYPE passed to OTAPI_Func.OTAPI_Func() "
577  "ERROR!!!!!!\n";
578  }
579 }
580 
581 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
582  const string& p_nymID, const string& p_assetID,
583  const string& p_basket, const string& p_accountID,
584  bool p_bBool, int32_t p_nTransNumsNeeded)
585 {
586  // otOut << "(Version of OTAPI_Func with 8 arguments.)\n";
587 
588  InitCustom();
589 
590  string strError =
591  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
592  if (!VerifyStringVal(p_serverID)) {
593  otOut << strError << "p_serverID";
594  }
595  if (!VerifyStringVal(p_nymID)) {
596  otOut << strError << "p_nymID";
597  }
598  if (!VerifyStringVal(p_assetID)) {
599  otOut << strError << "p_assetID";
600  }
601  if (!VerifyStringVal(p_accountID)) {
602  otOut << strError << "p_accountID";
603  }
604  if (!VerifyStringVal(p_basket)) {
605  otOut << strError << "p_basket";
606  }
607 
608  funcType = theType;
609  serverID = p_serverID;
610  nymID = p_nymID;
611  nTransNumsNeeded = p_nTransNumsNeeded;
612  bBool = p_bBool;
613  assetID = p_assetID;
614  basket = p_basket;
615  accountID = p_accountID;
616 }
617 
618 OTAPI_Func::OTAPI_Func(OTAPI_Func_Type theType, const string& p_serverID,
619  const string& p_nymID, const string& assetAccountID,
620  const string& currencyAcctID, const string& scale,
621  const string& minIncrement, const string& quantity,
622  const string& price, bool bSelling)
623 {
624  // otOut << "(Version of OTAPI_Func with 10 arguments.)\n";
625 
626  InitCustom();
627 
628  string strError =
629  "ERROR! Empty string passed to OTAPI_Func.OTAPI_Func() as: ";
630  if (!VerifyStringVal(p_serverID)) {
631  otOut << strError << "p_serverID";
632  }
633  if (!VerifyStringVal(p_nymID)) {
634  otOut << strError << "p_nymID";
635  }
636  if (!VerifyStringVal(assetAccountID)) {
637  otOut << strError << "assetAccountID";
638  }
639  if (!VerifyStringVal(currencyAcctID)) {
640  otOut << strError << "currencyAcctID";
641  }
642  if (!VerifyStringVal(scale)) {
643  otOut << strError << "scale";
644  }
645  if (!VerifyStringVal(minIncrement)) {
646  otOut << strError << "minIncrement";
647  }
648  if (!VerifyStringVal(quantity)) {
649  otOut << strError << "quantity";
650  }
651  if (!VerifyStringVal(price)) {
652  otOut << strError << "price";
653  }
654 
655  funcType = theType;
656  serverID = p_serverID;
657  nymID = p_nymID;
658  accountID = assetAccountID;
659  accountID2 = currencyAcctID;
660 
661  strData = scale;
662  strData2 = minIncrement;
663  strData3 = quantity;
664  strData4 = price;
665 
666  strData5 = ""; // Will be set after this function is called, since there
667  // were too many arguments.
668 
669  bBool = bSelling;
670 
671  nTransNumsNeeded = 3; // An opening transaction number, plus another for
672  // each asset account, total of 3.
673 }
674 
676 {
677  // -1 means error, no message was sent.
678  // 0 means NO error, yet still no message was sent.
679  // >0 means (usually) the request number is being returned.
680  //
681  switch (funcType) {
682  case CHECK_USER:
683  return OTAPI_Wrap::checkUser(serverID, nymID, nymID2);
684  case CREATE_USER_ACCT:
685  return OTAPI_Wrap::createUserAccount(serverID, nymID);
686  case DELETE_USER_ACCT:
687  return OTAPI_Wrap::deleteUserAccount(serverID, nymID);
688  case SEND_USER_MESSAGE:
689  return OTAPI_Wrap::sendUserMessage(serverID, nymID, nymID2, strData,
690  strData2);
692  // accountID stores here the sender's copy of the instrument, which is
693  // used only in the case of a cash purse.
694  return OTAPI_Wrap::sendUserInstrument(serverID, nymID, nymID2, strData,
695  strData2, accountID);
697  return OTAPI_Wrap::getNym_MarketOffers(serverID, nymID);
698  case CREATE_ASSET_ACCT:
699  return OTAPI_Wrap::createAssetAccount(serverID, nymID, assetID);
700  case DELETE_ASSET_ACCT:
701  return OTAPI_Wrap::deleteAssetAccount(serverID, nymID, accountID);
703  return OTAPI_Wrap::activateSmartContract(serverID, nymID, strData2);
704  case TRIGGER_CLAUSE:
705  return OTAPI_Wrap::triggerClause(serverID, nymID, stoll(strData),
706  strData2, strData3);
707  case EXCHANGE_BASKET:
708  return OTAPI_Wrap::exchangeBasket(serverID, nymID, assetID, basket,
709  bBool);
710  case GET_CONTRACT:
711  return OTAPI_Wrap::getContract(serverID, nymID, assetID);
712  case GET_MINT:
713  return OTAPI_Wrap::getMint(serverID, nymID, assetID);
714  case QUERY_ASSET_TYPES:
715  return OTAPI_Wrap::queryAssetTypes(serverID, nymID, strData);
716  case ISSUE_ASSET_TYPE:
717  return OTAPI_Wrap::issueAssetType(serverID, nymID, strData);
718  case ISSUE_BASKET:
719  return OTAPI_Wrap::issueBasket(serverID, nymID, basket);
720  case EXCHANGE_CASH:
721  return OTAPI_Wrap::exchangePurse(serverID, assetID, nymID, strData);
722  case KILL_MARKET_OFFER:
723  return OTAPI_Wrap::killMarketOffer(serverID, nymID, accountID,
724  stoll(strData));
725  case KILL_PAYMENT_PLAN:
726  return OTAPI_Wrap::killPaymentPlan(serverID, nymID, accountID,
727  stoll(strData));
728  case GET_BOX_RECEIPT:
729  return OTAPI_Wrap::getBoxReceipt(serverID, nymID, accountID, nData,
730  stoll(strData));
731  case PROCESS_INBOX:
732  return OTAPI_Wrap::processInbox(serverID, nymID, accountID, strData);
733  case DEPOSIT_CASH:
734  return OTAPI_Wrap::notarizeDeposit(serverID, nymID, accountID, strData);
735  case DEPOSIT_CHEQUE:
736  return OTAPI_Wrap::depositCheque(serverID, nymID, accountID, strData);
738  return OTAPI_Wrap::depositPaymentPlan(serverID, nymID, strData);
739  case WITHDRAW_CASH:
740  return OTAPI_Wrap::notarizeWithdrawal(serverID, nymID, accountID,
741  lData);
742  case WITHDRAW_VOUCHER:
743  return OTAPI_Wrap::withdrawVoucher(serverID, nymID, accountID, nymID2,
744  strData, lData);
745  case PAY_DIVIDEND:
746  return OTAPI_Wrap::payDividend(serverID, nymID, accountID, assetID,
747  strData, lData);
748  case SEND_TRANSFER:
749  return OTAPI_Wrap::notarizeTransfer(serverID, nymID, accountID,
750  accountID2, lData, strData);
751  case GET_MARKET_LIST:
752  return OTAPI_Wrap::getMarketList(serverID, nymID);
753  case GET_MARKET_OFFERS:
754  return OTAPI_Wrap::getMarketOffers(serverID, nymID, strData, lData);
756  return OTAPI_Wrap::getMarketRecentTrades(serverID, nymID, strData);
757  case CREATE_MARKET_OFFER:
759  accountID, accountID2, stoll(strData), stoll(strData2),
760  stoll(strData3), stoll(strData4), bBool, tData, strData5, lData);
762  return OTAPI_Wrap::usageCredits(serverID, nymID, nymID2,
763  stoll(strData));
764  default:
765  break;
766  }
767 
768  otOut << "ERROR! OTAPI_Func.Send() activated, with bad function type: "
769  << funcType << "\n";
770 
771  return -1;
772 }
773 
774 OT_OTAPI_OT int32_t
776  const string& IN_FUNCTION) const
777 {
778  Utility MsgUtil;
779  string strLocation = "OTAPI_Func::SendRequestLowLevel: " + IN_FUNCTION;
780 
782 
783  int32_t nRun =
784  theFunction.Run(); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
785 
786  if (nRun == -1) // if the requestNumber returned by the send-attempt is -1,
787  // that means it DIDN'T SEND (error)
788  {
789  otOut << strLocation << ": Failed to send message due to error.\n";
790 
791  theFunction.nRequestNum = -1;
792  }
793  else if (nRun == 0) // if the requestNumber returned by the send-attempt
794  // is 0, it means no error, but nothing was sent.
795  // (Like processing an empty box.)
796  {
797  otOut << strLocation << ": Didn't send this message, but NO error "
798  "occurred, either. (For example, a request to "
799  "process an empty Nymbox will return 0, "
800  "meaning, nothing was sent, but also no error "
801  "occurred.)\n";
802 
803  theFunction.nRequestNum = 0;
804  }
805  else if (nRun == (-2)) // -2 is also possible at some future date. (If the
806  // request number won't fit in an int32_t, this is
807  // returned and then you can retrieve the actual
808  // number via a separate call.)
809  {
810  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
811 
812  // TODO: Have an OT API call here, which retrieves the request number
813  // (It must be too large to fit into an integer, which is why this
814  // happened.)
815 
816  theFunction.nRequestNum = -1;
817  }
818  else {
819  theFunction.nRequestNum = nRun;
820  }
821 
822  // BY this point, we definitely have the request number, which means the
823  // message was actually SENT. (At least.) This also means we can use nRun
824  // later to query for a copy of that sent message (like if we need to
825  // clawback
826  // the transaction numbers from it later, once we confirm whether the server
827  // actually never got it.)
828  //
829  return theFunction.nRequestNum;
830 }
831 
833  const string& IN_FUNCTION)
834 {
835  int32_t nTotalRetries = 2;
836  return SendTransaction(theFunction, IN_FUNCTION, nTotalRetries);
837 }
838 
840  const string& IN_FUNCTION,
841  int32_t nTotalRetries) const
842 {
843  Utility MsgUtil;
844  string strLocation = "OTAPI_Func::SendTransaction: " + IN_FUNCTION;
845 
846  if (!MsgUtil.getIntermediaryFiles(theFunction.serverID, theFunction.nymID,
847  theFunction.accountID,
848  false)) // bForceDownload=false))
849  {
850  otOut << strLocation << ", getIntermediaryFiles returned false. (It "
851  "couldn't download files that it needed.)\n";
852  return "";
853  }
854 
855  // GET TRANSACTION NUMBERS HERE IF NECESSARY.
856  //
857  int32_t getnym_trnsnum_count = OTAPI_Wrap::GetNym_TransactionNumCount(
858  theFunction.serverID, theFunction.nymID);
859  int32_t configTxnCount = MsgUtil.getNbrTransactionCount();
860  bool b1 = (theFunction.nTransNumsNeeded > configTxnCount);
861  int32_t comparative = 0;
862 
863  if (b1) {
864  comparative = theFunction.nTransNumsNeeded;
865  }
866  else {
867  comparative = configTxnCount;
868  }
869 
870  if (getnym_trnsnum_count < comparative) {
871  otOut << strLocation << ", I don't have enough transaction numbers to "
872  "perform this transaction. Grabbing more "
873  "now...\n";
874  MsgUtil.setNbrTransactionCount(comparative);
875  MsgUtil.getTransactionNumbers(theFunction.serverID, theFunction.nymID);
876  MsgUtil.setNbrTransactionCount(configTxnCount);
877  }
878 
879  // second try
880  getnym_trnsnum_count =
882  if (getnym_trnsnum_count < comparative) {
883  otOut
884  << strLocation
885  << ", failure: MsgUtil.getTransactionNumbers. (Trying again...)\n";
886 
887  // (the final parameter, the 'false' is us telling getTransNumbers that
888  // it can skip the first call to getTransNumLowLevel)
889  //
890  MsgUtil.setNbrTransactionCount(comparative);
891  MsgUtil.getTransactionNumbers(serverID, nymID, false);
892  MsgUtil.setNbrTransactionCount(configTxnCount);
893  }
894 
895  // third try
896  getnym_trnsnum_count =
898  if (getnym_trnsnum_count < comparative) {
899  otOut
900  << strLocation
901  << ", failure: MsgUtil.getTransactionNumbers. (Trying again...)\n";
902 
903  // (the final parameter, the 'false' is us telling getTransNumbers that
904  // it can skip the first call to getTransNumLowLevel)
905  //
906  MsgUtil.setNbrTransactionCount(comparative);
907  MsgUtil.getTransactionNumbers(serverID, nymID, false);
908  MsgUtil.setNbrTransactionCount(configTxnCount);
909  }
910 
911  // Giving up, if still a failure by this point.
912  //
913  getnym_trnsnum_count = OTAPI_Wrap::GetNym_TransactionNumCount(
914  theFunction.serverID, theFunction.nymID);
915 
916  if (getnym_trnsnum_count < comparative) {
917  otOut
918  << strLocation
919  << ", third failure: MsgUtil.getTransactionNumbers. (Giving up.)\n";
920  return "";
921  }
922 
923  bool bCanRetryAfterThis = false;
924 
925  string strResult = SendRequestOnce(theFunction, IN_FUNCTION, true, true,
926  bCanRetryAfterThis);
927 
928  if (VerifyStringVal(strResult)) {
929  otOut << " Getting Intermediary files.. \n";
930 
931  if (!MsgUtil.getIntermediaryFiles(theFunction.serverID,
932  theFunction.nymID,
933  theFunction.accountID, true)) {
934  otOut << strLocation << ", getIntermediaryFiles returned false. "
935  "(After a success sending the transaction. "
936  "Strange...)\n";
937  return "";
938  }
939 
940  return strResult;
941  }
942 
943  //
944  // Maybe we have an old Inbox or something.
945  //
946 
947  // TODO!! SECURITY: This is where a GOOD CLIENT (vs. a test client)
948  // will verify these intermediary files against your LAST SIGNED RECEIPT,
949  // using OTAPI_Wrap::VerifySomethingorother().
950  // See verifyFiles() at the bottom of this file.
951  // Add some kind of warning Modal Dialog here, since it's actually
952  // normal for a NEW account (never had any receipts yet.) But for
953  // any other account, this should ALWAYS VERIFY!
954  //
955  // Another note: this should happen INSIDE the getIntermediaryFiles call
956  // itself,
957  // and all similar calls. You simply should not download those files,
958  // without verifying them also. Otherwise you could end up signing
959  // a future bad receipt, based on malicious, planted intermediary files.
960 
961  int32_t nRetries = nTotalRetries;
962 
963  while ((nRetries > 0) && !VerifyStringVal(strResult) &&
964  bCanRetryAfterThis) {
965  --nRetries;
966 
967  bool bWillRetryAfterThis = true;
968 
969  if ((nRetries == 0) || !bCanRetryAfterThis) {
970  bWillRetryAfterThis = false;
971  }
972 
973  strResult = SendRequestOnce(theFunction, IN_FUNCTION, true,
974  bWillRetryAfterThis, bCanRetryAfterThis);
975 
976  // In case of failure, we want to get these before we re-try.
977  // But in case of success, we also want to get these, so we can
978  // see the results of our success. So we get these either way...
979  //
980  if (VerifyStringVal(strResult)) {
981  if (!MsgUtil.getIntermediaryFiles(theFunction.serverID,
982  theFunction.nymID,
983  theFunction.accountID, true)) {
984  otOut << strLocation
985  << ", getIntermediaryFiles (loop) returned false even "
986  "after successfully sending the transaction.\n";
987  return "";
988  }
989  break;
990  }
991  }
992 
993  return strResult;
994 }
995 
997  const string& IN_FUNCTION) const
998 {
999  Utility MsgUtil;
1000 
1001  bool bCanRetryAfterThis = false;
1002 
1003  string strResult = SendRequestOnce(theFunction, IN_FUNCTION, false, true,
1004  bCanRetryAfterThis);
1005 
1006  if (!VerifyStringVal(strResult) && bCanRetryAfterThis) {
1007  strResult = SendRequestOnce(theFunction, IN_FUNCTION, false, false,
1008  bCanRetryAfterThis);
1009  }
1010  return strResult;
1011 }
1012 
1014  const string& IN_FUNCTION,
1015  bool bIsTransaction,
1016  bool bWillRetryAfterThis,
1017  bool& bCanRetryAfterThis) const
1018 {
1019  Utility MsgUtil;
1020  string strLocation = "OTAPI_Func::SendRequestOnce: " + IN_FUNCTION;
1021 
1022  bCanRetryAfterThis = false;
1023 
1024  string strReply = "";
1025  int32_t nlocalRequestNum = SendRequestLowLevel(
1026  theFunction, IN_FUNCTION); // <======== FIRST ATTEMPT!!!!!!;
1027 
1028  if ((nlocalRequestNum == -1) || (nlocalRequestNum == 0)) {
1029  return "";
1030  }
1031  else // 1 and default.
1032  {
1033  if (nlocalRequestNum < -1) {
1034  return "";
1035  }
1036 
1037  strReply = MsgUtil.ReceiveReplyLowLevel(
1038  theFunction.serverID, theFunction.nymID, nlocalRequestNum,
1039  IN_FUNCTION); // <==== Here we RECEIVE the REPLY...;
1040  }
1041 
1042  // Below this point, we definitely have a request number.
1043  // (But not yet necessarily a reply...)
1044  //
1045 
1046  // nlocalRequestNum is positive and contains the request number from
1047  // sending.
1048  //
1049  // nReplySuccess contains status of the REPLY to that sent message.
1050  // nReplySuccess contains:
1051  // 0 == FAILURE reply msg from server,
1052  // 1 == SUCCESS reply msg from server (transaction could be success or
1053  // fail.)
1054  // -1 == (ERROR)
1055  //
1056  // strReply contains the reply itself (or null.)
1057  //
1058  int32_t nReplySuccess = VerifyMessageSuccess(strReply);
1059 
1060  bool bMsgReplyError = (!VerifyStringVal(strReply) || (nReplySuccess < 0));
1061 
1062  bool bMsgReplySuccess = (!bMsgReplyError && (nReplySuccess > 0));
1063  bool bMsgReplyFailure = (!bMsgReplyError && (nReplySuccess == 0));
1064 
1065  bool bMsgTransSuccess;
1066  bool bMsgTransFailure;
1067 
1068  bool bMsgAnyError;
1069  bool bMsgAnyFailure;
1070 
1071  bool bMsgAllSuccess;
1072 
1073  // If you EVER are in a situation where you have to harvest numbers
1074  // back, it will ONLY be for transactions, not normal messages. (Those
1075  // are the only ones that USE transaction numbers.)
1076  //
1077  if (bIsTransaction) // This request contains a TRANSACTION...
1078  {
1079  int32_t nTransSuccess;
1080  int32_t nBalanceSuccess;
1081  if (bMsgReplySuccess) // If message was success, then let's see if the
1082  // transaction was, too.
1083  {
1085  theFunction.serverID, theFunction.nymID, theFunction.accountID,
1086  strReply);
1087 
1088  if (nBalanceSuccess > 0) {
1089  // Sometimes a transaction is sent that is meant to "fail" in
1090  // order to cancel itself from ever being run in the future.
1091  // It's being cancelled. In that case, whether the server reply
1092  // itself is acknowledged or rejection, either way,
1093  // IsCancelled() will be set to TRUE.
1094  // This is used when cancelling a cheque, or a payment plan, or
1095  // a smart contract, so that it can never be activated at some
1096  // future time.
1097  //
1098  // Therefore when we see that IsCancelled is set to TRUE, we
1099  // interpret it as a "success" as far as the UI is concerned,
1100  // even though behind the scenes, it is still "rejected" and
1101  // transaction numbers were harvested from it.
1102  //
1103  int32_t nTransCancelled =
1105  theFunction.serverID, theFunction.nymID,
1106  theFunction.accountID, strReply);
1107 
1108  // If it's not cancelled, then we assume it's a normal
1109  // transaction (versus a cancellation)
1110  // and we check for success/failure as normal...
1111  //
1112  if (1 != nTransCancelled) {
1114  theFunction.serverID, theFunction.nymID,
1115  theFunction.accountID, strReply);
1116  }
1117  else // If it WAS cancelled, then for the UI we say "Success"
1118  // even though OT behind the scenes is harvesting as
1119  // though it failed.
1120  { // (Which is what we want to happen, in the case that a
1121  // cancellation was performed.)
1122  // This way, the UI won't go off doing a bunch of
1123  // unnecessary retries for a "failed" transaction.
1124  // (After all, if it was cancelled, then we know for a fact
1125  // that all future retries will fail anyway.)
1126  //
1127  nTransSuccess = 1;
1128  }
1129  }
1130  else {
1131  nTransSuccess = -1;
1132  }
1133  }
1134  else {
1135  nBalanceSuccess = -1;
1136  nTransSuccess = -1;
1137  }
1138  // All of these booleans (except "error") represent RECEIVED ANSWERS
1139  // from the server.
1140  // In other words, "failure" does not mean "failed to find message."
1141  // Rather, it means "DEFINITELY got a reply, and that reply says
1142  // status==failure."
1143  //
1144 
1145  bool bMsgBalanceError =
1146  (!VerifyStringVal(strReply) || (nBalanceSuccess < 0));
1147  bool bMsgBalanceSuccess =
1148  (!bMsgReplyError && !bMsgBalanceError && (nBalanceSuccess > 0));
1149  bool bMsgBalanceFailure =
1150  (!bMsgReplyError && !bMsgBalanceError && (nBalanceSuccess == 0));
1151 
1152  bool bMsgTransError =
1153  (!VerifyStringVal(strReply) || (nTransSuccess < 0));
1154  bMsgTransSuccess = (!bMsgReplyError && !bMsgBalanceError &&
1155  !bMsgTransError && (nTransSuccess > 0));
1156  bMsgTransFailure = (!bMsgReplyError && !bMsgBalanceError &&
1157  !bMsgTransError && (nTransSuccess == 0));
1158 
1159  bMsgAnyError = (bMsgReplyError || bMsgBalanceError || bMsgTransError);
1160  bMsgAnyFailure =
1161  (bMsgReplyFailure || bMsgBalanceFailure || bMsgTransFailure);
1162 
1163  bMsgAllSuccess =
1164  (bMsgReplySuccess && bMsgBalanceSuccess && bMsgTransSuccess);
1165 
1166  }
1167  else // it's NOT a transaction, but a normal message..
1168  {
1169  bMsgTransSuccess = false;
1170  bMsgTransFailure = false;
1171 
1172  bMsgAnyError = (bMsgReplyError);
1173  bMsgAnyFailure = (bMsgReplyFailure);
1174 
1175  bMsgAllSuccess = (bMsgReplySuccess);
1176  }
1177 
1178  // We know the message SENT. The above logic is about figuring out whether
1179  // the reply message,
1180  // the transaction inside it, and the balance agreement inside that
1181  // transaction, whether
1182  // any of those three things is a definite error, a definite failure, or a
1183  // definite success.
1184  // (Any one of those things could be true, OR NOT, and we can only act as if
1185  // they are, if we
1186  // have definitive proof in any of those cases.)
1187  //
1188  // The below logic is about what sort of REPLY we may have gotten (if
1189  // anything.)
1190  // Without a definite reply we cannot claw back. But the Nymbox can show us
1191  // this answer,
1192  // either now, or later...
1193  //
1194  if (bMsgAllSuccess) {
1195  // the Msg was a complete success, including the message
1196  // AND the transaction AND the balance agreement.
1197  // Therefore, there's DEFINITELY nothing to clawback.
1198  //
1199  // (Thus I RemoveSentMessage for the message, since
1200  // I'm totally done with it now. NO NEED TO HARVEST anything, either.)
1201  //
1202  // var nRemoved =
1203  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nlocalRequestNum),
1204  // theFunction.serverID, theFunction.nymID);
1205  //
1206  // NOTE: The above call is unnecessary, since a successful reply means
1207  // we already received the successful server reply, and OT's
1208  // "ProcessServerReply"
1209  // already removed the sent message from the sent buffer (so no need to
1210  // do that here.)
1211 
1212  // otOut << strLocation << ", SendRequestOnce():
1213  // OT_API_RemoveSentMessage: " + nRemoved);
1214 
1215  return strReply;
1216 
1217  }
1218  // In this case we want to grab the Nymbox and see if the replyNotice is
1219  // there.
1220  // If it IS, then OT server DEFINITELY replied to it (the MESSAGE was a
1221  // success,
1222  // whether the transaction inside of it was success or fail.) So we know
1223  // bMsgReplySuccess
1224  // is true, if we find a replyNotice.
1225  // From there, we can also check for transaction success.
1226  //
1227  else if (bMsgAnyError || bMsgAnyFailure) // let's resync, and clawback
1228  // whatever transaction numbers we
1229  // might have used on the
1230  // Request...
1231  {
1232  bool bWasGetReqSent = false;
1233  int32_t nGetRequest = MsgUtil.getRequestNumber(
1234  theFunction.serverID, theFunction.nymID,
1235  bWasGetReqSent); // <==== RE-SYNC ATTEMPT...;
1236 
1237  // GET REQUEST WAS A SUCCESS.
1238  //
1239  if (bWasGetReqSent && (nGetRequest > 0)) {
1240  bCanRetryAfterThis = true;
1241 
1242  // But--if it was a TRANSACTION, then we're not done syncing yet!
1243  //
1244  if (bIsTransaction) {
1245  bCanRetryAfterThis = false;
1246 
1247  //
1248  // Maybe we have an old Inbox or something.
1249  // NEW CODE HERE FOR DEBUGGING (THIS BLOCK)
1250  //
1251  bool bForceDownload = true;
1252  if (!MsgUtil.getIntermediaryFiles(
1253  theFunction.serverID, theFunction.nymID,
1254  theFunction.accountID, bForceDownload)) {
1255  otOut << strLocation << ", getIntermediaryFiles returned "
1256  "false. (After a failure to send "
1257  "the transaction. Thus, I give "
1258  "up.)\n";
1259  return "";
1260  }
1261 
1262  bool bWasFound = false;
1263  bool bWasSent = false;
1264 
1265  OTfourbool the_foursome = {bMsgReplySuccess, bMsgReplyFailure,
1266  bMsgTransSuccess, bMsgTransFailure};
1267 
1268  bForceDownload = false;
1269 
1270  int32_t nProcessNymboxResult = MsgUtil.getAndProcessNymbox_8(
1271  theFunction.serverID, theFunction.nymID, bWasSent,
1272  bForceDownload, nlocalRequestNum, bWasFound,
1273  bWillRetryAfterThis, the_foursome);
1274 
1275  // bHarvestingForRetry,// bHarvestingForRetry is INPUT, in the
1276  // case nlocalRequestNum needs to be harvested before a flush
1277  // occurs.
1278 
1279  // bMsgReplySuccess, // bMsgReplySuccess is INPUT, and is in
1280  // case nlocalRequestNum needs to be HARVESTED before a FLUSH
1281  // happens.
1282  // bMsgReplyFailure, // bMsgReplyFailure is INPUT, and is in
1283  // case nlocalRequestNum needs to be HARVESTED before a FLUSH
1284  // happens.
1285  // bMsgTransSuccess, // bMsgTransSuccess is INPUT, and is in
1286  // case nlocalRequestNum needs to be HARVESTED before a FLUSH
1287  // happens.
1288  // bMsgTransFailure) // Etc.
1289 
1290  // FIX: Add '(' and ')' here to silence warning. But where?
1291  if ((bWasSent && (1 == nProcessNymboxResult)) ||
1292  (!bWasSent &&
1293  (0 == nProcessNymboxResult))) // success processing Nymbox.
1294  {
1295  bCanRetryAfterThis = true;
1296  }
1297 
1298  // This means a request number was returned, since the
1299  // processNymbox failed,
1300  // and hasn't been properly harvested, so we either need to
1301  // harvest it for a re-try,
1302  // or flush it.
1303  //
1304  else if (bWasSent && (nProcessNymboxResult > 1)) {
1305  string strNymbox = OTAPI_Wrap::LoadNymboxNoVerify(
1306  theFunction.serverID,
1307  theFunction.nymID); // FLUSH SENT MESSAGES!!!! (AND
1308  // HARVEST.);
1309 
1310  if (VerifyStringVal(strNymbox)) {
1312  false, theFunction.serverID, theFunction.nymID,
1313  strNymbox);
1314  }
1315  }
1316  } // if (bIsTransaction)
1317 
1318  } // if getRequest was success.
1319  else {
1320  otOut << strLocation << ", Failure: Never got reply from server, "
1321  "so tried getRequest, and that failed too. "
1322  "(I give up.)\n";
1323 
1324  // Note: cannot harvest transaction nums here because I do NOT know
1325  // for sure
1326  // whether the server has replied to the message or not! (Not until
1327  // I successfully
1328  // download my Nymbox.) Therefore, do NOT harvest or flush, but hold
1329  // back and wait
1330  // until the next attempt does a successful getNymbox and THEN do a
1331  // "flush sent" after
1332  // that. (That's the time we'll know for SURE what happened to the
1333  // original reply.)
1334  //
1335  // (Therefore LEAVE the sent message in the sent queue.)
1336 
1337  return "";
1338  }
1339  } // else if (bMsgAnyError || bMsgAnyFailure)
1340 
1341  // Returning an empty string.
1342 
1343  return "";
1344 }
1345 
1346 // used for passing and returning values when giving a
1347 // lambda function to a loop function.
1348 //
1349 // cppcheck-suppress uninitMemberVar
1351 {
1352 }
1353 
1355  const string& nymID)
1356 {
1357  OTDB::OfferListNym* offerList = nullptr;
1358 
1359  if (OTDB::Exists("nyms", serverID, "offers", nymID + ".bin")) {
1360  otWarn << "Offers file exists... Querying nyms...\n";
1361  OTDB::Storable* storable =
1363  "offers", nymID + ".bin");
1364 
1365  if (nullptr == storable) {
1366  otOut << "Unable to verify storable object. Probably doesn't "
1367  "exist.\n";
1368  return nullptr;
1369  }
1370 
1371  otWarn << "QueryObject worked. Now dynamic casting from storable to a "
1372  "(nym) offerList...\n";
1373  offerList = dynamic_cast<OTDB::OfferListNym*>(storable);
1374 
1375  if (nullptr == offerList) {
1376  otOut
1377  << "Unable to dynamic cast a storable to a (nym) offerList.\n";
1378  return nullptr;
1379  }
1380  }
1381 
1382  return offerList;
1383 }
1384 
1386 {
1387  string strLocation = "convert_offerlist_to_maps";
1388 
1389  MapOfMaps* map_of_maps = nullptr;
1390 
1391  // LOOP THROUGH THE OFFERS and sort them into a map_of_maps, key is:
1392  // scale-assetID-currencyID
1393  // the value for each key is a sub-map, with the key: transaction ID and
1394  // value: the offer data itself.
1395  //
1396  int32_t nCount = offerList.GetOfferDataNymCount();
1397  int32_t nTemp = nCount;
1398 
1399  if (nCount > 0) {
1400  for (int32_t nIndex = 0; nIndex < nCount; ++nIndex) {
1401  nTemp = nIndex;
1402  OTDB::OfferDataNym* offerDataPtr = offerList.GetOfferDataNym(nTemp);
1403 
1404  if (!offerDataPtr) {
1405  otOut << strLocation << ": Unable to reference (nym) offerData "
1406  "on offerList, at index: " << nIndex
1407  << "\n";
1408  return map_of_maps;
1409  }
1410 
1411  OTDB::OfferDataNym& offerData = *offerDataPtr;
1412  string strScale = offerData.scale;
1413  string strAssetTypeID = offerData.asset_type_id;
1414  string strCurrencyTypeID = offerData.currency_type_id;
1415  string strSellStatus = offerData.selling ? "SELL" : "BUY";
1416  string strTransactionID = offerData.transaction_id;
1417 
1418  string strMapKey =
1419  strScale + "-" + strAssetTypeID + "-" + strCurrencyTypeID;
1420 
1421  SubMap* sub_map = nullptr;
1422  if (nullptr != map_of_maps && !map_of_maps->empty() &&
1423  (map_of_maps->count(strMapKey) > 0)) {
1424  sub_map = (*map_of_maps)[strMapKey];
1425  }
1426 
1427  if (nullptr != sub_map) {
1428  otWarn << strLocation << ": The sub-map already exists!\n";
1429 
1430  // Let's just add this offer to the existing submap
1431  // (There must be other offers already there for the same
1432  // market,
1433  // since the submap already exists.)
1434  //
1435  // the sub_map for this market is mapped by BUY/SELL ==> the
1436  // actual
1437  // offerData.
1438  //
1439 
1440  (*sub_map)[strTransactionID] = &offerData;
1441  }
1442  else // submap does NOT already exist for this market. (Create
1443  // it...)
1444  {
1445  otWarn << strLocation
1446  << ": The sub-map does NOT already exist!\n";
1447  //
1448  // Let's create the submap with this new offer, and add it
1449  // to the main map.
1450  //
1451  sub_map = new SubMap();
1452  (*sub_map)[strTransactionID] = &offerData;
1453 
1454  if (nullptr != map_of_maps) {
1455  map_of_maps = new MapOfMaps;
1456  }
1457  (*map_of_maps)[strMapKey] = sub_map;
1458  }
1459 
1460  // Supposedly by this point I have constructed a map keyed by the
1461  // market, which returns a sub_map for each market. Each sub map
1462  // uses the key "BUY" or "SELL" and that points to the actual
1463  // offer data. (Like a Multimap.)
1464  //
1465  // Therefore we have sorted out all the buys and sells for each
1466  // market. Later on, we can loop through the main map, and for each
1467  // market, we can loop through all the buys and sells.
1468  } // for (constructing the map_of_maps and all the sub_maps, so that the
1469  // offers are sorted
1470  // by market and buy/sell status.
1471  }
1472 
1473  return map_of_maps;
1474 }
1475 
1476 OT_OTAPI_OT int32_t
1477  output_nymoffer_data(const OTDB::OfferDataNym& offer_data, int32_t nIndex,
1478  const MapOfMaps&, const SubMap&,
1479  the_lambda_struct&) // if 10 offers are printed for the
1480  // SAME market, nIndex will be 0..9
1481 { // extra_vals unused in this function, but not in others that share this
1482  // parameter profile.
1483  // (It's used as a lambda.)
1484 
1485  string strScale = offer_data.scale;
1486  string strAssetTypeID = offer_data.asset_type_id;
1487  string strCurrencyTypeID = offer_data.currency_type_id;
1488  string strSellStatus = offer_data.selling ? "SELL" : "BUY";
1489  string strTransactionID = offer_data.transaction_id;
1490  string strAvailableAssets = to_string(stoll(offer_data.total_assets) -
1491  stoll(offer_data.finished_so_far));
1492 
1493  if (0 == nIndex) // first iteration! (Output a header.)
1494  {
1495  otOut << "Scale:\t\t" << strScale << "\n";
1496  otOut << "Asset:\t\t" << strAssetTypeID << "\n";
1497  otOut << "Currency:\t" << strCurrencyTypeID << "\n";
1498  otOut << "\nIndex\tTrans#\tType\tPrice\tAvailable\n";
1499  }
1500 
1501  //
1502  // Okay, we have the offer_data, so let's output it!
1503  //
1504  cout << (nIndex) << "\t" << offer_data.transaction_id << "\t"
1505  << strSellStatus << "\t" << offer_data.price_per_scale << "\t"
1506  << strAvailableAssets << "\n";
1507 
1508  return 1;
1509 }
1510 
1511 // If you have a buy offer, to buy silver for $30, and to sell silver for $35,
1512 // what happens tomorrow when the market shifts, and you want to buy for $40
1513 // and sell for $45 ?
1514 //
1515 // Well, now you need to cancel certain sell orders from yesterday! Because why
1516 // on earth would you want to sell silver for $35 while buying it for $40?
1517 // (knotwork raised ) That would be buy-high, sell-low.
1518 //
1519 // Any rational trader would cancel the old $35 sell order before placing a new
1520 // $40 buy order!
1521 //
1522 // Similarly, if the market went DOWN such that my old offers were $40 buy / $45
1523 // sell, and my new offers are going to be $30 buy / $35 sell, then I want to
1524 // cancel certain buy orders for yesterday. After all, why on earth would you
1525 // want to buy silver for $40 meanwhile putting up a new sell order at $35!
1526 // You would immediately just turn around, after buying something, and sell it
1527 // for LESS?
1528 //
1529 // Since the user would most likely be forced anyway to do this, for reasons of
1530 // self-interest, it will probably end up as the default behavior here.
1531 //
1532 
1533 // RETURN VALUE: extra_vals will contain a list of offers that need to be
1534 // removed AFTER
1535 
1536 OT_OTAPI_OT int32_t
1537  find_strange_offers(const OTDB::OfferDataNym& offer_data, const int32_t,
1538  const MapOfMaps&, const SubMap&,
1539  the_lambda_struct& extra_vals) // if 10 offers are
1540  // printed
1541  // for the SAME market,
1542  // nIndex will be 0..9
1543 {
1544  string strLocation = "find_strange_offers";
1545  /*
1546  me: How about this — when you do "opentxs newoffer" I can alter that
1547  script to automatically cancel any sell offers for a lower amount
1548  than my new buy offer, if they're on the same market at the same scale.
1549  and vice versa. Vice versa meaning, cancel any bid offers for a higher
1550  amount than my new sell offer.
1551 
1552  knotwork: yeah that would work.
1553 
1554  So when placing a buy offer, check all the other offers I already have at
1555  the same scale,
1556  same asset and currency ID. (That is, the same "market" as denoted by
1557  strMapKey in "opentxs showmyoffers")
1558  For each, see if it's a sell offer and if so, if the amount is lower than
1559  the amount on
1560  the new buy offer, then cancel that sell offer from the market. (Because I
1561  don't want to buy-high, sell low.)
1562 
1563  Similarly, if placing a sell offer, then check all the other offers I
1564  already have at the
1565  same scale, same asset and currency ID, (the same "market" as denoted by
1566  strMapKey....) For
1567  each, see if it's a buy offer and if so, if the amount is higher than the
1568  amount of my new
1569  sell offer, then cancel that buy offer from the market. (Because I don't
1570  want some old buy offer
1571  for $10 laying around for the same stock that I'm SELLING for $8! If I dump
1572  100 shares, I'll receive
1573  $800--I don't want my software to automatically turn around and BUY those
1574  same shares again for $1000!
1575  That would be a $200 loss.)
1576 
1577  This is done here. This function gets called once for each offer that's
1578  active for this Nym.
1579  extra_vals contains the relevant info we're looking for, and offer_data
1580  contains the current
1581  offer (as we loop through ALL this Nym's offers, this function gets called
1582  for each one.)
1583  So here we just need to compare once, and add to the list if the comparison
1584  matches.
1585  */
1586  /*
1587  attr the_lambda_struct::the_vector // used for returning a list of
1588  something.
1589  attr the_lambda_struct::the_asset_acct // for newoffer, we want to remove
1590  existing offers for the same accounts in certain cases.
1591  attr the_lambda_struct::the_currency_acct // for newoffer, we want to remove
1592  existing offers for the same accounts in certain cases.
1593  attr the_lambda_struct::the_scale // for newoffer as well.
1594  attr the_lambda_struct::the_price // for newoffer as well.
1595  attr the_lambda_struct::bSelling // for newoffer as well.
1596  */
1597  otLog4 << strLocation << ": About to compare the new potential offer "
1598  "against one of the existing ones...";
1599 
1600  if ((extra_vals.the_asset_acct == offer_data.asset_acct_id) &&
1601  (extra_vals.the_currency_acct == offer_data.currency_acct_id) &&
1602  (extra_vals.the_scale == offer_data.scale)) {
1603  otLog4 << strLocation << ": the account IDs and the scale match...";
1604 
1605  // By this point we know the current offer_data has the same asset acct,
1606  // currency acct, and scale
1607  // as the offer we're comparing to all the rest.
1608  //
1609  // But that's not enough: we also need to compare some prices:
1610  //
1611  // So when placing a buy offer, check all the other offers I already
1612  // have.
1613  // For each, see if it's a sell offer and if so, if the amount is lower
1614  // than the amount on
1615  // the new buy offer, then cancel that sell offer from the market.
1616  // (Because I don't want to buy-high, sell low.)
1617  //
1618  if (!extra_vals.bSelling && offer_data.selling &&
1619  (stoll(offer_data.price_per_scale) < stoll(extra_vals.the_price))) {
1620  extra_vals.the_vector.push_back(offer_data.transaction_id);
1621  }
1622  // Similarly, when placing a sell offer, check all the other offers I
1623  // already have.
1624  // For each, see if it's a buy offer and if so, if the amount is higher
1625  // than the amount of my new
1626  // sell offer, then cancel that buy offer from the market.
1627  //
1628  else if (extra_vals.bSelling && !offer_data.selling &&
1629  (stoll(offer_data.price_per_scale) >
1630  stoll(extra_vals.the_price))) {
1631  extra_vals.the_vector.push_back(offer_data.transaction_id);
1632  }
1633  }
1634  // We don't actually do the removing here, since we are still looping
1635  // through the maps.
1636  // So we just add the IDs to a vector so that the caller can do the removing
1637  // once this loop is over.
1638 
1639  return 1;
1640 }
1641 
1643  SubMap& sub_map,
1644  LambdaFunc the_lambda)
1645 {
1646  the_lambda_struct extra_vals;
1647  return iterate_nymoffers_sub_map(map_of_maps, sub_map, the_lambda,
1648  extra_vals);
1649 }
1650 
1651 // low level. map_of_maps and sub_map must be good. (assumed.)
1652 //
1653 // extra_vals allows you to pass any extra data you want into your
1654 // lambda, for when it is called. (Like a functor.)
1655 //
1657  SubMap& sub_map,
1658  LambdaFunc the_lambda,
1659  the_lambda_struct& extra_vals)
1660 {
1661  // the_lambda must be good (assumed) and must have the parameter profile
1662  // like this sample:
1663  // def the_lambda(offer_data, nIndex, map_of_maps, sub_map, extra_vals)
1664  //
1665  // if 10 offers are printed for the SAME market, nIndex will be 0..9
1666 
1667  string strLocation = "iterate_nymoffers_sub_map";
1668 
1669  // Looping through the map_of_maps, we are now on a valid sub_map in this
1670  // iteration.
1671  // Therefore let's loop through the offers on that sub_map and output them!
1672  //
1673  // var range_sub_map = sub_map.range();
1674 
1675  SubMap* sub_mapPtr = &sub_map;
1676  if (!sub_mapPtr) {
1677  otOut << strLocation << ": No range retrieved from sub_map. It must be "
1678  "non-existent, I guess.\n";
1679  return -1;
1680  }
1681  if (sub_map.empty()) {
1682  // Should never happen since we already made sure all the sub_maps
1683  // have data on them. Therefore if this range is empty now, it's a
1684  // chaiscript
1685  // bug (extremely unlikely.)
1686  //
1687  otOut << strLocation << ": Error: A range was retrieved for the "
1688  "sub_map, but the range is empty.\n";
1689  return -1;
1690  }
1691 
1692  int32_t nIndex = -1;
1693  for (auto it = sub_map.begin(); it != sub_map.end(); ++it) {
1694  ++nIndex;
1695  // var offer_data_pair = range_sub_map.front();
1696 
1697  if (nullptr == it->second) {
1698  otOut << strLocation << ": Looping through range_sub_map range, "
1699  "and first offer_data_pair fails to "
1700  "verify.\n";
1701  return -1;
1702  }
1703 
1704  OTDB::OfferDataNym& offer_data = *it->second;
1705  int32_t nLambda =
1706  (*the_lambda)(offer_data, nIndex, map_of_maps, sub_map,
1707  extra_vals); // if 10 offers are printed for the SAME
1708  // market, nIndex will be 0..9;
1709  if (-1 == nLambda) {
1710  otOut << strLocation << ": Error: the_lambda failed.\n";
1711  return -1;
1712  }
1713  }
1714  sub_map.clear();
1715 
1716  return 1;
1717 }
1718 
1719 OT_OTAPI_OT int32_t
1721  LambdaFunc the_lambda) // low level. map_of_maps
1722  // must be
1723  // good. (assumed.)
1724 {
1725  the_lambda_struct extra_vals;
1726  return iterate_nymoffers_maps(map_of_maps, the_lambda, extra_vals);
1727 }
1728 
1729 // extra_vals allows you to pass any extra data you want into your
1730 // lambda, for when it is called. (Like a functor.)
1731 //
1732 OT_OTAPI_OT int32_t
1733  iterate_nymoffers_maps(MapOfMaps& map_of_maps, LambdaFunc the_lambda,
1734  the_lambda_struct& extra_vals) // low level.
1735  // map_of_maps
1736  // must be good.
1737  // (assumed.)
1738 {
1739  // the_lambda must be good (assumed) and must have the parameter profile
1740  // like this sample:
1741  // def the_lambda(offer_data, nIndex, map_of_maps, sub_map, extra_vals)
1742  // //
1743  // if 10 offers are printed for the SAME market, nIndex will be 0..9
1744 
1745  string strLocation = "iterate_nymoffers_maps";
1746 
1747  // Next let's loop through the map_of_maps and output the offers for each
1748  // market therein...
1749  //
1750  // var range_map_of_maps = map_of_maps.range();
1751  MapOfMaps* map_of_mapsPtr = &map_of_maps;
1752  if (!map_of_mapsPtr) {
1753  otOut << strLocation << ": No range retrieved from map_of_maps.\n";
1754  return -1;
1755  }
1756  if (map_of_maps.empty()) {
1757  otOut << strLocation << ": A range was retrieved for the map_of_maps, "
1758  "but the range is empty.\n";
1759  return -1;
1760  }
1761 
1762  int32_t nMainIndex = -1;
1763  for (auto it = map_of_maps.begin(); it != map_of_maps.end(); ++it) {
1764  ++nMainIndex; // so we can output a header on the FIRST one only.
1765 
1766  // var sub_map_pair = range_map_of_maps.front();
1767  if (nullptr == it->second) {
1768  otOut << strLocation << ": Looping through map_of_maps range, and "
1769  "first sub_map_pair fails to verify.\n";
1770  return -1;
1771  }
1772 
1773  string strMapKey = it->first;
1774 
1775  SubMap& sub_map = *it->second;
1776  if (sub_map.empty()) {
1777  otOut << strLocation << ": Error: Sub_map is empty (Then how is it "
1778  "even here?? Submaps are only added based "
1779  "on existing offers.)\n";
1780  return -1;
1781  }
1782 
1783  if (0 == nMainIndex) // this is the first iteration of the main output
1784  // loop...
1785  {
1786  // otOut << "\n** MY OFFERS **\n\n")
1787  }
1788 
1789  int32_t nSubMap = iterate_nymoffers_sub_map(map_of_maps, sub_map,
1790  the_lambda, extra_vals);
1791  if (-1 == nSubMap) {
1792  otOut << strLocation
1793  << ": Error: while trying to iterate_nymoffers_sub_map.\n";
1794  return -1;
1795  }
1796  }
1797  map_of_maps.clear();
1798 
1799  return 1;
1800 }
OTLOG_IMPORT OTLogStream otLog4
static EXPORT int32_t createUserAccount(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2015
EXPORT OT_OTAPI_OT MapOfMaps * convert_offerlist_to_maps(opentxs::OTDB::OfferListNym &offerList)
EXPORT OT_OTAPI_OT int32_t output_nymoffer_data(const opentxs::OTDB::OfferDataNym &offer_data, int32_t nIndex, const MapOfMaps &map_of_maps, const SubMap &sub_map, the_lambda_struct &extra_vals)
static EXPORT int32_t getMarketOffers(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &MARKET_ID, const int64_t &MAX_DEPTH)
Gets all offers for a specific market and their details (up until.
Definition: OTAPI.cpp:2311
EXPORT OT_UTILITY_OT int32_t getNbrTransactionCount() const
std::string accountID
std::map< std::string, opentxs::OTDB::OfferDataNym * > SubMap
OT_OTAPI_OT int32_t SendRequestLowLevel(OTAPI_Func &theFunction, const std::string &IN_FUNCTION) const
static EXPORT void FlushMessageBuffer()
Definition: OTAPI.cpp:2339
#define OT_OTAPI_OT
int32_t nTransNumsNeeded
EXPORT static OT_OTAPI_OT void CopyVariables()
std::string to_string(const T &t)
static EXPORT int32_t activateSmartContract(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_SMART_CONTRACT)
Definition: OTAPI.cpp:1416
static EXPORT int32_t payDividend(const std::string &SERVER_ID, const std::string &ISSUER_USER_ID, const std::string &DIVIDEND_FROM_ACCT_ID, const std::string &SHARES_ASSET_TYPE_ID, const std::string &DIVIDEND_MEMO, const int64_t &AMOUNT_PER_SHARE)
PAY DIVIDEND – to shareholders.
Definition: OTAPI.cpp:2247
std::string Server
static EXPORT int32_t getMint(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ASSET_ID)
Definition: OTAPI.cpp:2089
std::string the_scale
static EXPORT int32_t getContract(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ASSET_ID)
Definition: OTAPI.cpp:2082
OTLOG_IMPORT OTLogStream otOut
static EXPORT int32_t processInbox(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID, const std::string &ACCT_LEDGER)
Definition: OTAPI.cpp:2222
static EXPORT int32_t notarizeWithdrawal(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID, const int64_t &AMOUNT)
Definition: OTAPI.cpp:2175
std::string HisAcct
OTAPI_Func_Type
static EXPORT int32_t notarizeDeposit(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID, const std::string &THE_PURSE)
Definition: OTAPI.cpp:2183
EXPORT OT_OTAPI_OT int32_t iterate_nymoffers_sub_map(const MapOfMaps &map_of_maps, SubMap &sub_map, LambdaFunc the_lambda)
EXPORT OT_OTAPI_OT opentxs::OTDB::OfferListNym * loadNymOffers(const std::string &serverID, const std::string &nymID)
static EXPORT int32_t depositPaymentPlan(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_PAYMENT_PLAN)
Definition: OTAPI.cpp:2267
EXPORT Storable * QueryObject(StoredObjectType theObjectType, std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
Definition: OTStorage.cpp:788
OT_UTILITY_OT int32_t VerifyMessageSuccess(const string &strMessage)
static EXPORT int32_t sendUserInstrument(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &USER_ID_RECIPIENT, const std::string &RECIPIENT_PUBKEY, const std::string &THE_INSTRUMENT, const std::string &INSTRUMENT_FOR_SENDER)
Definition: OTAPI.cpp:2057
string GetVariable(const char *name)
static EXPORT int32_t getBoxReceipt(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const int32_t &nBoxType, const int64_t &TRANSACTION_NUMBER)
Definition: OTAPI.cpp:576
static EXPORT int32_t Message_IsTransactionCanceled(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:2433
static EXPORT int32_t getMarketList(const std::string &SERVER_ID, const std::string &USER_ID)
Retrieves details for each market.
Definition: OTAPI.cpp:2305
std::string the_price
static EXPORT int32_t deleteAssetAccount(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID)
Definition: OTAPI.cpp:586
static EXPORT std::string LoadNymboxNoVerify(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:1519
static EXPORT int32_t issueMarketOffer(const std::string &ASSET_ACCT_ID, const std::string &CURRENCY_ACCT_ID, const int64_t &MARKET_SCALE, const int64_t &MINIMUM_INCREMENT, const int64_t &TOTAL_ASSETS_ON_OFFER, const int64_t &PRICE_LIMIT, const bool &bBuyingOrSelling, const time64_t &LIFESPAN_IN_SECONDS, const std::string &STOP_SIGN, const int64_t &ACTIVATION_PRICE)
Definition: OTAPI.cpp:2292
static EXPORT int32_t queryAssetTypes(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ENCODED_MAP)
Definition: OTAPI.cpp:2379
std::string serverID
static EXPORT int32_t Message_GetTransactionSuccess(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:2441
static EXPORT int32_t usageCredits(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &USER_ID_CHECK, const int64_t &ADJUSTMENT)
Definition: OTAPI.cpp:2032
OT_OTAPI_OT std::string SendTransaction(OTAPI_Func &theFunction, const std::string &IN_FUNCTION)
static EXPORT int32_t notarizeTransfer(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_FROM, const std::string &ACCT_TO, const int64_t &AMOUNT, const std::string &NOTE)
Definition: OTAPI.cpp:2191
static EXPORT int32_t SmartContract_CountNumsNeeded(const std::string &THE_CONTRACT, const std::string &AGENT_NAME)
Definition: OTAPI.cpp:1190
static EXPORT OTVariable * FindVariable2(const std::string &str_var_name)
Definition: OT_ME.cpp:1146
std::string the_asset_acct
EXPORT OT_UTILITY_OT int32_t getRequestNumber(const std::string &serverID, const std::string &nymID)
OT_OTAPI_OT int32_t Run() const
static EXPORT int32_t withdrawVoucher(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID, const std::string &RECIPIENT_USER_ID, const std::string &CHEQUE_MEMO, const int64_t &AMOUNT)
Definition: OTAPI.cpp:2236
std::string HisNym
static EXPORT int32_t issueBasket(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_BASKET)
Definition: OTAPI.cpp:2132
static EXPORT int32_t exchangeBasket(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &BASKET_ASSET_ID, const std::string &THE_BASKET, const bool &BOOL_EXCHANGE_IN_OR_OUT)
Definition: OTAPI.cpp:2159
std::string HisPurse
static EXPORT int32_t exchangePurse(const std::string &SERVER_ID, const std::string &ASSET_TYPE_ID, const std::string &USER_ID, const std::string &THE_PURSE)
Definition: OTAPI.cpp:1916
std::string MyPurse
static EXPORT int32_t getNym_MarketOffers(const std::string &SERVER_ID, const std::string &USER_ID)
This &quot;Market Offer&quot; data is a lot more detailed than the.
Definition: OTAPI.cpp:2326
int32_t nRequestNum
EXPORT OT_UTILITY_OT bool getTransactionNumbers(const std::string &serverID, const std::string &nymID)
EXPORT OT_UTILITY_OT void setNbrTransactionCount(int32_t new_trans_dl)
OT_UTILITY_OT bool VerifyStringVal(const std::string &nValue)
std::string Args
std::vector< std::string > the_vector
EXPORT OT_UTILITY_OT std::string ReceiveReplyLowLevel(const std::string &serverID17, const std::string &nymID, int32_t nRequestNumber8, const std::string &IN_FUNCTION)
static EXPORT int32_t issueAssetType(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_CONTRACT)
Definition: OTAPI.cpp:2075
EXPORT OT_UTILITY_OT int32_t getAndProcessNymbox_8(const std::string &serverID, const std::string &nymID, bool &bWasMsgSent, bool bForceDownload, int32_t nRequestNumber, bool &bFoundNymboxItem, bool bHarvestingForRetry, const OTfourbool &bMsgFoursome)
std::string the_currency_acct
OTLOG_IMPORT OTLogStream otWarn
static EXPORT void FlushSentMessages(const bool &bHarvestingForRetry, const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_NYMBOX)
Definition: OTAPI.cpp:2358
static EXPORT int32_t deleteUserAccount(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2021
std::array< bool, 4 > OTfourbool
static EXPORT int32_t createAssetAccount(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ASSET_ID)
Definition: OTAPI.cpp:2096
EXPORT OT_OTAPI_OT int32_t find_strange_offers(const opentxs::OTDB::OfferDataNym &offer_data, int32_t nIndex, const MapOfMaps &map_of_maps, const SubMap &sub_map, the_lambda_struct &extra_vals)
OT_OTAPI_OT std::string SendRequestOnce(OTAPI_Func &theFunction, const std::string &IN_FUNCTION, bool bIsTransaction, bool bWillRetryAfterThis, bool &bCanRetryAfterThis) const
int32_t(* LambdaFunc)(const opentxs::OTDB::OfferDataNym &offer_data, int32_t nIndex, const MapOfMaps &map_of_maps, const SubMap &sub_map, the_lambda_struct &extra_vals)
static EXPORT int32_t GetNym_TransactionNumCount(const std::string &SERVER_ID, const std::string &NYM_ID)
Definition: OTAPI.cpp:888
EXPORT bool Exists(std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
Definition: OTStorage.cpp:584
std::string MyNym
static EXPORT int32_t killMarketOffer(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ASSET_ACCT_ID, const int64_t &TRANSACTION_NUMBER)
Definition: OTAPI.cpp:2274
EXPORT OT_UTILITY_OT bool getIntermediaryFiles(const std::string &serverID, const std::string &nymID, const std::string &accountID)
std::string & GetValueString()
Definition: OTVariable.hpp:267
#define OT_TIME_ZERO
Definition: Common.hpp:180
OT_OTAPI_OT std::string SendRequest(OTAPI_Func &theFunction, const std::string &IN_FUNCTION) const
static EXPORT int32_t depositCheque(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID, const std::string &THE_CHEQUE)
Definition: OTAPI.cpp:2259
static EXPORT int32_t triggerClause(const std::string &SERVER_ID, const std::string &USER_ID, const int64_t &TRANSACTION_NUMBER, const std::string &CLAUSE_NAME, const std::string &STR_PARAM)
Definition: OTAPI.cpp:1424
std::map< std::string, SubMap * > MapOfMaps
static EXPORT int32_t killPaymentPlan(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &FROM_ACCT_ID, const int64_t &TRANSACTION_NUMBER)
Definition: OTAPI.cpp:2283
OT_OTAPI_OT void InitCustom()
static EXPORT int32_t getMarketRecentTrades(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &MARKET_ID)
Gets all recent trades (up until maximum depth)
Definition: OTAPI.cpp:2319
std::string MyAcct
EXPORT OT_OTAPI_OT int32_t iterate_nymoffers_maps(MapOfMaps &map_of_maps, LambdaFunc the_lambda)
std::string nymID
static EXPORT int32_t sendUserMessage(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &USER_ID_RECIPIENT, const std::string &RECIPIENT_PUBKEY, const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:2047
static EXPORT int32_t checkUser(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &USER_ID_CHECK)
Definition: OTAPI.cpp:2040
static EXPORT int32_t Message_GetBalanceAgreementSuccess(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:1813