mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-14 14:28:11 +01:00
Compare commits
15 Commits
release-v0
...
d0614fd7a3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0614fd7a3 | ||
|
|
84223fabb0 | ||
|
|
4938a203f2 | ||
|
|
2a641567ba | ||
|
|
fbeece4fc9 | ||
|
|
6906e8ac1b | ||
|
|
1a86d371c3 | ||
|
|
e6c1c86dff | ||
|
|
ee8ab69d57 | ||
|
|
2279ed84dc | ||
|
|
497793ae8c | ||
|
|
052c722d76 | ||
|
|
53b06859fc | ||
|
|
7755b4c505 | ||
|
|
95da26211b |
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -1,6 +1,16 @@
|
|||||||
name: ci
|
name: ci
|
||||||
|
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- 'doc/**'
|
||||||
|
- '**/README.md'
|
||||||
|
- '**/LICENSE'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- 'doc/**'
|
||||||
|
- '**/README.md'
|
||||||
|
- '**/LICENSE'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
|||||||
@@ -1509,6 +1509,7 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if version_tuple(latest_tag) > version_tuple(current_version):
|
if version_tuple(latest_tag) > version_tuple(current_version):
|
||||||
|
self._latest_version = latest_tag
|
||||||
if not self._update_available:
|
if not self._update_available:
|
||||||
self._update_available = True
|
self._update_available = True
|
||||||
self.log.info(
|
self.log.info(
|
||||||
@@ -1528,6 +1529,7 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
self.log.info(f"Update v{latest_tag} already notified")
|
self.log.info(f"Update v{latest_tag} already notified")
|
||||||
else:
|
else:
|
||||||
self._update_available = False
|
self._update_available = False
|
||||||
|
self._latest_version = None
|
||||||
self.log.info(f"BasicSwap is up to date (v{current_version})")
|
self.log.info(f"BasicSwap is up to date (v{current_version})")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.log.warning(f"Error comparing versions: {e}")
|
self.log.warning(f"Error comparing versions: {e}")
|
||||||
@@ -2026,6 +2028,13 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
|
|
||||||
if self.ws_server and show_event:
|
if self.ws_server and show_event:
|
||||||
self.ws_server.send_message_to_all(json.dumps(event_data))
|
self.ws_server.send_message_to_all(json.dumps(event_data))
|
||||||
|
elif event_type == NT.UPDATE_AVAILABLE:
|
||||||
|
self.log.info(
|
||||||
|
f"Update available: v{event_data.get('latest_version', 'unknown')}"
|
||||||
|
)
|
||||||
|
if self.ws_server and show_event:
|
||||||
|
event_data["event"] = "update_available"
|
||||||
|
self.ws_server.send_message_to_all(json.dumps(event_data))
|
||||||
else:
|
else:
|
||||||
self.log.warning(f"Unknown notification {event_type}")
|
self.log.warning(f"Unknown notification {event_type}")
|
||||||
|
|
||||||
@@ -11260,6 +11269,16 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
settings_copy["notifications_outgoing_transactions"] = new_value
|
settings_copy["notifications_outgoing_transactions"] = new_value
|
||||||
settings_changed = True
|
settings_changed = True
|
||||||
|
|
||||||
|
if "notifications_swap_completed" in data:
|
||||||
|
new_value = data["notifications_swap_completed"]
|
||||||
|
ensure(
|
||||||
|
isinstance(new_value, bool),
|
||||||
|
"New notifications_swap_completed value not boolean",
|
||||||
|
)
|
||||||
|
if settings_copy.get("notifications_swap_completed", True) != new_value:
|
||||||
|
settings_copy["notifications_swap_completed"] = new_value
|
||||||
|
settings_changed = True
|
||||||
|
|
||||||
if "notifications_duration" in data:
|
if "notifications_duration" in data:
|
||||||
new_value = data["notifications_duration"]
|
new_value = data["notifications_duration"]
|
||||||
ensure(
|
ensure(
|
||||||
@@ -11274,6 +11293,15 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
settings_copy["notifications_duration"] = new_value
|
settings_copy["notifications_duration"] = new_value
|
||||||
settings_changed = True
|
settings_changed = True
|
||||||
|
|
||||||
|
if "check_updates" in data:
|
||||||
|
new_value = data["check_updates"]
|
||||||
|
ensure(
|
||||||
|
isinstance(new_value, bool), "New check_updates value not boolean"
|
||||||
|
)
|
||||||
|
if settings_copy.get("check_updates", True) != new_value:
|
||||||
|
settings_copy["check_updates"] = new_value
|
||||||
|
settings_changed = True
|
||||||
|
|
||||||
if settings_changed:
|
if settings_changed:
|
||||||
settings_path = os.path.join(self.data_dir, cfg.CONFIG_FILENAME)
|
settings_path = os.path.join(self.data_dir, cfg.CONFIG_FILENAME)
|
||||||
settings_path_new = settings_path + ".new"
|
settings_path_new = settings_path + ".new"
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ def describeEventEntry(event_type, event_msg):
|
|||||||
if event_type == EventLogTypes.LOCK_TX_B_INVALID:
|
if event_type == EventLogTypes.LOCK_TX_B_INVALID:
|
||||||
return "Detected invalid lock Tx B"
|
return "Detected invalid lock Tx B"
|
||||||
if event_type == EventLogTypes.LOCK_TX_A_REFUND_TX_PUBLISHED:
|
if event_type == EventLogTypes.LOCK_TX_A_REFUND_TX_PUBLISHED:
|
||||||
return "Lock tx A refund tx published"
|
return "Lock tx A pre-refund tx published"
|
||||||
if event_type == EventLogTypes.LOCK_TX_A_REFUND_SPEND_TX_PUBLISHED:
|
if event_type == EventLogTypes.LOCK_TX_A_REFUND_SPEND_TX_PUBLISHED:
|
||||||
return "Lock tx A refund spend tx published"
|
return "Lock tx A refund spend tx published"
|
||||||
if event_type == EventLogTypes.LOCK_TX_A_REFUND_SWIPE_TX_PUBLISHED:
|
if event_type == EventLogTypes.LOCK_TX_A_REFUND_SWIPE_TX_PUBLISHED:
|
||||||
@@ -471,7 +471,7 @@ def describeEventEntry(event_type, event_msg):
|
|||||||
if event_type == EventLogTypes.LOCK_TX_B_SPEND_TX_PUBLISHED:
|
if event_type == EventLogTypes.LOCK_TX_B_SPEND_TX_PUBLISHED:
|
||||||
return "Lock tx B spend tx published"
|
return "Lock tx B spend tx published"
|
||||||
if event_type == EventLogTypes.LOCK_TX_A_REFUND_TX_SEEN:
|
if event_type == EventLogTypes.LOCK_TX_A_REFUND_TX_SEEN:
|
||||||
return "Lock tx A refund tx seen in chain"
|
return "Lock tx A pre-refund tx seen in chain"
|
||||||
if event_type == EventLogTypes.LOCK_TX_A_REFUND_SPEND_TX_SEEN:
|
if event_type == EventLogTypes.LOCK_TX_A_REFUND_SPEND_TX_SEEN:
|
||||||
return "Lock tx A refund spend tx seen in chain"
|
return "Lock tx A refund spend tx seen in chain"
|
||||||
if event_type == EventLogTypes.SYSTEM_WARNING:
|
if event_type == EventLogTypes.SYSTEM_WARNING:
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ PIVX_VERSION_TAG = os.getenv("PIVX_VERSION_TAG", "")
|
|||||||
DASH_VERSION = os.getenv("DASH_VERSION", "22.1.3")
|
DASH_VERSION = os.getenv("DASH_VERSION", "22.1.3")
|
||||||
DASH_VERSION_TAG = os.getenv("DASH_VERSION_TAG", "")
|
DASH_VERSION_TAG = os.getenv("DASH_VERSION_TAG", "")
|
||||||
|
|
||||||
FIRO_VERSION = os.getenv("FIRO_VERSION", "0.14.14.3")
|
FIRO_VERSION = os.getenv("FIRO_VERSION", "0.14.15.0")
|
||||||
FIRO_VERSION_TAG = os.getenv("FIRO_VERSION_TAG", "")
|
FIRO_VERSION_TAG = os.getenv("FIRO_VERSION_TAG", "")
|
||||||
|
|
||||||
NAV_VERSION = os.getenv("NAV_VERSION", "7.0.3")
|
NAV_VERSION = os.getenv("NAV_VERSION", "7.0.3")
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ def startXmrDaemon(node_dir, bin_dir, daemon_bin, opts=[]):
|
|||||||
|
|
||||||
def startXmrWalletDaemon(node_dir, bin_dir, wallet_bin, opts=[]):
|
def startXmrWalletDaemon(node_dir, bin_dir, wallet_bin, opts=[]):
|
||||||
daemon_path = os.path.expanduser(os.path.join(bin_dir, wallet_bin))
|
daemon_path = os.path.expanduser(os.path.join(bin_dir, wallet_bin))
|
||||||
args = [daemon_path, "--non-interactive"]
|
args = [daemon_path]
|
||||||
|
|
||||||
needs_rewrite: bool = False
|
needs_rewrite: bool = False
|
||||||
config_to_remove = [
|
config_to_remove = [
|
||||||
|
|||||||
@@ -952,6 +952,32 @@ def js_notifications(self, url_split, post_string, is_json) -> bytes:
|
|||||||
return bytes(json.dumps(swap_client.getNotifications()), "UTF-8")
|
return bytes(json.dumps(swap_client.getNotifications()), "UTF-8")
|
||||||
|
|
||||||
|
|
||||||
|
def js_updatestatus(self, url_split, post_string, is_json) -> bytes:
|
||||||
|
swap_client = self.server.swap_client
|
||||||
|
from basicswap import __version__
|
||||||
|
|
||||||
|
return bytes(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"update_available": swap_client._update_available,
|
||||||
|
"current_version": __version__,
|
||||||
|
"latest_version": swap_client._latest_version,
|
||||||
|
"release_url": (
|
||||||
|
f"https://github.com/basicswap/basicswap/releases/tag/v{swap_client._latest_version}"
|
||||||
|
if swap_client._latest_version
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
"release_notes": (
|
||||||
|
f"New version v{swap_client._latest_version} is available. Click to view details on GitHub."
|
||||||
|
if swap_client._latest_version
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"UTF-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def js_identities(self, url_split, post_string: str, is_json: bool) -> bytes:
|
def js_identities(self, url_split, post_string: str, is_json: bool) -> bytes:
|
||||||
swap_client = self.server.swap_client
|
swap_client = self.server.swap_client
|
||||||
swap_client.checkSystemStatus()
|
swap_client.checkSystemStatus()
|
||||||
@@ -1559,6 +1585,7 @@ endpoints = {
|
|||||||
"rateslist": js_rates_list,
|
"rateslist": js_rates_list,
|
||||||
"generatenotification": js_generatenotification,
|
"generatenotification": js_generatenotification,
|
||||||
"checkupdates": js_checkupdates,
|
"checkupdates": js_checkupdates,
|
||||||
|
"updatestatus": js_updatestatus,
|
||||||
"notifications": js_notifications,
|
"notifications": js_notifications,
|
||||||
"identities": js_identities,
|
"identities": js_identities,
|
||||||
"automationstrategies": js_automationstrategies,
|
"automationstrategies": js_automationstrategies,
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ function ensureToastContainer() {
|
|||||||
updateHistoryDropdown();
|
updateHistoryDropdown();
|
||||||
|
|
||||||
this.initializeBalanceTracking();
|
this.initializeBalanceTracking();
|
||||||
|
this.checkForPendingUpdateNotification();
|
||||||
|
|
||||||
if (window.CleanupManager) {
|
if (window.CleanupManager) {
|
||||||
window.CleanupManager.registerResource('notificationManager', this, (mgr) => {
|
window.CleanupManager.registerResource('notificationManager', this, (mgr) => {
|
||||||
@@ -331,6 +332,29 @@ function ensureToastContainer() {
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkForPendingUpdateNotification: function() {
|
||||||
|
CleanupManager.setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/json/updatestatus');
|
||||||
|
const updateStatus = await response.json();
|
||||||
|
|
||||||
|
if (updateStatus.update_available && config.showUpdateNotifications) {
|
||||||
|
this.createToast(
|
||||||
|
`Update Available: v${updateStatus.latest_version}`,
|
||||||
|
'update_available',
|
||||||
|
{
|
||||||
|
subtitle: `Current: v${updateStatus.current_version} • Click to view release`,
|
||||||
|
releaseUrl: updateStatus.release_url,
|
||||||
|
releaseNotes: updateStatus.release_notes
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking for pending update notification:', error);
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
|
||||||
updateSettings: function(newSettings) {
|
updateSettings: function(newSettings) {
|
||||||
saveConfig(newSettings);
|
saveConfig(newSettings);
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -492,7 +492,7 @@
|
|||||||
|
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="checkbox" id="check_updates" name="check_updates" value="true" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"{% if general_settings.check_updates %} checked{% endif %}>
|
<input type="checkbox" id="check_updates" name="check_updates" value="true" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"{% if notification_settings.check_updates %} checked{% endif %}>
|
||||||
<label for="check_updates" class="ml-3 text-sm font-medium text-gray-700 dark:text-gray-300">Update Notifications</label>
|
<label for="check_updates" class="ml-3 text-sm font-medium text-gray-700 dark:text-gray-300">Update Notifications</label>
|
||||||
<button type="button" data-check-updates class="ml-3 text-xs bg-gray-600 hover:bg-gray-700 text-white font-medium py-1 px-3 rounded transition-colors focus:outline-none">
|
<button type="button" data-check-updates class="ml-3 text-xs bg-gray-600 hover:bg-gray-700 text-white font-medium py-1 px-3 rounded transition-colors focus:outline-none">
|
||||||
Check Now
|
Check Now
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ def page_settings(self, url_split, post_string):
|
|||||||
get_data_entry_or(form_data, "notifications_duration", "20")
|
get_data_entry_or(form_data, "notifications_duration", "20")
|
||||||
),
|
),
|
||||||
"check_updates": toBool(
|
"check_updates": toBool(
|
||||||
get_data_entry_or(form_data, "check_updates", "true")
|
get_data_entry_or(form_data, "check_updates", "false")
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
swap_client.editGeneralSettings(data)
|
swap_client.editGeneralSettings(data)
|
||||||
@@ -242,6 +242,7 @@ def page_settings(self, url_split, post_string):
|
|||||||
"notifications_duration": swap_client.settings.get(
|
"notifications_duration": swap_client.settings.get(
|
||||||
"notifications_duration", 20
|
"notifications_duration", 20
|
||||||
),
|
),
|
||||||
|
"check_updates": swap_client.settings.get("check_updates", True),
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_control_password = (
|
tor_control_password = (
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ Install Homebrew (See https://brew.sh/):
|
|||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
|
|
||||||
brew install python git gnupg pkg-config jq
|
brew install python git gnupg pkg-config jq zeromq
|
||||||
|
|
||||||
Close the terminal and open a new one to update the python symlinks.
|
Close the terminal and open a new one to update the python symlinks.
|
||||||
|
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ VOLUME $MONERO_DATA
|
|||||||
COPY entrypoint.sh /entrypoint.sh
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
|
||||||
CMD ["/monero/monero-wallet-rpc", "--non-interactive", "--config-file=/data/monero_wallet.conf", "--confirm-external-bind"]
|
CMD ["/monero/monero-wallet-rpc", "--config-file=/data/monero_wallet.conf", "--confirm-external-bind"]
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ VOLUME $WOWNERO_DATA
|
|||||||
COPY entrypoint.sh /entrypoint.sh
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
|
||||||
CMD ["/wownero/wownero-wallet-rpc", "--non-interactive", "--config-file=/data/wownero-wallet-rpc.conf", "--confirm-external-bind"]
|
CMD ["/wownero/wownero-wallet-rpc", "--config-file=/data/wownero-wallet-rpc.conf", "--confirm-external-bind"]
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ dev = [
|
|||||||
"pre-commit",
|
"pre-commit",
|
||||||
"pytest",
|
"pytest",
|
||||||
"ruff",
|
"ruff",
|
||||||
"black==25.9.0",
|
"black==25.11.0",
|
||||||
"selenium",
|
"selenium",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user