1
0
Commit Graph

145 Commits

Author SHA1 Message Date
Sander van Grieken
18f6b88982 don't sys.exit() from run_offline_command, this leads to wait on lock that never releases. 2025-08-26 12:24:03 +02:00
SomberNight
3ae9cad36d android: extend testnet package name hack to other chains
closes https://github.com/spesmilo/electrum/issues/10087
2025-07-29 12:18:42 +00:00
SomberNight
85fc95c71b wallet_db: add configvar for partial_writes, disable by default
Adds a new configvar `WALLET_PARTIAL_WRITES` to enable/disable partial writes for the walletDB.
This is a further restriction on top of the existing restrictions,
e.g. wallet files still need to have file encryption disabled for partial writes.
It defaults to off, so even for unencrypted wallets we disable partial writes for now.

This is used as a stopgap measure until we fix the issues found with the partial writes impl
(see https://github.com/spesmilo/electrum/issues/10000).
2025-07-15 14:03:48 +00:00
SomberNight
3c82b00c5e WalletDB() usage: trivial refactors and fixes
split off from https://github.com/spesmilo/electrum/pull/10027
2025-07-15 12:30:06 +00:00
SomberNight
8a99219456 follow-up prev: electrum-ecc should search for libsecp dll in electrum/
The hack needs to be applied before we try importing electrum_ecc, i.e. it needs to be in the main script.
However, it should also be applied if the main script is not invoked directly, but e.g. the user imports electrum directly.
Hence the duplication.
2025-06-15 18:25:42 +00:00
наб
20e690226c run_electrum: improve check_imports()
$ ./run_electrum
Error: No module named 'dns'. Try 'sudo python3 -m pip install <module-name>'
$ pip install dns
ERROR: Could not find a version that satisfies the requirement dns (from versions: none)
ERROR: No matching distribution found for dns
$ pip install dnspython
Collecting dnspython
  Downloading dnspython-2.7.0-py3-none-any.whl (313 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 313.6/313.6 kB 3.4 MB/s eta 0:00:00
Installing collected packages: dnspython
Successfully installed dnspython-2.7.0
$ ./run_electrum
Error: No module named 'certifi'. Try 'sudo python3 -m pip install <module-name>'

$ ./run_electrum
Error: No module named 'google'. Try 'sudo python3 -m pip install <module-name>'
$ pip install google
Collecting google
  Downloading google-3.0.0-py2.py3-none-any.whl (45 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.3/45.3 kB 569.4 kB/s eta 0:00:00
Collecting beautifulsoup4
  Downloading beautifulsoup4-4.13.4-py3-none-any.whl (187 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 187.3/187.3 kB 3.4 MB/s eta 0:00:00
Collecting soupsieve>1.2
  Downloading soupsieve-2.7-py3-none-any.whl (36 kB)
Collecting typing-extensions>=4.0.0
  Using cached typing_extensions-4.14.0-py3-none-any.whl (43 kB)
Installing collected packages: typing-extensions, soupsieve, beautifulsoup4, google
Successfully installed beautifulsoup4-4.13.4 google-3.0.0 soupsieve-2.7 typing-extensions-4.14.0
$ ./run_electrum
Error: No module named 'google'. Try 'sudo python3 -m pip install <module-name>'
$ pip install protobuf
Collecting protobuf
  Downloading protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl (321 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 321.1/321.1 kB 3.6 MB/s eta 0:00:00
Installing collected packages: protobuf
Successfully installed protobuf-6.31.1
$ ./run_electrum
Error: No module named 'aiorpcx'. Try 'sudo python3 -m pip install <module-name>'

$ ./run_electrum
Traceback (most recent call last):
  File "/home/nabijaczleweli/uwu/electrum/./run_electrum", line 95, in <module>
    from electrum.logging import get_logger, configure_logging  # import logging submodule first
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/nabijaczleweli/uwu/electrum/electrum/__init__.py", line 18, in <module>
    from .util import format_satoshis
  File "/home/nabijaczleweli/uwu/electrum/electrum/util.py", line 58, in <module>
    import aiohttp
ModuleNotFoundError: No module named 'aiohttp'
$ ./run_electrum
Traceback (most recent call last):
  File "/home/nabijaczleweli/uwu/electrum/./run_electrum", line 95, in <module>
    from electrum.logging import get_logger, configure_logging  # import logging submodule first
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/nabijaczleweli/uwu/electrum/electrum/__init__.py", line 18, in <module>
    from .util import format_satoshis
  File "/home/nabijaczleweli/uwu/electrum/electrum/util.py", line 59, in <module>
    from aiohttp_socks import ProxyConnector, ProxyType
ModuleNotFoundError: No module named 'aiohttp_socks'
$ pip install aiohttp aiohttp-socks
Requirement already satisfied: aiohttp in ./venv/lib/python3.11/site-packages (3.12.13)
Collecting aiohttp-socks
  Downloading aiohttp_socks-0.10.1-py3-none-any.whl (10 kB)
Requirement already satisfied: aiohappyeyeballs>=2.5.0 in ./venv/lib/python3.11/site-packages (from aiohttp) (2.6.1)
Requirement already satisfied: aiosignal>=1.1.2 in ./venv/lib/python3.11/site-packages (from aiohttp) (1.3.2)
Requirement already satisfied: attrs>=17.3.0 in ./venv/lib/python3.11/site-packages (from aiohttp) (25.3.0)
Requirement already satisfied: frozenlist>=1.1.1 in ./venv/lib/python3.11/site-packages (from aiohttp) (1.7.0)
Requirement already satisfied: multidict<7.0,>=4.5 in ./venv/lib/python3.11/site-packages (from aiohttp) (6.4.4)
Requirement already satisfied: propcache>=0.2.0 in ./venv/lib/python3.11/site-packages (from aiohttp) (0.3.2)
Requirement already satisfied: yarl<2.0,>=1.17.0 in ./venv/lib/python3.11/site-packages (from aiohttp) (1.20.1)
Collecting python-socks[asyncio]<3.0.0,>=2.4.3
  Downloading python_socks-2.7.1-py3-none-any.whl (54 kB)
$ ./run_electrum
Traceback (most recent call last):
  File "/home/nabijaczleweli/uwu/electrum/./run_electrum", line 95, in <module>
    from electrum.logging import get_logger, configure_logging  # import logging submodule first
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/nabijaczleweli/uwu/electrum/electrum/__init__.py", line 19, in <module>
    from .wallet import Wallet
  File "/home/nabijaczleweli/uwu/electrum/electrum/wallet.py", line 44, in <module>
    import electrum_ecc as ecc
ModuleNotFoundError: No module named 'electrum_ecc'
$ pip install electrum_ecc
Collecting electrum_ecc
  Downloading electrum_ecc-0.0.5.tar.gz (2.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.0/2.0 MB 7.9 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: electrum_ecc
  Building wheel for electrum_ecc (pyproject.toml) ... done
  Created wheel for electrum_ecc: filename=electrum_ecc-0.0.5-py3-none-linux_x86_64.whl size=1285621 sha256=f2d27f7635ad82efa533055a4952e92f4db08ccab60d5dea0f3443e1ab57d5a7
  Stored in directory: /mnt/filling/store/nabijaczleweli/.cache/pip/wheels/ad/4d/86/1607d5642f3437553a45658305d979155f8007a7108f5e6d79
Successfully built electrum_ecc
Installing collected packages: electrum_ecc
Successfully installed electrum_ecc-0.0.5
$ ./run_electrum
Error: at least one of ('pycryptodomex', 'cryptography') needs to be installed.
$ ./run_electrum
Traceback (most recent call last):
  File "/home/nabijaczleweli/uwu/electrum/./run_electrum", line 97, in <module>
    from electrum.logging import get_logger, configure_logging  # import logging submodule first
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/nabijaczleweli/uwu/electrum/electrum/__init__.py", line 19, in <module>
    from .wallet import Wallet
  File "/home/nabijaczleweli/uwu/electrum/electrum/wallet.py", line 47, in <module>
    from . import util, keystore, transaction, bitcoin, coinchooser, bip32, descriptor
  File "/home/nabijaczleweli/uwu/electrum/electrum/keystore.py", line 53, in <module>
    from .plugin import run_hook
  File "/home/nabijaczleweli/uwu/electrum/electrum/plugin.py", line 53, in <module>
    from .simple_config import SimpleConfig
  File "/home/nabijaczleweli/uwu/electrum/electrum/simple_config.py", line 12, in <module>
    from . import invoices
  File "/home/nabijaczleweli/uwu/electrum/electrum/invoices.py", line 7, in <module>
    from .json_db import StoredObject, stored_in
  File "/home/nabijaczleweli/uwu/electrum/electrum/json_db.py", line 29, in <module>
    import jsonpatch
ModuleNotFoundError: No module named 'jsonpatch'

$ ./run_electrum
Traceback (most recent call last):
  File "/home/nabijaczleweli/uwu/electrum/./run_electrum", line 99, in <module>
    from electrum.logging import get_logger, configure_logging  # import logging submodule first
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/nabijaczleweli/uwu/electrum/electrum/__init__.py", line 19, in <module>
    from .wallet import Wallet
  File "/home/nabijaczleweli/uwu/electrum/electrum/wallet.py", line 77, in <module>
    from .lnworker import LNWallet
  File "/home/nabijaczleweli/uwu/electrum/electrum/lnworker.py", line 78, in <module>
    from .submarine_swaps import SwapManager
  File "/home/nabijaczleweli/uwu/electrum/electrum/submarine_swaps.py", line 16, in <module>
    import electrum_aionostr as aionostr
ModuleNotFoundError: No module named 'electrum_aionostr'
2025-06-15 20:00:32 +02:00
Sander van Grieken
6f653af3ff whitespace, imports 2025-06-03 11:26:23 +02:00
ThomasV
972ebb0420 Daemon: do not set config.CURRENT_WALLET to None
Instead, raise a UserFacingException if the daemon has several wallets in memory.
2025-06-03 10:41:03 +02:00
ThomasV
9e225d1269 Replace config GUI_LAST_WALLET with CURRENT_WALLET
- CURRENT_WALLET is set when a single wallet is loaded in memory, and it
   remains set after Electrum stops running.
 - If several wallets are loaded at the same time, CURRENT_WALLET is unset,
   and RPCs must specify the wallet explicitly (using --wallet for the CLI)
 - The fallback to 'default_wallet' essentially only applies when
   creating a new wallet file
2025-06-02 14:05:53 +02:00
ghost43
fc13001bb9 Merge pull request #9875 from SomberNight/202505_pad_protocol_3
interface: add padding and some noise to protocol messages
2025-05-30 15:37:12 +00:00
SomberNight
6257d9e266 constants.py: add datadir_subdir, cli_flag, config_key methods
- use these to generalise recurring "switch-like" ifs
- this effectively also adds a `--mainnet` CLI option
    - closes https://github.com/spesmilo/electrum/issues/9790
2025-05-29 18:41:28 +00:00
SomberNight
447052b4ff interface: add padding and some noise to protocol messages
basic countermeasures against traffic analysis
2025-05-29 17:29:30 +00:00
f321x
8870838834 raise instead of overwriting the config file on syntax error 2025-05-15 17:21:16 +02:00
SomberNight
351cc6abd9 Revert "interface: add padding and some noise to protocol messages"
Unforeseen issues. Needs more work..

This reverts commit 097eabed1f.
2025-05-08 18:34:07 +00:00
SomberNight
097eabed1f interface: add padding and some noise to protocol messages
basic countermeasures against traffic analysis
2025-05-08 14:35:44 +00:00
SomberNight
2600a3bc74 requirements: bump max aiorpcx
and bump pinned aiorpcx and electrum-aionostr
2025-05-08 14:31:11 +00:00
Sander van Grieken
b12206482a android: remove setting SWAPSERVER_URL in config at startup for android.
This config var should have never been saved to the config file, therefore it is safe to remove
instead of setting to '' to overwrite any existing value.
2025-05-01 09:53:35 +02:00
SomberNight
d7bc6cbb3c add harden_memory_linux: harder for other processes to read our memory
This module tries to restrict the ability of other processes to access the memory of our process.
Traditionally, on Linux, one process can access the memory of another arbitrary process
if both are running as the same user (uid). (Root can ofc access the memory of ~any process)
Programs can opt-out from this by setting `prctl(PR_SET_DUMPABLE, 0);`

also see https://man.archlinux.org/man/PR_SET_DUMPABLE.2const.en

-----

Also, from https://unix.stackexchange.com/a/518452 :

In a terminal window:
```
% echo $$  # show our pid
6744
% read -sp 'secret password: '; echo
secret password:
%
```
Then in another terminal window:
```
% grep heap /proc/6744/maps
01bb7000-01c3e000 rw-p 00000000 00:00 0                                  [heap]
% dd if=/proc/6744/mem bs=1 skip=$((0x01bb7000)) count=$((0x01c3e000-0x01bb7000)) status=none |
    strings | less
...
% dd if=/proc/6744/mem bs=1 skip=$((0x01bb7000)) count=$((0x01c3e000-0x01bb7000)) status=none |
    strings | grep obiwan
obiwan_kenobi  # "secret password"
```
2025-04-18 00:54:30 +00:00
ThomasV
9d1ffe0c37 support for arguments to plugin commands:
- add a simple parser that only figures out where the config is,
   and does not complain if args are unknown
2025-03-16 15:01:22 +01:00
ThomasV
cb39737a39 Plugins call with cmd_only:
- pass temporary config to Plugins
 - load only enabled plugins
 - parse the command line again after plugins are loaded
2025-03-15 13:31:00 +01:00
ThomasV
4f79e516e4 run_electrum: add parse_command_line method 2025-03-15 13:22:28 +01:00
f321x
ae64583ebc add handling of plugin commands 2025-03-15 13:22:28 +01:00
SomberNight
5b2068976c config: remove a footgun 2025-02-07 16:22:44 +00:00
f321x
171aa5ee5a bump aiorpcx version 2025-01-20 12:11:55 +01:00
Sander van Grieken
897327da5a android: support regtest builds in a similar fashion to testnet builds, by package name. 2025-01-17 15:37:51 +01:00
SomberNight
fb5a1af666 bump min required Python version to 3.10 2025-01-10 18:52:49 +00:00
ThomasV
60f13a977e Swaps over Nostr
- Separation between SwapManager and its transport:
   Legacy transpport uses http, Nostr uses websockets
 - The transport uses a context to open/close connections.
   This context is not async, because it needs to be called
   from the GUI
 - Swapserver fees values are initialized to None instead
   of 0, so that any attempt to use them before the swap
   manager is initialized will raise an exception.
 - Remove swapserver fees disk caching (swap_pairs file)
 - Regtests use http transport
 - Android uses http transport (until QML is ready)
2024-11-12 09:32:25 +01:00
Sander van Grieken
974ed6828e run_electrum: allow running from git clone to override DeprecationWarning warnings 2024-10-30 11:35:17 +01:00
SomberNight
214e04d4bb hw plugins: cmdline: fix offline commands for encrypted hw wallets
```
$ ./run_electrum --testnet signmessage -w /home/user/.electrum/testnet/wallets/test_trezor_white_bip84 tb1q5pguna9y2g9y2gsu8r8gmxeye2cefvyly8dg02 heyheyhey -o
  0.84 | W | plugins.jade.jadepy.jade | No module named 'electrum.plugins.jade.jadepy.jade_ble'
  0.84 | W | plugins.jade.jadepy.jade | BLE scanning/connectivity will not be available
  3.73 | E | __main__ | error running command (without daemon)
Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/plugins/trezor/clientbase.py", line 151, in get_xpub
    node = trezorlib.btc.get_public_node(self.client, address_n).node
  File "/home/user/.local/lib/python3.10/site-packages/trezorlib/tools.py", line 274, in wrapped_f
    ret = f(*args, **kwargs)
  File "/home/user/.local/lib/python3.10/site-packages/trezorlib/btc.py", line 125, in get_public_node
    return client.call(
  File "/home/user/.local/lib/python3.10/site-packages/trezorlib/tools.py", line 297, in wrapped_f
    return f(client, *args, **kwargs)
  File "/home/user/.local/lib/python3.10/site-packages/trezorlib/client.py", line 260, in call
    resp = self._callback_pin(resp)
  File "/home/user/.local/lib/python3.10/site-packages/trezorlib/client.py", line 186, in _callback_pin
    pin = self.ui.get_pin(msg.type)
  File "/home/user/wspace/electrum/electrum/plugins/trezor/clientbase.py", line 308, in get_pin
    pin = self.handler.get_pin(msg.format(self.device), show_strength=show_strength)
AttributeError: 'NoneType' object has no attribute 'get_pin'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/wspace/electrum/./run_electrum", line 540, in handle_cmd
    result = fut.result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 458, in result
    return self.__get_result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/home/user/wspace/electrum/./run_electrum", line 227, in run_offline_command
    password = get_password_for_hw_device_encrypted_storage(plugins)
  File "/home/user/wspace/electrum/./run_electrum", line 212, in get_password_for_hw_device_encrypted_storage
    return client.get_password_for_storage_encryption()
  File "/home/user/wspace/electrum/electrum/plugin.py", line 523, in wrapper
    return run_in_hwd_thread(partial(func, *args, **kwargs))
  File "/home/user/wspace/electrum/electrum/plugin.py", line 516, in run_in_hwd_thread
    return fut.result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 458, in result
    return self.__get_result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/user/wspace/electrum/electrum/plugins/hw_wallet/plugin.py", line 260, in get_password_for_storage_encryption
    xpub = self.get_xpub(derivation, "standard")
  File "/home/user/wspace/electrum/electrum/plugin.py", line 523, in wrapper
    return run_in_hwd_thread(partial(func, *args, **kwargs))
  File "/home/user/wspace/electrum/electrum/plugin.py", line 513, in run_in_hwd_thread
    return func()
  File "/home/user/wspace/electrum/electrum/plugins/trezor/clientbase.py", line 150, in get_xpub
    with self.run_flow(creating_wallet=creating):
  File "/home/user/wspace/electrum/electrum/plugins/trezor/clientbase.py", line 89, in __exit__
    self.end_flow()
  File "/home/user/wspace/electrum/electrum/plugins/trezor/clientbase.py", line 82, in end_flow
    self.handler.finished()
AttributeError: 'NoneType' object has no attribute 'finished'
```
2024-10-10 21:25:34 +00:00
SomberNight
1257f21b1b constants: rm set_testnet/set_mainnet fns with AbstractNet.set_as_network 2024-09-16 15:27:45 +00:00
wakiyamap
1d9ff40d0b Add suport testnet4 2024-09-14 03:52:03 +09:00
SomberNight
5f95d919df requirements: bump pinned (and max) aiorpcx versions to 0.23.1
related https://github.com/spesmilo/electrum/issues/8954
2024-04-08 16:44:59 +00:00
SomberNight
bd492fbd14 cli/rpc: nicer error messages and error-passing
Previously, generally, in case of any error, commands would raise a generic "Exception()" and the CLI/RPC would convert that and return it as `str(e)`.

With this change, we now distinguish "user-facing exceptions" (e.g. "Password required" or "wallet not loaded") and "internal errors" (e.g. bugs).
- for "user-facing exceptions", the behaviour is unchanged
- for "internal errors", we now pass around the traceback (e.g. from daemon server to rpc client) and show it to the user (previously, assuming there was a daemon running, the user could only retrieve the exception from the log of that daemon). These errors use a new jsonrpc error code int (code 2).

As the logic only changes for "internal errors", I deem this change not to be compatibility-breaking.

----------
Examples follow.
Consider the following two commands:
```
@command('')
async def errorgood(self):
	from electrum.util import UserFacingException
	raise UserFacingException("heyheyhey")

@command('')
async def errorbad(self):
	raise Exception("heyheyhey")
```

----------
(before change)

CLI with daemon:
```
$ ./run_electrum --testnet daemon -d
starting daemon (PID 9221)
$ ./run_electrum --testnet errorgood
heyheyhey
$ ./run_electrum --testnet errorbad
heyheyhey
$ ./run_electrum --testnet stop
Daemon stopped
```

CLI without daemon:
```
$ ./run_electrum --testnet -o errorgood
heyheyhey
$ ./run_electrum --testnet -o errorbad
heyheyhey
```

RPC:
```
$ curl --data-binary '{"id":"curltext","jsonrpc":"2.0","method":"errorgood","params":[]}' http://user:pass@127.0.0.1:7777
{"id": "curltext", "jsonrpc": "2.0", "error": {"code": 1, "message": "heyheyhey"}}
$ curl --data-binary '{"id":"curltext","jsonrpc":"2.0","method":"errorbad","params":[]}' http://user:pass@127.0.0.1:7777
{"id": "curltext", "jsonrpc": "2.0", "error": {"code": 1, "message": "heyheyhey"}}
```

----------
(after change)

CLI with daemon:
```
$ ./run_electrum --testnet daemon -d
starting daemon (PID 9254)
$ ./run_electrum --testnet errorgood
heyheyhey
$ ./run_electrum --testnet errorbad
(inside daemon): Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/daemon.py", line 254, in handle
    response['result'] = await f(*params)
  File "/home/user/wspace/electrum/electrum/daemon.py", line 361, in run_cmdline
    result = await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/commands.py", line 163, in func_wrapper
    return await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/commands.py", line 217, in errorbad
    raise Exception("heyheyhey")
Exception: heyheyhey

internal error while executing RPC
$ ./run_electrum --testnet stop
Daemon stopped
```

CLI without daemon:
```
$ ./run_electrum --testnet -o errorgood
heyheyhey
$ ./run_electrum --testnet -o errorbad
  0.78 | E | __main__ | error running command (without daemon)
Traceback (most recent call last):
  File "/home/user/wspace/electrum/./run_electrum", line 534, in handle_cmd
    result = fut.result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 458, in result
    return self.__get_result()
  File "/usr/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/home/user/wspace/electrum/./run_electrum", line 255, in run_offline_command
    result = await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/commands.py", line 163, in func_wrapper
    return await func(*args, **kwargs)
  File "/home/user/wspace/electrum/electrum/commands.py", line 217, in errorbad
    raise Exception("heyheyhey")
Exception: heyheyhey
```

RPC:
```
$ curl --data-binary '{"id":"curltext","jsonrpc":"2.0","method":"errorgood","params":[]}' http://user:pass@127.0.0.1:7777
{"id": "curltext", "jsonrpc": "2.0", "error": {"code": 1, "message": "heyheyhey"}}
$ curl --data-binary '{"id":"curltext","jsonrpc":"2.0","method":"errorbad","params":[]}' http://user:pass@127.0.0.1:7777
{"id": "curltext", "jsonrpc": "2.0", "error": {"code": 2, "message": "internal error while executing RPC", "data": {"exception": "Exception('heyheyhey')", "traceback": "Traceback (most recent call last):\n  File \"/home/user/wspace/electrum/electrum/daemon.py\", line 254, in handle\n    response['result'] = await f(*params)\n  File \"/home/user/wspace/electrum/electrum/commands.py\", line 163, in func_wrapper\n    return await func(*args, **kwargs)\n  File \"/home/user/wspace/electrum/electrum/commands.py\", line 217, in errorbad\n    raise Exception(\"heyheyhey\")\nException: heyheyhey\n"}}}
```
2024-02-12 19:02:02 +00:00
SomberNight
0e5a1380ca i18n: simplify language default. only translate string if using GUI. 2024-01-16 17:23:43 +00:00
ThomasV
68159b3ef6 walletDB: replace 'manual_upgrades' parameter with 'upgrade', with opposite semantics 2023-09-22 15:02:07 +02:00
ThomasV
4e80ef818d Add unlock command to CLI (stores wallet password in memory) 2023-09-15 15:37:53 +02:00
SomberNight
b3514672d6 run_electrum: small clean-up in init_cmdline 2023-09-08 15:46:06 +00:00
SomberNight
b45c84f24f remove the kivy gui
We now use the qml gui on Android, and haven't been maintaining
the kivy GUI for a while.
2023-08-30 16:47:37 +00:00
SomberNight
90f39bce88 run_electrum: have daemon manage Plugins object, and call Plugins.stop
Plugins.stop was never called, so the Plugins thread only stopped
because of the is_running() check in run(), which triggers too late:
the Plugins thread was stopping after the main thread stopped.

E.g. playing around in the qt wizard with wallet creation for a Trezor,
and closing the wizard (only window):
``` 24.85 | E | p/plugin.Plugins |
Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/util.py", line 386, in run_jobs
    job.run()
  File "/home/user/wspace/electrum/electrum/plugin.py", line 430, in run
    client.timeout(cutoff)
  File "/home/user/wspace/electrum/electrum/plugin.py", line 363, in wrapper
    return run_in_hwd_thread(partial(func, *args, **kwargs))
  File "/home/user/wspace/electrum/electrum/plugin.py", line 355, in run_in_hwd_thread
    fut = _hwd_comms_executor.submit(func)
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 167, in submit
    raise RuntimeError('cannot schedule new futures after shutdown')
RuntimeError: cannot schedule new futures after shutdown
```
2023-08-24 17:15:14 +00:00
ThomasV
b96cc82333 Make storage a field of db
This comes from the jsonpatch_new branch.
I rather have in master now, because it touches a lot of filese.
2023-08-18 08:08:31 +02:00
ThomasV
0ebb6469ff CLI: make sure we do not load WalletDB while another process is accessing it
- do not load WalletDB in order to check keystore password
- do not allow --offline commands while a daemon is running
2023-08-18 08:05:54 +02:00
SomberNight
44ef5a35b7 CLI: fix regression re handling "unknown command", re locale
if qt is not installed, e.g. on a server, was getting:
```
$ ./run_electrum sadasdasddsa
Traceback (most recent call last):
  File "/home/user/wspace/electrum/./run_electrum", line 532, in <module>
    main()
  File "/home/user/wspace/electrum/./run_electrum", line 383, in main
    lang = get_default_language(gui_name=gui_name)
  File "/home/user/wspace/electrum/electrum/gui/default_lang.py", line 23, in get_default_language
    from PyQt5.QtCore import QLocale
ModuleNotFoundError: No module named 'PyQt5.QtCore'
```
2023-08-09 14:52:40 +00:00
SomberNight
20f4d44f09 cli: "daemon -d": init rpc credentials before os.fork()
follow-up 8b195ee77a
2023-08-03 22:42:08 +00:00
SomberNight
8b195ee77a cli: "./run_electrum daemon -d" to block until daemon becomes ready
Without this,
`$ python3 -m unittest electrum.tests.regtest.TestUnixSockets.test_unixsockets`
was failing on my machine but succeeding on CI, due to timing differences.
2023-08-03 17:21:05 +00:00
Sander van Grieken
db6779bf04 qt: show send tab if payment identifier is passed on the cmdline 2023-07-07 20:49:45 +02:00
Sander van Grieken
a2ca191de1 pass wallet to PaymentIdentifier instead of config and contacts 2023-06-28 16:49:28 +02:00
ThomasV
15eb765eac payment_identifiers:
- this separates GUI from core handling
 - the PaymentIdentifier class handles network requests
 - the GUI is agnostic about the type of PI
2023-06-28 16:49:28 +02:00
SomberNight
3ab47e1c45 (trivial) convert more config keys 2023-06-05 15:29:35 +00:00
SomberNight
ccc012674f unconditionally raise ImportError if asserts are disabled
I have reconsidered and now think that we should always hard-fail
if asserts asserts are disabled. It is just easier to reason about
the code knowing that asserts are evaluated.

If an end-user or library user has a concrete use case where this is
a problem, please open an issue and let us know.

follow-up
0f541be6f1
0e5464ca13
2023-06-01 17:34:32 +00:00
SomberNight
24980feab7 config: introduce ConfigVars
A new config API is introduced, and ~all of the codebase is adapted to it.
The old API is kept but mainly only for dynamic usage where its extra flexibility is needed.

Using examples, the old config API looked this:
```
>>> config.get("request_expiry", 86400)
604800
>>> config.set_key("request_expiry", 86400)
>>>
```

The new config API instead:
```
>>> config.WALLET_PAYREQ_EXPIRY_SECONDS
604800
>>> config.WALLET_PAYREQ_EXPIRY_SECONDS = 86400
>>>
```

The old API operated on arbitrary string keys, the new one uses
a static ~enum-like list of variables.

With the new API:
- there is a single centralised list of config variables, as opposed to
  these being scattered all over
- no more duplication of default values (in the getters)
- there is now some (minimal for now) type-validation/conversion for
  the config values

closes https://github.com/spesmilo/electrum/pull/5640
closes https://github.com/spesmilo/electrum/pull/5649

Note: there is yet a third API added here, for certain niche/abstract use-cases,
where we need a reference to the config variable itself.
It should only be used when needed:
```
>>> var = config.cv.WALLET_PAYREQ_EXPIRY_SECONDS
>>> var
<ConfigVarWithConfig key='request_expiry'>
>>> var.get()
604800
>>> var.set(3600)
>>> var.get_default_value()
86400
>>> var.is_set()
True
>>> var.is_modifiable()
True
```
2023-05-25 17:39:48 +00:00