Add trade escrow box

This commit is contained in:
Reckless_Satoshi 2022-01-08 09:19:30 -08:00
parent 3a8e172a73
commit 476fcf1d6f
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
4 changed files with 63 additions and 31 deletions

View File

@ -260,22 +260,26 @@ class Logics():
payment_hash = payment_hash,
expires_at = expires_at)
# Extend expiry time to allow for escrow deposit
## Not here, on func for confirming taker collar. order.expires_at = timezone.now() + timedelta(minutes=EXP_TRADE_ESCR_INVOICE)
order.save()
return True, {'bond_invoice':invoice,'bond_satoshis': bond_satoshis}
@classmethod
def gen_escrow_hodl_invoice(cls, order, user):
# Do not generate and cancel if an invoice is there and older than X minutes and unpaid still
print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
if order.trade_escrow:
# Check if status is INVGEN and still not expired
if order.taker_bond.status == LNPayment.Status.INVGEN:
if order.taker_bond.created_at > (timezone.now()+timedelta(minutes=EXP_TRADE_ESCR_INVOICE)): # Expired
if order.trade_escrow.status == LNPayment.Status.INVGEN:
print('CCCCCCCCCCCCCCCCCCC')
if order.trade_escrow.created_at > (timezone.now()+timedelta(minutes=EXP_TRADE_ESCR_INVOICE)): # Expired
cls.cancel_order(order, user, 4) # State 4, cancel order before trade escrow locked
return False, {'bad_request':'Invoice expired. You did not lock the trade escrow in time.'}
# Return the previous invoice there was with INVGEN status
else:
return True, {'escrow_invoice':order.trade_escrow.invoice,'escrow_satoshis':order.trade_escrow.num_satoshis}
return True, {'escrow_invoice': order.trade_escrow.invoice, 'escrow_satoshis':order.trade_escrow.num_satoshis}
# Invoice exists, but was already locked or settled
else:
return False, None # Does not return any context of a healthy locked escrow
@ -286,7 +290,7 @@ class Logics():
# Gen HODL Invoice
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(escrow_satoshis, description, ESCROW_EXPIRY*3600)
order.taker_bond = LNPayment.objects.create(
order.trade_escrow = LNPayment.objects.create(
concept = LNPayment.Concepts.TRESCROW,
type = LNPayment.Types.HODL,
sender = user,
@ -325,7 +329,7 @@ class Logics():
# If buyer, settle escrow and mark fiat sent
if cls.is_buyer(order, user):
if cls.settle_escrow(order): # KEY LINE - SETTLES THE TRADE ESCROW !!
if cls.settle_escrow(order): ##### !!! KEY LINE - SETTLES THE TRADE ESCROW !!!
order.trade_escrow.status = LNPayment.Status.SETLED
order.status = Order.Status.FSE
order.is_fiat_sent = True
@ -335,15 +339,13 @@ class Logics():
if not order.is_fiat_sent:
return False, {'bad_request':'You cannot confirm to have received the fiat before it is confirmed to be sent by the buyer.'}
# Make sure the trade escrow is at least as big as the buyer invoice
if order.trade_escrow.num_satoshis <= order.buyer_invoice.num_satoshis:
return False, {'bad_request':'Woah, something broke badly. Report in the public channels, or open a Github Issue.'}
# Double check the escrow is settled.
if LNNode.double_check_htlc_is_settled(order.trade_escrow.payment_hash):
# Make sure the trade escrow is at least as big as the buyer invoice
if order.trade_escrow.num_satoshis <= order.buyer_invoice.num_satoshis:
return False, {'bad_request':'Woah, something broke badly. Report in the public channels, or open a Github Issue.'}
# Double check the trade escrow is settled
elif cls.pay_buyer_invoice(order): # KEY LINE - PAYS THE BUYER !!
if cls.pay_buyer_invoice(order): ##### !!! KEY LINE - PAYS THE BUYER INVOICE !!!
order.status = Order.Status.PAY
order.buyer_invoice.status = LNPayment.Status.PAYING
else:

View File

@ -152,27 +152,27 @@ class OrderView(viewsets.ViewSet):
else:
return Response(context, status.HTTP_400_BAD_REQUEST)
# 7) If status is 'WF2'or'WTC'
elif (order.status == Order.Status.WF2 or order.status == Order.Status.WFE):
# 7 a. ) If seller and status is 'WF2' or 'WFE'
elif data['is_seller'] and (order.status == Order.Status.WF2 or order.status == Order.Status.WFE):
# If the two bonds are locked
# If the two bonds are locked, reply with an ESCROW HODL invoice.
if order.maker_bond.status == order.taker_bond.status == LNPayment.Status.LOCKED:
valid, context = Logics.gen_escrow_hodl_invoice(order, request.user)
if valid:
data = {**data, **context}
else:
return Response(context, status.HTTP_400_BAD_REQUEST)
# 7.a) And if user is Seller, reply with an ESCROW HODL invoice.
if data['is_seller']:
valid, context = Logics.gen_escrow_hodl_invoice(order, request.user)
if valid:
data = {**data, **context}
else:
return Response(context, status.HTTP_400_BAD_REQUEST)
# 7.b) If user is Buyer and status is 'WF2' or 'WFI'
elif data['is_buyer'] and (order.status == Order.Status.WF2 or order.status == Order.Status.WFI):
# 7.b) If user is Buyer, reply with an AMOUNT so he can send the buyer invoice.
elif data['is_buyer']:
valid, context = Logics.buyer_invoice_amount(order, request.user)
if valid:
data = {**data, **context}
else:
return Response(context, status.HTTP_400_BAD_REQUEST)
# If the two bonds are locked, reply with an AMOUNT so he can send the buyer invoice.
if order.maker_bond.status == order.taker_bond.status == LNPayment.Status.LOCKED:
valid, context = Logics.buyer_invoice_amount(order, request.user)
if valid:
data = {**data, **context}
else:
return Response(context, status.HTTP_400_BAD_REQUEST)
# 8) If status is 'CHA'or '' or '' and all HTLCS are in LOCKED
elif order.status == Order.Status.CHA: # TODO Add the other status
@ -365,6 +365,7 @@ class BookView(ListAPIView):
# Non participants should not see the status or who is the taker
for key in ('status','taker'):
del data[key]
book_data.append(data)
return Response(book_data, status=status.HTTP_200_OK)

View File

@ -100,6 +100,8 @@ export default class OrderPage extends Component {
badRequest: data.bad_request,
bondInvoice: data.bond_invoice,
bondSatoshis: data.bond_satoshis,
escrowInvoice: data.escrow_invoice,
escrowSatoshis: data.escrow_satoshis,
badRequest: data.bad_request,
});
});
@ -211,7 +213,7 @@ export default class OrderPage extends Component {
</ListItem>
<Divider />
<ListItem>
<ListItemText primary={msToTime( new Date(this.state.expiresAt) - Date.now())} secondary="Expires in "/>
<ListItemText primary={msToTime( new Date(this.state.expiresAt) - Date.now())} secondary="Expires"/>
</ListItem>
<LinearDeterminate />
</List>

View File

@ -45,6 +45,32 @@ export default class TradeBox extends Component {
</Grid>
);
}
showEscrowInvoice=()=>{
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b>Deposit {this.data.escrowSatoshis} Sats as trade collateral </b>
</Typography>
</Grid>
<Grid item xs={12} align="center">
<QRCode value={this.data.escrowInvoice} size={305}/>
</Grid>
<Grid item xs={12} align="center">
<TextField
hiddenLabel
variant="filled"
size="small"
defaultValue={this.data.escrowInvoice}
disabled="true"
helperText="This is a HODL LN invoice. It will be charged once you confirm you have received the fiat."
color = "secondary"
/>
</Grid>
</Grid>
);
}
showMakerWait=()=>{
return (
<Grid container spacing={1}>
@ -98,6 +124,7 @@ export default class TradeBox extends Component {
<Paper elevation={12} style={{ padding: 8,}}>
{this.data.bondInvoice ? this.showInvoice() : ""}
{this.data.isMaker & this.data.statusCode == 1 ? this.showMakerWait() : ""}
{this.data.isSeller & this.data.escrowInvoice != null ? this.showEscrowInvoice() : ""}
</Paper>
</Grid>
</Grid>