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,17 +260,21 @@ class Logics():
payment_hash = payment_hash, payment_hash = payment_hash,
expires_at = expires_at) 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() order.save()
return True, {'bond_invoice':invoice,'bond_satoshis': bond_satoshis} return True, {'bond_invoice':invoice,'bond_satoshis': bond_satoshis}
@classmethod @classmethod
def gen_escrow_hodl_invoice(cls, order, user): 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 # Do not generate and cancel if an invoice is there and older than X minutes and unpaid still
print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
if order.trade_escrow: if order.trade_escrow:
# Check if status is INVGEN and still not expired # Check if status is INVGEN and still not expired
if order.taker_bond.status == LNPayment.Status.INVGEN: if order.trade_escrow.status == LNPayment.Status.INVGEN:
if order.taker_bond.created_at > (timezone.now()+timedelta(minutes=EXP_TRADE_ESCR_INVOICE)): # Expired 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 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 False, {'bad_request':'Invoice expired. You did not lock the trade escrow in time.'}
# Return the previous invoice there was with INVGEN status # Return the previous invoice there was with INVGEN status
@ -286,7 +290,7 @@ class Logics():
# Gen HODL Invoice # Gen HODL Invoice
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(escrow_satoshis, description, ESCROW_EXPIRY*3600) 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, concept = LNPayment.Concepts.TRESCROW,
type = LNPayment.Types.HODL, type = LNPayment.Types.HODL,
sender = user, sender = user,
@ -325,7 +329,7 @@ class Logics():
# If buyer, settle escrow and mark fiat sent # If buyer, settle escrow and mark fiat sent
if cls.is_buyer(order, user): 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.trade_escrow.status = LNPayment.Status.SETLED
order.status = Order.Status.FSE order.status = Order.Status.FSE
order.is_fiat_sent = True order.is_fiat_sent = True
@ -335,15 +339,13 @@ class Logics():
if not order.is_fiat_sent: 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.'} return False, {'bad_request':'You cannot confirm to have received the fiat before it is confirmed to be sent by the buyer.'}
# 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 # 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: 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.'} 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 # Double check the escrow is settled.
elif cls.pay_buyer_invoice(order): # KEY LINE - PAYS THE BUYER !! if LNNode.double_check_htlc_is_settled(order.trade_escrow.payment_hash):
if cls.pay_buyer_invoice(order): ##### !!! KEY LINE - PAYS THE BUYER INVOICE !!!
order.status = Order.Status.PAY order.status = Order.Status.PAY
order.buyer_invoice.status = LNPayment.Status.PAYING order.buyer_invoice.status = LNPayment.Status.PAYING
else: else:

View File

@ -152,22 +152,22 @@ class OrderView(viewsets.ViewSet):
else: else:
return Response(context, status.HTTP_400_BAD_REQUEST) return Response(context, status.HTTP_400_BAD_REQUEST)
# 7) If status is 'WF2'or'WTC' # 7 a. ) If seller and status is 'WF2' or 'WFE'
elif (order.status == Order.Status.WF2 or order.status == Order.Status.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: if order.maker_bond.status == order.taker_bond.status == LNPayment.Status.LOCKED:
# 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) valid, context = Logics.gen_escrow_hodl_invoice(order, request.user)
if valid: if valid:
data = {**data, **context} data = {**data, **context}
else: else:
return Response(context, status.HTTP_400_BAD_REQUEST) return Response(context, status.HTTP_400_BAD_REQUEST)
# 7.b) If user is Buyer, reply with an AMOUNT so he can send the buyer invoice. # 7.b) If user is Buyer and status is 'WF2' or 'WFI'
elif data['is_buyer']: elif data['is_buyer'] and (order.status == Order.Status.WF2 or order.status == Order.Status.WFI):
# 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) valid, context = Logics.buyer_invoice_amount(order, request.user)
if valid: if valid:
data = {**data, **context} data = {**data, **context}
@ -365,6 +365,7 @@ class BookView(ListAPIView):
# Non participants should not see the status or who is the taker # Non participants should not see the status or who is the taker
for key in ('status','taker'): for key in ('status','taker'):
del data[key] del data[key]
book_data.append(data) book_data.append(data)
return Response(book_data, status=status.HTTP_200_OK) 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, badRequest: data.bad_request,
bondInvoice: data.bond_invoice, bondInvoice: data.bond_invoice,
bondSatoshis: data.bond_satoshis, bondSatoshis: data.bond_satoshis,
escrowInvoice: data.escrow_invoice,
escrowSatoshis: data.escrow_satoshis,
badRequest: data.bad_request, badRequest: data.bad_request,
}); });
}); });
@ -211,7 +213,7 @@ export default class OrderPage extends Component {
</ListItem> </ListItem>
<Divider /> <Divider />
<ListItem> <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> </ListItem>
<LinearDeterminate /> <LinearDeterminate />
</List> </List>

View File

@ -45,6 +45,32 @@ export default class TradeBox extends Component {
</Grid> </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=()=>{ showMakerWait=()=>{
return ( return (
<Grid container spacing={1}> <Grid container spacing={1}>
@ -98,6 +124,7 @@ export default class TradeBox extends Component {
<Paper elevation={12} style={{ padding: 8,}}> <Paper elevation={12} style={{ padding: 8,}}>
{this.data.bondInvoice ? this.showInvoice() : ""} {this.data.bondInvoice ? this.showInvoice() : ""}
{this.data.isMaker & this.data.statusCode == 1 ? this.showMakerWait() : ""} {this.data.isMaker & this.data.statusCode == 1 ? this.showMakerWait() : ""}
{this.data.isSeller & this.data.escrowInvoice != null ? this.showEscrowInvoice() : ""}
</Paper> </Paper>
</Grid> </Grid>
</Grid> </Grid>