Feature update

-- added option to request collateral refund if lender fails to issue loan
This commit is contained in:
sairaj mote 2023-09-05 03:18:45 +05:30
parent de4db1915c
commit fb41ba1617
5 changed files with 88 additions and 35 deletions

View File

@ -858,7 +858,7 @@ h3 {
display: flex;
flex-direction: column;
justify-items: flex-start;
gap: 1.5rem;
gap: 1rem;
background-color: rgba(var(--foreground-color), 1);
padding: 1rem;
border-radius: 0.5rem;

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -812,7 +812,7 @@ h3 {
display: flex;
flex-direction: column;
justify-items: flex-start;
gap: 1.5rem;
gap: 1rem;
background-color: rgba(var(--foreground-color), 1);
padding: 1rem;
border-radius: 0.5rem;

View File

@ -410,7 +410,7 @@
currency,
maximumFractionDigits: currency === 'usd' ? 2 : 8,
currencyDisplay: 'code'
}).slice(3)
}).slice(4)
if (currency === 'usd')
return `$ ${formattedAmount}`
else
@ -550,6 +550,7 @@
loanRequest(requestId, details) {
const { message: { borrower, coborrower, collateral: { btc_id, quantity, rate }, loan_amount, loan_collateral_req_id, loan_opening_process_id, policy_id }, vectorClock } = details;
const { duration, interest } = btcMortgage.policies[policy_id];
const isRequester = floCrypto.isSameAddr(borrower, floGlobals.myFloID) || floCrypto.isSameAddr(coborrower, floGlobals.myFloID)
const [isLending, setIsLending] = useState(false)
async function startLendingProcess() {
const confirmation = await getConfirmation('Start lending process?', { message: `You'll be participating in loan lending. Continue?`, confirmText: 'Continue', cancelText: 'Cancel' })
@ -557,6 +558,8 @@
return;
setIsLending(true)
btcMortgage.respondLoan(vectorClock, borrower, coborrower).then(() => {
floCloudAPI.sendApplicationData({ loan_opening_process_id }, 'in_process_loan_request')
.catch(error => console.log(error))
notify('Lending process started successfully.', 'success')
router.routeTo(location.hash)
}).catch(err => {
@ -569,7 +572,7 @@
return html`
<li class="loan-request">
${loan_opening_process_id ? html`
<p>Loan request: ${loan_opening_process_id}</p>
<p>${isRequester ? 'Your loan' : 'Loan'} request: ${loan_opening_process_id}</p>
`: ''}
<div class="flex flex-wrap align-items-start gap-1-5">
<div class="grid gap-0-3">
@ -611,6 +614,7 @@
`: ''}
</div>
</details>
${!isRequester ? html`
<button class="button button--primary margin-left-auto" onclick=${startLendingProcess} disabled=${isLending}>
${isLending ? html`
Starting lending process
@ -619,6 +623,7 @@
Start lending
`}
</button>
`: html``}
`
},
loanProcess(details = {}) {
@ -626,10 +631,9 @@
loanOpeningProcessID,
borrower, isBorrower, coborrower, isCoborrower, lender, isLender, loanAmount, policyID,
initiationTime, loanRequestTime, loanResponseTime, collateralLockAckTime,
hasProvidedCollateral, hasAgreedToLend, hasRequestedCollateralLock, hasLockedCollateral, hasIssuedLoan,
hasProvidedCollateral, hasAgreedToLend, hasRequestedCollateralLock, hasLockedCollateral, hasIssuedLoan, hasRequestedCollateralRefund,
collateralRequestID, loanRequestID, loanResponseID, collateralLockRequestID, collateralLockAckID
} = details
console.log(details)
return Component(() => {
const [verifyingCollateral, setVerifyCollateral] = useState(false)
let collateralAmount = 0
@ -668,7 +672,6 @@
setLockingCollateral(false)
}
}
// TODO: UI for coborrower to request collateral lock
async function requestCollateralLock() {
btcMortgage.requestCollateralLock(loanResponseID, coborrower, lender, await floDapps.user.private).then(() => {
notify('Collateral lock request sent successfully', 'success')
@ -688,6 +691,33 @@
}
}
// check if loan hasn't been issued even after 24 hours of collateral lock
let hasLockedCollateralForMoreThan24Hours = false
useEffect(() => {
if (isCoborrower && hasLockedCollateral && !hasIssuedLoan) {
const currentTime = new Date().getTime()
const timeDiff = currentTime - collateralLockAckTime
if (timeDiff > 86400000) {
hasLockedCollateralForMoreThan24Hours = true
}
}
}, [hasLockedCollateral, hasIssuedLoan])
const [requestingCollateralRefund, setRequestingCollateralRefund] = useState(false)
async function requestCollateralRefund() {
const confirmation = await getConfirmation('Request collateral refund?', { message: `You are about to request for collateral refund. Continue?`, confirmText: 'Request', cancelText: 'Cancel' })
if (!confirmation)
return;
try {
setRequestingCollateralRefund(true)
await btcMortgage.requestBanker.refundCollateral(collateralLockAckID, borrower, lender, await floDapps.user.private)
notify('Collateral refund requested successfully', 'success')
} catch (err) {
notify(err, 'error')
} finally {
setRequestingCollateralRefund(false)
}
}
return html`
<li class="loan-process">
<p>Loan request: ${loanOpeningProcessID}</p>
@ -743,9 +773,25 @@
<div class="details">
${hasLockedCollateral ? html`
<h4>Collateral locked</h4>
${hasLockedCollateralForMoreThan24Hours && !hasRequestedCollateralRefund ? html`
<p>
Loan has not been issued even after 24 hours of collateral lock.
You can request for collateral refund.
</p>
<button class="button button--primary margin-right-auto" disabled=${requestCollateralRefund} onclick=${requestCollateralRefund}>
${requestingCollateralRefund ? html`
Requesting collateral refund
<sm-spinner class="margin-left-0-5"></sm-spinner>
`: html`
Request collateral refund
`}
</button>
`: html`
<p>Collateral refund requested. It'll be refunded within 24 hrs.</p>
`}
`: html`
<h4>Waiting for collateral to be locked</h4>
<p>Loan borrower needs to lock collateral before loan can be issued.</p>
<p>${isCoborrower ? 'You need' : 'Loan co-borrower needs'} to lock collateral before loan can be issued.</p>
${hasAgreedToLend && (isBorrower || isCoborrower) ? html`
${floCrypto.isSameAddr(borrower, coborrower) ? html`
<button class="button button--primary margin-right-auto" disabled=${lockingCollateral} onclick=${lockCollateral}>
@ -974,8 +1020,6 @@
for (const key in floGlobals.loanRequests) {
const { message: { borrower, coborrower, loan_opening_process_id } } = floGlobals.loanRequests[key]
if (!loan_opening_process_id) continue // TODO: remove this check after all requests are updated
if (floCrypto.isSameAddr(borrower, floGlobals.myFloID) || floCrypto.isSameAddr(coborrower, floGlobals.myFloID))
continue // if user is borrower or coborrower, don't show loan request
if (floGlobals.inProcessRequests.has(loan_opening_process_id)) continue // if loan request is in process, don't show loan request
loanRequests.push(key)
}
@ -1204,6 +1248,11 @@
loansInProcess[loan_opening_process_id].hasLockedCollateral = true
loansInProcess[loan_opening_process_id].collateralLockAckID = key
break;
case 'type_refund_collateral_request':
loansInProcess[loan_opening_process_id].refundCollateralRequestTime = time
loansInProcess[loan_opening_process_id].refundCollateralRequestID = key
loansInProcess[loan_opening_process_id].hasRequestedCollateralRefund = true
break;
}
}
// sort by time
@ -1320,12 +1369,13 @@
console.info(result)
Promise.allSettled([
new Promise((resolve, reject) => {
btcMortgage.viewMyInbox(d => {
btcMortgage.viewMyInbox((d, e) => {
if (e) return
floGlobals.myInbox = {
...floGlobals.myInbox,
...d
}
console.log('INBOX', d)
console.log('MY INBOX', d)
if (floGlobals.loaded) {
router.routeTo(window.location.hash)
}
@ -1335,7 +1385,8 @@
})
}),
new Promise((resolve, reject) => {
btcMortgage.listLoanRequests(d => {
btcMortgage.listLoanRequests((d, e) => {
if (e) return
floGlobals.loanRequests = {
...floGlobals.loanRequests,
...d
@ -1350,19 +1401,22 @@
})
}),
new Promise((resolve, reject) => {
btcMortgage.viewMyOutbox(d => {
btcMortgage.viewMyOutbox((d, e) => {
if (e) return
floGlobals.myOutbox = {
...floGlobals.myOutbox,
...floGlobals.myOutbox || {},
...d
}
console.log('OUTBOX', d)
console.log('MY OUTBOX', d)
if (floGlobals.loaded) {
router.routeTo(window.location.hash)
}
resolve()
}).then(d => {
floGlobals.myOutbox = d;
console.log('OUTBOX', d)
floGlobals.myOutbox = {
...floGlobals.myOutbox || {},
...d
}
})
.catch(error => {
reject(error)
@ -1371,9 +1425,9 @@
new Promise((resolve, reject) => {
floCloudAPI.requestApplicationData('in_process_loan_request', {
callback: (d, e) => {
console.log('IN PROCESS LOAN REQUEST', d)
if (e) return
parseInProcessRequests(d)
console.log('IN PROCESS LOAN REQUEST', d)
if (floGlobals.loaded) {
router.routeTo(window.location.hash)
}

View File

@ -308,7 +308,7 @@
function validateAndStoreLoanFailDetails(t) {
return new Promise((resolve, reject) => {
if (!t.senders.has(BANKER_ID)) //Data not authorised by banker, abort
if (!t.senders.has(BANKER_ID)) //Data not authorized by banker, abort
return resolve(null);
let failure_details = parseLoanFailData(t.data, t.txid, t.time);
compactIDB.readData("loans", failure_details.loan_id).then(loan_details => {
@ -1077,9 +1077,6 @@
compactIDB.addData("outbox", result, result.vectorClock);
resolve(result);
}).catch(error => reject(error))
floCloudAPI.sendApplicationData({ loan_opening_process_id }, 'in_process_loan_request')
.catch(error => console.log(error))
}).catch(error => reject(error))
}).catch(error => reject(error))
}).catch(error => reject(error))
@ -1420,13 +1417,14 @@
const coborrower = floDapps.user.id;
let coborrower_pubKey = floDapps.user.public;
validate_collateralLock_ack(collateral_lock_ack_id, borrower, coborrower, lender).then(result => {
let { lender_pubKey, collateral_lock_id } = result;
let { lender_pubKey, collateral_lock_id, loan_opening_process_id } = result;
let locker = findLocker(coborrower_pubKey, lender_pubKey)
//create the tx hex and sign it
createUnlockCollateralTxHex(locker, collateral_lock_id, privKey).then(unlock_tx_hex => {
floCloudAPI.sendApplicationData({
borrower, coborrower, lender,
collateral_lock_ack_id, unlock_tx_hex
collateral_lock_ack_id, unlock_tx_hex,
loan_opening_process_id
}, TYPE_REFUND_COLLATERAL_REQUEST)
.then(result => {
compactIDB.addData("outbox", result, result.vectorClock);
@ -1845,5 +1843,6 @@
btcMortgage.policies = POLICIES;
btcMortgage.loans = LOANS;
btcMortgage.banker.id = BANKER_ID;
})(window.btcMortgage = {})