Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desktop client app #2

Merged
merged 59 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
078c5cb
Add: desktop basic structure
axiom90 Aug 16, 2024
1b62c56
Merge pull request #1 from meherett/add-network-param
axiom90 Aug 17, 2024
e907cf3
Add: Stylesheet, No EC-Multiply implementation
axiom90 Aug 17, 2024
6c6584e
Modify: BIP38 requirements location
meherett Aug 17, 2024
1ff4ce0
Add: ec-multiply ui
axiom90 Aug 20, 2024
39bf64a
Update: default log color
axiom90 Aug 20, 2024
bfe92f2
Modify: python-bip38 `build.yml` workflow
meherett Aug 20, 2024
5a426c4
Add: include all requirements `*.txt` files
meherett Aug 20, 2024
273e896
Update: intermediate passphrase, owner salt and seed generate
axiom90 Aug 21, 2024
128ac6c
Update: confirmation and create encrypted WIF
axiom90 Aug 22, 2024
bf71f2a
Update: validation improvements
axiom90 Aug 24, 2024
9e52e55
Update: intermediate passphrase validation
axiom90 Aug 24, 2024
91430c3
Update: all BIP39 exception massages
meherett Aug 24, 2024
30e8784
Change: public_key_type into wif_type arg
meherett Aug 24, 2024
b66bb1a
Update: Tox configuration for testing
meherett Aug 24, 2024
0251c79
Update: all BIP38 test funcs & value.json
meherett Aug 24, 2024
ad92077
Fix: lot and sequence logic & update exceptions
meherett Aug 24, 2024
e47ccb4
Bump: Python-BIP38 into v1.2.0 package
meherett Aug 24, 2024
16c57ea
Merge remote-tracking branch 'origin/master' into axiom90/desktop
axiom90 Aug 24, 2024
d668e74
Update: catch more exceptions
axiom90 Aug 26, 2024
79cf5c8
Update: label for WIF Type
meherett Aug 27, 2024
bf49326
Update: no longer removing combo shadow
axiom90 Aug 30, 2024
be7e251
Update: changed font
axiom90 Sep 3, 2024
dfe9932
Update: new font
axiom90 Oct 16, 2024
9dd56f5
Add: app icon and build script
axiom90 Oct 16, 2024
42127fa
Update: theme colors
axiom90 Oct 18, 2024
5d60840
Update: theme and ui adjustments
axiom90 Oct 20, 2024
fe40dab
Update: font
axiom90 Oct 20, 2024
e4e11cb
Update: combobox shadow
axiom90 Oct 21, 2024
906022f
Update: UI spacing and font
axiom90 Oct 22, 2024
390a44a
Update: app icon
axiom90 Oct 22, 2024
8d22102
Bump: bip38-desktop v0.1.0b2
axiom90 Oct 22, 2024
1ac79c8
Update: ui adjustments
axiom90 Oct 24, 2024
9d88e91
Update: logo
axiom90 Oct 24, 2024
8224c0e
Bump: bip38-desktop v0.1.0b3
axiom90 Oct 24, 2024
b8415fe
Update: build script added author
axiom90 Oct 25, 2024
80b3223
Add: BIP38 logo on README.md
meherett Oct 28, 2024
5ac11dd
Update: ui adjustments, show json for encrypt and passphrase
axiom90 Oct 28, 2024
a560e89
Update: BIP38 logo on README.md
meherett Oct 28, 2024
f06fc47
Bump: bip38-desktop v0.1.0b4
axiom90 Oct 28, 2024
519836a
Add: BIP38 desktop application video
meherett Oct 28, 2024
6828ad2
Add: BIP38 desktop application gif
meherett Oct 28, 2024
57d75d9
Add: BIP38 desktop application videos
meherett Oct 28, 2024
4d2c934
Update: BIP38 desktop application videos
meherett Oct 28, 2024
1b94723
Update: removed generate, minimum height and padding
axiom90 Oct 28, 2024
f31034f
Update: BIP38 logos
meherett Oct 29, 2024
3b738bf
Update: logo
axiom90 Oct 30, 2024
6faacf9
Fix: typo
axiom90 Oct 30, 2024
52589ea
Add: desktop requirement
axiom90 Oct 31, 2024
ce90a9a
Update: BIP38 README.md templates
meherett Oct 31, 2024
2e898d7
Update: requirement and docs
axiom90 Oct 31, 2024
f65068c
Bump: bip38-desktop v0.1.0
axiom90 Oct 31, 2024
4280875
Update: removed combobox shadow
axiom90 Oct 31, 2024
ed82ea3
Update: README.md gif
axiom90 Oct 31, 2024
79b13ba
Fix: removed outline
axiom90 Nov 1, 2024
666147a
Update: exclude unnecessary files for windows
axiom90 Nov 1, 2024
c7f0938
Update: linux app icon
axiom90 Nov 1, 2024
e8c364c
Add: release, manual, api-docs and donations links
meherett Nov 1, 2024
46b5bc7
Merge branch 'master' into axiom90/desktop
axiom90 Nov 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Bitcoin Improvement Proposal - 0038 / BIP38
<h1 align="center" style="border-bottom: none">
<img height="100" alt="BIP38" src="docs/static/svg/bip38.svg"><br>Bitcoin Improvement Proposal - 0038
</h1>

