Code Monkey home page Code Monkey logo

gap-microfinance's People

Contributors

bharatchhabra avatar morkeltry avatar parissai avatar

Watchers

 avatar  avatar

Forkers

gitter-badger

gap-microfinance's Issues

isIdBoxRegistered()

Interrogates IDBox blockchain to find if borrowerEthAddr is registered.
While no access to IDbox blockchain, use dummy structure : #8

Takes ( borrowerEthAddr, phoneNo, callback ) as params.
phoneNo is accepted only for compatibility with future functionality.

Will eventually call callback with a repaymentSchedule as params,
but for now, will just call callback with a truthy or falsey value.

Serve endpoints

Set up express,
Get a server running which is capable of serving endpoints and has routes for the endpoints in #5, #6 #8, #24 & #25 plus a route /sms for Twilio webhook. Comment out if unused.

We will probably need static pages served as well.
Liase with @jignasheth407 to find out if using React, file structure, etc.
EDIT - Looks like she's aiming to use Bootstrap 3.

Endpoint to link eth address to phone number

For demoing - In finished product, this should be done using IDbox.

USE SECURITY!

Preferably JWT, but at the least, IP whitelist or password check.
-this endpoint will be open to the world, even on localhost.

The results will not look like the IDbox blockchain in any case, so we can use any data structure and means of storage, if the dummy isIdBoxregistered() #18 matches the structure.

It is worth developing a hashing mechanism so that phone numbers are not discernable from the blockchain (though this is probably impossible is we keep the functionality of being able to search by ethAddress).

Twilio

  • Create webhook for SMS receipt
  • Use Twilio trial details
  • Use ngrok to start

Android caches pages

So that redirects always have the same status regardless of external changes.

Is cachebusting easy in jade?
Using the proper TTLs may be better.

investigate error in signup POST

mySQL connection
con.connect(function(err) => stuff)

throws:
Error: Cannot enqueue Handshake after already enqueuing a Handshake.
after attempting to connect more than once.

Move connection to start of file, or else test for connection before attempting connect.

/hasloanoffer

Mock of #23,
checking db for loan offers.

Accepts borrowerEthAddr as params,
responds with empty object if no offers or, if offer exists,

{ borrowerEthAddr,
 lenderName,
 amount,
 duration,  //  = endDate - startDate
 tx }

where

tx = {
  from: borrowerEthAddr,
  to: contractAddr,  // use env2 to set this as app constant - '0x12345' is fine
  gasPrice: "9000000000",
  gas: "85000",
  data: ""
};

as in #5

Twilio StatusCallBack url

How to set Status Callback URL for Twiml App? i mean can we use one status Callback URL for Video Calling, Voice Calling or need to set separately?

Lender portal: Lend Money page

Performs GET request to /registeroffer, passing lenderEthAddr as parameter

and expects to receive an array of objects { id; startDate; endDate; amount; duration; repaymentSchedule; lenderName; lenderEthAddr; borrowerEthAddr; txWithdraw; txRegister} representing offered loans in response.
(Some properties may be missing from the response object)

Don't use the red background. Please use something more like the login page.

Display text part of logo at top of screen.

The box at the top contains ' Hi, lenderName', with lenderEthAddr below it in the box in a lighter font-color. Logout should be below that in the box.

List returned objects with:

  • borrower address - Shorten this to the form 0x1234...cdef
  • story - shorten this to 15 characters, but include a hover which brings up full story as modal.
  • amount - in QI
  • history - this is an SVG, which is retrieved from /historyimg?borrower=0x76543 where 0x76543 is borrowerEthAddr. The SVG will be a bar chart, but you can use any SVG, as long as the request it makes for the file includes a variable querystring depending on the previously retrieved data.
  • duration - if no duration property was received, the calculate it from endDate - startDate
  • repaymentSchedule in the form (5+5+5+5+5+5+5+5) where the 5s are the days (ie the keys not the values) of repaymentSchedule. This may be up to 24 repayments long, but can be small text.
  • a button: Offer Loan, which calls a dummy function sendTx() with txRegister as parameter.

