mirror of
https://github.com/cryptoadvance/specter-desktop.git
synced 2026-08-13 12:33:29 +02:00
Some minor things to consolidate and some guidelines for Development.md (#63)
* Some minor things to consolidate and some guidelines for Development.md * Add a SpecterError derived from Exception * Adding vue.js, see #63 * bugfix introduced in #66 missing import pyserial and serial
This commit is contained in:
parent
8539b8ac44
commit
d9b9b2bc69
8 changed files with 94 additions and 4 deletions
|
|
@ -8,6 +8,14 @@ pytest --docker # needs a working docker-setup (but not bitcoind)
|
|||
pytest tests/test_specter -k Manager # Run all tests in a specific file matching "Manager"
|
||||
```
|
||||
|
||||
# Developing on tests
|
||||
There are some things worth taking a note here, especially if you rely on a specific state on the blockchain for your tests. Bitcoind is started only once for all the tests. Each time it's starting with the genesis-block. This has some implications:
|
||||
* The [halving-interval for regtest](https://github.com/bitcoin/bitcoin/blob/99813a9745fe10a58bedd7a4cb721faf14f907a4/src/chainparams.cpp#L258) is only 150-blocks
|
||||
* At the same time, still 100 blocks need to be minded in order to make the coins spendable.
|
||||
* This combination results in that you can't rely on how many coins get mined if you want some testcoin on your address
|
||||
* This also means that it makes a huge difference whether you run a test standalone or together with all other tests
|
||||
* Depending on whether you do one or the other, you cannot rely on transactionIDs. So if you run a test standalone twice, you can assert txids but you can't any longer when you run all the tests
|
||||
|
||||
# More on the bitcoind requirements
|
||||
Developing against a bitcoind-API makes most sense with the [Regtest Mode](https://bitcoin.org/en/developer-examples#regtest-mode). Depending on preferences and usecases, there are three major ways on how this dependency can be fullfilled:
|
||||
* Easiest way via Docker
|
||||
|
|
@ -46,6 +54,8 @@ In order to enable that, you need to activate pytest support by placing a settin
|
|||
"python.testing.pytestArgs": ["--docker"]
|
||||
}
|
||||
```
|
||||
**WARNING**: Make sure to never stop a unittest in between. Simply continue with the test and let it run through. Otherwise the docker-container used for the test won't get cleaned up and your subsequent test-runs will fail with strange issues. If you did that, simply kill the container (```docker ps; docker kill ...```)
|
||||
|
||||
More information on python-unit-tests on VS-Code can be found at the [VS-python-documentation](https://code.visualstudio.com/docs/python/testing).
|
||||
|
||||
## Debugging in VS-Code
|
||||
|
|
@ -83,8 +93,28 @@ You can easily create a .vscode/launch.json file via the debug-window. However t
|
|||
|
||||
More information on debugging can be found at the [python-tutorial](https://code.visualstudio.com/docs/python/python-tutorial#_configure-and-run-the-debugger).
|
||||
|
||||
# General File Layout
|
||||
# Guidelines and (for now) "best practices"
|
||||
|
||||
## General File Layout
|
||||
Python/flask is not very opinionated and everything is possible. After reading (this)[https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure] and (this)[https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure] we decided for the "src-approach", at least the most obvious parts of it.
|
||||
|
||||
setup.py is not (yet) as complex as listed there and setup.cfg is not even (yet?!) existing.
|
||||
If you see this to need some improvements, please make it in small steps and explain what the benefits of all of that.
|
||||
|
||||
## Some words about dependencies
|
||||
As a quite young project, we don't have many dependencies yet and as a quite secure-aware use-case, we don't even want to have too many dependencies. That's sometimes the reason that we decide to roll our own rather then taking in new dependencies.
|
||||
|
||||
## Some words specific to the frontend
|
||||
Also for that reason, we're avoiding npm and manage javascript dependencies by hand or do stuff manually. Feel free to use plain javascript in pages.
|
||||
However, we're planning (or even have started) to use vue.js without using vue.js-components (that would require a build). So feel free to use vue.js but either make a thoughtfull proposal on how to manage the vue.js build or don't use vue.js-components. Also, specter-desktop is not a one-page-app and also doesn't want to become one.
|
||||
This [security-link](https://vuejs.org/v2/guide/security.html) might be interesting when developing vue.js.
|
||||
|
||||
We're aware that currently the app is not very compatible on different browsers and there is no clear strategy yet on how (and whether at all) to fix that. High level consultancy help on that would be appreciated even so (or especially when) you take the above security/dependency requirements into account.
|
||||
|
||||
## Some word about style
|
||||
* The icons are coming from https://material.io/resources/icons/?style=baseline
|
||||
* Colorizing the icons make them much more expressive. Current favorite colors are:
|
||||
* nice orange #F5A623
|
||||
* nice blue #4A90E2
|
||||
* A designer would probably rant about all these bad choices. Professional help, especially in the frontend, is very much appreciated.
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ stem==1.7.1
|
|||
typing-extensions==3.7.4
|
||||
urllib3==1.25.6
|
||||
Werkzeug==0.16.0
|
||||
serial==0.0.97
|
||||
pyserial==3.4
|
||||
# only for testing currently
|
||||
docker==4.1.0
|
||||
pytest==5.2.2
|
||||
|
|
@ -50,6 +50,10 @@ def get_cli(conf):
|
|||
host=conf["host"], port=conf["port"], protocol=conf["protocol"])
|
||||
return cli
|
||||
|
||||
class SpecterError(Exception):
|
||||
''' A SpecterError contains meaningfull messages which can be passed directly to the user '''
|
||||
pass
|
||||
|
||||
class Specter:
|
||||
def __init__(self, data_folder="./data", config={}):
|
||||
if data_folder.startswith("~"):
|
||||
|
|
@ -689,7 +693,7 @@ class Wallet(dict):
|
|||
return None
|
||||
return self.balance["trusted"]+self.balance["untrusted_pending"]
|
||||
|
||||
def createpsbt(self, address:str, amount:float, subtract:bool=False, fee_rate:float=0.0, fee_unit="SAT_B", coinselects=[]):
|
||||
def createpsbt(self, address:str, amount:float, subtract:bool=False, fee_rate:float=0.0, fee_unit="SAT_B"):
|
||||
"""
|
||||
fee_rate: in sat/B or BTC/kB. Default (None) bitcoin core sets feeRate automatically.
|
||||
"""
|
||||
|
|
|
|||
6
src/specter/static/vue.min.js
vendored
Normal file
6
src/specter/static/vue.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -134,6 +134,7 @@ function hideLoader(){
|
|||
// e.addEventListener("click", showLoader);
|
||||
// });
|
||||
</script>
|
||||
<script src="/static/vue.min.js"></script>
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -122,6 +122,50 @@ def devices_filled_data_folder(empty_data_folder):
|
|||
]
|
||||
}
|
||||
''')
|
||||
with open(empty_data_folder+"/devices/specter.json", "w") as text_file:
|
||||
text_file.write('''
|
||||
{
|
||||
"name": "Specter",
|
||||
"type": "specter",
|
||||
"keys": [
|
||||
{
|
||||
"derivation": "m/48h/1h/0h/2h",
|
||||
"original": "Vpub5n9kKePTPPGtw3RddeJWJe29epEyBBcoHbbPi5HhpoG2kTVsSCUzsad33RJUt3LktEUUPPofcZczuudnwR7ZgkAkT6N2K2Z7wdyjYrVAkXM",
|
||||
"fingerprint": "08686ac6",
|
||||
"type": "wsh",
|
||||
"xpub": "tpubDFHpKypXq4kwUrqLotPs6fCic5bFqTRGMBaTi9s5YwwGymE8FLGwB2kDXALxqvNwFxB1dLWYBmmeFVjmUSdt2AsaQuPmkyPLBKRZW8BGCiL"
|
||||
},
|
||||
{
|
||||
"derivation": "m/84h/1h/0h",
|
||||
"original": "vpub5ZSem3mLXiSJzgDX6pJb2N9L6sJ8m6ejaksLPLSuB53LBzCi2mMsBg19eEUSDkHtyYp75GATjLgt5p3S43WjaVCXAWU9q9H5GhkwJBrMiAb",
|
||||
"fingerprint": "08686ac6",
|
||||
"type": "wpkh",
|
||||
"xpub": "tpubDDUotcvrYMUiy4ncDirveTfhmvggdj8nxcW5JgHpGzYz3UVscJY5aEzFvgUPk4YyajadBnsTBmE2YZmAtJC14Q21xncJgVaHQ7UdqMRVRbU"
|
||||
},
|
||||
{
|
||||
"derivation": "m/84h/1h/1h",
|
||||
"original": "vpub5ZSem3mLXiSK55jPzfLVhbHbTEwGzEFZv3xrGFCw1vGHSNw7WcVuJXysJLWcgENQd3iXSNQaeSXUBW55Hy4GAjSTjrWP4vpKKkUN9jiU1Tc",
|
||||
"fingerprint": "08686ac6",
|
||||
"type": "wpkh",
|
||||
"xpub": "tpubDDUotcvrYMUj3UJV7ZtqKgoy8JKprrjdHubbBb3r7qmwHsEH69g7h6xyanWaCYdVEEV3Yu7a6s4ceFnp8DjXeeFxY8eXvH7XTAC4gxfDNEW"
|
||||
},
|
||||
{
|
||||
"derivation": "m/84h/1h/2h",
|
||||
"original": "vpub5ZSem3mLXiSK64v64deytnDCoYqbUSYHvmVurUGVMEnXMyEybtF3FEnNuiFDDC6J18a81fv5ptQXaQaaRiYx8MRxahipgxPLdxubpYt1dkD",
|
||||
"fingerprint": "08686ac6",
|
||||
"type": "wpkh",
|
||||
"xpub": "tpubDDUotcvrYMUj4TVBBYDKWsjaUcE9M52MJd8emp7QTAJBDTY9BRRFdomVCAFAjWMNcKLe8Cd5HJwg3AJKFyEDcGFTNyryYJgYmNdJMhwB2RG"
|
||||
},
|
||||
{
|
||||
"derivation": "m/84h/1h/3h",
|
||||
"original": "vpub5ZSem3mLXiSK8cKzh4sHxTvN7mgYQA29HfoAZeCDtX1M2zdejN5XVAtVyqhk8eui18JTtZ9M3VD3AiWCz8VwrybhBUh3HxzS8js3mLVybDT",
|
||||
"fingerprint": "08686ac6",
|
||||
"type": "wpkh",
|
||||
"xpub": "tpubDDUotcvrYMUj6zu5oyRdaZSjnq56GnWCfXRuUz38zSWztUvpJuFjsjscGHhheyAncK4z15rLVukBdUDwpPBDLtRBykqC9KHeG9akJWRipKK"
|
||||
}
|
||||
]
|
||||
}
|
||||
''')
|
||||
return empty_data_folder # no longer empty, though
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ def test_BitcoinCli(bitcoin_regtest):
|
|||
cli = BitcoinCLI(brt.rpcconn.rpcuser, brt.rpcconn.rpcpassword, host=brt.rpcconn.ipaddress, port=brt.rpcconn.rpcport)
|
||||
cli.getblockchaininfo()
|
||||
# To investigate the Bitcoin API, here are some great resources:
|
||||
# https://bitcoin.org/en/developer-reference#bitcoin-core-apis
|
||||
# https://chainquery.com/bitcoin-cli
|
||||
# https://github.com/ChristopherA/Learning-Bitcoin-from-the-Command-Line
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ def test_WalletManager(bitcoin_regtest, devices_filled_data_folder, device_manag
|
|||
psbt = wallet.createpsbt(random_address,10, True, 10)
|
||||
# the most relevant stuff of the above object:
|
||||
assert len(psbt['tx']['vin']) == 1 # 1 input
|
||||
assert psbt['tx']['vin'][0]['txid'] == "730b41bd1e77b65770bfec73304da5c34cc1bad100394e6f5cc020bb5dbe65fd"
|
||||
assert len(psbt['tx']['vout']) == 2 # 2 outputs
|
||||
# Now let's send some money to this wallet (creating 10 more potential inputs)
|
||||
for i in range(0,4): # 40 coins as a whole
|
||||
|
|
@ -125,6 +126,7 @@ def test_WalletManager(bitcoin_regtest, devices_filled_data_folder, device_manag
|
|||
assert rpce.error_msg == "Insufficient funds"
|
||||
pass
|
||||
# But wallet.createpsbt supports it (by explicitely specifying inputs)!
|
||||
wallet.createpsbt(random_address, 60, True, 10)
|
||||
bitcoin_regtest.mine()
|
||||
psbt = wallet.createpsbt(random_address, 60, True, 10)
|
||||
assert len(psbt['tx']['vin']) == 3
|
||||
assert psbt['tx']['vin'][2]['txid'] == '730b41bd1e77b65770bfec73304da5c34cc1bad100394e6f5cc020bb5dbe65fd'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue