Add address submission and validation checks

This commit is contained in:
Reckless_Satoshi 2022-06-13 15:27:09 -07:00
parent c4396f504a
commit 8f93c8f7b6
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
4 changed files with 86 additions and 12 deletions

View File

@ -1,5 +1,5 @@
from datetime import timedelta
from tkinter import N
from tkinter import N, ON
from django.utils import timezone
from api.lightning.node import LNNode
from django.db.models import Q, Sum
@ -7,6 +7,7 @@ from django.db.models import Q, Sum
from api.models import OnchainPayment, Order, LNPayment, MarketTick, User, Currency
from api.tasks import send_message
from decouple import config
from api.utils import validate_onchain_address
import gnupg
@ -550,7 +551,7 @@ class Logics:
if suggested_mining_fee_rate > 50:
suggested_mining_fee_rate = 50
onchain_payment.suggested_mining_fee_rate = LNNode.estimate_fee(amount_sats=preliminary_amount)["mining_fee_rate"]
onchain_payment.suggested_mining_fee_rate = max(1.05, LNNode.estimate_fee(amount_sats=preliminary_amount)["mining_fee_rate"])
onchain_payment.swap_fee_rate = cls.compute_swap_fee_rate(onchain_payment.balance)
onchain_payment.save()
@ -621,6 +622,67 @@ class Logics:
return True, {"escrow_amount": escrow_amount}
@classmethod
def update_address(cls, order, user, address, mining_fee_rate):
# Empty address?
if not address:
return False, {
"bad_address":
"You submitted an empty invoice"
}
# only the buyer can post a buyer address
if not cls.is_buyer(order, user):
return False, {
"bad_request":
"Only the buyer of this order can provide a payout address."
}
# not the right time to submit
if (not (order.taker_bond.status == order.maker_bond.status ==
LNPayment.Status.LOCKED)
and not order.status == Order.Status.FAI):
return False, {
"bad_request":
"You cannot submit an adress are not locked."
}
# not a valid address (does not accept Taproot as of now)
if not validate_onchain_address(address):
return False, {
"bad_address":
"Does not look like a valid address"
}
if mining_fee_rate:
# not a valid mining fee
if float(mining_fee_rate) <= 1:
return False, {
"bad_address":
"The mining fee is too low."
}
elif float(mining_fee_rate) > 50:
return False, {
"bad_address":
"The mining fee is too high."
}
order.payout_tx.mining_fee_rate = float(mining_fee_rate)
# If not mining ee provider use backend's suggested fee rate
else:
order.payout_tx.mining_fee_rate = order.payout_tx.suggested_mining_fee_rate
tx = order.payout_tx
tx.address = address
tx.mining_fee_sats = int(tx.mining_fee_rate * 141)
tx.num_satoshis = cls.payout_amount(order, user)[1]["invoice_amount"]
tx.sent_satoshis = int(float(tx.num_satoshis) - float(tx.num_satoshis) * float(tx.swap_fee_rate)/100 - float(tx.mining_fee_sats))
tx.status = OnchainPayment.Status.VALID
tx.save()
order.is_swap = True
order.save()
cls.move_state_updated_payout_method(order)
return True, None
@classmethod
def update_invoice(cls, order, user, invoice):
@ -677,6 +739,15 @@ class Logics:
},
)
order.is_swap = False
order.save()
cls.move_state_updated_payout_method(order)
return True, None
@classmethod
def move_state_updated_payout_method(cls,order):
# If the order status is 'Waiting for invoice'. Move forward to 'chat'
if order.status == Order.Status.WFI:
order.status = Order.Status.CHA
@ -706,10 +777,9 @@ class Logics:
order.payout.status = LNPayment.Status.FLIGHT
order.payout.routing_attempts = 0
order.payout.save()
order.save()
order.save()
return True, None
return True
def add_profile_rating(profile, rating):
"""adds a new rating to a user profile"""

View File

@ -205,10 +205,14 @@ class OnchainPayment(models.Model):
num_satoshis = models.PositiveBigIntegerField(null=True,
validators=[
MinValueValidator(0.7 * MIN_SWAP_AMOUNT),
MinValueValidator(0.5 * MIN_SWAP_AMOUNT),
MaxValueValidator(1.5 * MAX_TRADE),
])
sent_satoshis = models.PositiveBigIntegerField(null=True,
validators=[
MinValueValidator(0.5 * MIN_SWAP_AMOUNT),
MaxValueValidator(1.5 * MAX_TRADE),
])
# fee in sats/vbyte with mSats decimals fee_msat
suggested_mining_fee_rate = models.DecimalField(max_digits=6,
decimal_places=3,

View File

@ -337,7 +337,7 @@ class OrderView(viewsets.ViewSet):
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 and onchain swap cost so he can send the buyer invoice/address
# If the two bonds are locked, reply with an AMOUNT and onchain swap cost so he can send the buyer invoice/address.
if (order.maker_bond.status == order.taker_bond.status ==
LNPayment.Status.LOCKED):
valid, context = Logics.payout_amount(order, request.user)
@ -467,7 +467,7 @@ class OrderView(viewsets.ViewSet):
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)
# 2.b) If action is 'update invoice'
# 2.b) If action is 'update address'
if action == "update_address":
valid, context = Logics.update_address(order, request.user,
address, mining_fee_rate)

View File

@ -578,7 +578,7 @@ class TradeBox extends Component {
};
fetch('/api/order/' + '?order_id=' + this.props.data.id, requestOptions)
.then((response) => response.json())
.then((data) => this.setState({badAddress:data_address})
.then((data) => this.setState({badAddress:data.bad_address})
& this.props.completeSetState(data));
}
@ -659,7 +659,7 @@ class TradeBox extends Component {
<Paper elevation={2}>
<Tabs value={this.state.receiveTab} variant="fullWidth" sx={{width:290}}>
<Tab disableRipple={true} label={<div style={{display:'flex', alignItems:'center', justifyContent:'center', flexWrap:'wrap'}}><BoltIcon/> Lightning</div>} onClick={() => this.setState({receiveTab:0})}/>
<Tab label={<div style={{display:'flex', alignItems:'center', justifyContent:'center', flexWrap:'wrap'}}><LinkIcon/> Onchain</div>} disabled={!this.props.data.swap_allowed} onClick={() => this.setState({receiveTab:1, miningFee: this.props.data.suggested_mining_fee_rate})} />
<Tab label={<div style={{display:'flex', alignItems:'center', justifyContent:'center', flexWrap:'wrap'}}><LinkIcon/> Onchain</div>} disabled={!this.props.data.swap_allowed} onClick={() => this.setState({receiveTab:1, miningFee: parseFloat(this.props.data.suggested_mining_fee_rate)})} />
</Tabs>
</Paper>
</ListItem>
@ -777,7 +777,7 @@ class TradeBox extends Component {
<div style={{height:10}}/>
<Grid item xs={12} align="center">
<Button onClick={null} variant='contained' color='primary'>{t("Submit")}</Button>
<Button onClick={this.handleClickSubmitAddressButton} variant='contained' color='primary'>{t("Submit")}</Button>
</Grid>
</div>
<List>