None of the items in this list need a heading (like amount, or repayments) - the data is enough.

The list should be scrollable at the bottom in case it contains a lot of items.
Once scrolled, the top of the visible list should show a 'Top' button to scroll the list back tot he top.

The bottom part of the screen should be a button to an offered loans page (don't build that page, just make the button) and this button should always be visible at the bottom of the screen.

hasActiveLoan()

Interrogates blockchain to find if borrowerEthAddr has a current loan.

Takes ( borrowerEthAddr, callback ) as params.

Will eventually call callback with a repaymentSchedule as params,
but for now, will just call callback with a truthy or falsey value.

Onboarding flow: phone number page

The submit button ('Register') will either take user to auth page, or to loans flow branching logic, depending on the result of isIdBoxregistered(ethAddr, phoneNo).

isIdBoxregistered() is asychronous and takes a callback as its third parameter - which will be called with either a truthy value, or false.
If truthy, user goes to loans flow branching logic,
if false, user goes to auth page

This check can be done on the click/ submit event of 'Register', or before rendering auth page, as appropriate for the framework.

Loans flow - route branching logic

Route to one of the 3 possible loans pages: repayments, eligibility and apply.
Note this is a change from yesterday's flow diagram.

Create dummy functions hasActiveLoan() and hasLoanOffer() and mock these functions so that they return (for testing purposes)

Make 2 async calls to the functions and await results.

if `hasActiveLoan (ethAddr) 
\\ route to repayments
else if hasLoanOffer (ethAddr)
\\ route to apply
else
\\ route to eligibility

Show attractive loading screen while waiting for results (eg GAP graphic from upwork)

set up database

and distribute secrets on gitter

We will discuss this, but at first guess:

  • BORROWERS:
    {ethAddr; phoneNo}
  • LENDERS:
    {id; name; capitalAvailable; minAmount; maxAmount; minduration; maxDuration; preferredAmount; preferredDuration}
  • OFFERED:
    { id; startDate; endDate; amount; repaymentSchedule; lenderName; lenderEthAddr; BorrowerEthAddr}
  • ACCEPTED:
    {id; fullyPaid; startDate; endDate; amount; repaymentSchedule; lenderName; lenderEthAddr; BorrowerEthAddr}
  • HISTORIES: (copy of blockchain data)
    {BorrowerEthAddr; lenderEthAddr; startDate; endDate; earlyRepaymentDays; lastSyncAddress}

repaymentSchedule should be an stringified object with numbered keys (cumulativeDays) having properties cumulativeAmount.
So a loan of QI100 issued on the 4th with repayments due of QI25 on the 9th, 14th, 19th and 24th of the month would have

repaymentSchedule = {
  '5': 25, 
  '10': 25, 
  '15': 25, 
  '20': 25 
}

to reduce on-chain processing.

Loans flow - eligiblity page

Makes call to dummy function getHistory(ethAddr), calls both populate(creditIndication()) on the response, which is expected to be an array of strings.

Renders all elements, constant height

Credit History shows 'None' until populated.
large middle element shows GAP background graphic until populated (ie once eligibility is a number)
Apply button has 0.75 opacity until populated, but is always active unless deactivated (or, if using top-down state, if eligibility===0)

write creditIndication() function which takes either an array of strings, 0 or -1 as argument and returns if array: array.length*150
if zero: 100
if -1 : -1

write populate() which populates middle element as shown in flow diagram and sets Apply opacity to 0.75 if eligibilty is -1, 1.0 otherwise

Make pages responsive

Especially for small mobile screens.
Everything should function and be presentable (no horizontal scroll bars, no elements overflowing outside their visible sections/ backgrounds) on all screen sizes, even 240x320

Loan decision endpoint

I suggest name the endpoint /offers

Accepts as params the fields from Apply page form #14, plus borrower eth address,

  • Borrower eth address
  • Amount
  • Duration (days)
  • History (may be array, 0 (no history) or -1 (do not lend))
  • Story (optional - for future functionality)

Compare these to lender's settings from db.
Choose a lender (based on preferences?)

EDIT:
If borrower has a loan offer in db already, use that.
/EDIT

If borrower meets criteria for a loan and does not already have anything outstanding on a loan
store details as an 'offer' in db and
respond with an object containing tx: a smart contract transaction object with as many mandatory fields filled as poss, AND a unique nonce.
See transaction structure and comment.
data field is a todo for later #21.

Liase with @jignasheth407 #14

Set an environment variable CONTRACT_ADDR in .env and use this in tx as to:

db_build.js for mySQL

Assume mySQL is installed and a database user has been created and has permissions.
Make a .js script which uses the existing user details, stored in a .env file and populates the mySQL database from the queries in /server/database/db_build.sql

The code can be copied direct from /server/database/db_build.js and modified for mySQL.

hasLoanOffer()

Interrogates blockchain to find if borrowerEthAddr has a loan offered.

Takes ( borrowerEthAddr, callback ) as params.

If loan offer exists, calls callback with (amount, duration, lenderEthAddr).
Otherwise does nothing.

If short of time will be mocked using an endpoint

Loans flow - Apply page

Text as in flow diagram.

Before render, make async call to hasLoanOffer(ethAddr)
If this returns an array, populate page with result, expecting:
result [2] to be Lender Name,
result [1] to be Duration in days,
result [3] to be Amount

Render form with
inputs:

  • Lender Name (hidden until populated, never editable)
  • Amount
  • Duration ___ days
  • Your Story
  • acceptTx (does not display)
  • rejectTx (does not display)

buttons :

  • Check Loan Offers (visible until populated; posts to loan decision endpoint /offers #5 - liase with @Parissai; Submitting this button awaits response from that endpoint and calls populate() with the result)
  • Take This Loan (hidden until populated; calls dummy function acceptLoan(acceptTx) )
  • Reject (hidden until populated; calls dummy function rejectLoan(acceptTx) ; this button can be smaller if it helps design)

Take this Loan and Reject buttons occupy the space on screen which was previously taken by Check Loan Offers.

page requires a populate() function which:

  • accepts an object with values for the inputs
  • populates the form inputs accordingly
  • makes LenderName field visible
  • removes or hides Check Loan Offers
  • and displays Take This Loan and Reject in its place.

Loans smart contract

which stores:

  • Loans made:
    {BorrowerEthAddr -> startDate; endDate; lenderEthAddr; amount; amountRepaid; scheduledRepayments (cumulativeDays -> cumulativeAmount) }
  • Histories:
    {BorrowerEthAddr -> startDate -> lenderEthAddr; startDate; endDate; earlyRepaymentDays}

and emits:

  • Loans made
  • Repayments made

Retrieve loan details endpoint

Accepts as params: borrower's eth address,
Responds with: details of the loan previously accepted by borrower.

Should map a repaymentSchedule object into an array of objects {date, amount}

Do not include loans where fullyPaid == true;
If not unpaid loans can be found, returns empty array.

Onboarding flow (frontend)

  • Check for existence of Metamask / Ethereum and branch to welcome page or phone number page
    See #17
  • Auth page (generate a short code to SMS to +44 123 44 806 14 instead of 'GAP')
    See #20
  • branch to SMS page or phone number page (use dummy logic function)
    See #19, #20
  • Beautiful welcome page :)
    See #17
  • Enter phone number page
    See #19

routing logic for repayments page

Currently /signup and /info redirect straight to /loan_offer where user is IDbox registered.
We will need to check if they already have a loan and redirect to a route for repyaments (check what already exists for this)

Tweak Apply page (loans-flow-3)

Use either top or bottom half of logo and/or background it.

Ensure values in amount prepended with 'QI '

Change 'Your Story', in consultation with Helena/ Ola if necessary.

Colour 'Check Loan Offers' and move upwards level with 'Story' textbox

Appropriate relative shading for 'Check Loan Offers' / 'Take This Loan' depending on populate()

Add Lender info

/registeroffer

endpoint accepts as params:

lenderEthAddr
and, optionally,
{ id; startDate; endDate; duration; repaymentSchedule; lenderName; lenderEthAddr; BorrowerEthAddr}

OR
offers: stringified array of { id; startDate; endDate; duration; repaymentSchedule; lenderName; lenderEthAddr; BorrowerEthAddr}objects.


If only lenderEthAddr provided, then retrieve an array of offers made by that lender from db, excluding those which are also in accepted loans.
If more fields than lenderEthAddr are provided, wrap params object in array.
If offers passed, unwrap into array

Filter array keeping only objects where
all of { duration; lenderEthAddr; BorrowerEthAddr } provided or
all of { startDate; endDate; lenderEthAddr; BorrowerEthAddr } provided

For each object, calculate startDate; endDate; duration if missing.

For each object, add two properties txWithdraw & txRegister which are clones of each other:

= {
  from: borrowerEthAddr,
  to: contractAddr,  // use env2 to set this as app constant - '0x12345' is fine
  gasPrice: "9000000000",
  gas: "85000",
  data: ""
};

as in #5

and respond with stringified resulting array

Onboarding flow: auth page

Page receives ethAddr and phoneNo.

The Done button should white fade the whole screen, except the button itself and
call isIdBoxregistered(ethAddr, phoneNo, branch)
where branch is a callback taking one parameter.

If that parameter is true, it causes user be taken to loans flow branching logic
If false, white fade is removed, and the middle text 'but you need to link your IDbox phone number' is changed to 'your phone number has not yet registered with IDbox'

isIdBoxregistered() can be called on the click/ submit event of 'Done' or, alternatively, before rendering the page, as appropriate for the framework.

IdBoxregistered(ethAddr, phoneNo) v3- websocket

(In onbording-3)
Await connection over websocket via (result of /ws-get-addy || 127.0.0.1 ) + /ws-listener.
If no connection, fallback to random.
If possible, create websocket listener as separate npm process.

ethAddress / IDbox ID registration contract

to be accessed from server.

Stores:
ethAddress -> (current) phoneNo

Emits:
ethAddress -> phoneNo

Need to brainstorm on protecting personal details.
For multiple lenders, this may require choosing between multiple one-of-many hash secrets and a shared lender hash secret.

Loans flow frontend

  • route branching logic - chooses between repayments and eligibility pages (use dummy logic)
    See #13
  • Apply for loan form / page
    See #14
  • Eligibility page (create a populate() function which populates page with values from an array)
    See #15
  • Repayments due page
    See #16

Onboarding flow: Welcome / explanation page

First render our beautiful welcome page,
then run redirectIfOnboard():
Check for Metamask (if (web3) will do this. If you don't have Metamask, do the check, but spoof the variable as true or false for testing)
set ethAddr = web3.eth.accounts[0] - if you don't have Metamask, then spoof with ethAddr = '0x654321';
We will use ethAddr all through both flows, so if not using state, this must be passed from page to page.

function redirectIfOnboard() {
  if (web3) {
     ethAddr =web3.eth? web3.eth.accounts[0] : '0x654321';
     /// route to phone number page
}}

For demo purposes set a listener for click anywhere on screen, which sets web3= true then calls redirectIfOnboard(). But comment out (don't delete) the listener once tested - we will use it for later testing.

loans-1 page

remove hardcoded table
style responsive table

Loan flow: repayments page

GET from endpoint /retrieve in #6 (liase with @Parissai ), passing ethAddr as params

Render all elements constant height - no text in Repayments and Repayment Instructions until populated.

Repayments will be populated with response of GET, which will include repayments: an array of objects {date, amount} (Amount is in QI so 25 -> 'QI 25')
Refresh links back to loans flow branch logic
Repayment Instructions will be populated with a button named 'Send to X' where X is the property tx.to from the result of the GET. This button calls a function repay (tx);

Write mock repay function :
setTimeout ( {\\ link back to loans flow branch logic as if Refresh was clicked}, 500)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.