mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-29 15:23:34 +03:00
Add trade escrow box
This commit is contained in:
parent
3a8e172a73
commit
476fcf1d6f
@ -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:
|
||||
|
35
api/views.py
35
api/views.py
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user