MediaWiki API result

This is the HTML representation of the JSON format. HTML is good for debugging, but is unsuitable for application use.

Specify the format parameter to change the output format. To see the non-HTML representation of the JSON format, set format=json.

See the complete documentation, or the API help for more information.

{
    "batchcomplete": "",
    "query": {
        "pages": {
            "6": {
                "pageid": 6,
                "ns": 0,
                "title": "API",
                "revisions": [
                    {
                        "user": "FellowTraveler",
                        "timestamp": "2015-07-08T22:53:49Z",
                        "slots": {
                            "main": {
                                "contentmodel": "wikitext",
                                "contentformat": "text/x-wiki",
                                "*": "=== API Docs ===\n* [https://github.com/Open-Transactions/opentxs/blob/develop/include/opentxs/client/OT_ME.hpp#L116 High-level API (C++)]\n\n* [https://github.com/Open-Transactions/opentxs/blob/develop/include/opentxs/client/OTAPI.hpp#L71 Low-level API (C++)]\n\nThe above two APIs are wrapped with SWIG, and thus available in [https://github.com/Open-Transactions/opentxs/tree/develop/wrappers many other languages.]\n\nThe general rule of thumb is: When coding, always prefer the high-level API. Only use the low-level API for functions where no high-level API version is available. If you are writing software that uses OT, and you need to copy some sample code, just get it from [https://github.com/Open-Transactions/Moneychanger the Moneychanger GUI.]\n\n----------------------\n\nNOTE: This page is old, but preserved in case of any usefulness.\n\n=== Introduction ===\n* See the [https://github.com/FellowTraveler/Open-Transactions/blob/master/include/otapi/OTMadeEasy.h#L159 OTMadeEasy] class, as well as the sample scripts provided in [https://github.com/FellowTraveler/Open-Transactions/blob/master/scripts/demo/php/php_ot_test.php PHP] [https://github.com/FellowTraveler/Open-Transactions/blob/master/scripts/demo/python/python_ot_test.py Python] and [https://github.com/FellowTraveler/Open-Transactions/blob/master/scripts/demo/csharp/Main.cs C-Sharp].\n\n* OT's high-level API is also available in OT [https://github.com/FellowTraveler/Open-Transactions/wiki/Client-side-scripting client-side scripts]\n\n* The '''opentxs list''' and [https://github.com/FellowTraveler/Open-Transactions/wiki/opentxs opentxs help] commands display a complete list of all the OT API functions available on the command line. The actual code for those commands, written using the OT high-level API, [https://github.com/FellowTraveler/Open-Transactions/blob/master/scripts/ot/ot_commands.ot#L1288 is available here for your perusal]. This way, you can test the complete OT functionality at the command line, and then flip through the actual code for each command, and see how the OT API calls are used. '''You might be surprised how simple they really are.'''\n\n* With that as your guide, a general rule of thumb is this: Anytime you need to do something, use the [https://github.com/FellowTraveler/Open-Transactions/blob/master/include/otapi/OTMadeEasy.h#L159 high-level API] to do it. Only if you can't find the function you are looking for, should you next resort to the [https://github.com/FellowTraveler/Open-Transactions/blob/master/include/otapi/OTAPI_Basic.h#L170 low-level API]. And remember, you can always the copy the code you need from the [https://github.com/FellowTraveler/Open-Transactions/blob/master/scripts/ot/ot_commands.ot#L1288 opentxs] tool, or from the test GUI, [http://github.com/FellowTraveler/otapij otapiJ].\n\nWhat does this mean for you? It means you no longer have to worry about synchronizing request numbers, or harvesting transaction numbers, or comparing inbox hashes, or downloading your nymbox, or dropped messages, or timeouts, or retries, etc! Instead, you use simple functions like '''send_transfer''' or '''withdraw_cash'''. The high-level API manages everything else behind the scenes.\n\nThe OT high-level API (OTMadeEasy) is now available in these languages: [http://www.chaiscript.com/ ChaiScript] ( [https://github.com/FellowTraveler/Open-Transactions/blob/master/include/otapi/OTMadeEasy.h#L159 ot script] ) and Java, CSharp, PHP, Python, D, Perl, and TCL. The [https://github.com/FellowTraveler/Open-Transactions/blob/master/include/otapi/OTAPI_Basic.h#L170 low-level API] is available in D, Python, PHP, Perl, Java, etc. (Via [http://www.swig.org/ SWIG] wrappers.)\n\n=== USE CASES for the OT API ===\n\n* '''(Client software starts up.)''' Initialize the library and load the wallet.\n* Display for user: '''Server Contracts, Nyms, Accounts, and Asset Types.'''\n* Change the wallet's ''display label'' for any server, asset type, account, or nym.\n* Import a server contract (or asset contract) to the wallet.\n* Create a new '''Pseudonym''' (public/private key pair).\n* Register a public key (a ''\"Nym\"'') at an OT server.\n* '''Issue a new digital Asset Type'''. (Uploading an asset contract.)\n* Retrieve Currency Contract (by ID).\n* '''Create a new Asset Account'''.\n* '''Write a cheque''' (or invoice)\n* '''Send a Message''' to another user (via the server, encrypted to the recipient's public key.)\n* '''Deposit a cheque'''\n* '''Withdraw cash''' . . . . <==== CHAUMIAN DIGITAL CASH!!\n* '''Deposit cash'''\n* Withdraw Voucher\n* '''Account-to-Account Transfer'''\n* Create a new '''Basket Currency'''\n* '''Exchange''' Digital Assets '''in and out of Baskets''' (from your Asset Accounts)\n* '''Process your Inbox''' (Receipts and pending transfers)\n* Set up a '''Payment Plan'''\n* Issue a '''Market Offer'''\n\n-------\n\n'''Initialize the library and Load your Wallet'''\n\n(The user starts up the wallet software.)\n\nCall '''OT_API_Init()'''\n\nThen call '''OT_API_LoadWallet()'''\n\n\n(NOTE: these above 2 steps are not necessary in OT-script, only Java and other languages.)\n\n'''Display the current list of server contracts on the screen'''\n\nCall '''OT_API_GetServerCount()''', which returns the number of server contracts in your wallet.\n\nFor each one, call '''OT_API_GetServer_ID()''' to get the Server ID (which is a hash of the contract.)\n\nAlso for each, call '''OT_API_GetServer_Name()''' to get the Display Name from the contract.\n\nIn your GUI, display the name on the screen, but use the ID behind the scenes (for your messages to the server.)\n\n'''Do the same thing for Nyms, Accounts, and Asset Types.'''\n\nYou can read about them on the [[API]] page, but here are the basic functions:\n\nOT_API_GetNymCount(void);\n\nOT_API_GetServerCount(void);\n\nOT_API_GetAssetTypeCount(void);\n\nOT_API_GetAccountCount(void);\n\nOT_API_GetNym_ID() and OT_API_GetNym_Name()\n\nOT_API_GetServer_ID() and OT_API_GetServer_Name()\n\nOT_API_GetAssetType_ID() and OT_API_GetAssetType_Name()\n\nOT_API_GetAccountWallet_ID() and OT_API_GetAccountWallet_Name()\n\nAlso: \n\nOT_API_GetAccountWallet_Balance()\n\nOT_API_GetAccountWallet_Type()\n\nOT_API_GetAccountWallet_AssetTypeID()\n\n\n'''Add a new server contract (or asset contract) to the wallet'''\n\nCall '''OT_API_AddServerContract()''' \n\nor '''OT_API_AddAssetContract()'''.\n\n\n'''Create a new Pseudonym'''\n\n(Each user's wallet may contain many pseudonyms. Each Nym consists of a public and a private key, aka a \"key pair\".)\n\nCall '''OT_API_CreateNym()'''\n\nThis creates a new key pair _(\"Nym\")_ in your wallet, which you can use for communications with an OT server.\n\n(That is, for opening asset accounts and performing various other transactions. A Nym is a \"user account\".)\n\n(You can create as many of these pseudonyms as you want.)\n\n(You can register the same nyms at multiple servers.)\n\n(The same Nym will have the same Nym ID and public key on every server.)\n\nExample \n\n<pre>\ndef details_create_nym(nKeybits, strName)\n{\n    var madeEasy = OT_ME()    \n    var strNymID = madeEasy.create_pseudonym(nKeybits, \"\", \"\")  // returns new Nym ID\n    \n    if (!VerifyStringVal(strNymID))\n    {\n        OT_API_Output(0, \"details_create_nym: Failed in OT_ME::create_pseudonym(keybits == \" + nKeybits.to_string() + \")\\n\")\n        return (0)\n    }\n    OT_API_Output(0, \"Success creating! \" + nKeybits.to_string() + \" keybits, new ID: \") // stderr\n    print(strNymID) // stdout\n    OT_API_Output(0, \"\\n\") //stderr\n    // -------------------\n    var bSetName = OT_API_SetNym_Name(strNymID, // subject\n                                      strNymID, // signer\n                                      strName)\n    if (!bSetName)\n    {\n        OT_API_Output(0, \"Failed in OT_API_SetNym_Name(name == \" + strName + \")\\n\")\n        return (0)\n    }\n    // -------------------    \n    OT_API_Output(0, \"Success setting name to: \" + strName + \"\\n\\n\") // stderr\n    return 1\n}\n</pre>\n\n'''Register a public key (aka \"Nym\") at an OT server'''\n\n<pre>\n    var madeEasy\t= OT_ME()\n    if (VerifyExists(\"Server\") && VerifyExists(\"MyNym\"))\n    {        \n        var strResponse = madeEasy.register_nym(Server, MyNym)\n        var nSuccess    = VerifyMessageSuccess(strResponse)\n        switch(nSuccess)\n        {\n            case (1)\n            {\n                OT_API_Output(0, \"\\n\\n SUCCESS in register_nym! Server response:\\n\\n\");\n                print(strResponse) // stdout\n                break\n            }\n            default\n            {\n                OT_API_Output(0, \"\\n\\n Failure or Error in register_nym!\\n\")\n                \n                if (VerifyStringVal(strResponse))\n                {\n                    OT_API_Output(0, \"Server response:\\n\\n\");\n                    print(strResponse) // stdout\n                }\n                break\n            }\n        }\n</pre>\n\n'''Change the wallet's label for any server/asset type/account/nym'''\n\n(This is only a client-side label, for display purposes only.)\n\n'''OT_API_SetNym_Name()'''\n\n'''OT_API_SetAccountWallet_Name()'''\n\n'''OT_API_SetAssetType_Name()'''\n\n'''OT_API_SetServer_Name()'''\n\n----------------------------\n\n'''Issue a new digital Asset Type'''\n\nUser uploads a new currency contract to the server, so users can create asset accounts based on that asset type.\n\nServer replies with a new issuer account ID (The new Issuer account appears inside your wallet's account list, so go ahead and iterate the list again, in order to display the updated list of accounts on the screen.)\n\nHigh-level API version (in OT script):\n\n<pre>\n        var madeEasy\t= OT_ME()\n        OT_API_Output(0, \"Please paste a currency contract, followed by an EOF or a ~ by itself on a blank line:\\n\\n\")\n        var strContract = OT_CLI_ReadUntilEOF() \n        var strResponse\t= madeEasy.issue_asset_type(Server, MyNym, strContract)\n        var nStatus     = VerifyMessageSuccess(strResponse)\n        \n        switch(nStatus)\n        {\n            case (1)\n            {\n                OT_API_Output(0, \"\\n\\n SUCCESS in issue_asset! Server response:\\n\\n\");\n                print(strResponse) // stdout\n                break\n            }\n            default\n            {\n                OT_API_Output(0, \"\\n\\n Failure or error in issue_asset. nStatus: \"+nStatus.to_string()+\"\\n\")\n                if (VerifyStringVal(strResponse))\n                {\n                    OT_API_Output(0, \"Server response:\\n\\n\");\n                    print(strResponse) // stdout\n                }\n                break\n            }\n        }\n</pre>\n\n'''Retrieve Currency Contract (by ID)'''\n\nUser wants to download a currency contract from the server (for a given asset type ID.)\n\n(The asset type ID is a hash of the contract, so OT will know if you get the wrong one, since this is verified whenever a contract is loaded up.)\n\nHigh-level API version (in OT script):\n\n<pre>\n    var madeEasy\t= OT_ME()\n    var strRetrieved   = madeEasy.retrieve_contract(Server, MyNym, strContractID)\n    var nRetrieved     = VerifyMessageSuccess(strRetrieved)    \n    var strSuccess = \"ERROR\"\n    if (1 == nRetrieved)\n    {   strSuccess = \"SUCCESS\" }\n    else if (0 == nRetrieved)\n    {   strSuccess = \"FAILED\" }\n    OT_API_Output(0, \"\\n\\n \" + strSuccess + \" retrieving contract: \"+strContractID+\"\\n\\n\")\n</pre>\n\n'''Create a new Asset Account'''\n\nExample in OT Script, from the \"sample scripts\":https://github.com/FellowTraveler/Open-Transactions/tree/master/scripts/samples folder:\n\n<pre>\n    def OT_ME::create_asset_acct(SERVER_ID, NYM_ID, ASSET_TYPE_ID) \n    {\n        var ot_Msg := OTAPI_Func()\n        // -------------------------\n        var theRequest := OTAPI_Func(ot_Msg.CREATE_ASSET_ACCT, SERVER_ID, NYM_ID, ASSET_TYPE_ID)\n        var     strResponse = theRequest.SendRequest(theRequest, \"CREATE_ASSET_ACCT\")\n        \n        return strResponse\n    }\n</pre>\n\nIf it was a SUCCESS, then refresh the list of accounts in your display (from the OT API) since your new asset account should now be there.\n\n(You can also use the \"decode\" command in the test wallet anytime you want to base64-decode something.)\n\n--------------------------\n\n'''TRANSACTIONS'''\n\nFYI: Balance agreement, combined with transaction numbers, is what makes it possible for the server and all other parties to _eliminate account history, instead storing only the last signed receipt._ (Of course they have the ''choice'' to keep their own records--but they are no longer ''forced'' to do so.)\n\nIn order to do any transaction, the wallet's _balance agreement_ process requires that you have the latest copy of your account, inbox, and outbox files. You don't have to worry about this too much, since the high-level API will usually handle it for you.\n\n'''You might ask: ''\"But what if I download my account, or my outbox, and the server has maliciously inserted data into them?\"'' '''\n''No problem'' -- Open Transactions stores the last signed receipt from the server, and is able to verify the new intermediary files against that last receipt. You can see this happening when you run the command-line test client, and receipts can be verified programmatically using '''OT_API_VerifyAccountReceipt()'''.  \n\nThe [[Triple-Signed Receipts]] on Open Transactions ensure that this sort of protection is available to all parties, '''while simultaneously not having to store any transaction history!'''\n\n------------------\n\n'''Write a Cheque'''\n\nAlice writes a cheque (offline):  Call '''OT_API_WriteCheque()'''\n\nAlice then gives cheque to Bob (offline), _or_ online if she prefers via '''OT_API_sendUserMessage()''' function.\n\nIf Alice has Bob's UserID but not his public key, her wallet first uses '''OT_API_checkUser()''' to retrieve his public key from the server, and then encrypts the cheque before sending it.\n\nNOTE: a quality wallet software will keep track of ALL instruments! Even when Alice gives a cheque to Bob, her wallet should still store a copy of that cheque. Until when? Until at least after he has cashed it... when he does that, a chequeReceipt will appear in her inbox. Only when she accepts that receipt, signing a new balance agreement, is she finally free of the transaction number that was on that cheque. (It was still signed-out to her, all the way up until that time.) \n\nWHAT IF Bob had never cashed it? WHAT IF he lost it? Is Alice supposed to just keep signing for that number forever? (The chequeReceipt will never appear in her inbox. She is doomed to continue signing for this number on all of her receipts on into the future, ad infinitum, with no hope of ever closing it out!) \n\nFear not, there is a solution: '''OT_API_DiscardCheque()'''. (Lucky you saved a copy of that cheque in your wallet, eh?) This function will retrieve Alice's transaction # back from the cheque, so that her wallet is free to use it on her next valid transaction, and then close it out normally.\n\n'''Deposit a cheque'''\n\n(A voucher is also a cheque, so you may deposit a voucher here the same as any other cheque.)\n\nBob sends message to server requesting deposit: \n\n'''(High level API version, in Java.)'''\n\n<pre>\n    public boolean depositCheque(String serverID, String nymID, String accountID, String cheque) {\n\n        System.out.println(\"In depositCheque serverID:\" + serverID + \" nymID:\" + nymID + \" acount ID:\" + accountID);\n\n        // ---------------------------------------------------\n        OTAPI_Func theRequest = new OTAPI_Func(OTAPI_Func.FT.DEPOSIT_CHEQUE, serverID, nymID, accountID, cheque);\n        String strResponse = OTAPI_Func.SendTransaction(theRequest, \"DEPOSIT_CHEQUE\"); // <========================\n\n        if (null == strResponse) {\n            System.out.println(\"OTAPI_Func.SendTransaction() failed, in depositCheque.\");\n            return false;\n        }\n        // -------------------------------------------------------------------------------------- \n\n        return true;\n    }\n</pre>\n\n'''Withdraw cash'''\n\nAlice's wallet first makes sure she has the latest public mint file, by calling '''OT_API_getMint()'''.\n\n(Note: if the mint she already has is within its valid date range, there's no need to do this.)\n\n(Note: If she does call getMint, Alice needs to check the server reply and make sure it was successful before continuing with the withdrawal. The public mint keys are necessary for cash withdrawal.)\n\nAlice then withdraws from her asset account, by messaging server:  '''OT_API_notarizeWithdrawal()'''\n\nServer replies with chaumian cash, which is stored in the purse folder in local storage.\n\nHere is the full Java implementation of Withdraw Cash:\n\n<pre>\n    public boolean withdrawCash(String serverID, String nymID, String accountID, String amount) \n    {\n        String serverResponseMessage = null;\n        System.out.println(\"In withdrawCash serverID:\" + serverID + \" nymID:\" + nymID + \" acount ID:\" + accountID);\n        String assetID = otapi.OT_API_GetAccountWallet_AssetTypeID(accountID);\n\n        // ---------------------------------------- \n        // Make sure we have the proper asset contract for the withdrawal.\n        //\n        String assetContract = otapi.OT_API_LoadAssetContract(assetID);\n        if (assetContract == null) {\n            OTAPI_Func theRequest = new OTAPI_Func(OTAPI_Func.FT.GET_CONTRACT, serverID, nymID, assetID);\n            String strResponse = OTAPI_Func.SendRequest(theRequest, \"GET_CONTRACT\");\n\n            if (null == strResponse) {\n                System.out.println(\"IN withdrawCash: OTAPI_Func.SendRequest(GET_CONTRACT) failed. (I give up.) (Unable to find asset contract.)\");\n                return false;\n            }\n            // ----------------------------------------\n            assetContract = otapi.OT_API_LoadAssetContract(assetID);\n            if (assetContract == null) {\n                System.out.println(\"OT_API_LoadAssetContract returned null even after OT_API_getContract (Unable to find asset contract.)\");\n                return false;\n            }\n        }\n        // ---------------------------------------------------------\n        // Download the public mintfile if it's not there, or if it's expired.\n        // Also load it up into memory as a string (just to make sure it works.)\n        // Then we can actually send the withdrawal transaction request. (Until\n        // then, why bother?)\n        //\n        String mintFile;\n\n        // expired or missing.\n        if (1 != otapi.OT_API_Mint_IsStillGood(serverID, assetID)) \n        {\n            // ----------------------------------------\n            OTAPI_Func theRequest = new OTAPI_Func(OTAPI_Func.FT.GET_MINT, serverID, nymID, assetID);\n            String strResponse = OTAPI_Func.SendRequest(theRequest, \"GET_MINT\");\n\n            if (null == strResponse) {\n                System.out.println(\"IN withdrawCash: OTAPI_Func.SendRequest(GET_MINT) failed. (I give up.) (Unable to get mint.)\");\n                return false;\n            }\n            // ----------------------------------------\n            mintFile = otapi.OT_API_LoadMint(serverID, assetID);\n            if (mintFile == null) {\n                System.out.println(\"OT_API_LoadMint returned null even after OT_API_getMint (I give up.) (Unable to find mint.)\");\n                return false;\n            }\n        }\n        else // current mint IS available already on local storage (and not expired.)\n        {\n            mintFile = otapi.OT_API_LoadMint(serverID, assetID);\n            if (mintFile == null) {\n                System.out.println(\"OT_API_LoadMint returned null even after successful OT_API_Mint_IsStillGood (I give up.) (Unable to find mint.)\");\n                return false;\n            }\n        }        \n        // ---------------------------------------------------\n        // By this point, the mintfile is DEFINITELY good (available, not null, \n        // not expired, and loaded up.) Now we know for a fact that when the API\n        // call is made to withdraw cash, that it will find the mint properly.\n        //\n        OTAPI_Func theRequest = new OTAPI_Func(OTAPI_Func.FT.WITHDRAW_CASH, serverID, nymID, accountID, amount);\n        String strResponse = OTAPI_Func.SendTransaction(theRequest, \"WITHDRAW_CASH\"); // <========================\n\n        if (null == strResponse) {\n            System.out.println(\"OTAPI_Func.SendTransaction() failed, in withdrawCash.\");\n            return false;\n        }\n        // --------------------------------------------------------------------------------------\n\n        return true;\n    }\n</pre>\n\n'''Deposit cash'''\n\nHere is the complete Java implementation for Deposit Cash:\n\n<pre>\npublic boolean depositCash(String serverID, String nymID, String accountID, String purse, boolean isToken) {\n\n        System.out.println(\"In depositCash serverID:\" + serverID + \" nymID:\" + nymID + \" acount ID:\" + accountID + \" isToken:\" + isToken);\n        Utility.setOtDepositCash(null);\n        String oldPurse = purse;\n        if (isToken) {\n            purse = getNewPurse(purse, serverID, nymID, accountID);\n            System.out.println(\"purse after getting from push purse:\" + purse);\n            if (purse == null) {\n                Utility.setOtDepositCash(oldPurse);\n                return false;\n            }\n        }\n        // ----------------------------------------\n        OTAPI_Func theRequest = new OTAPI_Func(OTAPI_Func.FT.DEPOSIT_CASH, serverID, nymID, accountID, purse);\n        String strResponse = OTAPI_Func.SendTransaction(theRequest, \"DEPOSIT_CASH\"); // <========================\n\n        if (null == strResponse) {\n            System.out.println(\"IN depositCash: OTAPI_Func.SendTransaction(() failed. (I give up.) \");\n\n            if (isToken) {\n                System.out.println(\"IN depositCash, failed action for single token\");\n                String assetID = otapi.OT_API_GetAccountWallet_AssetTypeID(accountID);\n                boolean importStatus = otapi.OT_API_Wallet_ImportPurse(serverID, assetID, nymID, purse) == 1 ? true : false;\n                System.out.println(\"Since failure of depositCashPurse, OT_API_Wallet_ImportPurse called, status of import:\" + importStatus);\n                if (!importStatus) {\n                    Utility.setOtDepositCash(purse);\n                }\n            }\n\n            return false;\n        }\n        // ----------------------------------------\n        return true;\n    }\n</pre>\n\n--------------------------------------\n\nNote about local storage: Usually whenever something important is downloaded from the server, the OT API will save it automatically to the default storage context, and you can then load it up using another API call. This is usually the most convenient way to do things.\n\n--------------------------------------\n\n\n'''Account-to-Account Transfer'''\n\nA _pending transfer_ will go into your outbox, and the recipient's inbox, pending acceptance by the recipient.\n\nFYI, every asset account has its own inbox and outbox for handling pending transactions, as well as receipts.\n\nFYI, every Nym similarly has its own Nymbox, used for receiving messages from other users, and for receiving new transaction numbers from the server.\n\nHere is the OT Script implementation of Send Transfer, from the \"sample scripts\":https://github.com/FellowTraveler/Open-Transactions/tree/master/scripts/samples folder:\n\n<pre>\n    def OT_ME::send_transfer(SERVER_ID, NYM_ID, ACCT_FROM, ACCT_TO, AMOUNT, NOTE) \n    {\n        var ot_Msg := OTAPI_Func()\n        // -------------------------\n        var theRequest := OTAPI_Func(ot_Msg.SEND_TRANSFER, SERVER_ID, NYM_ID, ACCT_FROM, ACCT_TO, AMOUNT, NOTE)\n        var     strResponse = theRequest.SendTransaction(theRequest, \"SEND_TRANSFER\")\n        \n        return strResponse\n    }\n</pre>\n\n'''Withdraw Voucher'''\n\nA voucher is like a \"money order\" or \"cashier's cheque\".  It's a cheque, but drawn on a server account, instead of your own account.\n\nWithdrawing in voucher form is similar to withdrawing in cash: the server debits your asset account, and then gives you an official cheque.\n\nBut with cash, it's automatically saved to your purse, whereas with a voucher, you have to read the voucher out of the server reply, and display it on the screen!\n\nHere is the complete Java code to perform Withdraw Voucher:\n\n<pre>\npublic String withdrawVoucher(String serverID, String nymID, String accountID, String amount, String chequeMemo, String recepientNymID) {\n\n        System.out.println(\"In withdrawVoucher serverID:\" + serverID + \" nymID:\" + nymID + \" acount ID:\" + accountID);\n\n        // ---------------------------------------------------\n        OTAPI_Func theRequest = new OTAPI_Func(OTAPI_Func.FT.WITHDRAW_VOUCHER, serverID, nymID, accountID, recepientNymID, chequeMemo, amount);\n        String strResponse = OTAPI_Func.SendTransaction(theRequest, \"WITHDRAW_VOUCHER\"); // <========================\n\n        if (null == strResponse) {\n            System.out.println(\"OTAPI_Func.SendTransaction() failed, in withdrawVoucher.\");\n            return null;\n        }\n        // ---------------------------------------------------------\n        String ledger = otapi.OT_API_Message_GetLedger(strResponse);\n        if (ledger == null) {\n            System.out.println(\" ledger is null, returned by OT_API_Message_GetLedger, serverResponseMessage passed as argument\");\n            return null;\n        }\n        String transaction = otapi.OT_API_Ledger_GetTransactionByIndex(serverID, nymID, accountID, ledger, 0);\n        if (transaction == null) {\n            System.out.println(\"withdrawVoucher: transaction is null, returned by OT_API_Ledger_GetTransactionByIndex, argument passed, index 0 and ledger :\" + ledger);\n            return null;\n        }\n        // ---------------------------------------------------------\n        String output = otapi.OT_API_Transaction_GetVoucher(serverID, nymID, accountID, transaction);\n        System.out.println(\"output returned by OT_API_Transaction_GetVoucher:\" + output);\n\n        return output;\n    }\n</pre>\n\n\n---------------\n\n'''BASKET CURRENCIES'''\n\n'''Create a new Basket Currency'''\n\nFirst, invent the basket in your head. Give it name: _\"Clams.\"_\n\nNext, give it a ratio in terms of other existing currencies:  _\"10 Clams equals a basket of 5 dollars, 3 Euro, and 20 Bitcoin\"_\n\nCall '''OT_API_GenerateBasketCreation()''' to begin creating the basket. The _\"10 Clams\"_ from above is set here.\n\nNext, call '''OT_API_AddBasketCreationItem()''' for EACH currency in the basket. In the above example, I would call this function 3 times, in order to set the _\"5 dollars\"_ the _\"3 Euro\"_ and the _\"20 Bitcoin\"_ from above.\n\nNow that the basket has been defined, call '''OT_API_issueBasket()''' to actually create the basket currency on the server.\n\n(Now you have created a new asset type--a basket--which the server will control. Any user may now create accounts using this type!  And from there, they can write cheques, withdraw cash, trade on markets, etc. the same as with any other asset type.)\n\n\n'''Exchange Digital Assets in/out of a Basket Currency (from your Asset Accounts)'''\n\nFirst, call '''OT_API_GenerateBasketExchange()''' to setup the exchange. You'll need to know the basket's asset type, and you'll need to have an existing asset account of that type. You will also set the \"transfer multiple\" in that call. \n\nWhat's the transfer multiple? Remember the ratio above: \"10 Clams equals a basket of 5 dollars, 3 Euro, and 20 Bitcoin\" \n\nHere are examples of the transfer multiple:\n\n\"10 Clams ==    5 USD,   3 EUR,   20 BIT\" (Transfer multiple: 1)\n\n\"20 Clams ==  10 USD,   6 EUR,   40 BIT\" (Transfer multiple: 2)\n\n\"30 Clams ==  15 USD,   9 EUR,   60 BIT\" (Transfer multiple: 3)\n\n\"40 Clams ==  20 USD, 12 EUR,   80 BIT\" (Transfer multiple: 4)\n\n\"50 Clams ==  25 USD, 15 EUR, 100 BIT\" (Transfer multiple: 5)\n\nNext, call '''OT_API_AddBasketExchangeItem()''' for each currency type in the basket. You will need to to pass the asset account ID for an existing asset account, for each currency type (since you are converting in or out, from your basket account, to your asset accounts.)\n\nTherefore you will call this function once for USD, once for EUR, and once for BIT, in that example, passing in your USD asset acct ID, your EUR asset acct ID, and your Bitcoin asset account ID.\n\nNow that it's all set up, call '''OT_API_exchangeBasket()''' to actually message the server and perform the exchange.\n\n'''Interesting''': ''basket currencies themselves require no more additional system resources than normal currencies!'' The magic happens during the exchange process. The server simply stores internal asset accounts for the dollars, euros, and bitcoins (say), and it manages the issuer account for the basket, and it also manages the exchanging in and out, by moving digital assets in or out of the internal backing accounts.  After that point, a basket is just another Asset Type ID, and requires no additional resources.  You can even have baskets made up of other baskets, nested 10 times, and it won't affect the speed of operation of the server!\n\n------------------------\n\n'''PROCESSING YOUR INBOX'''\n\n'''Process the Receipts and Pending Transfers in your Inbox'''\n\nIf you wish, call '''OT_API_getInbox()''' to grab the latest inbox from the server. \n\nIn the high-level API, this is often just automated for you, but nevertheless, check out the dl_acct_files.ot script. See also show_inbox.ot, etc.\n \n During this time, your user has the opportunity to peruse the inbox, and to decide which transactions therein he wishes to accept or reject. Usually the inbox is display on the screen, then the user selects various items to accept or reject, and then the user clicks \"Process Inbox\" and then you do this:\n \nThen call '''OT_API_Ledger_CreateResponse()''' in order to create a 'response' ledger for that inbox, which will be sent to the server to signal your responses to the various inbox transactions.\n\nThen call '''OT_API_Ledger_GetCount()''' (pass it the inbox) to find out how many transactions are inside of it.  Use that count to LOOP through them...\n\nUse '''OT_API_Ledger_GetTransactionByIndex()''' to grab each transaction as you iterate through the inbox. (There are various introspection functions you can use in the API here if you wish to display the inbox items on the screen for the user...) \n\nNext call '''OT_API_Transaction_CreateResponse()''' for each transaction in the inbox, to create a response to it, accepting or rejecting it. This function creates the response and adds it to the response ledger.\n\nNext, call '''OT_API_Ledger_FinalizeResponse()''' which will create a _Balance Agreement_ for the ledger.\n\nFinally, call '''OT_API_processInbox()''' to send your message to the server and process the various items.\n\n(See the accept_inbox.ot script.)\n\nIf the message was successful, then use '''OT_API_Message_GetBalanceAgreementSuccess()''' and '''OT_API_Message_GetTransactionSuccess()''' to see just _how_ successful.\n\n---------------------------------\n\n'''MARKETS and PAYMENT PLANS'''\n\n'''Setup a Payment Plan'''\n\nThe Merchant draws up the Payment Plan using '''OT_API_ProposePaymentPlan'''\n\nThen he sends it to the Customer, who calls '''OT_API_ConfirmPaymentPlan'''\n\nThe Customer's wallet activates the payment plan by sending it to the server using this function: '''OT_API_depositPaymentPlan()'''\n\n(Receipts will process into the respective parties' inboxes.)\n\nUse OT_API_cancelCronItem() to cancel any payment plan (or market offer.)\n\nIf the message was successful, then use '''OT_API_Message_GetBalanceAgreementSuccess()''' and '''OT_API_Message_GetTransactionSuccess()''' as described above in the _deposit cash_ instructions.\n\n'''Issue a [[Markets|Market]] Offer'''\n\nCall this function: '''OT_API_issueMarketOffer()'''\n\n(That's the low-level one. See create_offer.ot script for the high-level version.)\n\nCall '''OT_API_Message_GetSuccess''' to find out if the message was a SUCCESS or FAILURE.\n\nIf the message was successful, then use '''OT_API_Message_GetBalanceAgreementSuccess()''' and '''OT_API_Message_GetTransactionSuccess()''' as described above in the _deposit cash_ instructions.\nSee the OTScript and Java versions of these calls.\n\nOnce an offer goes onto the market, multiple trades may occur between it and the other offers on the market.\n\n(According to the rules in the offers.) Receipts will process into the respective parties' inboxes after each trade.\n\n'''Cancel a Market Offer'''\n\nUse '''OT_API_cancelNymMarketOffer''' to remove an offer from a market.\n\nIf the message was successful, then use '''OT_API_Message_GetBalanceAgreementSuccess()''' and '''OT_API_Message_GetTransactionSuccess()'''\n\n'''Retrieving Market Data from OT Server:'''\n\n'''OT_API_getMarketList''' retrieves a list of all the markets available on a specific server, and details for each market. If the server call is a success, the data will be retrieved from the OT server, and written to local storage using the OT Storage API, at this path or key (inside your data_folder location): '''markets/SERVER_ID/market_data.bin'''\n\nIf you want to verify whether the data is now available in local storage (after a successful call to getMarketList), your code would look like this: \n\n'''if (otapi.Exists(\"markets\", serverID, \"market_data.bin\")) bFoundFile = true;'''\n\nHere is some Java code that reads the market list object from local storage, assuming bFoundFile is true:\n\n<pre>\n\tMarketList marketList = null;\n\tStorable storable = null;\n\n\tif (otapi.Exists(\"markets\", serverID, \"market_data.bin\")) \n\t{\n\t\tstorable =\n\t\t\totapi.QueryObject(StoredObjectType.STORED_OBJ_MARKET_LIST,\n\t\t\t\t\"markets\", serverID, \"market_data.bin\");\n\t\tif (storable==null)\n\t\t\treturn null;\n            marketList = MarketList.ot_dynamic_cast(storable);\n        }\n</pre>\n\nOnce you have the market list, here is some sample Java code to read the details of an individual market from that list:\n\n<pre>\npublic static Object getMarketDetails(String marketID)\n{\n\tMarketList marketList = Utility.getMarketList();\n\n\tif (marketList == null) \n\t{\n\t\treturn null;\n\t}\n\n\tfor (int i=0; i < marketList.GetMarketDataCount(); i++)\n\t{\n\t\tMarketData marketData = marketList.GetMarketData(i);\n\n\t\tif (marketData == null)\n\t\t\tcontinue;\n\n\t\tString [] row = new String[2];\n\n\t\tif (marketID.equals(marketData.getMarket_id())) \n\t\t{\n\t\t\tString[] data = new String[2];\n\t\t\tmarketData.getLast_sale_price();\n\t\t\tmarketData.getCurrent_ask();\n\t\t\t\n\t\t\t// Etc!! This is where you get the market details.\n\t\t}\n\t}\n\n\t// return custom object here (row/data or whatever), or null if failure..\n\treturn null;\n}\n</pre>\n\n'''OT_API_getMarketOffers''' retrieves publicly-available info for all offers on a specific market, up until maximum depth, and saves the data here: '''markets/SERVER_ID/offers/MARKET_ID.bin'''\n\n(See testwallet/OTAPI.i for ALL DATA OBJECTS that are used in local storage, including market offers, recent trades, etc. See the code above for a sample on how those data objects are used.)\n\n'''OT_API_getMarketRecentTrades''': Retrieves all recent trades on a market (up until maximum depth), and stores them here: '''markets/SERVER_ID/recent/MARKET_ID.bin'''\n\nTo retrieve the offers that a specific Nym has out on the market, use: '''OT_API_getNym_MarketOffers'''\n\nThis _getNym_MarketOffers_ data is _private_ and thus a lot more detailed than what's retrieved via '''OT_API_Market_GetOffers''', which is more meant for public use. \n\nAfter a successful retrieval, you can load the data from this location: '''nyms/SERVER_ID/offers/NYM_ID.bin'''\n\nIf you want to see the Nym's private list of his ''completed trades'', the path to load it from is here:\n\n'''nyms/trades/SERVER_ID/NYM_ID'''\n\nThere is no need to send a server message in this last case--just read the data from local storage directly. (When market trading receipts are accepted and cleared out of your inbox, this is where they will go. So there's no need to download them, since they were already downloaded through your inbox previously.)\n\nAs before, the appropriate data object can be found in testwallet/OTAPI.i along with all the others.\n\n----------------------\n\nI will be very responsive to developer needs and questions regarding the OT API, so I encourage you to play with the software and contact me anytime.\n\nSee also:\n\n[[Opentxs | opentxs command-line tool]]\n\n[[List of Classes | The OT C++ class library]]\n\n[[OTX | The OTX protocol]]"
                            }
                        },
                        "comment": "slight re-arrangement"
                    }
                ]
            },
            "1": {
                "pageid": 1,
                "ns": 0,
                "title": "Main Page",
                "revisions": [
                    {
                        "user": "FellowTraveler",
                        "timestamp": "2019-07-21T19:34:32Z",
                        "slots": {
                            "main": {
                                "contentmodel": "wikitext",
                                "contentformat": "text/x-wiki",
                                "*": "== Open-Transactions ==\n\n'''[http://www.opentransactions.org/open-transactions.pdf Click here for white paper.]'''\n\nThe Open-Transactions project is a collaborative effort to develop a robust, commercial-grade, fully-featured, '''free-software toolkit''' implementing the [[OTX|OTX protocol]] as well as a full-strength '''financial cryptography''' [[List_of_Classes|library]], API, GUI, command-line interface, and prototype notary server. The project is managed by a worldwide community of volunteers that use the Internet to communicate, plan, and develop the Open-Transactions toolkit and its related documentation.\n\n===Financial Cryptography===\n\nFinancial cryptography means using using strong cryptographic techniques to create secure financial instruments, such as digital signing to create non-repudiable contracts, and encryption to create untraceable digital cash. In OT, transactions are unforgeable, receipts are destructible, and balances cannot be falsified or changed without user consent. OT is able to prove all balances, as well as which instruments are valid, and which transactions have closed, without storing any history except the last signed receipt.\n\nOpen-Transactions implements financial instruments as Ricardian Contracts; contracts which can be understood both by humans and manipulated by software. \n\nAll contracts in Open-Transactions use the same basic structure: all parties involved sign an agreement which is notarized by an independent third party witness. This technique is known as [[Triple-Signed Receipts]]. Importantly, transactions are formed and signed on the client side first, before being notarized by any server. An OT client is thus ensured that an OT notary server cannot falsify his receipts against his will, since the server can't forge the client's signature.\n\nThis basic structure can be built upon to create many types of financial instruments.\n\n===Financial Instruments===\n\nFinancial instruments are any representation of a financial agreement between two or more parties.\n\nThe simplest financial instrument is a deposit agreement. A custodian of some asset (legal tender, or maybe gold) stores it on behalf of a depositor and agrees to redeem it on demand when presented with proof of a valid claim on the asset.\n\nOther types of financial instruments include securities, of which there can be many variations. A security is an instrument that entitles the bearer to a certain revenue stream, either because it represents a loan or perhaps because it represents equity in a business.\n\nFinancial instruments in Open-Transactions have an issuer, who creates the contracts and is responsible for fulfilling the terms, and one or more bearers. Financial instruments are liabilities of the issuer owed to the bearers.\n\n===Working with Financial Instruments===\n\nOpen-Transactions is designed to provide the highest security possible for both the issuers and bearers of financial instruments. Servers in Open-Transactions act as notaries which can witness and confirm balances, but cannot change them. Every party associated in a financial instrument can prove their balance to any other party, and no party can alter the balance of any other party without their agreement. Even a malicious notary cannot do this.\n\nOpen-Transactions represents quantities of a given unit type as deposit agreements, which are signed by the bearer and a notary.\n\nPortions of a balance may be transferred between users via several asset-independent transaction types, including:\n\n; Transfers\n: An atomic movement of funds from one account to a different account, like a bank account-to-account transfer.\n; Cheques\n: A payment which is not deducted from the sender's account until the recipient claims it.\n; Vouchers\n: A payment which is deducted from the senders account at the time of creation.\n; Invoices\n: A payment request which the recipient can opt to pay from any of his accounts.\n; Cash\n: Anonymous cryptographic tokens which can be securely redeemed by the recipient without revealing the sender.\n; Market offers\n: Open agreements to exchange a given quantity of one instrument type for a given quantity of another instrument type.\n; Smart Contracts\n: Customizable agreements between multiple parties, containing user-defined scripted clauses, hooks, and variables.\n\n==Use Cases==\n\n===Encouraged use cases===\n\nEncouraged uses cases are officially supported by Open-Transactions.\n\n====Deposit accounting====\n\nEntities that hold assets on behalf of depositors can use Open-Transactions to issue promissory notes as negotiable instruments.\n\nExamples of such depositories includes:\n\n* Precious metals\n* Central bank currencies\n* Cryptocurrencies\n\n====Payments====\n\nUsers of OT negotiable instruments can authorize recurring payments to pay for services which operate on a billing cycle.\n\n====Bearer Securities====\n\nThe negotiable instruments created by Open-Transactions can be used as the basis for financial products such as loans.\n\n===Discouraged use cases===\n\nDiscouraged use cases are not supported by Open-Transactions, either because they violate the security requirements, or because they conflict with the philosophical goals of the project.\n\nIn many cases, discouraged use cases may be achievable, but users are required to create and support their own smart contracts.\n\n====Third party balance editing====\n\nThe only entity in Open-Transactions that can edit a balance is the holder of that balance receipt. Open-Transactions does not and will not include any functionality to bypass this design decision.\n\n------------------\n\n=== More Information ===\n\n[http://opentransactions.org/wiki/index.php/About About Open-Transactions]\n\nThis product includes software developed by Ben Laurie for use in the [https://github.com/benlaurie/lucre Lucre] project.\n\nCredit for the OT logo goes to: [http://www.michpalmer.com/ moltenmich]\n\n=== Mailing list and IRC ===\n\nMailing list: [email protected]\n\n[http://opentransactions.org/mailman/listinfo/ot-dev_opentransactions.org Subscribe to mailing list]\n\nIRC channel: '''#opentransactions''' on irc.freenode.net\n\n=== Sponsors and Contributors ===\n\nThe OT community gratefully acknowledges the support and contributions of the following individuals and businesses to OT development: Chris Odom, Cameron Garnham, Randy Waterhouse, [[Monetas]].\n\n=== Install Programs ===\n\n[http://nightowl.cc/Moneychanger.dmg Mac OSX install for Moneychanger GUI] Self-contained.\n<br />Note: This Mac install of Moneychanger includes the notary server as well.<br />It can be found at: /Applications/moneychanger-qt.app/Contents/MacOS/opentxs-notary\n\n[https://bitcointalk.org/index.php?topic=77301.msg859040#msg859040 (old) Windows binary installer ]\n\n=== White Paper ===\n\n[http://www.opentransactions.org/open-transactions.pdf Open-Transactions White Paper]\n\n=== Source Code ===\n\n[http://github.com/Open-Transactions/opentxs Open-Transactions source code on github] (core library, client API, and 'opentxs' command-line client)\n\n[http://github.com/Open-Transactions/opentxs-notary Notary server source code on github] (Install OT core first)\n\n[http://github.com/Open-Transactions/Moneychanger Moneychanger GUI source code on github] (Install OT core first, and then build Moneychanger with the latest version of Qt Creator)"
                            }
                        },
                        "comment": ""
                    }
                ]
            }
        }
    }
}