diff --git a/api/logics.py b/api/logics.py
index 11fb8384..0ce55f5f 100644
--- a/api/logics.py
+++ b/api/logics.py
@@ -1,5 +1,6 @@
from datetime import timedelta
from tkinter import N, ON
+from tokenize import Octnumber
from django.utils import timezone
from api.lightning.node import LNNode
from django.db.models import Q, Sum
@@ -526,6 +527,10 @@ class Logics:
It sets the fees to be applied to this order if onchain Swap is used.
If the user submits a LN invoice instead. The returned OnchainPayment goes unused.
'''
+ # Make sure no invoice payout is attached to order
+ order.payout = None
+
+ # Create onchain_payment
onchain_payment = OnchainPayment.objects.create(receiver=user)
# Compute a safer available onchain liquidity: (confirmed_utxos - reserve - pending_outgoing_txs))
@@ -647,11 +652,10 @@ class Logics:
"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"
- }
+ valid, context = validate_onchain_address(address)
+ if not valid:
+ return False, context
+
if mining_fee_rate:
# not a valid mining fee
if float(mining_fee_rate) <= 1:
@@ -715,6 +719,11 @@ class Logics:
"You cannot submit an invoice only after expiration or 3 failed attempts"
}
+ # cancel onchain_payout if existing
+ if order.payout_tx:
+ order.payout_tx.status = OnchainPayment.Status.CANCE
+ order.payout_tx.save()
+
num_satoshis = cls.payout_amount(order, user)[1]["invoice_amount"]
payout = LNNode.validate_ln_invoice(invoice, num_satoshis)
@@ -1325,6 +1334,9 @@ class Logics:
# Pay onchain to address
else:
+ if not order.payout_tx.status == OnchainPayment.Status.VALID:
+ return False
+
valid = LNNode.pay_onchain(order.payout_tx)
if valid:
order.payout_tx.status = OnchainPayment.Status.MEMPO
diff --git a/api/utils.py b/api/utils.py
index 89205726..b303a24e 100644
--- a/api/utils.py
+++ b/api/utils.py
@@ -19,15 +19,28 @@ def validate_onchain_address(address):
validation = addr.validate('btc', address.encode('utf-8'))
if not validation.valid:
- return False
+ return False, {
+ "bad_address":
+ "Does not look like a valid address"
+ }
NETWORK = str(config('NETWORK'))
if NETWORK == 'mainnet':
if validation.network == 'main':
- return True
+ return True, None
+ else:
+ return False, {
+ "bad_address":
+ "This is not a bitcoin mainnet address"
+ }
elif NETWORK == 'testnet':
if validation.network == 'test':
- return True
+ return True, None
+ else:
+ return False, {
+ "bad_address":
+ "This is not a bitcoin testnet address"
+ }
market_cache = {}
@ring.dict(market_cache, expire=3) # keeps in cache for 3 seconds
diff --git a/frontend/src/components/TradeBox.js b/frontend/src/components/TradeBox.js
index 527e6ec8..5d5700fb 100644
--- a/frontend/src/components/TradeBox.js
+++ b/frontend/src/components/TradeBox.js
@@ -1,6 +1,6 @@
import React, { Component } from "react";
import { withTranslation, Trans} from "react-i18next";
-import { Alert, AlertTitle, Tabs, Tab, IconButton, Box, Link, Paper, Rating, Button, Tooltip, CircularProgress, Grid, Typography, TextField, List, ListItem, ListItemText, Divider, ListItemIcon, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "@mui/material"
+import { Alert, AlertTitle, ToggleButtonGroup, ToggleButton, IconButton, Box, Link, Paper, Rating, Button, Tooltip, CircularProgress, Grid, Typography, TextField, List, ListItem, ListItemText, Divider, ListItemIcon, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "@mui/material"
import QRCode from "react-qr-code";
import Countdown, { zeroPad} from 'react-countdown';
import Chat from "./EncryptedChat"
@@ -654,16 +654,21 @@ class TradeBox extends Component {
currencyCode: this.props.data.currencyCode})}
+
+
+