Skip to content

Commit

Permalink
Better windows build (via docker) (#23)
Browse files Browse the repository at this point in the history
- Added svg export to Flow diagrams
- Can open tx, wallet, psbt files now directly via argument
- newer version of qr-tools to improve fps
- Speed improvements in label syncing (label.duimp, needed for label
comparision is now faster)
- added labuage icons in menus
  • Loading branch information
andreasgriffin authored Nov 9, 2024
1 parent a7f2cff commit 7e73fad
Show file tree
Hide file tree
Showing 54 changed files with 1,953 additions and 386 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ jobs:
libxrender-dev \
libxi-dev \
libxkbcommon-dev \
libxkbcommon-x11-dev
libxkbcommon-x11-dev \
libsecp256k1-0
sudo /usr/bin/Xvfb $DISPLAY -screen 0 1280x1024x24 &
- name: Start Xvfb
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ MANIFEST
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
Expand Down Expand Up @@ -198,6 +197,7 @@ bitcoin_safe.dist-info
# translation files
*.po
*.csv
*.xcf

screenshots*/
.DS_Store
Expand All @@ -219,4 +219,5 @@ bitcoin_safe
*.so.0
*.so.1
version
tools/libusb/
tools/libusb/
*.dll
41 changes: 33 additions & 8 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,25 +111,50 @@
"request": "launch",
"program": "tools/build.py",
"args": [
"--targets",
// // "deb",
// "appimage",
// "--sign",
"--targets", "appimage", "windows",
],
"console": "integratedTerminal",
"preLaunchTask": "Poetry Install" // label of the task
},{
"name": "Sign",
"name": "Build Linux (Current Files)",
"type": "python",
"request": "launch",
"program": "tools/build.py",
"args": [
"--targets", "appimage",
"--commit", "None",
],
"console": "integratedTerminal",
"preLaunchTask": "Poetry Install" // label of the task
},{
"name": "Build Windows (Current Files)",
"type": "python",
"request": "launch",
"program": "tools/build.py",
"args": [
// "--targets",
// // "deb",
// "appimage",
"--targets", "windows",
"--commit", "None",
],
"console": "integratedTerminal",
"preLaunchTask": "Poetry Install" // label of the task
},{
"name": "Sign",
"type": "python",
"request": "launch",
"program": "tools/build.py",
"args": [
"--sign",
],
"console": "integratedTerminal"
},{
"name": "Lock no cache",
"type": "python",
"request": "launch",
"program": "tools/build.py",
"args": [
"--lock",
],
"console": "integratedTerminal"
},{
"name": "Current File",
"type": "python",
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- **Easy** Multisig-Wallet Setup
- Step-by-Step instructions for a secure MultiSig setup with PDF backup sheets
- Test transactions ensure that all hardware signers are ready
- Full support for [Coldcard](https://coldcard.com/), [Coldcard Q](https://coldcard.com/), [Bitbox02](https://shiftcrypto.ch/bitbox02/?ref=MOB4dk7gpm), [Blockstream Jade](https://store.blockstream.com/?code=XEocg5boS77D), and Specter DIY, supporting QR, USB, SD-card
- Full support for [Coldcard](https://store.coinkite.com/promo/8BFF877000C34A86F410), [Coldcard Q](https://store.coinkite.com/promo/8BFF877000C34A86F410), [Bitbox02](https://shiftcrypto.ch/bitbox02/?ref=MOB4dk7gpm), [Blockstream Jade](https://store.blockstream.com/?code=XEocg5boS77D), and Specter DIY, supporting QR, USB, SD-card
- **Secure**: Hardware signers only
- All wallets require hardware signers/wallets for safe seed storage
- Powered by **[BDK](https://github.com/bitcoindevkit/bdk)**
Expand Down Expand Up @@ -64,6 +64,7 @@
- CSV import for batch transactions
- Label import and export using [BIP329](https://bip329.org/)
- Label import from Electrum wallet
- Export of the money flow diagram to svg
- Drag and drop for Transactions, PSBTs, and CSV files

- **Wallet Features**
Expand All @@ -88,7 +89,7 @@

- **Languages**

- 🇺🇸 English, 🇨🇳 Chinese - 简体中文, 🇪🇸 Spanish - español de España, 🇯🇵 Japanese - 日本語, 🇷🇺 Russian - русский, 🇵🇹 Portuguese - português europeu, 🇮🇳 Hindi - हिन्दी, Arabic - العربية, 🇮🇹 Italian - italiano, (more upon request)
- 🇺🇸 English, 🇨🇳 Chinese - 简体中文, 🇪🇸 Spanish - español de España, 🇯🇵 Japanese - 日本語, 🇷🇺 Russian - русский, 🇵🇹 Portuguese - português europeu, 🇮🇳 Hindi - हिन्दी, Arabic - العربية, 🇮🇹 Italian - italiano, 🇫🇷 French - Français, 🇩🇪 German - Deutsch, (more upon request)

- **Transaction / PSBT Creation**

Expand Down
2 changes: 1 addition & 1 deletion bitcoin_safe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# this is the source of the version information
__version__ = "1.0.0b2"
__version__ = "1.0.0b3"
16 changes: 12 additions & 4 deletions bitcoin_safe/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import sys

from .dynamic_lib_load import ensure_pyzbar_works
# all import must be absolute, because this is the entry script for pyinstaller
from bitcoin_safe.dynamic_lib_load import ensure_pyzbar_works

# this setsup the logging
from .logging_setup import setup_logging # type: ignore
from bitcoin_safe.logging_setup import setup_logging # type: ignore

ensure_pyzbar_works()

Expand All @@ -12,8 +13,8 @@

from PyQt6.QtWidgets import QApplication

from .gui.qt.main import MainWindow
from .gui.qt.util import custom_exception_handler
from bitcoin_safe.gui.qt.main import MainWindow
from bitcoin_safe.gui.qt.util import custom_exception_handler


def parse_args() -> argparse.Namespace:
Expand All @@ -23,6 +24,13 @@ def parse_args() -> argparse.Namespace:
parser.add_argument(
"--profile", action="store_true", help="Enable profiling. VIsualize with snakeviz .prof_stats"
)
parser.add_argument(
"open_files_at_startup",
metavar="FILE",
type=str,
nargs="*",
help="File to process, can be of type tx, psbt, wallet files.",
)

return parser.parse_args()

Expand Down
69 changes: 27 additions & 42 deletions bitcoin_safe/dynamic_lib_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@


import logging
import os
import platform
import sys
from ctypes.util import find_library
Expand All @@ -39,7 +38,7 @@
import bitcoin_usb
import bitcointx

from .html import link
from .html_utils import link
from .i18n import translate

logger = logging.getLogger(__name__)
Expand All @@ -57,51 +56,44 @@ def show_message_before_quit(msg: str) -> None:
sys.exit(app.exec())


def get_libsecp256k1_electrumsv_path() -> str:
from electrumsv_secp256k1 import _libsecp256k1

# Get the platform-specific path to the binary library
if platform.system() == "Windows":
# On Windows, construct the path to the DLL
here = os.path.dirname(os.path.abspath(_libsecp256k1.__file__))
lib_path = os.path.join(here, "libsecp256k1.dll")
else:
# On Linux and macOS, directly use the __file__ attribute
lib_path = _libsecp256k1.__file__
return lib_path


def get_libsecp256k1_os_path() -> str | None:
"This cannot be used directly, because it doesnt return an absolute path"
lib_name = "secp256k1"
return find_library(lib_name)


def get_packaged_libsecp256k1_path() -> str | None:
# for apppimage it is
# __file__ = squashfs-root/usr/lib/python3.10/site-packages/bitcoin_safe/dynamic_lib_load.py
# and the lib is in
# squashfs-root/usr/lib/libsecp256k1.so.0.0.0
packaged_lib_path = Path(__file__).parent.parent.parent.parent
for name in ["libsecp256k1.so.0.0.0", "libsecp256k1.so.0"]:
lib_path = packaged_lib_path / name
if lib_path.exists():
return str(lib_path)
if platform.system() == "Linux":
# for apppimage it is
# __file__ = squashfs-root/usr/lib/python3.10/site-packages/bitcoin_safe/dynamic_lib_load.py
# and the lib is in
# squashfs-root/usr/lib/libsecp256k1.so.0.0.0

for name in ["libsecp256k1.so.0.0.0", "libsecp256k1.so.0"]:
lib_path = Path(__file__).parent.parent.parent.parent / name
logger.info(f"Searching for {name} in {lib_path.absolute()}")
if lib_path.exists():
return str(lib_path)

elif platform.system() == "Windows":
# for exe the dlls are packages in the same folder as dynamic_lib_load.py
# packaged in setup: __file__ = C:/Program Files/Bitcoin Safe/_internals/bitcoin_safe/dynamic_lib_load.pyc
# the dll is in: C:/Program Files/Bitcoin Safe/_internals/libsecp256k1-2.dll
for name in ["libsecp256k1-2.dll"]:
# logger.info(f"file in {Path(__file__).absolute()}")
lib_path = Path(__file__).parent.parent / name
logger.info(f"Searching for {name} in {lib_path.absolute()}")
if lib_path.exists():
return str(lib_path)

return None


def setup_libsecp256k1() -> None:
"""The operating system might, or might not provide libsecp256k1 needed for bitcointx
Therefore we require https://pypi.org/project/electrumsv-secp256k1/ in the build process as additional_requires
and point the bicointx library here to this binary.
"""
The packaged versions com with libsecp256k1
This isn't ideal, but:
# electrumsv-secp256k1 offers libsecp256k1 prebuild for different platforms
# which is needed for bitcointx.
# bitcointx and with it the prebuild libsecp256k1 is not used for anything security critical
# key derivation with bitcointx is restricted to testnet/regtest/signet
# and the PSBTTools using bitcointx is safe because it handles no key material
Only if you install it via pip/git, libsecp256k1 is required to be on the system
"""

lib_path = None
Expand All @@ -112,13 +104,6 @@ def setup_libsecp256k1() -> None:
logger.info(f"libsecp256k1 found in package.: {packaged_libsecp256k1_path}")
lib_path = packaged_libsecp256k1_path

# Fallback choice is the electrumsv version
if not lib_path:
binary_lib_path_from_electrumsv = get_libsecp256k1_electrumsv_path()
if binary_lib_path_from_electrumsv:
logger.info(f"libsecp256k1 found via fallbackmethod: {binary_lib_path_from_electrumsv}")
lib_path = binary_lib_path_from_electrumsv

if lib_path:
logger.info(f"Setting libsecp256k1: {lib_path}")
bitcoin_usb.set_custom_secp256k1_path(lib_path)
Expand Down
Binary file removed bitcoin_safe/gui/icons/flows.png
Binary file not shown.
67 changes: 67 additions & 0 deletions bitcoin_safe/gui/icons/flows.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion bitcoin_safe/gui/qt/about_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
QWidget,
)

from bitcoin_safe.html import link
from bitcoin_safe.html_utils import link


class LicenseDialog(QDialog):
Expand Down
8 changes: 7 additions & 1 deletion bitcoin_safe/gui/qt/address_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
from ...i18n import translate
from ...rpc import send_rpc_command
from ...signals import Signals, UpdateFilter, UpdateFilterReason, WalletSignals
from ...util import Satoshis, block_explorer_URL
from ...util import Satoshis, block_explorer_URL, time_logger
from ...wallet import TxStatus, Wallet
from .category_list import CategoryEditor
from .my_treeview import (
Expand Down Expand Up @@ -327,6 +327,11 @@ def dropEvent(self, event: QDropEvent) -> None: # type: ignore[override]
event.accept()
return

elif mime_data.hasUrls():
# Iterate through the list of dropped file URLs
for url in mime_data.urls():
# Convert URL to local file path
self.signals.open_file_path.emit(url.toLocalFile())
event.ignore()

def on_double_click(self, idx: QModelIndex) -> None:
Expand Down Expand Up @@ -381,6 +386,7 @@ def on_update_fx_rates(self):
update_filter = UpdateFilter(addresses=addresses_with_balance, reason=UpdateFilterReason.NewFxRates)
self.update_with_filter(update_filter)

@time_logger
def update_with_filter(self, update_filter: UpdateFilter) -> None:
if update_filter.refresh_all:
return self.update_content()
Expand Down
2 changes: 1 addition & 1 deletion bitcoin_safe/gui/qt/block_buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from bitcoin_safe.config import UserConfig
from bitcoin_safe.util import block_explorer_URL_of_projected_block, unit_fee_str

from ...html import html_f
from ...html_utils import html_f
from ...mempool import MempoolData, fee_to_color, mempoolFeeColors
from .invisible_scroll_area import InvisibleScrollArea
from .util import center_in_widget, open_website
Expand Down
1 change: 1 addition & 0 deletions bitcoin_safe/gui/qt/data_tab_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from PyQt6.QtWidgets import QApplication, QWidget

T = TypeVar("T")
T2 = TypeVar("T2")


class DataTabWidget(Generic[T], HistTabWidget):
Expand Down
Loading

0 comments on commit 7e73fad

Please sign in to comment.