diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 11bf95ae..cef85d81 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7] + python-version: [3.6, 3.7, 3.8] steps: - uses: actions/checkout@v1 @@ -14,24 +14,33 @@ jobs: uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Install pip run: | python -m pip install --upgrade pip - pip install -r requirements.txt - - name: Lint with black + - name: Lint all code with black run: | pip install black # stop the build if the code was not reformatted by black black . --check - - name: Lint with flake8 + - name: Lint all code with flake8 run: | pip install flake8 - # stop the build if there are Python syntax errors or undefined names + # stop the build if there are syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --ignore=E203,E221,E261,E731,W503 --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest + # exit-zero treats all errors as warnings + flake8 . --count --exit-zero --ignore=E203,E221,E261,E731,W503 --max-complexity=10 --max-line-length=88 --statistics + - name: Install the poetry tool run: | - pip install pytest - cd .. - python -m pytest ./tinydecred/tests/unit/ + pip install poetry + - name: Install the decred package and its dependencies (including pytest) + working-directory: ./decred/ + run: | + poetry install + - name: Test the decred package with pytest + working-directory: ./decred/ + run: | + poetry run pytest ./tests/unit/ + - name: Build the decred package + working-directory: ./decred/ + run: | + poetry build diff --git a/.gitignore b/.gitignore index f74d830d..92573157 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,11 @@ +examples/testnet +decred/dist +tinywallet/dist +decred/poetry.lock __pycache__/ +.pytest_cache +.coverage +.venv +*.egg-info *.sublime-project *.sublime-workspace -examples/testnet -.coverage diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..e951634b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,33 @@ +# Contribution guidelines + +Thank you for contributing to this project! The developers are part of the +[Decred community](https://decred.org/community/) and coordinate in a +[chat](https://chat.decred.org/#/room/#tinydecred:decred.org) on the +[Matrix](https://matrix.org/) platform, you'll need a (free) account to access +it. + +## Bugs and new features + +If you found a bug, before creating an issue please search among the +[open ones](https://github.com/decred/tinydecred/issues). Please add as many +useful details as you can. + +If you'd like to request a new feature, either create an issue (again, after +searching first) or chat with us on Matrix (see above). + +## Development + +The [Poetry](https://python-poetry.org/) tool is used for dependency management +and packaging. You'll reformat your changes with the +[Black](https://black.readthedocs.io/) tool and run tests using +[pytest](https://www.pytest.org/). + +Before each pull request is merged, a Github workflow action is run to make +sure that the changes meet some minimum requirements. The action definition +[file](./.github/workflows/python.yml) is a useful summary of the commands +you'll run while developing. + +## More information + +Please find more information in the dcrd +[contribution guidelines](https://github.com/decred/dcrd/blob/master/docs/code_contribution_guidelines.md). diff --git a/README.md b/README.md index 6a79b884..16303fb5 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,23 @@ -tinydecred -========== +# tinydecred [![Build Status](https://github.com/decred/tinydecred/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/tinydecred/actions) -[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](https://copyfree.org/) -## Overview +TinyDecred is a Python 3 toolkit that can be used to integrate +[Decred](https://decred.org/) into Python projects. -A Python 3 Decred toolkit. The modules in TinyDecred can be used to integrate -Decred into Python projects. Everything needed to create wallets to send and -receive DCR. +The [`decred`](./decred) package contains everything needed to create wallets +to send and receive DCR. -## Features +The [`tinywallet`](./tinywallet) package contains a wallet based on the +`decred` toolkit. -1. Pure-Python secp256k1 elliptic curve. - -1. Serializable and de-serializable python versions of important types -from the dcrd/wire package: `MsgTx`, `BlockHeader`, `OutPoint`, etc. - -1. BIP-0044 keys. Account creation and management. PGP mnemonic seeds. - -1. Network parameters for mainnet, testnet3, and simnet. - -1. Clients for the dcrdata block explorer API (websockets, pubsub, HTTP). - -1. Experimental PyQt5 light wallet. - -## Installation - -Install by cloning the git repo. -The parent directory of *tinydecred* will need to be in `sys.path`. -You can add it by setting the `PYTHONPATH` environment variable. -Alternatively, you can put a symlink to the *tinydecred* directory in your -Python installation's *lib/site-packages/* directory or other `sys.path` -directory. - -All dependencies are available through PyPi. - -``` -pip3 install -r requirements.txt -``` - -though depending on your setup, you may need `sudo`, and `pip3` might be `pip`. - -You're probably okay to use newer versions of PyQt5, but `5.9.2` has been -remarkably stable. - -## Examples - -In the examples directory, there are scripts for creating and using wallets, -and for using dcrdata and matplotlib to plot Decred network data. - -## TinyDecred GUI Wallet - -TinyDecred is the name of the package as well as the experimental light wallet -GUI application. -**The light wallet is experimental, and should not be used on mainnet.** - -To start the wallet, navigate to the `tinydecred` package directory, and run - -``` -python app.py --testnet -``` - -The wallet runs as a system-tray application, of which the major difference is -that "closing" the wallet actually just removes the entry from the taskbar and -minimizes the window "to the system tray". -The wallet can then be "opened" again through the icon in the system tray. - -![alt text][screenshot] - -TinyDecred is pretty small. -Like Decred, it's meant to be an omnipresent yet largely invisible and -unobtrusive part of your digital environment. -The small dialog size keeps user interactions focused. -Bells and whistles are minimized in favor of simplicity whenever possible. -Blockchain mechanics are invisible. -The goal is to make using Decred easier than pulling change out of your pocket. +Each package may be installed from the [Python Package Index](https://pypi.org/) +using the [`pip`](https://pip.pypa.io/) command as usual. ## Roadmap -In no particular order +In no particular order: - Staking - Schnorr signatures and Edwards curve @@ -88,4 +26,6 @@ In no particular order - Decred DEX integration - Lightning network -[screenshot]: https://user-images.githubusercontent.com/6109680/62095772-08b4ce80-b247-11e9-81ae-66931ebb07be.png +## Contributing + +See the [contribution guidelines](./CONTRIBUTING.md). diff --git a/.coveragerc b/decred/.coveragerc similarity index 100% rename from .coveragerc rename to decred/.coveragerc diff --git a/pydecred/README.md b/decred/README.md similarity index 90% rename from pydecred/README.md rename to decred/README.md index f1e9cec5..e1f9890e 100644 --- a/pydecred/README.md +++ b/decred/README.md @@ -1,25 +1,31 @@ -## PyDecred +# decred -PyDecred is a set of modules that enable Decred-compatible blockchain -applications. The **dcrdata** module contains a dcrdata client and a TinyDecred -*Blockchain API* implementation. +The `decred` package contains everything needed to create +[Decred](https://decred.org/) applications in Python. -The **wire** module mirrors it's dcrd golang counterpart, providing serializable -transactions and blocks. +## Features -Network parameters are implemented as modules **mainnet**, **testnet**, and -**simnet**. +1. Pure-Python secp256k1 elliptic curve. + +1. Serializable and de-serializable python versions of important types +from the `dcrd/wire` package: `MsgTx`, `BlockHeader`, `OutPoint`, etc. + +1. BIP-0044 keys. Account creation and management. PGP mnemonic seeds. + +1. Network parameters for mainnet, testnet3, and simnet. + +1. Clients for the dcrdata block explorer API (websockets, pubsub, HTTP). ## DcrdataClient DcrdataClient is a dcrdata API client written in Python 3. The constructor takes a single argument, which is the path to a dcrdata server, -including protocol, e.g. `https://explorer.dcrdata.org`. The available endpoints -are gathered from the server when the client is created. +including protocol, e.g. `https://explorer.dcrdata.org/`. The available +endpoints are gathered from the server when the client is created. ``` -from tinydecred.pydecred.dcrdata import DcrdataClient +from decred.dcr.dcrdata import DcrdataClient import json client = DcrdataClient("https://explorer.dcrdata.org") @@ -33,13 +39,17 @@ The acquired list does not include some endpoints, particularly the Insight API endpoints. You can print an endpoint guide to the console with `client.endpointGuide()`, - or a Python list of URLs is returned from `client.endpointList()`. Depending on the version of dcrdata they are running, different servers might have different sets of endpoints. -### Examples +## Examples + +In the [`examples`](./examples) directory there are scripts for creating and +using wallets, and for using dcrdata and matplotlib to plot Decred network data. + +Here are some more examples: ``` def dumpResponse(obj): diff --git a/__init__.py b/decred/decred/__init__.py similarity index 100% rename from __init__.py rename to decred/decred/__init__.py diff --git a/config.py b/decred/decred/config.py similarity index 98% rename from config.py rename to decred/decred/config.py index 9721f4b9..cdac2f28 100644 --- a/config.py +++ b/decred/decred/config.py @@ -11,8 +11,9 @@ from appdirs import AppDirs -from tinydecred.pydecred import nets -from tinydecred.util import helpers +from decred.dcr import nets +from decred.util import helpers + # Set the data directory in a OS-appropriate location. _ad = AppDirs("TinyDecred", False) diff --git a/crypto/__init__.py b/decred/decred/crypto/__init__.py similarity index 100% rename from crypto/__init__.py rename to decred/decred/crypto/__init__.py diff --git a/crypto/crypto.py b/decred/decred/crypto/crypto.py similarity index 99% rename from crypto/crypto.py rename to decred/decred/crypto/crypto.py index b356b773..7b3ef9ce 100644 --- a/crypto/crypto.py +++ b/decred/decred/crypto/crypto.py @@ -13,10 +13,10 @@ from blake256.blake256 import blake_hash import nacl.secret -from tinydecred.util.encode import ByteArray -from tinydecred.crypto import rando -from tinydecred.crypto.secp256k1.curve import curve as Curve, PublicKey, PrivateKey -from tinydecred.util import encode +from decred.util import encode +from decred.util.encode import ByteArray +from . import rando +from .secp256k1.curve import curve as Curve, PublicKey, PrivateKey KEY_SIZE = 32 diff --git a/crypto/mnemonic.py b/decred/decred/crypto/mnemonic.py similarity index 98% rename from crypto/mnemonic.py rename to decred/decred/crypto/mnemonic.py index 13f04177..4328c1c9 100644 --- a/crypto/mnemonic.py +++ b/decred/decred/crypto/mnemonic.py @@ -6,8 +6,9 @@ PGP-based mnemonic seed generation. """ -from tinydecred.util.encode import ByteArray -from tinydecred.crypto.crypto import sha256ChecksumByte +from decred.util.encode import ByteArray +from .crypto import sha256ChecksumByte + alternatingWords = """aardvark adroitness diff --git a/crypto/opcode.py b/decred/decred/crypto/opcode.py similarity index 100% rename from crypto/opcode.py rename to decred/decred/crypto/opcode.py diff --git a/crypto/rando.py b/decred/decred/crypto/rando.py similarity index 100% rename from crypto/rando.py rename to decred/decred/crypto/rando.py diff --git a/crypto/secp256k1/__init__.py b/decred/decred/crypto/secp256k1/__init__.py similarity index 100% rename from crypto/secp256k1/__init__.py rename to decred/decred/crypto/secp256k1/__init__.py diff --git a/crypto/secp256k1/bytepoints.py b/decred/decred/crypto/secp256k1/bytepoints.py similarity index 100% rename from crypto/secp256k1/bytepoints.py rename to decred/decred/crypto/secp256k1/bytepoints.py diff --git a/crypto/secp256k1/curve.py b/decred/decred/crypto/secp256k1/curve.py similarity index 99% rename from crypto/secp256k1/curve.py rename to decred/decred/crypto/secp256k1/curve.py index 3f6e729c..cf5d6b76 100644 --- a/crypto/secp256k1/curve.py +++ b/decred/decred/crypto/secp256k1/curve.py @@ -8,9 +8,10 @@ dcrd golang version. """ -from tinydecred.util.encode import ByteArray -from tinydecred.crypto.rando import generateSeed -from tinydecred.crypto.secp256k1.field import FieldVal, BytePoints +from decred.util.encode import ByteArray +from decred.crypto.rando import generateSeed +from .field import BytePoints, FieldVal + COORDINATE_LEN = 32 PUBKEY_COMPRESSED_LEN = COORDINATE_LEN + 1 diff --git a/crypto/secp256k1/field.py b/decred/decred/crypto/secp256k1/field.py similarity index 99% rename from crypto/secp256k1/field.py rename to decred/decred/crypto/secp256k1/field.py index 00c58189..c628d5e2 100644 --- a/crypto/secp256k1/field.py +++ b/decred/decred/crypto/secp256k1/field.py @@ -7,8 +7,9 @@ from base64 import b64decode from zlib import decompress as zdecompress -from tinydecred.util.encode import ByteArray -from tinydecred.crypto.secp256k1.bytepoints import secp256k1BytePoints +from decred.util.encode import ByteArray +from .bytepoints import secp256k1BytePoints + # Constants used to make the code more readable. twoBitsMask = 0x03 diff --git a/pydecred/__init__.py b/decred/decred/dcr/__init__.py similarity index 100% rename from pydecred/__init__.py rename to decred/decred/dcr/__init__.py diff --git a/pydecred/account.py b/decred/decred/dcr/account.py similarity index 99% rename from pydecred/account.py rename to decred/decred/dcr/account.py index 8f63e0b0..de24f64c 100644 --- a/pydecred/account.py +++ b/decred/decred/dcr/account.py @@ -3,11 +3,11 @@ See LICENSE for details """ -from tinydecred.util import helpers, encode -from tinydecred.crypto import opcode, crypto -from tinydecred.pydecred import txscript -from tinydecred.pydecred.vsp import VotingServiceProvider -from tinydecred.pydecred import nets +from decred.crypto import opcode, crypto +from decred.util import encode, helpers +from . import nets, txscript +from .vsp import VotingServiceProvider + log = helpers.getLogger("DCRACCT") diff --git a/pydecred/calc.py b/decred/decred/dcr/calc.py similarity index 99% rename from pydecred/calc.py rename to decred/decred/dcr/calc.py index aceed474..a1b35bb4 100644 --- a/pydecred/calc.py +++ b/decred/decred/dcr/calc.py @@ -4,10 +4,13 @@ Some network math. """ -import math + import bisect -from tinydecred.util import helpers -from tinydecred.pydecred import constants as C, mainnet +import math + +from decred.util import helpers +from . import constants as C, mainnet + NETWORK = mainnet MODEL_DEVICE = { diff --git a/pydecred/constants.py b/decred/decred/dcr/constants.py similarity index 99% rename from pydecred/constants.py rename to decred/decred/dcr/constants.py index fcc262e4..4ed11562 100644 --- a/pydecred/constants.py +++ b/decred/decred/dcr/constants.py @@ -4,8 +4,10 @@ Just some constants. """ + import os + PYDECRED_PACKAGEDIR = os.path.dirname(os.path.realpath(__file__)) FAVICON = os.path.join(PYDECRED_PACKAGEDIR, "favicon-32x32.png") LOGO = os.path.join(PYDECRED_PACKAGEDIR, "logo.svg") diff --git a/pydecred/dcrdata.py b/decred/decred/dcr/dcrdata.py similarity index 99% rename from pydecred/dcrdata.py rename to decred/decred/dcr/dcrdata.py index fe7fcd2a..0dc99d9c 100644 --- a/pydecred/dcrdata.py +++ b/decred/decred/dcr/dcrdata.py @@ -5,24 +5,25 @@ DcrdataClient.endpointList() for available enpoints. """ -from urllib.parse import urlparse, urlencode -import time +import atexit import calendar -import threading +import json +import select import ssl import sys -import select -import atexit +import threading +import time +from urllib.parse import urlparse, urlencode import websocket -import json -from tinydecred.util import helpers, database, tinyhttp -from tinydecred.crypto import crypto -from tinydecred.util import encode, chains -from tinydecred.wallet import api -from tinydecred.pydecred import txscript, calc, account -from tinydecred.pydecred.wire import msgtx, wire, msgblock -from tinydecred.util.database import KeyValueDatabase + +from decred.crypto import crypto +from decred.util import chains, database, encode, helpers, tinyhttp +from decred.util.database import KeyValueDatabase +from decred.wallet import api +from . import account, calc, txscript +from .wire import msgblock, msgtx, wire + ByteArray = encode.ByteArray BuildyBytes = encode.BuildyBytes diff --git a/pydecred/favicon-32x32.png b/decred/decred/dcr/favicon-32x32.png similarity index 100% rename from pydecred/favicon-32x32.png rename to decred/decred/dcr/favicon-32x32.png diff --git a/pydecred/logo.svg b/decred/decred/dcr/logo.svg similarity index 100% rename from pydecred/logo.svg rename to decred/decred/dcr/logo.svg diff --git a/pydecred/mainnet.py b/decred/decred/dcr/mainnet.py similarity index 99% rename from pydecred/mainnet.py rename to decred/decred/dcr/mainnet.py index 6aa1f995..2fec46c9 100644 --- a/pydecred/mainnet.py +++ b/decred/decred/dcr/mainnet.py @@ -6,7 +6,9 @@ mainnet holds mainnet parameters. Any values should mirror exactly https://github.com/decred/dcrd/blob/master/chaincfg/mainnetparams.go """ -import tinydecred.pydecred.constants as C + +from . import constants as C + Name = "mainnet" DefaultPort = "9108" diff --git a/pydecred/nets.py b/decred/decred/dcr/nets.py similarity index 82% rename from pydecred/nets.py rename to decred/decred/dcr/nets.py index f2515930..80566abb 100644 --- a/pydecred/nets.py +++ b/decred/decred/dcr/nets.py @@ -1,8 +1,10 @@ """ -Copyright (c) 2019, Brian Stafford +Copyright (c) 2019, The Decred developers +See LICENSE for details """ -from tinydecred.pydecred import mainnet, testnet, simnet +from . import mainnet, testnet, simnet + mainnet = mainnet testnet = testnet diff --git a/pydecred/rpc.py b/decred/decred/dcr/rpc.py similarity index 99% rename from pydecred/rpc.py rename to decred/decred/dcr/rpc.py index c7745978..c96e7f98 100644 --- a/pydecred/rpc.py +++ b/decred/decred/dcr/rpc.py @@ -1,9 +1,15 @@ +""" +Copyright (c) 2019, The Decred developers +See LICENSE for details +""" + import base64 import ssl -from tinydecred.util import tinyhttp -from tinydecred.util.encode import ByteArray -from tinydecred.pydecred.wire.msgtx import MsgTx -from tinydecred.pydecred.wire.msgblock import BlockHeader + +from decred.util import tinyhttp +from decred.util.encode import ByteArray +from .wire.msgblock import BlockHeader +from .wire.msgtx import MsgTx class Client(object): diff --git a/pydecred/simnet.py b/decred/decred/dcr/simnet.py similarity index 100% rename from pydecred/simnet.py rename to decred/decred/dcr/simnet.py diff --git a/pydecred/testnet.py b/decred/decred/dcr/testnet.py similarity index 99% rename from pydecred/testnet.py rename to decred/decred/dcr/testnet.py index 9717a305..edac2ada 100644 --- a/pydecred/testnet.py +++ b/decred/decred/dcr/testnet.py @@ -6,6 +6,7 @@ testnet holds testnet3 parameters. Any values should mirror exactly https://github.com/decred/dcrd/blob/master/chaincfg/testnetparams.go """ + Name = "testnet3" DefaultPort = "19108" DNSSeeds = [ diff --git a/pydecred/txscript.py b/decred/decred/dcr/txscript.py similarity index 99% rename from pydecred/txscript.py rename to decred/decred/dcr/txscript.py index 43b56eb0..2d33e903 100644 --- a/pydecred/txscript.py +++ b/decred/decred/dcr/txscript.py @@ -8,11 +8,11 @@ import math -from tinydecred.crypto import crypto, opcode -from tinydecred.crypto.secp256k1.curve import curve as Curve -from tinydecred.pydecred.wire import msgtx, wire -from tinydecred.util import helpers -from tinydecred.util.encode import ByteArray +from decred.crypto import crypto, opcode +from decred.crypto.secp256k1.curve import curve as Curve +from decred.util import helpers +from decred.util.encode import ByteArray +from .wire import msgtx, wire log = helpers.getLogger("TXSCRIPT") diff --git a/pydecred/vsp.py b/decred/decred/dcr/vsp.py similarity index 98% rename from pydecred/vsp.py rename to decred/decred/dcr/vsp.py index acddc39b..14f3888d 100644 --- a/pydecred/vsp.py +++ b/decred/decred/dcr/vsp.py @@ -8,10 +8,10 @@ import time -from tinydecred.crypto import crypto -from tinydecred.pydecred import constants, nets, txscript -from tinydecred.util import encode, tinyhttp -from tinydecred.util.encode import ByteArray +from decred.crypto import crypto +from decred.util import encode, tinyhttp +from decred.util.encode import ByteArray +from . import constants, nets, txscript # The duration purchase info is good for. diff --git a/pydecred/wire/__init__.py b/decred/decred/dcr/wire/__init__.py similarity index 100% rename from pydecred/wire/__init__.py rename to decred/decred/dcr/wire/__init__.py diff --git a/pydecred/wire/msgblock.py b/decred/decred/dcr/wire/msgblock.py similarity index 98% rename from pydecred/wire/msgblock.py rename to decred/decred/dcr/wire/msgblock.py index 6d6c9389..d5ef90ae 100644 --- a/pydecred/wire/msgblock.py +++ b/decred/decred/dcr/wire/msgblock.py @@ -6,8 +6,9 @@ Based on dcrd MsgBlock. """ -from tinydecred.util.encode import ByteArray -from tinydecred.crypto.crypto import hashH +from decred.crypto.crypto import hashH +from decred.util.encode import ByteArray + # chainhash.HashSize in go HASH_SIZE = 32 diff --git a/pydecred/wire/msgtx.py b/decred/decred/dcr/wire/msgtx.py similarity index 99% rename from pydecred/wire/msgtx.py rename to decred/decred/dcr/wire/msgtx.py index c5d73702..67893681 100644 --- a/pydecred/wire/msgtx.py +++ b/decred/decred/dcr/wire/msgtx.py @@ -6,9 +6,9 @@ Based on dcrd MsgTx. """ -from tinydecred.util.encode import ByteArray -from tinydecred.crypto.crypto import hashH -from tinydecred.pydecred.wire import wire +from decred.crypto.crypto import hashH +from decred.util.encode import ByteArray +from . import wire # TxVersion is the current latest supported transaction version. diff --git a/pydecred/wire/wire.py b/decred/decred/dcr/wire/wire.py similarity index 99% rename from pydecred/wire/wire.py rename to decred/decred/dcr/wire/wire.py index 7d029bae..b2023769 100644 --- a/pydecred/wire/wire.py +++ b/decred/decred/dcr/wire/wire.py @@ -6,7 +6,8 @@ Constants and common routines from the dcrd wire package. """ -from tinydecred.util.encode import ByteArray +from decred.util.encode import ByteArray + # fmt: off MaxInt8 = (1 << 7) - 1 diff --git a/util/__init__.py b/decred/decred/util/__init__.py similarity index 100% rename from util/__init__.py rename to decred/decred/util/__init__.py diff --git a/util/chains.py b/decred/decred/util/chains.py similarity index 93% rename from util/chains.py rename to decred/decred/util/chains.py index f1340893..746eafaa 100644 --- a/util/chains.py +++ b/decred/decred/util/chains.py @@ -1,4 +1,9 @@ -from tinydecred.pydecred import account as dcracct, nets as dcrnets +""" +Copyright (c) 2019, The Decred developers +See LICENSE for details +""" + +from decred.dcr import account as dcracct, nets as dcrnets class BipIDs: diff --git a/util/database.py b/decred/decred/util/database.py similarity index 99% rename from util/database.py rename to decred/decred/util/database.py index a04b1845..9037d3ce 100644 --- a/util/database.py +++ b/decred/decred/util/database.py @@ -15,7 +15,6 @@ import sqlite3 import threading -import time class NoValue(Exception): diff --git a/util/encode.py b/decred/decred/util/encode.py similarity index 99% rename from util/encode.py rename to decred/decred/util/encode.py index 4932266e..75b8e099 100644 --- a/util/encode.py +++ b/decred/decred/util/encode.py @@ -8,6 +8,7 @@ import struct + NONE = "None".encode() diff --git a/util/helpers.py b/decred/decred/util/helpers.py similarity index 100% rename from util/helpers.py rename to decred/decred/util/helpers.py diff --git a/util/tinyhttp.py b/decred/decred/util/tinyhttp.py similarity index 96% rename from util/tinyhttp.py rename to decred/decred/util/tinyhttp.py index 5e728085..5833dbb7 100644 --- a/util/tinyhttp.py +++ b/decred/decred/util/tinyhttp.py @@ -4,10 +4,12 @@ DcrdataClient.endpointList() for available enpoints. """ + import json from urllib.parse import urlencode import urllib.request as urlrequest -from tinydecred.util.helpers import formatTraceback + +from .helpers import formatTraceback def get(uri, **kwargs): diff --git a/wallet/__init__.py b/decred/decred/wallet/__init__.py similarity index 100% rename from wallet/__init__.py rename to decred/decred/wallet/__init__.py diff --git a/wallet/accounts.py b/decred/decred/wallet/accounts.py similarity index 98% rename from wallet/accounts.py rename to decred/decred/wallet/accounts.py index 084133ba..107bb95a 100644 --- a/wallet/accounts.py +++ b/decred/decred/wallet/accounts.py @@ -9,8 +9,9 @@ The tinycrypto package relies heavily on the lower-level crypto modules. """ -from tinydecred.crypto import crypto -from tinydecred.util import encode, helpers, chains +from decred.crypto import crypto +from decred.util import chains, encode, helpers + ByteArray = encode.ByteArray BuildyBytes = encode.BuildyBytes diff --git a/wallet/api.py b/decred/decred/wallet/api.py similarity index 100% rename from wallet/api.py rename to decred/decred/wallet/api.py diff --git a/wallet/wallet.py b/decred/decred/wallet/wallet.py similarity index 97% rename from wallet/wallet.py rename to decred/decred/wallet/wallet.py index 1efd16b3..eee31644 100644 --- a/wallet/wallet.py +++ b/decred/decred/wallet/wallet.py @@ -3,12 +3,15 @@ Copyright (c) 2019, The Decred developers See LICENSE for details """ + from threading import Lock as Mutex -from tinydecred.util import helpers, encode, chains -from tinydecred.util.database import KeyValueDatabase -from tinydecred.crypto import crypto, mnemonic, rando -from tinydecred.wallet import accounts -from tinydecred import config + +from decred import config +from decred.crypto import crypto, mnemonic, rando +from decred.util import chains, encode, helpers +from decred.util.database import KeyValueDatabase +from . import accounts + cfg = config.load() diff --git a/examples/create_testnet_wallet.py b/decred/examples/create_testnet_wallet.py similarity index 87% rename from examples/create_testnet_wallet.py rename to decred/examples/create_testnet_wallet.py index cc114b8f..ca9b8470 100644 --- a/examples/create_testnet_wallet.py +++ b/decred/examples/create_testnet_wallet.py @@ -8,12 +8,12 @@ import os from getpass import getpass -from tinydecred import config +from decred import config # Set the configuration for testnet before loading TD modules. config.load("testnet") -from tinydecred.util.helpers import mkdir -from tinydecred.wallet.wallet import Wallet +from decred.util.helpers import mkdir +from decred.wallet.wallet import Wallet # Create an encrypted, password-protected wallet file. diff --git a/examples/plot_ticket_price.py b/decred/examples/plot_ticket_price.py similarity index 85% rename from examples/plot_ticket_price.py rename to decred/examples/plot_ticket_price.py index cac13bad..70d5937c 100644 --- a/examples/plot_ticket_price.py +++ b/decred/examples/plot_ticket_price.py @@ -2,12 +2,12 @@ Copyright (c) 2019, The Decred developers This example script will pull ticket price data from dcrdata and plot using -matplotlib. The matplotlib package is not a tinydecred dependency, so it should +matplotlib. The matplotlib package is not a decred dependency, so it should be installed separately with `pip3 install matplotlib`. """ -from tinydecred.pydecred.dcrdata import DcrdataClient -from tinydecred.util.helpers import mktime +from decred.dcr.dcrdata import DcrdataClient +from decred.util.helpers import mktime try: from matplotlib import pyplot as plt diff --git a/examples/send_testnet.py b/decred/examples/send_testnet.py similarity index 90% rename from examples/send_testnet.py rename to decred/examples/send_testnet.py index 477b4329..7576a187 100644 --- a/examples/send_testnet.py +++ b/decred/examples/send_testnet.py @@ -10,14 +10,14 @@ import os from getpass import getpass -from tinydecred import config +from decred import config # Set the configuration for testnet before loading TD modules. config.load("testnet") -from tinydecred.pydecred import testnet -from tinydecred.pydecred.dcrdata import DcrdataBlockchain -from tinydecred.wallet.wallet import Wallet +from decred.dcr import testnet +from decred.dcr.dcrdata import DcrdataBlockchain +from decred.wallet.wallet import Wallet # We need a class that implements the Signals API. diff --git a/decred/pyproject.toml b/decred/pyproject.toml new file mode 100644 index 00000000..9bfdb807 --- /dev/null +++ b/decred/pyproject.toml @@ -0,0 +1,39 @@ +[tool.poetry] +name = "decred" +version = "0.0.1" +description = "A Python 3 Decred toolkit." +license = "ISC" +homepage = "https://decred.org/" +repository = "https://github.com/decred/tinydecred/" +documentation = "https://github.com/decred/tinydecred/blob/master/decred" +authors = [ + "Brian Stafford ", + "The Decred developers " +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: ISC License (ISCL)", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Topic :: Office/Business :: Financial" +] + +[tool.poetry.dependencies] +python = "^3.6" +appdirs = "^1.4.3" +base58 = "^2.0.0" +blake256 = "^0.1.1" +pynacl = "^1.3.0" +websocket_client = "^0.57.0" + +[tool.poetry.dev-dependencies] +pytest = "^5.2" +pyflakes = "^2.1.1" +black = "^19.10b0" + +[build-system] +requires = ["poetry>=1.0.2"] +build-backend = "poetry.masonry.api" diff --git a/tests/integration/pydecred/test_dcrdata.py b/decred/tests/integration/dcr/test_dcrdata.py similarity index 97% rename from tests/integration/pydecred/test_dcrdata.py rename to decred/tests/integration/dcr/test_dcrdata.py index 786c8c83..5e63facc 100644 --- a/tests/integration/pydecred/test_dcrdata.py +++ b/decred/tests/integration/dcr/test_dcrdata.py @@ -4,15 +4,16 @@ """ import os -import unittest from tempfile import TemporaryDirectory import time +import unittest + +from decred.crypto import crypto, rando +from decred.crypto.secp256k1 import curve as Curve +from decred.dcr import account, dcrdata, mainnet, testnet, txscript +from decred.dcr.wire import msgtx +from decred.util import encode -from tinydecred.pydecred import mainnet, testnet, txscript, dcrdata, account -from tinydecred.pydecred.wire import msgtx -from tinydecred.crypto import crypto, rando -from tinydecred.util import encode -from tinydecred.crypto.secp256k1 import curve as Curve ByteArray = encode.ByteArray diff --git a/tests/integration/pydecred/test_rpc.py b/decred/tests/integration/dcr/test_rpc.py similarity index 97% rename from tests/integration/pydecred/test_rpc.py rename to decred/tests/integration/dcr/test_rpc.py index 6a7a38c3..4a3717cf 100644 --- a/tests/integration/pydecred/test_rpc.py +++ b/decred/tests/integration/dcr/test_rpc.py @@ -1,10 +1,17 @@ -import pytest +""" +Copyright (c) 2019, the Decred developers +See LICENSE for details +""" + import os -from tinydecred.pydecred import rpc -from tinydecred.util.encode import ByteArray -from tinydecred.util import helpers -from tinydecred.pydecred.wire.msgtx import MsgTx -from tinydecred.pydecred.wire.msgblock import BlockHeader + +import pytest + +from decred.dcr import rpc +from decred.dcr.wire.msgblock import BlockHeader +from decred.dcr.wire.msgtx import MsgTx +from decred.util import helpers +from decred.util.encode import ByteArray @pytest.fixture diff --git a/tests/integration/pydecred/test_vsp.py b/decred/tests/integration/dcr/test_vsp.py similarity index 96% rename from tests/integration/pydecred/test_vsp.py rename to decred/tests/integration/dcr/test_vsp.py index f212a860..6ab78b9d 100644 --- a/tests/integration/pydecred/test_vsp.py +++ b/decred/tests/integration/dcr/test_vsp.py @@ -4,7 +4,8 @@ """ import unittest -from tinydecred.pydecred import testnet, vsp + +from decred.dcr import testnet, vsp class TestVSPLive(unittest.TestCase): diff --git a/tests/unit/crypto/secp256k1/test_curve.py b/decred/tests/unit/crypto/secp256k1/test_curve.py similarity index 99% rename from tests/unit/crypto/secp256k1/test_curve.py rename to decred/tests/unit/crypto/secp256k1/test_curve.py index 479713c8..a21f169e 100644 --- a/tests/unit/crypto/secp256k1/test_curve.py +++ b/decred/tests/unit/crypto/secp256k1/test_curve.py @@ -5,7 +5,7 @@ import unittest -from tinydecred.crypto.secp256k1 import curve +from decred.crypto.secp256k1 import curve class TestCurve(unittest.TestCase): diff --git a/tests/unit/crypto/secp256k1/test_field.py b/decred/tests/unit/crypto/secp256k1/test_field.py similarity index 99% rename from tests/unit/crypto/secp256k1/test_field.py rename to decred/tests/unit/crypto/secp256k1/test_field.py index e7d493f5..0e777208 100644 --- a/tests/unit/crypto/secp256k1/test_field.py +++ b/decred/tests/unit/crypto/secp256k1/test_field.py @@ -5,7 +5,7 @@ import unittest -from tinydecred.crypto.secp256k1 import field +from decred.crypto.secp256k1 import field class TestField(unittest.TestCase): diff --git a/tests/unit/crypto/test_crypto.py b/decred/tests/unit/crypto/test_crypto.py similarity index 97% rename from tests/unit/crypto/test_crypto.py rename to decred/tests/unit/crypto/test_crypto.py index fa57e9b4..40da8d24 100644 --- a/tests/unit/crypto/test_crypto.py +++ b/decred/tests/unit/crypto/test_crypto.py @@ -5,9 +5,9 @@ import unittest -from tinydecred.crypto import crypto, rando -from tinydecred.pydecred import mainnet -from tinydecred.util.encode import ByteArray +from decred.crypto import crypto, rando +from decred.dcr import mainnet +from decred.util.encode import ByteArray testSeed = ByteArray( diff --git a/tests/unit/crypto/test_mnemonic.py b/decred/tests/unit/crypto/test_mnemonic.py similarity index 95% rename from tests/unit/crypto/test_mnemonic.py rename to decred/tests/unit/crypto/test_mnemonic.py index c7d6c3cc..3d3241be 100644 --- a/tests/unit/crypto/test_mnemonic.py +++ b/decred/tests/unit/crypto/test_mnemonic.py @@ -5,8 +5,8 @@ import unittest -from tinydecred.crypto import mnemonic -from tinydecred.util.encode import ByteArray +from decred.crypto import mnemonic +from decred.util.encode import ByteArray class TestMnemonic(unittest.TestCase): diff --git a/tests/unit/pydecred/test-data/sighash.json b/decred/tests/unit/dcr/test-data/sighash.json similarity index 100% rename from tests/unit/pydecred/test-data/sighash.json rename to decred/tests/unit/dcr/test-data/sighash.json diff --git a/tests/unit/pydecred/test_calc.py b/decred/tests/unit/dcr/test_calc.py similarity index 99% rename from tests/unit/pydecred/test_calc.py rename to decred/tests/unit/dcr/test_calc.py index 32c18074..8bcd2419 100644 --- a/tests/unit/pydecred/test_calc.py +++ b/decred/tests/unit/dcr/test_calc.py @@ -5,10 +5,9 @@ import unittest -from tinydecred.pydecred import mainnet -from tinydecred.pydecred.calc import SubsidyCache - -from tinydecred.util import chains +from decred.dcr import mainnet +from decred.dcr.calc import SubsidyCache +from decred.util import chains class TestSubsidyCache(unittest.TestCase): diff --git a/tests/unit/pydecred/test_txscript.py b/decred/tests/unit/dcr/test_txscript.py similarity index 99% rename from tests/unit/pydecred/test_txscript.py rename to decred/tests/unit/dcr/test_txscript.py index d0bca975..b3519e23 100644 --- a/tests/unit/pydecred/test_txscript.py +++ b/decred/tests/unit/dcr/test_txscript.py @@ -6,19 +6,19 @@ from base58 import b58decode import json import os -import unittest from tempfile import TemporaryDirectory import time +import unittest -from tinydecred.crypto import crypto, opcode, rando -from tinydecred.crypto.secp256k1 import curve as Curve -from tinydecred.pydecred import account, mainnet, testnet, txscript, vsp -from tinydecred.pydecred.calc import SubsidyCache -from tinydecred.pydecred.wire import msgtx, wire -from tinydecred.util import database -from tinydecred.util.encode import ByteArray -from tinydecred.wallet.accounts import createAccount +from decred.crypto import crypto, opcode, rando +from decred.crypto.secp256k1 import curve as Curve +from decred.dcr import account, mainnet, testnet, txscript, vsp +from decred.dcr.calc import SubsidyCache +from decred.dcr.wire import msgtx, wire +from decred.util import database +from decred.util.encode import ByteArray +from decred.wallet.accounts import createAccount testSeed = ByteArray( diff --git a/tests/unit/pydecred/wire/test_msgblock.py b/decred/tests/unit/dcr/wire/test_msgblock.py similarity index 96% rename from tests/unit/pydecred/wire/test_msgblock.py rename to decred/tests/unit/dcr/wire/test_msgblock.py index c944a318..726bde3b 100644 --- a/tests/unit/pydecred/wire/test_msgblock.py +++ b/decred/tests/unit/dcr/wire/test_msgblock.py @@ -5,8 +5,8 @@ import unittest -from tinydecred.util.encode import ByteArray -from tinydecred.pydecred.wire import msgblock +from decred.dcr.wire import msgblock +from decred.util.encode import ByteArray class TestBlockHeader(unittest.TestCase): diff --git a/tests/unit/pydecred/wire/test_msgtx.py b/decred/tests/unit/dcr/wire/test_msgtx.py similarity index 99% rename from tests/unit/pydecred/wire/test_msgtx.py rename to decred/tests/unit/dcr/wire/test_msgtx.py index ff081ea5..344e0a66 100644 --- a/tests/unit/pydecred/wire/test_msgtx.py +++ b/decred/tests/unit/dcr/wire/test_msgtx.py @@ -3,13 +3,13 @@ See LICENSE for details """ -import unittest import time +import unittest -from tinydecred.util.encode import ByteArray -from tinydecred.pydecred.wire import msgtx, wire -from tinydecred.crypto import rando -from tinydecred.util import helpers +from decred.crypto import rando +from decred.dcr.wire import msgtx, wire +from decred.util import helpers +from decred.util.encode import ByteArray def newHash(): diff --git a/tests/unit/pydecred/wire/test_wire.py b/decred/tests/unit/dcr/wire/test_wire.py similarity index 91% rename from tests/unit/pydecred/wire/test_wire.py rename to decred/tests/unit/dcr/wire/test_wire.py index 1eeb15be..d145ab4f 100644 --- a/tests/unit/pydecred/wire/test_wire.py +++ b/decred/tests/unit/dcr/wire/test_wire.py @@ -5,9 +5,9 @@ import unittest -from tinydecred.pydecred.wire import wire -from tinydecred.util import helpers -from tinydecred.util.encode import ByteArray +from decred.dcr.wire import wire +from decred.util import helpers +from decred.util.encode import ByteArray class TestWire(unittest.TestCase): diff --git a/tests/unit/util/test_database.py b/decred/tests/unit/util/test_database.py similarity index 97% rename from tests/unit/util/test_database.py rename to decred/tests/unit/util/test_database.py index cdf17f3d..7acbc1a7 100644 --- a/tests/unit/util/test_database.py +++ b/decred/tests/unit/util/test_database.py @@ -6,9 +6,8 @@ import os.path import unittest -from tinydecred.util import database -from tinydecred.util import helpers -from tinydecred.util.encode import ByteArray +from decred.util import database, helpers +from decred.util.encode import ByteArray class TBlobber: diff --git a/tests/unit/util/test_encode.py b/decred/tests/unit/util/test_encode.py similarity index 98% rename from tests/unit/util/test_encode.py rename to decred/tests/unit/util/test_encode.py index 3b199e51..e52834a0 100644 --- a/tests/unit/util/test_encode.py +++ b/decred/tests/unit/util/test_encode.py @@ -5,7 +5,7 @@ import unittest -from tinydecred.util import encode +from decred.util import encode ByteArray = encode.ByteArray diff --git a/tests/unit/wallet/test_accounts.py b/decred/tests/unit/wallet/test_accounts.py similarity index 92% rename from tests/unit/wallet/test_accounts.py rename to decred/tests/unit/wallet/test_accounts.py index 01d1f4ca..6e952ff4 100644 --- a/tests/unit/wallet/test_accounts.py +++ b/decred/tests/unit/wallet/test_accounts.py @@ -3,15 +3,16 @@ See LICENSE for details """ -import unittest import os from tempfile import TemporaryDirectory +import unittest + +from decred.crypto import crypto, rando +from decred.dcr import nets +from decred.util import chains, database, helpers +from decred.util.encode import ByteArray +from decred.wallet import accounts -from tinydecred.crypto import crypto, rando -from tinydecred.util.encode import ByteArray -from tinydecred.pydecred import nets -from tinydecred.util import helpers, database, chains -from tinydecred.wallet import accounts testSeed = ByteArray( "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index de44ce9a..00000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -PyQt5==5.9.2 -websocket_client -blake256 -base58 -pynacl -appdirs diff --git a/tinywallet/README.md b/tinywallet/README.md new file mode 100644 index 00000000..fba3c970 --- /dev/null +++ b/tinywallet/README.md @@ -0,0 +1,27 @@ +# TinyWallet + +TinyWallet is a light [Decred](https://decred.org/) wallet GUI application +based on PyQt5. + +**The light wallet is experimental, and should not be used on mainnet.** + +To start the wallet install the `tinywallet` package from the Python Package +Index and run the `tinywallet` command. + +The wallet runs as a system-tray application, of which the major difference is +that "closing" the wallet actually just removes the entry from the taskbar and +minimizes the window "to the system tray". +The wallet can then be "opened" again through the icon in the system tray. + +![alt text][screenshot] + +TinyDecred is pretty small. +Like Decred, it's meant to be an omnipresent yet largely invisible and +unobtrusive part of your digital environment. +The small dialog size keeps user interactions focused. +Bells and whistles are minimized in favor of simplicity whenever possible. +Blockchain mechanics are invisible. +The goal is to make using Decred easier than pulling change out of your pocket. + +[screenshot]: +https://user-images.githubusercontent.com/6109680/62095772-08b4ce80-b247-11e9-81ae-66931ebb07be.png diff --git a/tinywallet/poetry.lock b/tinywallet/poetry.lock new file mode 100644 index 00000000..a89da2bb --- /dev/null +++ b/tinywallet/poetry.lock @@ -0,0 +1,561 @@ +[[package]] +category = "main" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +name = "appdirs" +optional = false +python-versions = "*" +version = "1.4.3" + +[[package]] +category = "dev" +description = "Atomic file writes." +marker = "sys_platform == \"win32\"" +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.3.0" + +[package.extras] +azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] +dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] +docs = ["sphinx", "zope.interface"] +tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] + +[[package]] +category = "main" +description = "Base58 and Base58Check implementation" +name = "base58" +optional = false +python-versions = ">=3.5" +version = "2.0.0" + +[[package]] +category = "dev" +description = "The uncompromising code formatter." +name = "black" +optional = false +python-versions = ">=3.6" +version = "19.10b0" + +[package.dependencies] +appdirs = "*" +attrs = ">=18.1.0" +click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" +toml = ">=0.9.4" +typed-ast = ">=1.4.0" + +[package.extras] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +category = "main" +description = "A Python module supporting blake256 hashing" +name = "blake256" +optional = false +python-versions = "*" +version = "0.1.1" + +[[package]] +category = "main" +description = "Foreign Function Interface for Python calling C code." +name = "cffi" +optional = false +python-versions = "*" +version = "1.13.2" + +[package.dependencies] +pycparser = "*" + +[[package]] +category = "dev" +description = "Composable command line interface toolkit" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "7.0" + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.4.3" + +[[package]] +category = "main" +description = "" +develop = true +name = "decred" +optional = false +python-versions = "^3.6" +version = "0.1.0" + +[package.dependencies] +appdirs = "^1.4.3" +base58 = "^2.0.0" +blake256 = "^0.1.1" +pynacl = "^1.3.0" +websocket_client = "^0.57.0" + +[package.source] +reference = "" +type = "directory" +url = "/home/nl/devel/decred/tinydecred/decred" + +[[package]] +category = "dev" +description = "Read metadata from Python packages" +marker = "python_version < \"3.8\"" +name = "importlib-metadata" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +version = "1.4.0" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "rst.linker"] +testing = ["packaging", "importlib-resources"] + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.5" +version = "8.1.0" + +[[package]] +category = "dev" +description = "Core utilities for Python packages" +name = "packaging" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.1" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + +[[package]] +category = "dev" +description = "Utility library for gitignore style pattern matching of file paths." +name = "pathspec" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.7.0" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.1" + +[package.dependencies] +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.8.1" + +[[package]] +category = "main" +description = "C parser in Python" +name = "pycparser" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.19" + +[[package]] +category = "dev" +description = "passive checker of Python programs" +name = "pyflakes" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.1.1" + +[[package]] +category = "main" +description = "Python binding to the Networking and Cryptography (NaCl) library" +name = "pynacl" +optional = false +python-versions = "*" +version = "1.3.0" + +[package.dependencies] +cffi = ">=1.4.1" +six = "*" + +[package.extras] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +tests = ["pytest (>=3.2.1,<3.3.0 || >3.3.0)", "hypothesis (>=3.27.0)"] + +[[package]] +category = "dev" +description = "Python parsing module" +name = "pyparsing" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "2.4.6" + +[[package]] +category = "main" +description = "Python bindings for the Qt cross platform UI and application toolkit" +name = "pyqt5" +optional = false +python-versions = "*" +version = "5.12.3" + +[package.dependencies] +PyQt5_sip = ">=4.19.14,<13" + +[[package]] +category = "main" +description = "The sip module support for PyQt5" +name = "pyqt5-sip" +optional = false +python-versions = ">=3.5" +version = "12.7.0" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=3.5" +version = "5.3.4" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[package.extras] +checkqa-mypy = ["mypy (v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +category = "dev" +description = "Alternative regular expression module, to replace re." +name = "regex" +optional = false +python-versions = "*" +version = "2020.1.8" + +[[package]] +category = "main" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.14.0" + +[[package]] +category = "dev" +description = "Python Library for Tom's Obvious, Minimal Language" +name = "toml" +optional = false +python-versions = "*" +version = "0.10.0" + +[[package]] +category = "dev" +description = "a fork of Python 2 and 3 ast modules with type comment support" +name = "typed-ast" +optional = false +python-versions = "*" +version = "1.4.1" + +[[package]] +category = "dev" +description = "Measures number of Terminal column cells of wide-character codes" +name = "wcwidth" +optional = false +python-versions = "*" +version = "0.1.8" + +[[package]] +category = "main" +description = "WebSocket client for Python. hybi13 is supported." +name = "websocket-client" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.57.0" + +[package.dependencies] +six = "*" + +[[package]] +category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\"" +name = "zipp" +optional = false +python-versions = ">=3.6" +version = "2.0.1" + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] + +[metadata] +content-hash = "85190d6710709b08b6332d82d6803257c531cc9ce9bcbdf0afab9fafc5e47669" +python-versions = "^3.6" + +[metadata.files] +appdirs = [ + {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, + {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, +] +atomicwrites = [ + {file = "atomicwrites-1.3.0-py2.py3-none-any.whl", hash = "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"}, + {file = "atomicwrites-1.3.0.tar.gz", hash = "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"}, +] +attrs = [ + {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, + {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, +] +base58 = [ + {file = "base58-2.0.0-py3-none-any.whl", hash = "sha256:4c7f5687da771b519cf86b3236250e7c3543368c576404c9fe2d992a287666e0"}, + {file = "base58-2.0.0.tar.gz", hash = "sha256:c83584a8b917dc52dd634307137f2ad2721a9efb4f1de32fc7eaaaf87844177e"}, +] +black = [ + {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, + {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, +] +blake256 = [ + {file = "blake256-0.1.1.tar.gz", hash = "sha256:802945f2f07454d726fd0b0ee5c54dd133d686cb6f05b3d85af2d55ac17075f5"}, +] +cffi = [ + {file = "cffi-1.13.2-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43"}, + {file = "cffi-1.13.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396"}, + {file = "cffi-1.13.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54"}, + {file = "cffi-1.13.2-cp27-cp27m-win32.whl", hash = "sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159"}, + {file = "cffi-1.13.2-cp27-cp27m-win_amd64.whl", hash = "sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97"}, + {file = "cffi-1.13.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579"}, + {file = "cffi-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc"}, + {file = "cffi-1.13.2-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f"}, + {file = "cffi-1.13.2-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858"}, + {file = "cffi-1.13.2-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42"}, + {file = "cffi-1.13.2-cp34-cp34m-win32.whl", hash = "sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b"}, + {file = "cffi-1.13.2-cp34-cp34m-win_amd64.whl", hash = "sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20"}, + {file = "cffi-1.13.2-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3"}, + {file = "cffi-1.13.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25"}, + {file = "cffi-1.13.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5"}, + {file = "cffi-1.13.2-cp35-cp35m-win32.whl", hash = "sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c"}, + {file = "cffi-1.13.2-cp35-cp35m-win_amd64.whl", hash = "sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b"}, + {file = "cffi-1.13.2-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04"}, + {file = "cffi-1.13.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652"}, + {file = "cffi-1.13.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57"}, + {file = "cffi-1.13.2-cp36-cp36m-win32.whl", hash = "sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e"}, + {file = "cffi-1.13.2-cp36-cp36m-win_amd64.whl", hash = "sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d"}, + {file = "cffi-1.13.2-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410"}, + {file = "cffi-1.13.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a"}, + {file = "cffi-1.13.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12"}, + {file = "cffi-1.13.2-cp37-cp37m-win32.whl", hash = "sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e"}, + {file = "cffi-1.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a"}, + {file = "cffi-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d"}, + {file = "cffi-1.13.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3"}, + {file = "cffi-1.13.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db"}, + {file = "cffi-1.13.2-cp38-cp38-win32.whl", hash = "sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506"}, + {file = "cffi-1.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba"}, + {file = "cffi-1.13.2.tar.gz", hash = "sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346"}, +] +click = [ + {file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"}, + {file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"}, +] +colorama = [ + {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, + {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, +] +decred = [] +importlib-metadata = [ + {file = "importlib_metadata-1.4.0-py2.py3-none-any.whl", hash = "sha256:bdd9b7c397c273bcc9a11d6629a38487cd07154fa255a467bf704cd2c258e359"}, + {file = "importlib_metadata-1.4.0.tar.gz", hash = "sha256:f17c015735e1a88296994c0697ecea7e11db24290941983b08c9feb30921e6d8"}, +] +more-itertools = [ + {file = "more-itertools-8.1.0.tar.gz", hash = "sha256:c468adec578380b6281a114cb8a5db34eb1116277da92d7c46f904f0b52d3288"}, + {file = "more_itertools-8.1.0-py3-none-any.whl", hash = "sha256:1a2a32c72400d365000412fe08eb4a24ebee89997c18d3d147544f70f5403b39"}, +] +packaging = [ + {file = "packaging-20.1-py2.py3-none-any.whl", hash = "sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73"}, + {file = "packaging-20.1.tar.gz", hash = "sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334"}, +] +pathspec = [ + {file = "pathspec-0.7.0-py2.py3-none-any.whl", hash = "sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424"}, + {file = "pathspec-0.7.0.tar.gz", hash = "sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +py = [ + {file = "py-1.8.1-py2.py3-none-any.whl", hash = "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"}, + {file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"}, +] +pycparser = [ + {file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"}, +] +pyflakes = [ + {file = "pyflakes-2.1.1-py2.py3-none-any.whl", hash = "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0"}, + {file = "pyflakes-2.1.1.tar.gz", hash = "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"}, +] +pynacl = [ + {file = "PyNaCl-1.3.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621"}, + {file = "PyNaCl-1.3.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39"}, + {file = "PyNaCl-1.3.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255"}, + {file = "PyNaCl-1.3.0-cp27-cp27m-win32.whl", hash = "sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f"}, + {file = "PyNaCl-1.3.0-cp27-cp27m-win_amd64.whl", hash = "sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0"}, + {file = "PyNaCl-1.3.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1"}, + {file = "PyNaCl-1.3.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e"}, + {file = "PyNaCl-1.3.0-cp34-abi3-macosx_10_6_intel.whl", hash = "sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1"}, + {file = "PyNaCl-1.3.0-cp34-abi3-manylinux1_i686.whl", hash = "sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786"}, + {file = "PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl", hash = "sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415"}, + {file = "PyNaCl-1.3.0-cp34-cp34m-win32.whl", hash = "sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b"}, + {file = "PyNaCl-1.3.0-cp34-cp34m-win_amd64.whl", hash = "sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae"}, + {file = "PyNaCl-1.3.0-cp35-cp35m-win32.whl", hash = "sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310"}, + {file = "PyNaCl-1.3.0-cp35-cp35m-win_amd64.whl", hash = "sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a"}, + {file = "PyNaCl-1.3.0-cp36-cp36m-win32.whl", hash = "sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20"}, + {file = "PyNaCl-1.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b"}, + {file = "PyNaCl-1.3.0-cp37-cp37m-win32.whl", hash = "sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56"}, + {file = "PyNaCl-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715"}, + {file = "PyNaCl-1.3.0-cp38-cp38-win32.whl", hash = "sha256:53126cd91356342dcae7e209f840212a58dcf1177ad52c1d938d428eebc9fee5"}, + {file = "PyNaCl-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:bf459128feb543cfca16a95f8da31e2e65e4c5257d2f3dfa8c0c1031139c9c92"}, + {file = "PyNaCl-1.3.0.tar.gz", hash = "sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c"}, +] +pyparsing = [ + {file = "pyparsing-2.4.6-py2.py3-none-any.whl", hash = "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"}, + {file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"}, +] +pyqt5 = [ + {file = "PyQt5-5.12.3-5.12.6-cp35.cp36.cp37.cp38-abi3-macosx_10_6_intel.whl", hash = "sha256:54c7efbcc83b343dca2774e21a414cb0d19806a482e4a7d305f8743ea57910b5"}, + {file = "PyQt5-5.12.3-5.12.6-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl", hash = "sha256:3cc3877c7891437a923c2a509490ca7966abc9b36b1f9bfa0e580712d600b6b2"}, + {file = "PyQt5-5.12.3-5.12.6-cp35.cp36.cp37.cp38-none-win32.whl", hash = "sha256:d0471fe5567ade30f5f8fd354b57548cb5abf6f26fcf9c703b416a1411d6ffba"}, + {file = "PyQt5-5.12.3-5.12.6-cp35.cp36.cp37.cp38-none-win_amd64.whl", hash = "sha256:53d2183ab3edc1a2aa117a720dfd6cf81a9381911bd6a345290fc1a44daeb024"}, +] +pyqt5-sip = [ + {file = "PyQt5_sip-12.7.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:1910c1cb5a388d4e59ebb2895d7015f360f3f6eeb1700e7e33e866c53137eb9e"}, + {file = "PyQt5_sip-12.7.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b43ba2f18999d41c3df72f590348152e14cd4f6dcea2058c734d688dfb1ec61f"}, + {file = "PyQt5_sip-12.7.0-cp35-cp35m-win32.whl", hash = "sha256:fabff832046643cdb93920ddaa8f77344df90768930fbe6bb33d211c4dcd0b5e"}, + {file = "PyQt5_sip-12.7.0-cp35-cp35m-win_amd64.whl", hash = "sha256:8274ed50f4ffbe91d0f4cc5454394631edfecd75dc327aa01be8bc5818a57e88"}, + {file = "PyQt5_sip-12.7.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:ef3c7a0bf78674b0dda86ff5809d8495019903a096c128e1f160984b37848f73"}, + {file = "PyQt5_sip-12.7.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3c330ff1f70b3eaa6f63dce9274df996dffea82ad9726aa8e3d6cbe38e986b2f"}, + {file = "PyQt5_sip-12.7.0-cp36-cp36m-win32.whl", hash = "sha256:9047d887d97663790d811ac4e0d2e895f1bf2ecac4041691487de40c30239480"}, + {file = "PyQt5_sip-12.7.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9f6ab1417ecfa6c1ce6ce941e0cebc03e3ec9cd9925058043229a5f003ae5e40"}, + {file = "PyQt5_sip-12.7.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06bc66b50556fb949f14875a4c224423dbf03f972497ccb883fb19b7b7c3b346"}, + {file = "PyQt5_sip-12.7.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:482a910fa73ee0e36c258d7646ef38f8061774bbc1765a7da68c65056b573341"}, + {file = "PyQt5_sip-12.7.0-cp37-cp37m-win32.whl", hash = "sha256:1c7ad791ec86247f35243bbbdd29cd59989afbe0ab678e0a41211f4407f21dd8"}, + {file = "PyQt5_sip-12.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:da69ba17f6ece9a85617743cb19de689f2d63025bf8001e2facee2ec9bcff18f"}, + {file = "PyQt5_sip-12.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:02d94786bada670ab17a2b62ce95b3cf8e3b40c99d36007593a6334d551840bb"}, + {file = "PyQt5_sip-12.7.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c3ab9ea1bc3f4ce8c57ebc66fb25cd044ef92ed1ca2afa3729854ecc59658905"}, + {file = "PyQt5_sip-12.7.0-cp38-cp38-win32.whl", hash = "sha256:7695dfafb4f5549ce1290ae643d6508dfc2646a9003c989218be3ce42a1aa422"}, + {file = "PyQt5_sip-12.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:091fbbe10a7aebadc0e8897a9449cda08d3c3f663460d812eca3001ca1ed3526"}, + {file = "PyQt5_sip-12.7.0.tar.gz", hash = "sha256:0a067ade558befe4d46335b13d8b602b5044363bfd601419b556d4ec659bca18"}, +] +pytest = [ + {file = "pytest-5.3.4-py3-none-any.whl", hash = "sha256:c13d1943c63e599b98cf118fcb9703e4d7bde7caa9a432567bcdcae4bf512d20"}, + {file = "pytest-5.3.4.tar.gz", hash = "sha256:1d122e8be54d1a709e56f82e2d85dcba3018313d64647f38a91aec88c239b600"}, +] +regex = [ + {file = "regex-2020.1.8-cp27-cp27m-win32.whl", hash = "sha256:4e8f02d3d72ca94efc8396f8036c0d3bcc812aefc28ec70f35bb888c74a25161"}, + {file = "regex-2020.1.8-cp27-cp27m-win_amd64.whl", hash = "sha256:e6c02171d62ed6972ca8631f6f34fa3281d51db8b326ee397b9c83093a6b7242"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:4eae742636aec40cf7ab98171ab9400393360b97e8f9da67b1867a9ee0889b26"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bd25bb7980917e4e70ccccd7e3b5740614f1c408a642c245019cff9d7d1b6149"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3e77409b678b21a056415da3a56abfd7c3ad03da71f3051bbcdb68cf44d3c34d"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:07b39bf943d3d2fe63d46281d8504f8df0ff3fe4c57e13d1656737950e53e525"}, + {file = "regex-2020.1.8-cp36-cp36m-win32.whl", hash = "sha256:23e2c2c0ff50f44877f64780b815b8fd2e003cda9ce817a7fd00dea5600c84a0"}, + {file = "regex-2020.1.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27429b8d74ba683484a06b260b7bb00f312e7c757792628ea251afdbf1434003"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0e182d2f097ea8549a249040922fa2b92ae28be4be4895933e369a525ba36576"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e3cd21cc2840ca67de0bbe4071f79f031c81418deb544ceda93ad75ca1ee9f7b"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ecc6de77df3ef68fee966bb8cb4e067e84d4d1f397d0ef6fce46913663540d77"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:26ff99c980f53b3191d8931b199b29d6787c059f2e029b2b0c694343b1708c35"}, + {file = "regex-2020.1.8-cp37-cp37m-win32.whl", hash = "sha256:7bcd322935377abcc79bfe5b63c44abd0b29387f267791d566bbb566edfdd146"}, + {file = "regex-2020.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:10671601ee06cf4dc1bc0b4805309040bb34c9af423c12c379c83d7895622bb5"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:98b8ed7bb2155e2cbb8b76f627b2fd12cf4b22ab6e14873e8641f266e0fb6d8f"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6a6ba91b94427cd49cd27764679024b14a96874e0dc638ae6bdd4b1a3ce97be1"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:6a6ae17bf8f2d82d1e8858a47757ce389b880083c4ff2498dba17c56e6c103b9"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0932941cdfb3afcbc26cc3bcf7c3f3d73d5a9b9c56955d432dbf8bbc147d4c5b"}, + {file = "regex-2020.1.8-cp38-cp38-win32.whl", hash = "sha256:d58e4606da2a41659c84baeb3cfa2e4c87a74cec89a1e7c56bee4b956f9d7461"}, + {file = "regex-2020.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:e7c7661f7276507bce416eaae22040fd91ca471b5b33c13f8ff21137ed6f248c"}, + {file = "regex-2020.1.8.tar.gz", hash = "sha256:d0f424328f9822b0323b3b6f2e4b9c90960b24743d220763c7f07071e0778351"}, +] +six = [ + {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, + {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, +] +toml = [ + {file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"}, + {file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"}, + {file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +wcwidth = [ + {file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"}, + {file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"}, +] +websocket-client = [ + {file = "websocket_client-0.57.0-py2.py3-none-any.whl", hash = "sha256:0fc45c961324d79c781bab301359d5a1b00b13ad1b10415a4780229ef71a5549"}, + {file = "websocket_client-0.57.0.tar.gz", hash = "sha256:d735b91d6d1692a6a181f2a8c9e0238e5f6373356f561bb9dc4c7af36f452010"}, +] +zipp = [ + {file = "zipp-2.0.1-py3-none-any.whl", hash = "sha256:e013e7800f60ec4dde789ebf4e9f7a54236e4bbf5df2a1a4e20ce9e1d9609d67"}, + {file = "zipp-2.0.1.tar.gz", hash = "sha256:b338014b9bc7102ca69e0fb96ed07215a8954d2989bc5d83658494ab2ba634af"}, +] diff --git a/tinywallet/pyproject.toml b/tinywallet/pyproject.toml new file mode 100644 index 00000000..3e8d45d8 --- /dev/null +++ b/tinywallet/pyproject.toml @@ -0,0 +1,41 @@ +[tool.poetry] +name = "tinywallet" +version = "0.0.1" +description = "A Python 3 Decred wallet." +license = "ISC" +homepage = "https://decred.org/" +repository = "https://github.com/decred/tinydecred/" +documentation = "https://github.com/decred/tinydecred/blob/master/tinywallet" +authors = [ + "Brian Stafford ", + "The Decred developers " +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: X11 Applications :: Qt", + "Intended Audience :: End Users/Desktop", + "License :: OSI Approved :: ISC License (ISCL)", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Topic :: Office/Business :: Financial" +] + +[tool.poetry.dependencies] +python = "^3.6" +decred = {path = "../decred/"} +pyqt5 = "=5.12.3" + +[tool.poetry.dev-dependencies] +pytest = "^5.2" +pyflakes = "^2.1.1" +black = "^19.10b0" + +[tool.poetry.scripts] +tinywallet = "tinywallet.app:main" + +[build-system] +requires = ["poetry>=1.0.2"] +build-backend = "poetry.masonry.api" diff --git a/tinywallet/tinywallet/__init__.py b/tinywallet/tinywallet/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/app.py b/tinywallet/tinywallet/app.py similarity index 88% rename from app.py rename to tinywallet/tinywallet/app.py index c1d0359c..b7cd74c9 100644 --- a/app.py +++ b/tinywallet/tinywallet/app.py @@ -11,14 +11,16 @@ from PyQt5 import QtGui, QtCore, QtWidgets -from tinydecred import config -from tinydecred.pydecred import constants as DCR -from tinydecred.pydecred.dcrdata import DcrdataBlockchain -from tinydecred.ui import screens, ui, qutilities as Q -from tinydecred.util import helpers, database -from tinydecred.wallet.wallet import Wallet - -# the directory of the tinydecred package +from decred import config +from decred.dcr import constants as DCR +from decred.dcr.dcrdata import DcrdataBlockchain +from decred.util import helpers, database +from decred.wallet.wallet import Wallet + +from tinywallet import screens, ui, qutilities as Q + + +# the directory of the tinywallet package PACKAGEDIR = os.path.dirname(os.path.realpath(__file__)) # some commonly used ui constants @@ -35,27 +37,6 @@ currentWallet = "current.wallet" -def tryExecute(f, *a, **k): - """ - Execute the function, catching exceptions and logging as an error. Return - False to indicate an exception. - - Args: - f (func): The function. - *a (tuple): Optional positional arguments. - **k (dict): Optional keyword arguments. - - Returns: - value or bool: `False` on failure, the function's return value on - success. - """ - try: - return f(*a, **k) - except Exception as e: - log.error("tryExecute %s failed: %s" % (f.__name__, formatTraceback(e))) - return False - - class TinySignals(object): """ Implements the Signals API as defined in tinydecred.api. TinySignals is used @@ -93,6 +74,8 @@ def __init__(self, qApp): """ super().__init__() self.qApp = qApp + self.cfg = config.load() + self.log = self.init_logging() self.wallet = None # trackedCssItems are CSS-styled elements to be updated if dark mode is # enabled/disabled. @@ -122,7 +105,7 @@ def __init__(self, qApp): # The initialized DcrdataBlockchain will not be connected, as that is a # blocking operation. It will be called when the wallet is open. self.dcrdata = DcrdataBlockchain( - dcrdataDB, cfg.net, self.getNetSetting("dcrdata"), skipConnect=True, + dcrdataDB, self.cfg.net, self.getNetSetting("dcrdata"), skipConnect=True, ) self.registerSignal(ui.WALLET_CONNECTED, self.syncWallet) @@ -150,6 +133,18 @@ def __init__(self, qApp): self.initialize() + def init_logging(self): + """ + Initialize logging for the entire app. + """ + logDir = os.path.join(config.DATA_DIR, "logs") + helpers.mkdir(logDir) + logFilePath = os.path.join(logDir, "tinydecred.log") + log = helpers.prepareLogger("APP", logFilePath, logLvl=0) + log.info("configuration file at %s" % config.CONFIG_PATH) + log.info("data directory at %s" % config.DATA_DIR) + return log + def initialize(self): """ Show the initial screen based on the presence of a wallet file. @@ -177,6 +172,27 @@ def waiting(self): """ self.appWindow.stack(self.waitingScreen) + def tryExecute(self, f, *a, **k): + """ + Execute the function, catching exceptions and logging as an error. Return + False to indicate an exception. + + Args: + f (func): The function. + *a (tuple): Optional positional arguments. + **k (dict): Optional keyword arguments. + + Returns: + value or bool: `False` on failure, the function's return value on + success. + """ + try: + return f(*a, **k) + except Exception as e: + err_msg = "tryExecute {} failed: {}" + self.log.error(err_msg.format(f.__name__, formatTraceback(e))) + return False + def waitThread(self, f, cb, *a, **k): """ Wait thread shows a waiting screen while the provided function is run @@ -195,7 +211,7 @@ def unwaiting(*cba, **cbk): self.appWindow.pop(self.waitingScreen) cb(*cba, **cbk) - self.makeThread(tryExecute, unwaiting, f, *a, **k) + self.makeThread(self.tryExecute, unwaiting, f, *a, **k) def openWallet(self, path, pw): """ @@ -212,7 +228,7 @@ def openWallet(self, path, pw): self.setWallet(w) self.home() except Exception as e: - log.warning( + self.log.warning( "exception encountered while attempting to open wallet: %s" % formatTraceback(e) ) @@ -263,16 +279,16 @@ def netDirectory(self): Returns: str: Absolute filepath of the directory for the selected network. """ - return os.path.join(config.DATA_DIR, cfg.net.Name) + return os.path.join(config.DATA_DIR, self.cfg.net.Name) def loadSettings(self): """ Load settings from the TinyConfig. """ - settings = self.settings = cfg.get("settings") + settings = self.settings = self.cfg.get("settings") if not settings: self.settings = settings = {} - cfg.set("settings", self.settings) + self.cfg.set("settings", self.settings) for k, v in (("theme", Q.LIGHT_THEME),): if k not in settings: settings[k] = v @@ -280,13 +296,13 @@ def loadSettings(self): # if currentWallet not in netSettings: netSettings[currentWallet] = os.path.join(self.netDirectory(), WALLET_FILE_NAME) helpers.mkdir(self.netDirectory()) - cfg.save() + self.cfg.save() def saveSettings(self): """ Save the current settings. """ - cfg.save() + self.cfg.save() def getSetting(self, *keys): """ @@ -298,7 +314,7 @@ def getSetting(self, *keys): Returns: mixed: Value of setting for *keys. """ - return cfg.get("settings", *keys) + return self.cfg.get("settings", *keys) def getNetSetting(self, *keys): """ @@ -310,7 +326,7 @@ def getNetSetting(self, *keys): Returns: mixed: Value of network setting for *keys. """ - return cfg.get("networks", cfg.net.Name, *keys) + return self.cfg.get("networks", self.cfg.net.Name, *keys) def setNetSetting(self, k, v): """ @@ -320,7 +336,7 @@ def setNetSetting(self, k, v): k (str): Network setting key string. v (value): Network setting value. """ - cfg.get("networks", cfg.net.Name)[k] = v + self.cfg.get("networks", self.cfg.net.Name)[k] = v def registerSignal(self, sig, cb, *a, **k): """ @@ -354,7 +370,7 @@ def emitSignal(self, sig, *sigA, **sigK): """ sr = self.signalRegistry if sig not in sr: - # log.warning("attempted to call un-registered signal %s" % sig) + # self.log.warning("attempted to call un-registered signal %s" % sig) return for s in sr[sig]: sa, sk = s[1], s[3] @@ -418,7 +434,7 @@ def step2(pw, a, k): self.appWindow.pop(self.pwDialog) return r except Exception as e: - log.warning( + self.log.warning( "exception encountered while performing wallet action: %s" % formatTraceback(e) ) @@ -547,7 +563,7 @@ def exception_hook(exctype, value, tb): sys.exit(1) -def runTinyDecred(): +def main(): """ Start the TinyDecred application. """ @@ -574,11 +590,4 @@ def runTinyDecred(): if __name__ == "__main__": - # Initialize logging for the entire app. - logDir = os.path.join(config.DATA_DIR, "logs") - helpers.mkdir(logDir) - log = helpers.prepareLogger("APP", os.path.join(logDir, "tinydecred.log"), logLvl=0) - log.info("configuration file at %s" % config.CONFIG_PATH) - log.info("data directory at %s" % config.DATA_DIR) - cfg = config.load() - runTinyDecred() + main() diff --git a/ui/fonts/EBGaramond-Bold.ttf b/tinywallet/tinywallet/fonts/EBGaramond-Bold.ttf similarity index 100% rename from ui/fonts/EBGaramond-Bold.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-Bold.ttf diff --git a/ui/fonts/EBGaramond-BoldItalic.ttf b/tinywallet/tinywallet/fonts/EBGaramond-BoldItalic.ttf similarity index 100% rename from ui/fonts/EBGaramond-BoldItalic.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-BoldItalic.ttf diff --git a/ui/fonts/EBGaramond-ExtraBold.ttf b/tinywallet/tinywallet/fonts/EBGaramond-ExtraBold.ttf similarity index 100% rename from ui/fonts/EBGaramond-ExtraBold.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-ExtraBold.ttf diff --git a/ui/fonts/EBGaramond-ExtraBoldItalic.ttf b/tinywallet/tinywallet/fonts/EBGaramond-ExtraBoldItalic.ttf similarity index 100% rename from ui/fonts/EBGaramond-ExtraBoldItalic.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-ExtraBoldItalic.ttf diff --git a/ui/fonts/EBGaramond-Italic.ttf b/tinywallet/tinywallet/fonts/EBGaramond-Italic.ttf similarity index 100% rename from ui/fonts/EBGaramond-Italic.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-Italic.ttf diff --git a/ui/fonts/EBGaramond-Medium.ttf b/tinywallet/tinywallet/fonts/EBGaramond-Medium.ttf similarity index 100% rename from ui/fonts/EBGaramond-Medium.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-Medium.ttf diff --git a/ui/fonts/EBGaramond-MediumItalic.ttf b/tinywallet/tinywallet/fonts/EBGaramond-MediumItalic.ttf similarity index 100% rename from ui/fonts/EBGaramond-MediumItalic.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-MediumItalic.ttf diff --git a/ui/fonts/EBGaramond-Regular.ttf b/tinywallet/tinywallet/fonts/EBGaramond-Regular.ttf similarity index 100% rename from ui/fonts/EBGaramond-Regular.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-Regular.ttf diff --git a/ui/fonts/EBGaramond-SemiBold.ttf b/tinywallet/tinywallet/fonts/EBGaramond-SemiBold.ttf similarity index 100% rename from ui/fonts/EBGaramond-SemiBold.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-SemiBold.ttf diff --git a/ui/fonts/EBGaramond-SemiBoldItalic.ttf b/tinywallet/tinywallet/fonts/EBGaramond-SemiBoldItalic.ttf similarity index 100% rename from ui/fonts/EBGaramond-SemiBoldItalic.ttf rename to tinywallet/tinywallet/fonts/EBGaramond-SemiBoldItalic.ttf diff --git a/ui/fonts/MaterialIcons-Regular.ttf b/tinywallet/tinywallet/fonts/MaterialIcons-Regular.ttf similarity index 100% rename from ui/fonts/MaterialIcons-Regular.ttf rename to tinywallet/tinywallet/fonts/MaterialIcons-Regular.ttf diff --git a/ui/fonts/Roboto-Black.ttf b/tinywallet/tinywallet/fonts/Roboto-Black.ttf similarity index 100% rename from ui/fonts/Roboto-Black.ttf rename to tinywallet/tinywallet/fonts/Roboto-Black.ttf diff --git a/ui/fonts/Roboto-BlackItalic.ttf b/tinywallet/tinywallet/fonts/Roboto-BlackItalic.ttf similarity index 100% rename from ui/fonts/Roboto-BlackItalic.ttf rename to tinywallet/tinywallet/fonts/Roboto-BlackItalic.ttf diff --git a/ui/fonts/Roboto-Bold.ttf b/tinywallet/tinywallet/fonts/Roboto-Bold.ttf similarity index 100% rename from ui/fonts/Roboto-Bold.ttf rename to tinywallet/tinywallet/fonts/Roboto-Bold.ttf diff --git a/ui/fonts/Roboto-BoldItalic.ttf b/tinywallet/tinywallet/fonts/Roboto-BoldItalic.ttf similarity index 100% rename from ui/fonts/Roboto-BoldItalic.ttf rename to tinywallet/tinywallet/fonts/Roboto-BoldItalic.ttf diff --git a/ui/fonts/Roboto-Italic.ttf b/tinywallet/tinywallet/fonts/Roboto-Italic.ttf similarity index 100% rename from ui/fonts/Roboto-Italic.ttf rename to tinywallet/tinywallet/fonts/Roboto-Italic.ttf diff --git a/ui/fonts/Roboto-Light.ttf b/tinywallet/tinywallet/fonts/Roboto-Light.ttf similarity index 100% rename from ui/fonts/Roboto-Light.ttf rename to tinywallet/tinywallet/fonts/Roboto-Light.ttf diff --git a/ui/fonts/Roboto-LightItalic.ttf b/tinywallet/tinywallet/fonts/Roboto-LightItalic.ttf similarity index 100% rename from ui/fonts/Roboto-LightItalic.ttf rename to tinywallet/tinywallet/fonts/Roboto-LightItalic.ttf diff --git a/ui/fonts/Roboto-Medium.ttf b/tinywallet/tinywallet/fonts/Roboto-Medium.ttf similarity index 100% rename from ui/fonts/Roboto-Medium.ttf rename to tinywallet/tinywallet/fonts/Roboto-Medium.ttf diff --git a/ui/fonts/Roboto-MediumItalic.ttf b/tinywallet/tinywallet/fonts/Roboto-MediumItalic.ttf similarity index 100% rename from ui/fonts/Roboto-MediumItalic.ttf rename to tinywallet/tinywallet/fonts/Roboto-MediumItalic.ttf diff --git a/ui/fonts/Roboto-Regular.ttf b/tinywallet/tinywallet/fonts/Roboto-Regular.ttf similarity index 100% rename from ui/fonts/Roboto-Regular.ttf rename to tinywallet/tinywallet/fonts/Roboto-Regular.ttf diff --git a/ui/fonts/Roboto-Thin.ttf b/tinywallet/tinywallet/fonts/Roboto-Thin.ttf similarity index 100% rename from ui/fonts/Roboto-Thin.ttf rename to tinywallet/tinywallet/fonts/Roboto-Thin.ttf diff --git a/ui/fonts/Roboto-ThinItalic.ttf b/tinywallet/tinywallet/fonts/Roboto-ThinItalic.ttf similarity index 100% rename from ui/fonts/Roboto-ThinItalic.ttf rename to tinywallet/tinywallet/fonts/Roboto-ThinItalic.ttf diff --git a/ui/fonts/RobotoMono-Bold.ttf b/tinywallet/tinywallet/fonts/RobotoMono-Bold.ttf similarity index 100% rename from ui/fonts/RobotoMono-Bold.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-Bold.ttf diff --git a/ui/fonts/RobotoMono-BoldItalic.ttf b/tinywallet/tinywallet/fonts/RobotoMono-BoldItalic.ttf similarity index 100% rename from ui/fonts/RobotoMono-BoldItalic.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-BoldItalic.ttf diff --git a/ui/fonts/RobotoMono-Italic.ttf b/tinywallet/tinywallet/fonts/RobotoMono-Italic.ttf similarity index 100% rename from ui/fonts/RobotoMono-Italic.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-Italic.ttf diff --git a/ui/fonts/RobotoMono-Light.ttf b/tinywallet/tinywallet/fonts/RobotoMono-Light.ttf similarity index 100% rename from ui/fonts/RobotoMono-Light.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-Light.ttf diff --git a/ui/fonts/RobotoMono-LightItalic.ttf b/tinywallet/tinywallet/fonts/RobotoMono-LightItalic.ttf similarity index 100% rename from ui/fonts/RobotoMono-LightItalic.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-LightItalic.ttf diff --git a/ui/fonts/RobotoMono-Medium.ttf b/tinywallet/tinywallet/fonts/RobotoMono-Medium.ttf similarity index 100% rename from ui/fonts/RobotoMono-Medium.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-Medium.ttf diff --git a/ui/fonts/RobotoMono-MediumItalic.ttf b/tinywallet/tinywallet/fonts/RobotoMono-MediumItalic.ttf similarity index 100% rename from ui/fonts/RobotoMono-MediumItalic.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-MediumItalic.ttf diff --git a/ui/fonts/RobotoMono-Regular.ttf b/tinywallet/tinywallet/fonts/RobotoMono-Regular.ttf similarity index 100% rename from ui/fonts/RobotoMono-Regular.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-Regular.ttf diff --git a/ui/fonts/RobotoMono-Thin.ttf b/tinywallet/tinywallet/fonts/RobotoMono-Thin.ttf similarity index 100% rename from ui/fonts/RobotoMono-Thin.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-Thin.ttf diff --git a/ui/fonts/RobotoMono-ThinItalic.ttf b/tinywallet/tinywallet/fonts/RobotoMono-ThinItalic.ttf similarity index 100% rename from ui/fonts/RobotoMono-ThinItalic.ttf rename to tinywallet/tinywallet/fonts/RobotoMono-ThinItalic.ttf diff --git a/ui/icons/back.svg b/tinywallet/tinywallet/icons/back.svg similarity index 100% rename from ui/icons/back.svg rename to tinywallet/tinywallet/icons/back.svg diff --git a/ui/icons/home.svg b/tinywallet/tinywallet/icons/home.svg similarity index 100% rename from ui/icons/home.svg rename to tinywallet/tinywallet/icons/home.svg diff --git a/ui/icons/spinner.svg b/tinywallet/tinywallet/icons/spinner.svg similarity index 100% rename from ui/icons/spinner.svg rename to tinywallet/tinywallet/icons/spinner.svg diff --git a/ui/icons/x.svg b/tinywallet/tinywallet/icons/x.svg similarity index 100% rename from ui/icons/x.svg rename to tinywallet/tinywallet/icons/x.svg diff --git a/util/mpl.py b/tinywallet/tinywallet/mpl.py similarity index 96% rename from util/mpl.py rename to tinywallet/tinywallet/mpl.py index b7399b75..8c4a0aba 100644 --- a/util/mpl.py +++ b/tinywallet/tinywallet/mpl.py @@ -1,5 +1,6 @@ """ Copyright (c) 2019, Brian Stafford +Copyright (c) 2019, the Decred developers See LICENSE for details """ @@ -7,15 +8,15 @@ import time import matplotlib +from matplotlib import font_manager as FontManager from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure -from matplotlib import font_manager as FontManager - from mpl_toolkits.mplot3d import Axes3D # noqa: F401 (flake8 ignore) -from tinydecred.pydecred import constants as C -import tinydecred.ui.ui as UI -from tinydecred.util import helpers +from decred.dcr import constants as C +from decred.util import helpers + +from . import ui as UI MPL_COLOR = "#333333" diff --git a/ui/qutilities.py b/tinywallet/tinywallet/qutilities.py similarity index 99% rename from ui/qutilities.py rename to tinywallet/tinywallet/qutilities.py index 223f7037..712614e6 100644 --- a/ui/qutilities.py +++ b/tinywallet/tinywallet/qutilities.py @@ -1,13 +1,18 @@ """ Copyright (c) 2019, Brian Stafford +Copyright (c) 2019, the Decred developers See LICENSE for detail PyQt5 utilities. """ + import re -from tinydecred.util import helpers + from PyQt5 import QtCore, QtWidgets, QtGui +from decred.util import helpers + + log = helpers.getLogger("QUTIL") # , logLvl=0) # Some colors, diff --git a/ui/screens.py b/tinywallet/tinywallet/screens.py similarity index 99% rename from ui/screens.py rename to tinywallet/tinywallet/screens.py index 6a9002ae..01af94ad 100644 --- a/ui/screens.py +++ b/tinywallet/tinywallet/screens.py @@ -1,18 +1,24 @@ """ Copyright (c) 2019, Brian Stafford +Copyright (c) 2019, the Decred developers See LICENSE for detail """ + import os -import time import random +import time from urllib.parse import urlparse + from PyQt5 import QtGui, QtCore, QtWidgets -from tinydecred import config -from tinydecred.ui import qutilities as Q, ui -from tinydecred.wallet.wallet import Wallet -from tinydecred.util import helpers, chains -from tinydecred.pydecred import constants as DCR -from tinydecred.pydecred.vsp import VotingServiceProvider + +from decred import config +from decred.dcr import constants as DCR +from decred.dcr.vsp import VotingServiceProvider +from decred.util import helpers, chains +from decred.wallet.wallet import Wallet + +from . import qutilities as Q, ui + UI_DIR = os.path.dirname(os.path.realpath(__file__)) log = helpers.getLogger("APPUI") # , logLvl=0) @@ -530,10 +536,10 @@ def balanceUpdated(self, bal): """ A BALANCE_SIGNAL receiver that updates the displayed balance. """ - dcr = bal.total * 1e-8 // 0.01 * 0.01 + dcrs = bal.total * 1e-8 // 0.01 * 0.01 availStr = "%.8f" % (bal.available * 1e-8,) - self.totalBalance.setText("{0:,.2f}".format(dcr)) - self.totalBalance.setToolTip("%.8f" % dcr) + self.totalBalance.setText("{0:,.2f}".format(dcrs)) + self.totalBalance.setToolTip("%.8f" % dcrs) self.availBalance.setText("%s spendable" % availStr.rstrip("0").rstrip(".")) staked = bal.staked / bal.total if bal.total > 0 else 0 self.statsLbl.setText("%s%% staked" % helpers.formatNumber(staked * 100)) diff --git a/ui/ui.py b/tinywallet/tinywallet/ui.py similarity index 91% rename from ui/ui.py rename to tinywallet/tinywallet/ui.py index 671cb403..84fcfe2d 100644 --- a/ui/ui.py +++ b/tinywallet/tinywallet/ui.py @@ -1,9 +1,12 @@ """ Copyright (c) 2019, Brian Stafford +Copyright (c) 2019, the Decred developers See LICENSE for details """ + import os + PACKAGEDIR = os.path.dirname(os.path.realpath(__file__)) FONTDIR = os.path.join(PACKAGEDIR, "fonts")