IOUs Guide
This ious guide assumes that you have already completed the TheM>Getting Started>Quick Start guide and are familiar with TheM class, TheM submodule initialization, and creating/listening for custom events. This guide also assumes that you have already installed the amplifi_mobile_sdk package into your project and placed the following minified libraries in the /lib folder of your project: axios.min.js (Optional - fetch will be used if axios is not present), crypto-js.min.js, lz-string.min.js, moment.min.js, and socket.io.min.js. In addition, you should have completed the Onboarding Guide tutorial in order to create and onboard multiple users which can be logged into your ampliFi instance. You will need one user that will act as the borrower and a different user that will act as the lender.
Note that in order to make a payment on an IOU, the IOU must first be registered and accepted by the lender, the borrower's main account must have available funds, and the back-office where the borrower's main account resides must support account to account transfers.
1. In the src folder of your project (from the Quick Start guide of the TheM Getting Started section), create a new file called ious.js
with the following code.
ious.js
const subClassesToInit = [
"accounts",
//"attachments",
//"beneficiaries",
"cards",
//"cheques",
"common",
//"companies",
//"externalAccounts",
"family",
//"fdrs",
//"fundstransfer",
//"fxrates",
//"genericRequests",
"ious",
//"messages",
//"onboarding",
//"payees",
//"remittance",
//"restrictions",
//"statics",
"user"
];
export const iousTutorial = async (subClasses = "") => {
TheM = new ClassTheM({
config: {
AFiInstanceId: "test",
modulesFolder: "",
modulesFolderOnboarding: "",
webworkerFolder: "../TheM/",
baseLibURL: "../demo/lib/",
backEndURL: AMPLIFI_CORE_URL,
socketURL: AMPLIFI_BASE_URL,
},
libs: {
}
});
//Emulate user device before initializing TheM submodules
TheM.thisDevice = {
...thisDevice,
TheM,
deviceTag: DEVICE_TAG,
};
//Initialize desired submodules
//Some modules depend on others so must be initialized together
//For instance, most submodules require the "common" subclass to be initialized
await TheM.doInit(subClasses);
//ious workflow to try
//Uncomment to run the whole workflow or follow the instructions in the browser
/*
//Prepare for logging in
//Log in using the instructions in the browser or use the doAuthenticate method from the device emulator we created during onboarding
await TheM.thisDevice.doAuthenticate(DEVICE_TAG);
//Pull fresh ious and accounts data from the server if necessary
await TheM.ious.doUpdate();
await TheM.accounts.doUpdate();
//Uncomment below to register a new IOU
//await TheM.ious.doRegister({ borrowerAFiUserId: TheM.user.AFiUserId, lenderAFiUserId: "PUT_AFiUserId_OF_LENDER_HERE", amount: 10.01, currency: "USD", narrative: "Loan request" });
//Get IouAccount instance for the current user
const iouAccountToPay = TheM.ious.forUser(TheM.user.AFiUserId);
const amountToPay = 1.01;
if (!iouAccountToPay || iouAccountToPay.transactions.length < 1) {
throw "Need to register an IOU before attempting to make a payment."
}
//Make sure there are available funds in the users main account
const mainAccountAFiAccountId = TheM.accounts.main.AFiAccountId;
console.log(`The user's main account: ${JSON.stringify(TheM.accounts.main)}`);
console.log(`The user's main account AFiAccountId: ${mainAccountAFiAccountId}`);
console.log(`The user's main account available funds: ${TheM.accounts.main.balance.available}`);
//Make a payment on the IouAccount if possible
try {
if (TheM.accounts.main.balance.available > 0) { //If the available amount is less than the amountToPay, a partial payment is still possible
await iouAccountToPay.doPay(iouAccountToPay.transactions[iouAccountToPay.transactions.length - 1], amountToPay);
} else {
throw "The source account does not have funds available";
}
} catch (err) {
console.error(err);
}
//Get the total owed by/to the current user
console.log(`TheM.ious.balance: ${JSON.stringify(TheM.ious.balance)}`);
//Logout when finished
//await TheM.user.doLogout();
*/
};
await iousTutorial(subClassesToInit.join(" "));
2. The ious module expects the user to be using some type of device so make sure the android-demo-device.js file used during onboarding is still in your /src folder.
3. Create a new file in the /demo folder of your project called ious.html with the following code.
ious.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<title>ampliFi</title>
<script>
var TheM;
var TheM_config;
</script>
<script src="../lib/socket.io.min.js"></script>
<script src="../lib/lz-string.min.js"></script>
<script src="../lib/moment.min.js"></script>
<script src="../lib/axios.min.js"></script>
<script src="../lib/crypto-js.min.js"></script>
<script type="module" src="/../src/ious.js"></script>
<style>
html {
color: white;
background-color: black;
}
</style>
</head>
<body>
<div>
Hit F12 to open the browser console.
Start working with TheM by typing "TheM" into the browser console.
</div>
<br />
<br />
<div>
1. In order to log a user in, we will need to prepare the user credentials using the encryptedServerSecret
stored locally during onboarding the company. Type the following to retrieve the encryptedServerSecret. (Or skip
steps 1-5
by using the doAuthenticate method in the device emulator like so, `await
TheM.thisDevice.doAuthenticate(DEVICE_TAG);`.)
<br /><br />
<code>let { encryptedServerSecret } = await TheM.thisDevice.retrieveLocally("encryptedServerSecret", true);</code>
<br /><br />
Type <code>encryptedServerSecret</code> into the browser console and hit enter to view the encryptedServerSecret
value.
<br /><br />
2. Since we are using an emulated android device to log in, we need to get the cryptotext value like so.
<br /><br />
<code>
let _SUPER_SECRET = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";<br />
let _dtsValueString = (new Date()).valueOf().toString();<br />
let serverSecret = CryptoJS.AES.decrypt(encryptedServerSecret, _SUPER_SECRET).toString(CryptoJS.enc.Utf8);<br />
let cryptotext = CryptoJS.AES.encrypt((TheM.thisDevice.deviceTag) + _dtsValueString, serverSecret).toString();
</code>
<br /><br />
3. Set a socket connection for bidirectional communication.
<br /><br />
<pre><code>TheM.thisDevice.halfRef = TheM.common.GetRandomSTR(40);<br />let manager = new TheM.io.Manager(TheM.config.socketURL + "?halfRef=" + TheM.thisDevice.halfRef, {<br /> autoConnect: false<br />});<br />let socket = manager.socket("/");</code></pre>
<br />
4. Open the socket connection.
<br /><br />
<pre><code>manager.connect(function (data) {<br /> console.log("established real-time comm channel for onboarding");<br /> TheM.thisDevice.isRealTimeCommAvailable = true;<br />});</code></pre>
<br />
5. Log the user in using the deviceTag obtained during onboarding and the newly created cryptotext.
<br /><br />
<pre><code>const credentials = {<br /> "dtsValueString": _dtsValueString,<br /> "deviceTag": "PUT_DEVICE_TAG_HERE",<br /> "deviceData": TheM.thisDevice.data,<br /> "channel": TheM.thisDevice.platform,<br /> "dynamicScreensVersion": TheM.thisDevice.dynamicScreensVersion,<br /> "socket": {<br /> halfRef: TheM.thisDevice.halfRef<br /> },<br /> "pushMessToken": TheM.thisDevice.pushMessToken,<br /> "cryptotext": cryptotext<br />};<br />await TheM.user.doLogin(credentials);</code></pre>
<br />
6. After authentication, pull fresh data from the server if necessary.
<br /><br />
<code>await TheM.ious.doUpdate();<br />await TheM.accounts.doUpdate();</code>
<br /><br />
7. Register a new IOU.
<br />
<pre><code>await TheM.ious.doRegister({<br /> borrowerAFiUserId: TheM.user.AFiUserId,<br /> lenderAFiUserId: "PUT_AFiUserId_OF_LENDER_HERE",<br /> amount: 10.01,<br /> currency: "USD",<br /> narrative: "Loan request"<br />});</code></pre>
8. Get IouAccount instance for the current user.
<br /><br />
<code>const iouAccountToPay = TheM.ious.forUser(TheM.user.AFiUserId);</code>
<br /><br />
9. Make sure there are available funds in the users main account.
<br /><br />
<code>TheM.accounts.main.balance.available</code>
<br /><br />
10. Make a payment on the IouAccount if possible.
<br />
<pre><code>try {<br /> if (TheM.accounts.main.balance.available > 0) { //If the available amount is less than the amountToPay, a partial payment is still possible<br /> await iouAccountToPay.doPay(iouAccountToPay.transactions[iouAccountToPay.transactions.length - 1], amountToPay);<br /> } else {<br /> throw "The source account does not have funds available";<br /> }<br />} catch (err) {<br /> console.error(err);<br />}</code></pre>
11. Keep exploring TheM.ious properties and methods and log out when finished.
<br /><br />
<code>
await TheM.user.doLogout();
</code>
<br /><br />
</div>
</body>
</html>
4. Start a server in the root folder of your project.
5. Open a browser and enter the following URL: http://localhost:8000/demo/
6. Click on the link for "ious.html" and follow the instructions to log in, register a new IOU instance, check the user's main account balance, attempt to make a payment on the IOU, and log out.