<p align="center">
<a href="https://github.com/meherett/python-bip38/releases" target="_blank">Releases</a> · <a href="https://talonlab.gitbook.io/bip38/manual" target="_blank">Manual</a> · <a href="https://bip38.readthedocs.io" target="_blank">API Docs</a> · <a href="#donations">Donation</a>
</p>

<div align="center">

[![Build Status](https://img.shields.io/github/actions/workflow/status/meherett/python-bip38/build.yml)](https://github.com/meherett/python-bip38/actions/workflows/build.yml)
[![PyPI Version](https://img.shields.io/pypi/v/bip38.svg?color=blue)](https://pypi.org/project/bip38)
Expand All @@ -7,10 +15,14 @@
[![PyPI Python Version](https://img.shields.io/pypi/pyversions/bip38.svg)](https://pypi.org/project/bip38)
[![Coverage Status](https://coveralls.io/repos/github/meherett/python-bip38/badge.svg?branch=master)](https://coveralls.io/github/meherett/python-bip38)

</div>

A Python library for the implementation of Bitcoin Improvement Proposal - 0038 / (BIP38) protocol.
This library supports both [No EC-multiply](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki#encryption-when-ec-multiply-flag-is-not-used) and [EC-multiply](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki#encryption-when-ec-multiply-mode-is-used) modes and is compatible with over 150+ cryptocurrencies.
It's specifically tailored for Pay-to-PubKey-Hash (P2PKH) address types.

![Desktop Application](docs/static/gif/bip38.gif)

For more info see the [Passphrase-protected private key - BIP38](https://en.bitcoin.it/wiki/BIP_0038) spec.

## Installation
Expand Down Expand Up @@ -417,7 +429,7 @@ BIP38 Decrypted: {
To get started, just fork this repo, clone it locally, and run:

```
pip install -e .[tests,docs]
pip install -e .[desktop,tests,docs]
```

## Testing
Expand Down Expand Up @@ -450,9 +462,8 @@ This module supports more than 150+ cryptocurrencies, including the following:

Buy me a coffee if You found this tool helpful:

- **Bitcoin** - 12uaGVdX1t86FXLQ4yYPrRQDCK7xGGu82r
- **Ethereum / Tether** - 0xCCAad7A87fd81553d0F93F743Fb4Fc6B213b228B
- **Bitcoin / Ethereum / Tether** - With Unstoppable [hd.wallet](https://ud.me/hd.wallet)
- **Bitcoin** - 16c7ajUwHEMaafrceuYSrd35SDjmfVdjoS
- **Ethereum / ERC20** - 0xD3cbCB0B6F82A03C715D665b72dC44CEf54e6D9B

Thank you very much for your support.

Expand Down
89 changes: 89 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python3

# Copyright © 2024, Eyoel Tadesse <[email protected]>
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit

from cx_Freeze import setup, Executable

import platform

from desktop.info import __version__ as version
from bip38.info import __author__ as author

app_name = "BIP38"

if platform.system() == "Windows":
icon_path = "desktop/ui/images/icon/icon.ico"
else:
icon_path = "desktop/ui/images/svg/logo.svg"

msi_shortcut_table = [
(
"DesktopShortcut", # Shortcut
"DesktopFolder", # Directory_
app_name, # Name that will be show on the link
"TARGETDIR", # Component_
f"[TARGETDIR]{app_name}.exe", # Target exe to exexute
None, # Arguments
None, # Description
None, # Hotkey
None, # Icon
None, # IconIndex
None, # ShowCmd
'TARGETDIR' # WkDir
)
]

msi_directory_table = [
("ProgramMenuFolder", "TARGETDIR", "."),
("BIP38Menu", "ProgramMenuFolder", "BIP38~1|BIP38")
]

msi_data = {
"Shortcut": msi_shortcut_table,
"Directory": msi_directory_table
}

bdist_msi_opt = {
"add_to_path": False,
"data": msi_data,
"initial_target_dir": f"[ProgramFiles64Folder]\\{app_name}",
"install_icon": icon_path,
"upgrade_code": "{E4A369F6-FC76-3013-A420-3BB9B370711C}"
}

build_exe_opt = {
"packages": ["_scrypt"],
"excludes": ["tkinter", "PySide6.QtNetwork", "PySide6.translations"],
"bin_excludes": [
"Qt6Network.dll", "Qt6OpenGL.dll", "Qt6Pdf.dll", "Qt6Qml.dll", "Qt6QmlMeta.dll",
"Qt6QmlModels.dll", "Qt6QmlWorkerScript.dll", "Qt6Quick.dll", "Qt6VirtualKeyboard.dll",
"qgif.dll", "qicns.dll", "qjpeg.dll", "qpdf.dll", "qtga.dll", "qtiff.dll", "qwbmp.dll", "qwebp.dll",
"qtvirtualkeyboardplugin.dll", "qtuiotouchplugin.dll", "qdirect2d.dll", "qoffscreen.dll", "qminimal.dll"
],
"include_msvcr": True
}

executables = [
Executable(
"launch.py",
base="gui",
icon=icon_path,
target_name=app_name,
shortcut_name=app_name,
shortcut_dir="BIP38Menu",
copyright=f"Copyright (C) 2024 {app_name}"
)
]

setup(
name=app_name,
author=author,
version=version,
executables=executables,
options={
"build_exe": build_exe_opt,
"bdist_msi": bdist_msi_opt
}
)
5 changes: 5 additions & 0 deletions desktop/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python3

# Copyright © 2024, Eyoel Tadesse <[email protected]>
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit
115 changes: 115 additions & 0 deletions desktop/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python3

# Copyright © 2024, Eyoel Tadesse <[email protected]>
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit

from typing import Optional

import json

from PySide6.QtWidgets import (
QMainWindow, QWidget, QStackedWidget,
QFrame, QComboBox
)
from PySide6.QtCore import (
Qt, QFileSystemWatcher, Signal, QSize
)
from PySide6.QtGui import (
QFontDatabase, QIcon
)

from desktop.utils import (
resolve_path, put_svg
)
from desktop.ui.ui_bip38 import Ui_MainWindow
from desktop.info import __version__ as desktop_ver
from bip38.info import __version__ as library_ver

class Application(QMainWindow):
_instance: Optional['Application'] = None
ui: Ui_MainWindow = None
theme_watcher: QFileSystemWatcher = None
resized: Signal = Signal(object)

def __new__(cls, *args, **kwargs) -> 'Application':
"""
Create a new instance if not already created, implementing the Singleton pattern.
"""
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance

def __init__(self) -> None:
"""
Initialize the Application instance if not already initialized.
"""
if not hasattr(self, 'initialized'):
super().__init__()
self.initialize()
self.initialized = True

@classmethod
def instance(cls) -> 'Application':
"""
Get the singleton instance of the Application.

:return: The singleton instance of Application.
"""
if not cls._instance:
cls._instance = cls()
return cls._instance

def initialize(self) -> None:
"""
Perform initialization tasks for the application, such as setting up the UI and loading resources.
"""
self.ui = Ui_MainWindow()
self.ui.setupUi(self)

self.detached_window = None

self.setWindowTitle("Bitcoin Improvement Proposal - 0038")
self.bip38_icon = QIcon(resolve_path("desktop/ui/images/icon/icon.ico"))
self.setWindowIcon(self.bip38_icon)

put_svg(
self.ui.bip38LogoHLayout,
resolve_path("desktop/ui/images/svg/full-logo.svg"),
84,
44
)
self.ui.bip38LogoHLayout.setContentsMargins(0, 0, 5, 0)

css_path = resolve_path("desktop/ui/css/theme.css")
self.theme_watcher = QFileSystemWatcher([css_path])
self.theme_watcher.fileChanged.connect(lambda: self.load_stylesheet(css_path))
QFontDatabase.addApplicationFont(resolve_path("desktop/ui/font/HDWallet.ttf"))
self.load_stylesheet(css_path)

info = {
"library": library_ver,
"desktop": desktop_ver
}
self.ui.outputQTextEdit.setPlaceholderText(json.dumps(info, indent=4))

# remove combo box shadow
for qComboBox in self.findChildren(QComboBox):
qComboBox.findChild(QFrame).setWindowFlags(Qt.Popup | Qt.NoDropShadowWindowHint)

def load_stylesheet(self, path: str) -> None:
"""
Load and apply a stylesheet from the specified path.

:param path: The path to the stylesheet file.
"""
try:
with open(path, 'r', encoding='utf-8') as style_file:
stylesheet = style_file.read()
self.setStyleSheet(stylesheet)
except Exception as e:
print(f"Failed to load stylesheet: {e}")

def resizeEvent(self, event) -> None:
super().resizeEvent(event)
self.resized.emit(event)
7 changes: 7 additions & 0 deletions desktop/info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python3

# Copyright © 2024, Eyoel Tadesse <[email protected]>
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit

__version__: str = "v0.1.0"
Loading