UI improvements

This commit is contained in:
sairaj mote 2023-09-07 18:10:55 +05:30
parent a1351ae2b3
commit 2aec3d297f
5 changed files with 312 additions and 151 deletions

View File

@ -183,6 +183,7 @@ details summary {
align-items: center;
gap: 0.5rem;
color: var(--accent-color);
font-weight: 500;
}
details summary .down-arrow {
fill: var(--accent-color);
@ -773,6 +774,14 @@ h3 {
width: 1.2em;
}
.loan {
display: grid;
gap: 1rem;
background-color: rgba(var(--foreground-color), 1);
padding: max(1rem, 1.5vw);
border-radius: 0.5rem;
}
.loan-process {
display: grid;
gap: 1rem;
@ -781,6 +790,22 @@ h3 {
border-radius: 0.5rem;
--progress-line-thickness: 0.15rem;
}
.loan-process__type {
position: relative;
padding-bottom: 0.5rem;
color: rgba(var(--text-color), 0.8);
}
.loan-process__type::before {
content: "";
position: absolute;
height: 0.2rem;
width: 40%;
left: 0;
bottom: 0;
transform: translateY(-50%);
border-radius: 0 0.5rem 0.5rem 0;
background-color: var(--accent-color);
}
.loan-process ul {
display: grid;
}

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -165,6 +165,7 @@ details summary {
align-items: center;
gap: 0.5rem;
color: var(--accent-color);
font-weight: 500;
.down-arrow {
fill: var(--accent-color);
}
@ -729,6 +730,13 @@ h3 {
}
}
}
.loan {
display: grid;
gap: 1rem;
background-color: rgba(var(--foreground-color), 1);
padding: max(1rem, 1.5vw);
border-radius: 0.5rem;
}
.loan-process {
display: grid;
gap: 1rem;
@ -736,6 +744,22 @@ h3 {
padding: max(1rem, 1.5vw);
border-radius: 0.5rem;
--progress-line-thickness: 0.15rem;
&__type {
position: relative;
padding-bottom: 0.5rem;
color: rgba(var(--text-color), 0.8);
&::before {
content: "";
position: absolute;
height: 0.2rem;
width: 40%;
left: 0;
bottom: 0;
transform: translateY(-50%);
border-radius: 0 0.5rem 0.5rem 0;
background-color: var(--accent-color);
}
}
ul {
display: grid;
li {

View File

@ -530,7 +530,7 @@
} else {
notify('Loan request sent to collateral provider', 'success')
}
location.hash = '#/home/my-loans'
location.hash = '#/home/in-process'
closePopup()
} catch (err) {
console.error(err)
@ -645,9 +645,9 @@
const {
loanOpeningProcessID,
borrower, isBorrower, coborrower, isCoborrower, lender, isLender, loanAmount, policyID,
initiationTime, loanRequestTime, loanResponseTime, collateralLockAckTime,
initiationTime, loanRequestTime, loanResponseTime, collateralLockAckTime, loanIssuedTime,
hasProvidedCollateral, hasAgreedToLend, hasRequestedCollateralLock, hasLockedCollateral, hasIssuedLoan, hasRequestedCollateralRefund,
collateralRequestID, loanRequestID, loanResponseID, collateralLockRequestID, collateralLockAckID
collateralRequestID, loanRequestID, loanResponseID, collateralLockRequestID, collateralLockAckID, loanID
} = details
return Component(() => {
const [verifyingCollateral, setVerifyCollateral] = useState(false)
@ -706,7 +706,8 @@
await btcMortgage.sendLoanAmount(collateralLockAckID, borrower, coborrower, await floDapps.user.private)
notify('Loan issued successfully', 'success')
} catch (err) {
notify(err.message, 'error')
notify(err.message || err, 'error')
console.error(err)
} finally {
setIsIssuingLoan(false)
}
@ -773,131 +774,200 @@
openPopup('request_details_popup')
}
return html`
<li class="loan-process">
<div class="flex align-center gap-1 space-between">
<p>Loan request: ${loanOpeningProcessID}</p>
<button class="button button--colored button--small" onclick=${showLoanRequestDetails}>View details</button>
</div>
<ul>
${!isLender ? html`
<li class=${`${hasProvidedCollateral ? 'done' : ''}`}>
<li class="loan-process">
<div class="flex align-center gap-1 space-between">
${isBorrower ? html`
<h4 class="loan-process__type">Borrowing</h4>
`: html`
${isCoborrower ? html`
<h4 class="loan-process__type">Co-borrowing</h4>
`: html`
<h4 class="loan-process__type">Lending</h4>
`
}
`}
<button class="button button--colored button--small" onclick=${showLoanRequestDetails}>View details</button>
</div>
<ul>
${!isLender ? html`
<li class=${`${hasProvidedCollateral ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
<div class="line"></div>
</div>
<div class="details">
<h4>Initiated loan request</h4>
${hasProvidedCollateral ? html`
<time>${getFormattedTime(initiationTime)}</time>
`: html`
${isCoborrower ? html`
<p>Verify that you have <b>${formatAmount(collateralAmount)}</b> as collateral</p>
<button class="button button--primary margin-right-auto" disabled=${verifyingCollateral} onclick=${verifyCollateral}>
${verifyingCollateral ? html`
Verifying collateral
<sm-spinner class="margin-left-0-5"></sm-spinner>
`: html`
Verify collateral
`}
</button>
`: html`
<p>Waiting for Co-Borrower to confirm collateral availability</p>
`}
`}
</div>
</li>
`: ''}
<li class=${`${hasAgreedToLend ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
<div class="line"></div>
</div>
<div class="details">
<h4>Initiated loan request</h4>
${hasProvidedCollateral ? html`
<time>${getFormattedTime(initiationTime)}</time>
${hasAgreedToLend ? html`
<h4>Started lending process</h4>
<time>${getFormattedTime(loanResponseTime)}</time>
`: html`
${isCoborrower ? html`
<p>Verify that you have <b>${formatAmount(collateralAmount)}</b> as collateral</p>
<button class="button button--primary margin-right-auto" disabled=${verifyingCollateral} onclick=${verifyCollateral}>
${verifyingCollateral ? html`
Verifying collateral
<h4>Waiting for a lender</h4>
<p>Your loan request has been posted to the marketplace. Waiting for a lender to start lending process.</p>
`}
</div>
</li>
<li class=${`${hasLockedCollateral ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
<div class="line"></div>
</div>
<div class="details">
${hasLockedCollateral ? html`
<h4>Collateral locked</h4>
${hasLockedCollateralForMoreThan24Hours ? html`
${hasRequestedCollateralRefund ? html`
<p>Collateral refund requested. It'll be refunded within 24 hrs.</p>
`: 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`
<time>${getFormattedTime(collateralLockAckTime)}</time>
`}
`: html`
<h4>Waiting for collateral to be locked</h4>
<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}>
${lockingCollateral ? html`
Locking collateral
<sm-spinner class="margin-left-0-5"></sm-spinner>
`: html`
Lock collateral
`}
</button>
`: html`
<button class="button button--primary margin-right-auto" onclick=${requestCollateralLock}>Request collateral lock</button>
`}
`: ''}
`}
</div>
</li>
<li class=${`${hasIssuedLoan ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
</div>
<div class="details">
${hasIssuedLoan ? html`
<h4>Loan issued</h4>
<time>${getFormattedTime(loanIssuedTime)}</time>
`: html`
${hasLockedCollateral && isLender ? html`
<button class="button button--primary margin-right-auto" disabled=${isIssuingLoan} onclick=${issueLoan}>
${isIssuingLoan ? html`
Issuing loan
<sm-spinner class="margin-left-0-5"></sm-spinner>
`: html`
Verify collateral
Issue loan
`}
</button>
`: html`
<p>Waiting for Co-Borrower to confirm collateral availability</p>
<h4>Waiting for loan to be issued</h4>
`}
`}
</div>
</li>
`: ''}
<li class=${`${hasAgreedToLend ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
<div class="line"></div>
</div>
<div class="details">
${hasAgreedToLend ? html`
<h4>Started lending process</h4>
<time>${getFormattedTime(loanResponseTime)}</time>
`: html`
<h4>Waiting for a lender</h4>
<p>Your loan request has been posted to the marketplace. Waiting for a lender to start lending process.</p>
`}
</div>
</li>
<li class=${`${hasLockedCollateral ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
<div class="line"></div>
</div>
<div class="details">
${hasLockedCollateral ? html`
<h4>Collateral locked</h4>
${hasLockedCollateralForMoreThan24Hours ? html`
${hasRequestedCollateralRefund ? html`
<p>Collateral refund requested. It'll be refunded within 24 hrs.</p>
`: 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`
<time>${getFormattedTime(collateralLockAckTime)}</time>
`}
`: html`
<h4>Waiting for collateral to be locked</h4>
<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}>
${lockingCollateral ? html`
Locking collateral
<sm-spinner class="margin-left-0-5"></sm-spinner>
`: html`
Lock collateral
`}
</button>
`: html`
<button class="button button--primary margin-right-auto" onclick=${requestCollateralLock}>Request collateral lock</button>
`}
`: ''}
`}
</div>
</li>
<li class=${`${hasIssuedLoan ? 'done' : ''}`}>
<div class="progress">
<div class="circle"></div>
</div>
<div class="details">
${hasIssuedLoan ? html`
<h4>Loan issued</h4>
`: html`
${hasLockedCollateral && isLender ? html`
<button class="button button--primary margin-right-auto" disabled=${isIssuingLoan} onclick=${issueLoan}>
${isIssuingLoan ? html`
Issuing loan
<sm-spinner class="margin-left-0-5"></sm-spinner>
`: html`
Issue loan
`}
</button>
`: html`
<h4>Waiting for loan to be issued</h4>
`}
`}
</div>
</li>
</ul>
</li>
`
</ul>
<p class="margin-left-auto">Request ID: #${loanOpeningProcessID}</p>
</li>
`
})()
},
loan(loanID) {
const {
blocktime, borrower, borrower_sign, btc_start_rate,
coborrower, coborrower_sign, collateral_lock_id, collateral_value,
lender, lender_sign, loan_amount, loan_id, loan_opening_process_id, loan_transfer_id,
open_time, policy_id, } = btcMortgage.loans[loanID]
return html`
<li class="loan">
<sm-copy value=${loan_id} clip-text>
<p>Loan ID: ${loan_id}</p>
</sm-copy>
<div class="flex flex-wrap gap-1-5 align-items-start">
<div class="grid gap-0-3">
<p>Loan amount</p>
<b>${formatAmount(loan_amount, 'usd')}</b>
</div>
<div class="grid gap-0-3">
<p>Collateral amount</p>
<b>${formatAmount(collateral_value)}</b>
</div>
<div class="grid gap-0-3">
<p>Duration</p>
<b>${btcMortgage.policies[policy_id]?.duration}</b>
</div>
<div class="grid gap-0-3">
<p>Interest</p>
<b>${btcMortgage.policies[policy_id]?.interest * 100}% p.a</b>
</div>
<div class="grid gap-0-3">
<p>Loan start date</p>
<b>${getFormattedTime(open_time)}</b>
</div>
</div>
<details>
<summary>
Borrower details
<svg class="icon down-arrow" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M24 24H0V0h24v24z" fill="none" opacity=".87"></path><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z"></path></svg>
</summary>
<div class="grid gap-1-5">
<div class="grid">
<p>Borrower</p>
<sm-copy value=${getBtcAddress(borrower)}>
<b>${getBtcAddress(borrower)}</b>
</sm-copy>
</div>
${!floCrypto.isSameAddr(borrower, coborrower) ? html`
<div class="grid">
<p>Collateral provider</p>
<sm-copy value=${getBtcAddress(coborrower)}>
<b>${getBtcAddress(coborrower)}</b>
</sm-copy>
</div>
`: ''}
</div>
</details>
</li>
`
}
}
// routing logic
const router = new Router({
@ -1060,6 +1130,7 @@
let userAddressTimeInterval;
function renderHome(appState) {
const { lastPage, page, params: { } = {}, wildcards: [section = 'my-loans'] = [] } = appState || {};
const balanceCard = Component(() => {
const [btcBalance, setBtcBalance] = useState(floGlobals.memoBalance['BTC'])
const [floBalance, setFloBalance] = useState(floGlobals.memoBalance['FLO'])
@ -1164,7 +1235,8 @@
} else {
// user homepage
const inbox = Component(() => {
const { borrowed, coborrowed, lent } = groupLoanProcess()
const inProcessRequests = groupLoanProcess()
const { borrowed, coBorrowed, lent } = groupLoans()
const [view, setView] = useState(section)
let loanRequests = [];
for (const key in floGlobals.loanRequests) {
@ -1178,25 +1250,29 @@
setView(e.target.value)
}
if (
coborrowed.length === 0 && view === 'coborrowed'
|| lent.length === 0 && view === 'lent'
|| loanRequests.length === 0 && view === 'lend'
coBorrowed.length === 0 && view === 'coBorrowed' ||
lent.length === 0 && view === 'lent' ||
loanRequests.length === 0 && view === 'lend'
) {
// if no loans in coborrowed or lent or loan requests, redirect to my-loans
// if there are no loans in the selected view, switch to my-loans
history.replaceState(null, null, `#/home/my-loans`)
setView('my-loans')
}
return html`
<section class="grid gap-1">
<sm-chips onchange=${handleChange}>
<sm-chip value="in-process" selected=${view === 'in-process'}>
In process
${inProcessRequests.length ? html`<span class="badge">${inProcessRequests.length}</span>` : ''}
</sm-chip>
<sm-chip value="my-loans" selected=${view === 'my-loans'}>
My Loans
My loans
${borrowed.length ? html`<span class="badge">${borrowed.length}</span>` : ''}
</sm-chip>
${coborrowed.length ? html`
<sm-chip value="coborrowed" selected=${view === 'coborrowed'}>
Coborrowed
<span class="badge">${coborrowed.length}</span>
${coBorrowed.length ? html`
<sm-chip value="coBorrowed" selected=${view === 'coBorrowed'}>
Co-borrowed
<span class="badge">${coBorrowed.length}</span>
</sm-chip>
` : ''}
${lent.length ? html`
@ -1216,7 +1292,7 @@
${view === 'my-loans' ? html`
${borrowed.length ? html`
<ul class="grid gap-1">
${borrowed.map(loan => render.loanProcess(loan))}
${borrowed.map(loan => render.loan(loan))}
</ul>
<a href="#/apply-loan" class="button button--primary margin-right-auto">Apply for a new loan</a>
`: html`
@ -1229,9 +1305,25 @@
</div>
`}
`: ''}
${view === 'coborrowed' && coborrowed.length ? html`
${view === 'in-process' ? html`
${inProcessRequests.length ? html`
<ul class="grid gap-1">
${inProcessRequests.map(loan => render.loanProcess(loan))}
</ul>
<a href="#/apply-loan" class="button button--primary margin-right-auto">Apply for a new loan</a>
`: html`
<div class="grid gap-2 align-center justify-center" style="padding: 2vw 0;">
<div class="grid gap-0-5">
<h1>Looking for USD loans?</h1>
<p>Get a loan against your BTC collateral</p>
</div>
<a href="#/apply-loan" class="button button--primary margin-right-auto">Apply for a loan</a>
</div>
`}
`: ''}
${view === 'coBorrowed' && coBorrowed.length ? html`
<ul class="grid gap-1">
${coborrowed.map(loan => render.loanProcess(loan))}
${coBorrowed.map(loan => render.loanProcess(loan))}
</ul>
`: html``}
${view === 'lent' && lent.length ? html`
@ -1240,13 +1332,12 @@
</ul>
`: html``}
${view === 'lend' ? html`
<div class="grid gap-2 align-center justify-center" style="padding: 2vw 0;">
<div class="grid">
<h2>Earn interest on your USD tokens</h2>
<p>Lend your USD tokens to earn interest assured by BTC collateral.</p>
<div class="grid gap-2 align-center justify-center" style="padding: 2vw 0;">
<div class="grid">
<h2>Earn interest on your USD tokens</h2>
<p>Lend your USD tokens to earn interest assured by BTC collateral.</p>
</div>
</div>
</div>
${loanRequests.length ? html`
<ul id="loan_requests_list">
${loanRequests.reverse().map(requestId => render.loanRequest(requestId, floGlobals.loanRequests[requestId]))}
@ -1289,6 +1380,8 @@
for (const key in allMessages) {
const { message: { borrower, coborrower, loan_amount, policy_id, loan_opening_process_id, lender, loan_request_id, collateral_lock_id } = {}, type, time } = allMessages[key];
if (!loan_opening_process_id) continue
if (Object.values(btcMortgage.loans).find(loan => loan.loan_opening_process_id === loan_opening_process_id))
continue // Loan is already open
if (!loansInProcess[loan_opening_process_id]) {
loansInProcess[loan_opening_process_id] = {
loanOpeningProcessID: loan_opening_process_id,
@ -1358,17 +1451,36 @@
return Object.values(loansInProcess).sort((a, b) => {
return (b.initiationTime || b.loanResponseTime) - (a.initiationTime || a.loanResponseTime)
})
.reduce((acc, loan) => { // group by borrower, coborrower and lender
if (loan.isBorrower)
acc.borrowed.push(loan)
else if (loan.isCoborrower)
acc.coborrowed.push(loan)
else if (loan.isLender)
acc.lent.push(loan)
// .reduce((acc, loan) => { // group by borrower, coborrower and lender
// if (loan.isBorrower)
// acc.borrowing.push(loan)
// else if (loan.isCoborrower)
// acc.coBorrowing.push(loan)
// else if (loan.isLender)
// acc.lending.push(loan)
// return acc
// }, {
// borrowing: [],
// coBorrowing: [],
// lending: []
// })
}
function groupLoans() {
console.log(btcMortgage.loans)
return Object.values(btcMortgage.loans)
.reduce((acc, loan) => {
const { loan_id, borrower, coborrower, lender } = loan
if (floCrypto.isSameAddr(borrower, floDapps.user.id) && floCrypto.isSameAddr(coborrower, floDapps.user.id))
acc.borrowed.push(loan_id)
else if (floCrypto.isSameAddr(coborrower, floDapps.user.id))
acc.coBorrowed.push(loan_id)
else if (floCrypto.isSameAddr(lender, floDapps.user.id))
acc.lent.push(loan_id)
return acc
}, {
borrowed: [],
coborrowed: [],
coBorrowed: [],
lent: []
})
}

View File

@ -535,7 +535,7 @@
if (token_tx.transactionDetails.senderAddress != floCrypto.toFloID(lender))
return reject("Sender is not lender");
if (token_tx.parsedFloData.tokenAmount !== loan_amount)
return reject("Token amount doesnot match the loan amount");
return reject("Token amount doesn't match the loan amount");
resolve(true);
}).catch(error => reject(error))
})
@ -572,7 +572,7 @@
floBlockchainAPI.getTx(closing_txid).then(tx => {
let closing_details = parseLoanCloseData(tx.floData, tx.txid, tx.time);
if (loan_id !== closing_details.loan_id)
return reject("Closing doesnot match the loan ID")
return reject("Closing doesn't match the loan ID")
getLoanDetails(closing_details.loan_id).then(loan_details => {
validateLoanClosing(loan_details, closing_details)
.then(result => resolve(Object.assign(loan_details, closing_details)))
@ -585,7 +585,7 @@
const validateLoanClosing = btcMortgage.validateLoanClosing = function (loan_details, closing_details) {
return new Promise((resolve, reject) => {
if (closing_details.loan_id !== loan_details.loan_id)
return reject("Closing doesnot belong to this loan")
return reject("Closing doesn't belong to this loan")
if (!floCrypto.validateFloID(closing_details.borrower))
return reject("Invalid borrower floID");
if (closing_details.borrower != loan_details.borrower)
@ -655,7 +655,7 @@
floBlockchainAPI.getTx(failure_txid).then(tx => {
let failure_details = parseLoanFailData(tx.floData, tx.txid, tx.time);
if (loan_id !== failure_details.loan_id)
return reject("Failure doesnot match the loan ID")
return reject("Failure doesn't match the loan ID")
getLoanDetails(failure_details.loan_id).then(loan_details => {
validateLoanFailure(loan_details, failure_details)
.then(result => resolve(Object.assign(loan_details, failure_details)))
@ -668,7 +668,7 @@
const validateLoanFailure = btcMortgage.validateLoanFailure = function (loan_details, failure_details) {
return new Promise((resolve, reject) => {
if (failure_details.loan_id !== loan_details.loan_id)
return reject("Failure doesnot belong to this loan")
return reject("Failure doesn't belong to this loan")
if (!floCrypto.validateFloID(failure_details.lender))
return reject("Invalid lender floID");
if (failure_details.lender != loan_details.lender)
@ -1076,7 +1076,7 @@
let lender_floID = floCrypto.toFloID(lender);
floTokenAPI.getBalance(lender_floID, CURRENCY).then(lender_tokenBalance => {
if (lender_tokenBalance < loan_amount)
return reject(RequestValidationError(TYPE_LENDER_RESPONSE, "lender doesnot have sufficient funds to lend"));
return reject(RequestValidationError(TYPE_LENDER_RESPONSE, "lender doesn't have sufficient funds to lend"));
result.lender = lender;
result.lender_pubKey = pubKey;
resolve(result);
@ -1237,12 +1237,12 @@
}
//for retrying failsafe
btcOperator.retryFailSafe = function (fail_safe_id) {
btcOperator.retryFailSafe = function (fail_safe_id, privKey) {
return new Promise((resolve, reject) => {
compactIDB.readData("fail_safe", fail_safe_id).then(fail_safe_data => {
let { borrower, coborrower } = parseLoanOpenData(fail_safe_data);
let receivers = [borrower, coborrower].map(addr => floCrypto.toFloID(addr));
floBlockchainAPI.writeDataMultiple([privKey], loan_blockchain_data, receivers).then(loan_txid => {
floBlockchainAPI.writeDataMultiple([privKey], fail_safe_data, receivers).then(loan_txid => {
compactIDB.removeData("fail_safe", fail_safe_id); //remove fail safe as data is added to blockchain
resolve(loan_txid)
}).catch(error => reject(error))
@ -1552,7 +1552,7 @@
getLoanDetails(loan_id).then(loan_details => {
let policy = POLICIES[loan_details.policy_id];
if (isNaN(policy.pre_liquidation_threshold))
return reject("This loan policy doesnot allow pre-liquidation");
return reject("This loan policy doesn't allow pre-liquidation");
getRate["USD"].then(cur_btc_rate => {
if (cur_btc_rate >= loan_details.btc_start_rate)
return reject("BTC rate hasn't reduced from the start rate");
@ -1636,7 +1636,7 @@
return reject(RequestValidationError(TYPE_PRELIQUATE_COLLATERAL_REQUEST, "Loan already closed"));
let policy = POLICIES[loan_details.policy_id];
if (isNaN(policy.pre_liquidation_threshold))
return reject("This loan policy doesnot allow pre-liquidation");
return reject("This loan policy doesn't allow pre-liquidation");
getRate["USD"].then(cur_btc_rate => {
if (cur_btc_rate >= loan_details.btc_start_rate)
return reject(RequestValidationError(TYPE_PRELIQUATE_COLLATERAL_REQUEST, "BTC rate hasn't reduced from the start rate"));
@ -1726,7 +1726,7 @@
if (tx.ins.some(i => i.outpoint.hash !== collateral_lock_id))//vin other than this collateral is present in tx, ABORT
return reject("Transaction Hex contains other/non collateral inputs");
if (tx.ins.length != collateral_utxos.length)
return reject("Transaction hex doesnot contain full collateral as input")
return reject("Transaction hex doesn't contain full collateral as input")
//check output
let return_amount = total_collateral_value - liquidate_amount;
if (return_amount > 0) {