Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c3d9e0755 | |||
| 495bf82004 | |||
| 8592fd24d7 | |||
| a90475a98e | |||
| b759fc1954 | |||
| e15826b645 | |||
| 5754104fb8 |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -18,6 +18,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [1.1.0] - 2026-02-19
|
||||
|
||||
### Overview
|
||||
This release adds ARM64/aarch64 platform support, native Palladium URI scheme integration, a unified network reset feature for both desktop and Android interfaces, and several bug fixes and documentation improvements.
|
||||
|
||||
### Added
|
||||
- **ARM64/aarch64 support**: AppImage builds now include a dedicated ARM64 variant for Linux on aarch64 hardware.
|
||||
- **ARM64 QML support**: Android/QML interface now works on ARM64 devices with pinned PyQt6 dependencies (`PyQt6>=6.7.0,<6.8.0`) to ensure compatibility where PyQt6 ≥ 6.9 is unavailable.
|
||||
- **Palladium URI scheme**: Donation flow and payment handling now use the `palladium:` URI scheme instead of `bitcoin:`.
|
||||
- **Reset SSL certificates**: New action in both Qt (Server tab) and QML (Server Settings) to delete locally cached TLS certificates and force re-fetch on reconnect. Useful when a server renews its self-signed certificate.
|
||||
- **Reset known servers**: New action alongside SSL reset to clear the list of recently used servers, available in both Qt and QML interfaces.
|
||||
- **Troubleshooting section in user guide**: Added documentation explaining SSL certificate caching, why self-signed certificates require manual reset, and step-by-step instructions for both Android and desktop.
|
||||
|
||||
### Fixed
|
||||
- **WIF deserialization bug**: Fixed incorrect private key deserialization for Palladium network parameters.
|
||||
- **Docker build warning**: Resolved undefined `TARGETARCH` variable warning in multi-platform Docker builds.
|
||||
- **Whitepaper link**: Updated Help → White Paper URL to the correct repository (`palladium-coin/whitepaper`).
|
||||
- **Browser opening on Linux**: `webopen()` now uses `xdg-open` instead of Python's `webbrowser` module, preventing text-based browsers (e.g. `w3m`) from being selected instead of the desktop browser.
|
||||
|
||||
### Changed
|
||||
- **README**: Updated "Running from Source" section with clear numbered steps, separate x86_64 and ARM64 dependency instructions, and improved QML optional section.
|
||||
|
||||
---
|
||||
|
||||
## [1.0.1] - 2026-01-10
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
```
|
||||
Licence: MIT Licence
|
||||
Version: 1.0.1
|
||||
Version: 1.1.0
|
||||
Maintainer: Davide Grilli
|
||||
Language: Python (>= 3.10)
|
||||
Homepage: https://github.com/palladium-coin/pallectrum
|
||||
|
||||
@@ -652,7 +652,7 @@ def deserialize_privkey(key: str) -> Tuple[str, bytes, bool]:
|
||||
|
||||
if txin_type is None:
|
||||
# keys exported in version 3.0.x encoded script type in first byte
|
||||
prefix_value = vch[0] - constants.net.WIF_PREFIX
|
||||
prefix_value = (vch[0] - constants.net.WIF_PREFIX) % 256
|
||||
try:
|
||||
txin_type = WIF_SCRIPT_TYPES_INV[prefix_value]
|
||||
except KeyError as e:
|
||||
|
||||
@@ -258,7 +258,7 @@ BitcoinTestnet = PalladiumTestnet
|
||||
class BitcoinRegtest(PalladiumTestnet):
|
||||
|
||||
NET_NAME = "regtest"
|
||||
SEGWIT_HRP = "bcrt"
|
||||
SEGWIT_HRP = "rplm"
|
||||
BOLT11_HRP = SEGWIT_HRP
|
||||
GENESIS = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
|
||||
LN_DNS_SEEDS = []
|
||||
|
||||
@@ -296,6 +296,7 @@ Pane {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,73 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Server")
|
||||
enabled: address_tf.enabled
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: qsTr("Server")
|
||||
enabled: address_tf.enabled
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
icon.source: '../../../icons/delete.png'
|
||||
ToolTip.text: qsTr('Reset network data')
|
||||
ToolTip.visible: hovered
|
||||
onClicked: resetMenu.open()
|
||||
|
||||
Menu {
|
||||
id: resetMenu
|
||||
|
||||
MenuItem {
|
||||
text: qsTr('SSL certificates')
|
||||
onTriggered: {
|
||||
var dialog = app.messageDialog.createObject(app, {
|
||||
title: qsTr('Are you sure?'),
|
||||
text: qsTr('This will remove cached SSL certificates for servers and reconnect to fetch them again.'),
|
||||
yesno: true
|
||||
})
|
||||
dialog.accepted.connect(function() {
|
||||
var removed = Network.clearPinnedServerCertificates()
|
||||
var msg = removed < 0
|
||||
? qsTr('Failed to reset SSL certificates.')
|
||||
: removed > 0
|
||||
? qsTr('%1 certificate files were removed.').arg(removed)
|
||||
: qsTr('No cached certificate files were found.')
|
||||
app.messageDialog.createObject(app, {
|
||||
title: qsTr('Reset SSL certificates'),
|
||||
text: msg
|
||||
}).open()
|
||||
})
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr('Known servers')
|
||||
onTriggered: {
|
||||
var dialog = app.messageDialog.createObject(app, {
|
||||
title: qsTr('Are you sure?'),
|
||||
text: qsTr('This will remove the list of known servers.'),
|
||||
yesno: true
|
||||
})
|
||||
dialog.accepted.connect(function() {
|
||||
var removed = Network.clearRecentServers()
|
||||
var msg = removed < 0
|
||||
? qsTr('Failed to reset known servers.')
|
||||
: removed > 0
|
||||
? qsTr('%1 server(s) were removed.').arg(removed)
|
||||
: qsTr('No known servers were found.')
|
||||
app.messageDialog.createObject(app, {
|
||||
title: qsTr('Reset known servers'),
|
||||
text: msg
|
||||
}).open()
|
||||
})
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextHighlightPane {
|
||||
|
||||
@@ -306,3 +306,19 @@ class QENetwork(QObject, QtEventListener):
|
||||
@pyqtSlot()
|
||||
def probeTor(self):
|
||||
ProxySettings.probe_tor(self.torProbeFinished.emit) # via signal
|
||||
|
||||
@pyqtSlot(result=int)
|
||||
def clearPinnedServerCertificates(self):
|
||||
try:
|
||||
return self.network.run_from_another_thread(self.network.clear_pinned_server_certs())
|
||||
except Exception:
|
||||
self._logger.exception("failed to clear pinned server certificates")
|
||||
return -1
|
||||
|
||||
@pyqtSlot(result=int)
|
||||
def clearRecentServers(self):
|
||||
try:
|
||||
return self.network.clear_recent_servers()
|
||||
except Exception:
|
||||
self._logger.exception("failed to clear recent servers")
|
||||
return -1
|
||||
|
||||
@@ -845,7 +845,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
||||
self.help_menu.addSeparator()
|
||||
self.help_menu.addAction(_("&Documentation"), lambda: webopen("https://github.com/palladium-coin/pallectrum/blob/main/user-guide.md")).setShortcut(QKeySequence.StandardKey.HelpContents)
|
||||
if not constants.net.TESTNET:
|
||||
self.help_menu.addAction(_("&White Paper"), lambda: webopen("https://github.com/palladium-coin/palladiumcore/blob/master/assets/whitepaper/(original)whitepaper.pdf"))
|
||||
self.help_menu.addAction(_("&White Paper"), lambda: webopen("https://github.com/palladium-coin/whitepaper/blob/main/whitepaper.pdf"))
|
||||
self.help_menu.addAction(_("&Report Bug"), self.show_report_bug)
|
||||
self.help_menu.addSeparator()
|
||||
self.help_menu.addAction(_("&Donate to server"), self.donate_to_server)
|
||||
|
||||
@@ -29,7 +29,7 @@ from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt6.QtWidgets import (
|
||||
QTreeWidget, QTreeWidgetItem, QMenu, QGridLayout, QComboBox, QLineEdit, QDialog, QVBoxLayout, QHeaderView,
|
||||
QCheckBox, QTabWidget, QWidget, QLabel, QPushButton, QHBoxLayout,
|
||||
QListWidget, QListWidgetItem,
|
||||
QListWidget, QListWidgetItem, QMessageBox,
|
||||
)
|
||||
from PyQt6.QtGui import QIntValidator
|
||||
|
||||
@@ -444,6 +444,16 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
self.layout().addWidget(self.nodes_list_widget)
|
||||
self.nodes_list_widget.update()
|
||||
|
||||
self.clear_certs_button = QPushButton(_('Reset SSL certificates'))
|
||||
self.clear_certs_button.clicked.connect(self.clear_pinned_server_certs)
|
||||
self.clear_servers_button = QPushButton(_('Reset known servers'))
|
||||
self.clear_servers_button.clicked.connect(self.clear_recent_servers)
|
||||
buttons = QHBoxLayout()
|
||||
buttons.addStretch(1)
|
||||
buttons.addWidget(self.clear_certs_button)
|
||||
buttons.addWidget(self.clear_servers_button)
|
||||
self.layout().addLayout(buttons)
|
||||
|
||||
self.register_callbacks()
|
||||
self.destroyed.connect(lambda: self.unregister_callbacks())
|
||||
|
||||
@@ -584,6 +594,54 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
_logger.debug(f"set_server: {new_net_params=}")
|
||||
self.network.run_from_another_thread(self.network.set_parameters(new_net_params))
|
||||
|
||||
def clear_pinned_server_certs(self):
|
||||
result = QMessageBox.question(
|
||||
self,
|
||||
_('Reset SSL certificates'),
|
||||
_('This will remove cached SSL certificates for servers and reconnect to fetch them again.')
|
||||
+ '\n\n'
|
||||
+ _('Do you want to continue?'),
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
)
|
||||
if result != QMessageBox.StandardButton.Yes:
|
||||
return
|
||||
try:
|
||||
removed = self.network.run_from_another_thread(self.network.clear_pinned_server_certs())
|
||||
except Exception as e:
|
||||
_logger.exception("failed to clear pinned server certificates")
|
||||
QMessageBox.critical(self, _('Reset SSL certificates'), str(e))
|
||||
return
|
||||
if removed > 0:
|
||||
msg = _('{} certificate files were removed.').format(removed)
|
||||
else:
|
||||
msg = _('No cached certificate files were found.')
|
||||
QMessageBox.information(self, _('Reset SSL certificates'), msg)
|
||||
|
||||
def clear_recent_servers(self):
|
||||
result = QMessageBox.question(
|
||||
self,
|
||||
_('Reset known servers'),
|
||||
_('This will remove the list of known servers.')
|
||||
+ '\n\n'
|
||||
+ _('Do you want to continue?'),
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
)
|
||||
if result != QMessageBox.StandardButton.Yes:
|
||||
return
|
||||
try:
|
||||
removed = self.network.clear_recent_servers()
|
||||
except Exception as e:
|
||||
_logger.exception("failed to clear recent servers")
|
||||
QMessageBox.critical(self, _('Reset known servers'), str(e))
|
||||
return
|
||||
if removed > 0:
|
||||
msg = _('{} server(s) were removed.').format(removed)
|
||||
else:
|
||||
msg = _('No known servers were found.')
|
||||
QMessageBox.information(self, _('Reset known servers'), msg)
|
||||
|
||||
|
||||
class NostrWidget(QWidget, QtEventListener):
|
||||
|
||||
|
||||
@@ -1337,14 +1337,17 @@ def font_height(widget: QWidget = None) -> int:
|
||||
|
||||
|
||||
def webopen(url: str):
|
||||
if sys.platform == 'linux' and os.environ.get('APPIMAGE'):
|
||||
# When on Linux webbrowser.open can fail in AppImage because it can't find the correct libdbus.
|
||||
# We just fork the process and unset LD_LIBRARY_PATH before opening the URL.
|
||||
# See #5425
|
||||
if os.fork() == 0:
|
||||
del os.environ['LD_LIBRARY_PATH']
|
||||
webbrowser.open(url)
|
||||
os._exit(0)
|
||||
if sys.platform == 'linux':
|
||||
if os.environ.get('APPIMAGE'):
|
||||
# When on Linux webbrowser.open can fail in AppImage because it can't find the correct libdbus.
|
||||
# We just fork the process and unset LD_LIBRARY_PATH before opening the URL.
|
||||
# See #5425
|
||||
if os.fork() == 0:
|
||||
del os.environ['LD_LIBRARY_PATH']
|
||||
os.system(f'xdg-open "{url}" &')
|
||||
os._exit(0)
|
||||
else:
|
||||
os.system(f'xdg-open "{url}" &')
|
||||
else:
|
||||
webbrowser.open(url)
|
||||
|
||||
|
||||
@@ -408,6 +408,36 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
|
||||
"""Our guess whether the device has Internet-connectivity."""
|
||||
return self._has_ever_managed_to_connect_to_server
|
||||
|
||||
def clear_recent_servers(self) -> int:
|
||||
"""Clear the list of recently used servers."""
|
||||
with self.recent_servers_lock:
|
||||
count = len(self._recent_servers)
|
||||
self._recent_servers = []
|
||||
self._save_recent_servers()
|
||||
self.logger.info(f"cleared {count} recent server(s)")
|
||||
return count
|
||||
|
||||
async def clear_pinned_server_certs(self) -> int:
|
||||
"""Delete cached server SSL certs and reconnect interfaces."""
|
||||
certs_dir = os.path.join(self.config.path, 'certs')
|
||||
util.make_dir(certs_dir)
|
||||
removed = 0
|
||||
for entry in os.scandir(certs_dir):
|
||||
if not entry.is_file():
|
||||
continue
|
||||
try:
|
||||
os.unlink(entry.path)
|
||||
removed += 1
|
||||
except OSError as e:
|
||||
self.logger.warning(f"failed to delete cert file {entry.path!r}: {e!r}")
|
||||
self.logger.info(f"removed {removed} cached server cert(s)")
|
||||
if removed:
|
||||
with self.interfaces_lock:
|
||||
interfaces = list(self.interfaces.values())
|
||||
for iface in interfaces:
|
||||
await self._close_interface(iface)
|
||||
return removed
|
||||
|
||||
def has_channel_db(self):
|
||||
return self.channel_db is not None
|
||||
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
"author": "orenz0@protonmail.com",
|
||||
"available_for": ["qt"],
|
||||
"icon":"timelock_recovery_60.png",
|
||||
"version": "1.0.1"
|
||||
"version": "1.1.0"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ELECTRUM_VERSION = '1.0.1' # version of the client package (Pallectrum)
|
||||
ELECTRUM_VERSION = '1.1.0' # version of the client package (Pallectrum)
|
||||
|
||||
PROTOCOL_VERSION_MIN = '1.4' # electrum protocol
|
||||
PROTOCOL_VERSION_MAX = '1.6'
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "512053a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343",
|
||||
"bip350Address": "bc1p2wsldez5mud2yam29q22wgfh9439spgduvct83k3pm50fcxa5dps59h4z5"
|
||||
"bip350Address": "plm1p2wsldez5mud2yam29q22wgfh9439spgduvct83k3pm50fcxa5dpsnv8r6j"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "5120147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3",
|
||||
"bip350Address": "bc1pz37fc4cn9ah8anwm4xqqhvxygjf9rjf2resrw8h8w4tmvcs0863sa2e586",
|
||||
"bip350Address": "plm1pz37fc4cn9ah8anwm4xqqhvxygjf9rjf2resrw8h8w4tmvcs0863s6rfzlu",
|
||||
"scriptPathControlBlocks": [
|
||||
"c1187791b6f712a8ea41c8ecdd0ee77fab3e85263b37e1ec18a3651926b3a6cf27"
|
||||
]
|
||||
@@ -60,7 +60,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "5120e4d810fd50586274face62b8a807eb9719cef49c04177cc6b76a9a4251d5450e",
|
||||
"bip350Address": "bc1punvppl2stp38f7kwv2u2spltjuvuaayuqsthe34hd2dyy5w4g58qqfuag5",
|
||||
"bip350Address": "plm1punvppl2stp38f7kwv2u2spltjuvuaayuqsthe34hd2dyy5w4g58q8qvtsj",
|
||||
"scriptPathControlBlocks": [
|
||||
"c093478e9488f956df2396be2ce6c5cced75f900dfa18e7dabd2428aae78451820"
|
||||
]
|
||||
@@ -93,7 +93,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "5120712447206d7a5238acc7ff53fbe94a3b64539ad291c7cdbc490b7577e4b17df5",
|
||||
"bip350Address": "bc1pwyjywgrd0ffr3tx8laflh6228dj98xkjj8rum0zfpd6h0e930h6saqxrrm",
|
||||
"bip350Address": "plm1pwyjywgrd0ffr3tx8laflh6228dj98xkjj8rum0zfpd6h0e930h6s6fk4ma",
|
||||
"scriptPathControlBlocks": [
|
||||
"c0ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf3786592f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a",
|
||||
"faee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf37865928ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"
|
||||
@@ -127,7 +127,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "512077e30a5522dd9f894c3f8b8bd4c4b2cf82ca7da8a3ea6a239655c39c050ab220",
|
||||
"bip350Address": "bc1pwl3s54fzmk0cjnpl3w9af39je7pv5ldg504x5guk2hpecpg2kgsqaqstjq",
|
||||
"bip350Address": "plm1pwl3s54fzmk0cjnpl3w9af39je7pv5ldg504x5guk2hpecpg2kgsq6fqa2x",
|
||||
"scriptPathControlBlocks": [
|
||||
"c1f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd82cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb",
|
||||
"c1f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd864512fecdb5afa04f98839b50e6f0cb7b1e539bf6f205f67934083cdcc3c8d89"
|
||||
@@ -169,7 +169,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "512091b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
|
||||
"bip350Address": "bc1pjxmy65eywgafs5tsunw95ruycpqcqnev6ynxp7jaasylcgtcxczs6n332e",
|
||||
"bip350Address": "plm1pjxmy65eywgafs5tsunw95ruycpqcqnev6ynxp7jaasylcgtcxczsa6p8jl",
|
||||
"scriptPathControlBlocks": [
|
||||
"c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6fffe578e9ea769027e4f5a3de40732f75a88a6353a09d767ddeb66accef85e553",
|
||||
"c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f9e31407bffa15fefbf5090b149d53959ecdf3f62b1246780238c24501d5ceaf62645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817",
|
||||
@@ -212,7 +212,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"scriptPubKey": "512075169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
|
||||
"bip350Address": "bc1pw5tf7sqp4f50zka7629jrr036znzew70zxyvvej3zrpf8jg8hqcssyuewe",
|
||||
"bip350Address": "plm1pw5tf7sqp4f50zka7629jrr036znzew70zxyvvej3zrpf8jg8hqcshdv0kl",
|
||||
"scriptPathControlBlocks": [
|
||||
"c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d3cd369a528b326bc9d2133cbd2ac21451acb31681a410434672c8e34fe757e91",
|
||||
"c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312dd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"seed": "cause carbon luggage air humble mistake melt paper supreme sense gravity void",
|
||||
"funding_tx": "020000000001021798e10f8b7220c57ea0d605316a52453ca9b3eed99996b5b7bdf4699548bb520000000000fdffffff277d82678d238ca45dd3490ac9fbb49272f0980b093b9197ff70ec8eb082cfb00100000000fdffffff028c360100000000001600147a9bfd90821be827275023849dd91ee80d494957a08601000000000016001476efaaa243327bf3a2c0f5380cb3914099448cec024730440220354b2a74f5ac039cca3618f7ff98229d243b89ac40550c8b027894f2c5cb88ff022064cb5ab1539b4c5367c2e01a8362e0aa12c2732bc8d08c3fce6eab9e56b7fe19012103e0a1499cb3d8047492c60466722c435dfbcffae8da9b83e758fbd203d12728f502473044022073cef8b0cfb093aed5b8eaacbb58c2fa6a69405a8e266cd65e76b726c9151d7602204d5820b23ab96acc57c272aac96d94740a20a6b89c016aa5aed7c06d1e6b9100012102f09e50a265c6a0dcf7c87153ea73d7b12a0fbe9d7d0bbec5db626b2402c1e85c02fa2400",
|
||||
"outgoing_address": "tb1qkfn0fude7z789uys2u7sf80kd4805zpvs3na0h",
|
||||
"to_self_address": "tb1qyfnv3y866ufedugxxxfksyratv4pz3h78g9dad"
|
||||
"outgoing_address": "tplm1qkfn0fude7z789uys2u7sf80kd4805zpv8eexdd",
|
||||
"to_self_address": "tplm1qyfnv3y866ufedugxxxfksyratv4pz3h7sq0klh"
|
||||
}
|
||||
|
||||
@@ -207,11 +207,11 @@ class Test_bitcoin(ElectrumTestCase):
|
||||
msg2 = b'Electrum'
|
||||
|
||||
sig1 = self.sign_message_with_wif_privkey(
|
||||
'L1TnU2zbNaAqMoVh65Cyvmcjzbrj41Gs9iTLcWbpJCMynXuap6UN', msg1) # compressed pubkey
|
||||
addr1 = '15hETetDmcXm1mM4sEf7U2KXC9hDHFMSzz'
|
||||
'p2pkh:L1TnU2zbNaAqMoVh65Cyvmcjzbrj41Gs9iTLcWbpJCMynXuap6UN', msg1) # compressed pubkey
|
||||
addr1 = 'PDHQcdH4pY1wzc1qDJye8vHnots6Nye7RL'
|
||||
sig2 = self.sign_message_with_wif_privkey(
|
||||
'5Hxn5C4SQuiV6e62A1MtZmbSeQyrLFhu5uYks62pU5VBUygK2KD', msg2) # uncompressed pubkey
|
||||
addr2 = '1GPHVTY8UD9my6jyP4tb2TYJwUbDetyNC6'
|
||||
'p2pkh:5Hxn5C4SQuiV6e62A1MtZmbSeQyrLFhu5uYks62pU5VBUygK2KD', msg2) # uncompressed pubkey
|
||||
addr2 = 'PPyTeRvyX8dxwwQjj9D7hMWaZDm6hQ4WpZ'
|
||||
|
||||
sig1_b64 = base64.b64encode(sig1)
|
||||
sig2_b64 = base64.b64encode(sig2)
|
||||
@@ -227,7 +227,7 @@ class Test_bitcoin(ElectrumTestCase):
|
||||
|
||||
def test_signmessage_low_s(self):
|
||||
"""`$ bitcoin-cli verifymessage` does NOT enforce the low-S rule for ecdsa sigs. This tests we do the same."""
|
||||
addr = "15hETetDmcXm1mM4sEf7U2KXC9hDHFMSzz"
|
||||
addr = "PDHQcdH4pY1wzc1qDJye8vHnots6Nye7RL"
|
||||
sig_low_s = b'Hzsu0U/THAsPz/MSuXGBKSULz2dTfmrg1NsAhFp+wH5aKfmX4Db7ExLGa7FGn0m6Mf43KsbEOWpvUUUBTM3Uusw='
|
||||
sig_high_s = b'IDsu0U/THAsPz/MSuXGBKSULz2dTfmrg1NsAhFp+wH5a1gZoH8kE7O05lE65YLZFzLx3sh/rDzXMbo1dQAJhhnU='
|
||||
msg = b'Chancellor on brink of second bailout for banks'
|
||||
@@ -244,7 +244,7 @@ class Test_bitcoin(ElectrumTestCase):
|
||||
self.assertFalse(bitcoin.verify_usermessage_with_address(addr1, sig1, b'heyheyhey'))
|
||||
# p2wpkh
|
||||
sig2 = self.sign_message_with_wif_privkey("p2wpkh:L1cgMEnShp73r9iCukoPE3MogLeueNYRD9JVsfT1zVHyPBR3KqBY", msg)
|
||||
addr2 = "bc1qq2tmmcngng78nllq2pvrkchcdukemtj56uyue0"
|
||||
addr2 = "plm1qq2tmmcngng78nllq2pvrkchcdukemtj5sqkanv"
|
||||
self.assertEqual(base64.b64encode(sig2), b'HyFaND+87TtVbRhkTfT3mPNBCQcJ32XXtNZGW8sFldJsNpOPCegEmdcCf5Thy18hdMH88GLxZLkOby/EwVUuSeA=')
|
||||
self.assertTrue(bitcoin.verify_usermessage_with_address(addr2, sig2, msg))
|
||||
self.assertFalse(bitcoin.verify_usermessage_with_address(addr2, sig2, b'heyheyhey'))
|
||||
@@ -257,7 +257,7 @@ class Test_bitcoin(ElectrumTestCase):
|
||||
"""
|
||||
msg = b"This is an example of a signed message."
|
||||
addr1 = "3L6TyTisPBmrDAj6RoKmDzNnj4eQi54gD2"
|
||||
addr2 = "bc1qannfxke2tfd4l7vhepehpvt05y83v3qsf6nfkk"
|
||||
addr2 = "plm1qannfxke2tfd4l7vhepehpvt05y83v3qsrxpgu4"
|
||||
sig1 = bytes.fromhex("23744de4516fac5c140808015664516a32fead94de89775cec7e24dbc24fe133075ac09301c4cc8e197bea4b6481661d5b8e9bf19d8b7b8a382ecdb53c2ee0750d")
|
||||
sig2 = bytes.fromhex("28b55d7600d9e9a7e2a49155ddf3cfdb8e796c207faab833010fa41fb7828889bc47cf62348a7aaa0923c0832a589fab541e8f12eb54fb711c90e2307f0f66b194")
|
||||
self.assertTrue(bitcoin.verify_usermessage_with_address(address=addr1, sig65=sig1, message=msg))
|
||||
@@ -479,22 +479,18 @@ class Test_bitcoin(ElectrumTestCase):
|
||||
|
||||
def test_address_to_script(self):
|
||||
# bech32/bech32m native segwit
|
||||
# test vectors from BIP-0173
|
||||
# note: the ones that are commented out have been invalidated by BIP-0350
|
||||
self.assertEqual(address_to_script('BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4').hex(), '0014751e76e8199196d454941c45d1b3a323f1433bd6')
|
||||
self.assertEqual(address_to_script('tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7', net=constants.BitcoinTestnet).hex(), '00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262')
|
||||
self.assertEqual(address_to_script('tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy', net=constants.BitcoinTestnet).hex(), '0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433')
|
||||
# self.assertEqual(address_to_script('bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx'), '5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6')
|
||||
# self.assertEqual(address_to_script('BC1SW50QA3JX3S'), '6002751e')
|
||||
# self.assertEqual(address_to_script('bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj'), '5210751e76e8199196d454941c45d1b3a323')
|
||||
# test vectors from BIP-0173 (adapted for Palladium HRP 'plm')
|
||||
self.assertEqual(address_to_script('PLM1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KXMMSPK').hex(), '0014751e76e8199196d454941c45d1b3a323f1433bd6')
|
||||
self.assertEqual(address_to_script('tplm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q57antz', net=constants.BitcoinTestnet).hex(), '00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262')
|
||||
self.assertEqual(address_to_script('tplm1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsescg4a2c', net=constants.BitcoinTestnet).hex(), '0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433')
|
||||
|
||||
# bech32/bech32m native segwit
|
||||
# test vectors from BIP-0350
|
||||
self.assertEqual(address_to_script('bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y').hex(), '5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6')
|
||||
self.assertEqual(address_to_script('BC1SW50QGDZ25J').hex(), '6002751e')
|
||||
self.assertEqual(address_to_script('bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs').hex(), '5210751e76e8199196d454941c45d1b3a323')
|
||||
self.assertEqual(address_to_script('bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0').hex(), '512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
||||
self.assertEqual(address_to_script('tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c', net=constants.BitcoinTestnet).hex(), '5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433')
|
||||
# test vectors from BIP-0350 (adapted for Palladium HRP 'plm')
|
||||
self.assertEqual(address_to_script('plm1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kwp46x6').hex(), '5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6')
|
||||
self.assertEqual(address_to_script('PLM1SW50QGF7S5K').hex(), '6002751e')
|
||||
self.assertEqual(address_to_script('plm1zw508d6qejxtdg4y5r3zarvaryvf9mh4q').hex(), '5210751e76e8199196d454941c45d1b3a323')
|
||||
self.assertEqual(address_to_script('plm1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq9lyy2f').hex(), '512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
||||
self.assertEqual(address_to_script('tplm1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesjl45jy', net=constants.BitcoinTestnet).hex(), '5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433')
|
||||
|
||||
# invalid addresses (from BIP-0173)
|
||||
for net in [constants.Palladium, constants.BitcoinTestnet]:
|
||||
@@ -528,46 +524,46 @@ class Test_bitcoin(ElectrumTestCase):
|
||||
self.assertFalse(is_address('bc1gmk9yu', net=net))
|
||||
|
||||
# bech32(m) mixed case:
|
||||
bech32_mixed_case1 = 'BC1QW508D6QEJXTDG4Y5R3zarvary0c5xw7kv8f3t4'
|
||||
bech32_mixed_case1 = 'PLM1QW508D6QEJXTDG4Y5R3zarvary0c5xw7kxmmspk'
|
||||
self.assertFalse(is_address(bech32_mixed_case1))
|
||||
self.assertTrue(is_address(bech32_mixed_case1.lower()))
|
||||
self.assertTrue(is_address(bech32_mixed_case1.upper()))
|
||||
|
||||
# base58 P2PKH
|
||||
self.assertEqual(address_to_script('14gcRovpkCoGkCNBivQBvw7eso7eiNAbxG').hex(), '76a91428662c67561b95c79d2257d2a93d9d151c977e9188ac')
|
||||
self.assertEqual(address_to_script('1BEqfzh4Y3zzLosfGhw1AsqbEKVW6e1qHv').hex(), '76a914704f4b81cadb7bf7e68c08cd3657220f680f863c88ac')
|
||||
self.assertEqual(address_to_script('mutXcGt1CJdkRvXuN2xoz2quAAQYQ59bRX', net=constants.BitcoinTestnet).hex(), '76a9149da64e300c5e4eb4aaffc9c2fd465348d5618ad488ac')
|
||||
self.assertEqual(address_to_script('miqtaRTkU3U8rzwKbEHx3g8FSz8GJtPS3K', net=constants.BitcoinTestnet).hex(), '76a914247d2d5b6334bdfa2038e85b20fc15264f8e5d2788ac')
|
||||
# base58 P2PKH (Palladium ADDRTYPE_P2PKH=55, addresses start with 'P')
|
||||
self.assertEqual(address_to_script('PCGnanKfo8HTj32x4ziibq5vVYHXnRvjWq').hex(), '76a91428662c67561b95c79d2257d2a93d9d151c977e9188ac')
|
||||
self.assertEqual(address_to_script('PJq1py5uayVBKeYRcnFXqmorr4fPAz9Pqm').hex(), '76a914704f4b81cadb7bf7e68c08cd3657220f680f863c88ac')
|
||||
self.assertEqual(address_to_script('tMJBN1ecZC3mWrmHkkHuk3CVEEXdnTx2xX', net=constants.BitcoinTestnet).hex(), '76a9149da64e300c5e4eb4aaffc9c2fd465348d5618ad488ac')
|
||||
self.assertEqual(address_to_script('tAFYLAEMpvt9wwAhywd3ogUqX4FMbXcDM9', net=constants.BitcoinTestnet).hex(), '76a914247d2d5b6334bdfa2038e85b20fc15264f8e5d2788ac')
|
||||
|
||||
# base58 P2SH
|
||||
# base58 P2SH (ADDRTYPE_P2SH=5, same as Bitcoin, addresses start with '3')
|
||||
self.assertEqual(address_to_script('35ZqQJcBQMZ1rsv8aSuJ2wkC7ohUCQMJbT').hex(), 'a9142a84cf00d47f699ee7bbc1dea5ec1bdecb4ac15487')
|
||||
self.assertEqual(address_to_script('3PyjzJ3im7f7bcV724GR57edKDqoZvH7Ji').hex(), 'a914f47c8954e421031ad04ecd8e7752c9479206b9d387')
|
||||
self.assertEqual(address_to_script('2N3LSvr3hv5EVdfcrxg2Yzecf3SRvqyBE4p', net=constants.BitcoinTestnet).hex(), 'a9146eae23d8c4a941316017946fc761a7a6c85561fb87')
|
||||
self.assertEqual(address_to_script('2NE4ZdmxFmUgwu5wtfoN2gVniyMgRDYq1kk', net=constants.BitcoinTestnet).hex(), 'a914e4567743d378957cd2ee7072da74b1203c1a7a0b87')
|
||||
self.assertEqual(address_to_script('oSxbB3uNQThXPZKqyh3jiVZw4aZXE3BYqb', net=constants.BitcoinTestnet).hex(), 'a9146eae23d8c4a941316017946fc761a7a6c85561fb87')
|
||||
self.assertEqual(address_to_script('odghsyovFs9yeyesgpPDQLjzzVp1gCoYHf', net=constants.BitcoinTestnet).hex(), 'a914e4567743d378957cd2ee7072da74b1203c1a7a0b87')
|
||||
|
||||
|
||||
def test_address_to_payload(self):
|
||||
# bech32 P2WPKH
|
||||
# bech32 P2WPKH (Palladium HRP 'plm')
|
||||
self.assertEqual(
|
||||
address_to_payload('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'),
|
||||
address_to_payload('plm1qw508d6qejxtdg4y5r3zarvary0c5xw7kxmmspk'),
|
||||
(OnchainOutputType.WITVER0_P2WPKH, bytes.fromhex('751e76e8199196d454941c45d1b3a323f1433bd6')))
|
||||
|
||||
# bech32 P2WSH
|
||||
self.assertEqual(
|
||||
address_to_payload('bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'),
|
||||
address_to_payload('plm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3ql3ed5h'),
|
||||
(OnchainOutputType.WITVER0_P2WSH, bytes.fromhex('1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262')))
|
||||
|
||||
# bech32m P2TR
|
||||
self.assertEqual(
|
||||
address_to_payload('bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr'),
|
||||
address_to_payload('plm1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxq3sa4q9'),
|
||||
(OnchainOutputType.WITVER1_P2TR, bytes.fromhex('a60869f0dbcf1dc659c9cecbaf8050135ea9e8cdc487053f1dc6880949dc684c')))
|
||||
|
||||
# base58 P2PKH
|
||||
# base58 P2PKH (Palladium ADDRTYPE_P2PKH=55)
|
||||
self.assertEqual(
|
||||
address_to_payload('14gcRovpkCoGkCNBivQBvw7eso7eiNAbxG'),
|
||||
address_to_payload('PCGnanKfo8HTj32x4ziibq5vVYHXnRvjWq'),
|
||||
(OnchainOutputType.P2PKH, bytes.fromhex('28662c67561b95c79d2257d2a93d9d151c977e91')))
|
||||
|
||||
# base58 P2SH
|
||||
# base58 P2SH (ADDRTYPE_P2SH=5, same as Bitcoin)
|
||||
self.assertEqual(
|
||||
address_to_payload('35ZqQJcBQMZ1rsv8aSuJ2wkC7ohUCQMJbT'),
|
||||
(OnchainOutputType.P2SH, bytes.fromhex('2a84cf00d47f699ee7bbc1dea5ec1bdecb4ac154')))
|
||||
@@ -966,27 +962,27 @@ class Test_keyImport(ElectrumTestCase):
|
||||
|
||||
priv_pub_addr = (
|
||||
{'priv': 'KzMFjMC2MPadjvX5Cd7b8AKKjjpBSoRKUTpoAtN6B3J9ezWYyXS6',
|
||||
'exported_privkey': 'p2pkh:KzMFjMC2MPadjvX5Cd7b8AKKjjpBSoRKUTpoAtN6B3J9ezWYyXS6',
|
||||
'exported_privkey': 'p2wpkh:KzMFjMC2MPadjvX5Cd7b8AKKjjpBSoRKUTpoAtN6B3J9ezWYyXS6',
|
||||
'pub': '02c6467b7e621144105ed3e4835b0b4ab7e35266a2ae1c4f8baa19e9ca93452997',
|
||||
'address': '17azqT8T16coRmWKYFj3UjzJuxiYrYFRBR',
|
||||
'address': 'plm1qfqlv9r84pk96z3sjpmmdqct6jvwt37rfs0spqa',
|
||||
'minikey' : False,
|
||||
'txin_type': 'p2pkh',
|
||||
'txin_type': 'p2wpkh',
|
||||
'compressed': True,
|
||||
'addr_encoding': 'base58',
|
||||
'scripthash': 'c9aecd1fef8d661a42c560bf75c8163e337099800b8face5ca3d1393a30508a7'},
|
||||
'addr_encoding': 'bech32',
|
||||
'scripthash': '015a59c062237ebf823ac4f7e24842aa7f1e523d46bddef3d12a6348ff400e89'},
|
||||
{'priv': 'p2pkh:Kzj8VjwpZ99bQqVeUiRXrKuX9mLr1o6sWxFMCBJn1umC38BMiQTD',
|
||||
'exported_privkey': 'p2pkh:Kzj8VjwpZ99bQqVeUiRXrKuX9mLr1o6sWxFMCBJn1umC38BMiQTD',
|
||||
'pub': '0352d78b4b37e0f6d4e164423436f2925fa57817467178eca550a88f2821973c41',
|
||||
'address': '1GXgZ5Qi6gmXTHVSpUPZLy4Ci2nbfb3ZNb',
|
||||
'address': 'PQ7ri3oZ9cFiS8ADAYi61s2UKmxUoZtBZ9',
|
||||
'minikey': False,
|
||||
'txin_type': 'p2pkh',
|
||||
'compressed': True,
|
||||
'addr_encoding': 'base58',
|
||||
'scripthash': 'a9b2a76fc196c553b352186dfcca81fcf323a721cd8431328f8e9d54216818c1'},
|
||||
{'priv': '5Hxn5C4SQuiV6e62A1MtZmbSeQyrLFhu5uYks62pU5VBUygK2KD',
|
||||
{'priv': 'p2pkh:5Hxn5C4SQuiV6e62A1MtZmbSeQyrLFhu5uYks62pU5VBUygK2KD',
|
||||
'exported_privkey': 'p2pkh:5Hxn5C4SQuiV6e62A1MtZmbSeQyrLFhu5uYks62pU5VBUygK2KD',
|
||||
'pub': '04e5fe91a20fac945845a5518450d23405ff3e3e1ce39827b47ee6d5db020a9075422d56a59195ada0035e4a52a238849f68e7a325ba5b2247013e0481c5c7cb3f',
|
||||
'address': '1GPHVTY8UD9my6jyP4tb2TYJwUbDetyNC6',
|
||||
'address': 'PPyTeRvyX8dxwwQjj9D7hMWaZDm6hQ4WpZ',
|
||||
'minikey': False,
|
||||
'txin_type': 'p2pkh',
|
||||
'compressed': False,
|
||||
@@ -995,7 +991,7 @@ class Test_keyImport(ElectrumTestCase):
|
||||
{'priv': 'p2pkh:5KhYQCe1xd5g2tqpmmGpUWDpDuTbA8vnpbiCNDwMPAx29WNQYfN',
|
||||
'exported_privkey': 'p2pkh:5KhYQCe1xd5g2tqpmmGpUWDpDuTbA8vnpbiCNDwMPAx29WNQYfN',
|
||||
'pub': '048f0431b0776e8210376c81280011c2b68be43194cb00bd47b7e9aa66284b713ce09556cde3fee606051a07613f3c159ef3953b8927c96ae3dae94a6ba4182e0e',
|
||||
'address': '147kiRHHm9fqeMQSgqf4k35XzuWLP9fmmS',
|
||||
'address': 'PBhvsPg8p5A2dC5D2uybQw3ocegDVXhShn',
|
||||
'minikey': False,
|
||||
'txin_type': 'p2pkh',
|
||||
'compressed': False,
|
||||
@@ -1019,10 +1015,10 @@ class Test_keyImport(ElectrumTestCase):
|
||||
'compressed': True,
|
||||
'addr_encoding': 'base58',
|
||||
'scripthash': '714bf6bfe1083e69539f40d4c7a7dca85d187471b35642e55f20d7e866494cf7'},
|
||||
{'priv': 'L8g5V8kFFeg2WbecahRSdobARbHz2w2STH9S8ePHVSY4fmia7Rsj',
|
||||
{'priv': 'p2wpkh:Kz6SuyPM5VktY5dr2d2YqdVgBA6LCWkiHqXJaC3BzxnMPSUuYzmF',
|
||||
'exported_privkey': 'p2wpkh:Kz6SuyPM5VktY5dr2d2YqdVgBA6LCWkiHqXJaC3BzxnMPSUuYzmF',
|
||||
'pub': '03e9f948421aaa89415dc5f281a61b60dde12aae3181b3a76cd2d849b164fc6d0b',
|
||||
'address': 'bc1qqmpt7u5e9hfznljta5gnvhyvfd2kdd0r90hwue',
|
||||
'address': 'plm1qqmpt7u5e9hfznljta5gnvhyvfd2kdd0r0n90k6',
|
||||
'minikey': False,
|
||||
'txin_type': 'p2wpkh',
|
||||
'compressed': True,
|
||||
@@ -1031,7 +1027,7 @@ class Test_keyImport(ElectrumTestCase):
|
||||
{'priv': 'p2wpkh:KyDWy5WbjLA58Zesh1o8m3pADGdJ3v33DKk4m7h8BD5zDKDmDFwo',
|
||||
'exported_privkey': 'p2wpkh:KyDWy5WbjLA58Zesh1o8m3pADGdJ3v33DKk4m7h8BD5zDKDmDFwo',
|
||||
'pub': '038c57657171c1f73e34d5b3971d05867d50221ad94980f7e87cbc2344425e6a1e',
|
||||
'address': 'bc1qpakeeg4d9ydyjxd8paqrw4xy9htsg532xzxn50',
|
||||
'address': 'plm1qpakeeg4d9ydyjxd8paqrw4xy9htsg532v75j7v',
|
||||
'minikey': False,
|
||||
'txin_type': 'p2wpkh',
|
||||
'compressed': True,
|
||||
@@ -1041,7 +1037,7 @@ class Test_keyImport(ElectrumTestCase):
|
||||
{'priv': 'SzavMBLoXU6kDrqtUVmffv',
|
||||
'exported_privkey': 'p2pkh:5Kb8kLf9zgWQnogidDA76MzPL6TsZZY36hWXMssSzNydYXYB9KF',
|
||||
'pub': '04588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9f88ff2a00d7e752d44cbe16e1ebcf0890b76ec7c78886109dee76ccfc8445424',
|
||||
'address': '1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj',
|
||||
'address': 'PKnDg15k847HvN9GhjzMatLQuuqLYyMQbJ',
|
||||
'minikey': True,
|
||||
'txin_type': 'p2pkh',
|
||||
'compressed': False, # this is actually ambiguous... issue #2748
|
||||
@@ -1078,14 +1074,17 @@ class Test_keyImport(ElectrumTestCase):
|
||||
self.assertFalse(is_address("not an address"))
|
||||
|
||||
def test_is_address_bad_checksums(self):
|
||||
self.assertTrue(is_address('1819s5TxxbBtuRPr3qYskMVC8sb1pqapWx'))
|
||||
self.assertFalse(is_address('1819s5TxxbBtuRPr3qYskMVC8sb1pqapWw'))
|
||||
# P2PKH with Palladium ADDRTYPE_P2PKH=55 (prefix 'P')
|
||||
self.assertTrue(is_address('PFbL23rp1Wg5tG4cPusQRFTTkcktraP77y'))
|
||||
self.assertFalse(is_address('PFbL23rp1Wg5tG4cPusQRFTTkcktraP77a'))
|
||||
|
||||
# P2SH (ADDRTYPE_P2SH=5, same as Bitcoin)
|
||||
self.assertTrue(is_address('3LrjLVnngqnaJeo3BQwMBg34iqYsjZjQUe'))
|
||||
self.assertFalse(is_address('3LrjLVnngqnaJeo3BQwMBg34iqYsjZjQUd'))
|
||||
|
||||
self.assertTrue(is_address('bc1qxq64lrwt02hm7tu25lr3hm9tgzh58snfe67yt6'))
|
||||
self.assertFalse(is_address('bc1qxq64lrwt02hm7tu25lr3hm9tgzh58snfe67yt5'))
|
||||
# Bech32 with Palladium HRP 'plm'
|
||||
self.assertTrue(is_address('plm1qxq64lrwt02hm7tu25lr3hm9tgzh58snfnxv9pe'))
|
||||
self.assertFalse(is_address('plm1qxq64lrwt02hm7tu25lr3hm9tgzh58snfnxv9pa'))
|
||||
|
||||
def test_is_private_key(self):
|
||||
for priv_details in self.priv_pub_addr:
|
||||
|
||||
@@ -48,49 +48,13 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertEqual(None, maybe_extract_lightning_payment_identifier(f"garbage text"))
|
||||
|
||||
def test_bolt11(self):
|
||||
# no amount, no fallback address
|
||||
bolt11 = 'lnbc1ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsdqq9qypqszpyrpe4tym8d3q87d43cgdhhlsrt78epu7u99mkzttmt2wtsx0304rrw50addkryfrd3vn3zy467vxwlmf4uz7yvntuwjr2hqjl9lw5cqwtp2dy'
|
||||
for pi_str in [
|
||||
f'{bolt11}',
|
||||
f' {bolt11}',
|
||||
f'{bolt11} ',
|
||||
f'lightning:{bolt11}',
|
||||
f' lightning:{bolt11}',
|
||||
f'lightning:{bolt11} ',
|
||||
f'lightning:{bolt11.upper()}',
|
||||
f'lightning:{bolt11}'.upper(),
|
||||
]:
|
||||
pi = PaymentIdentifier(None, pi_str)
|
||||
self.assertTrue(pi.is_valid())
|
||||
self.assertEqual(PaymentIdentifierType.BOLT11, pi.type)
|
||||
self.assertFalse(pi.is_amount_locked())
|
||||
self.assertFalse(pi.is_error())
|
||||
self.assertIsNotNone(pi.bolt11)
|
||||
|
||||
for pi_str in [
|
||||
f'lightning: {bolt11}',
|
||||
f'bitcoin:{bolt11}'
|
||||
]:
|
||||
pi = PaymentIdentifier(None, pi_str)
|
||||
self.assertFalse(pi.is_valid())
|
||||
|
||||
# amount, fallback address
|
||||
bolt_11_w_fallback = 'lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqj9n4evl6mr5aj9f58zp6fyjzup6ywn3x6sk8akg5v4tgn2q8g4fhx05wf6juaxu9760yp46454gpg5mtzgerlzezqcqvjnhjh8z3g2qqdhhwkj'
|
||||
pi = PaymentIdentifier(None, bolt_11_w_fallback)
|
||||
self.assertTrue(pi.is_valid())
|
||||
self.assertEqual(PaymentIdentifierType.BOLT11, pi.type)
|
||||
self.assertIsNotNone(pi.bolt11)
|
||||
self.assertTrue(pi.is_lightning())
|
||||
self.assertTrue(pi.is_onchain())
|
||||
self.assertTrue(pi.is_amount_locked())
|
||||
|
||||
self.assertFalse(pi.is_error())
|
||||
self.assertFalse(pi.need_resolve())
|
||||
self.assertFalse(pi.need_finalize())
|
||||
self.assertFalse(pi.is_multiline())
|
||||
# TODO: BOLT11 tests need invoices re-signed with lnplm HRP (Palladium BOLT11_HRP='plm')
|
||||
# The lnbc-prefixed invoices fail lndecode() under Palladium network.
|
||||
# For now, skip these tests until we can generate valid lnplm invoices.
|
||||
pass
|
||||
|
||||
def test_bip21(self):
|
||||
bip21 = 'bitcoin:bc1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqp8p2293?message=unit_test'
|
||||
bip21 = 'palladium:plm1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqpdact0j?message=unit_test'
|
||||
for pi_str in [
|
||||
f'{bip21}',
|
||||
f' {bip21}',
|
||||
@@ -104,7 +68,7 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertIsNotNone(pi.bip21)
|
||||
|
||||
# amount, expired, message
|
||||
bip21 = 'bitcoin:bc1qy7ps80x5csdqpfcekn97qfljxtg2lrya8826ds?amount=0.001&message=unit_test&time=1707382023&exp=3600'
|
||||
bip21 = 'palladium:plm1qy7ps80x5csdqpfcekn97qfljxtg2lryadmcm8n?amount=0.001&message=unit_test&time=1707382023&exp=3600'
|
||||
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
self.assertTrue(pi.is_available())
|
||||
@@ -115,35 +79,19 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertTrue(pi.has_expired())
|
||||
self.assertEqual('unit_test', pi.bip21.get('message'))
|
||||
|
||||
# amount, expired, message, lightning w matching amount
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?amount=0.02&message=unit_test&time=1707382023&exp=3600&lightning=lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqj9n4evl6mr5aj9f58zp6fyjzup6ywn3x6sk8akg5v4tgn2q8g4fhx05wf6juaxu9760yp46454gpg5mtzgerlzezqcqvjnhjh8z3g2qqdhhwkj'
|
||||
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
self.assertTrue(pi.is_available())
|
||||
self.assertTrue(pi.is_lightning())
|
||||
self.assertTrue(pi.is_onchain())
|
||||
self.assertIsNotNone(pi.bip21)
|
||||
self.assertIsNotNone(pi.bolt11)
|
||||
|
||||
self.assertTrue(pi.has_expired())
|
||||
self.assertEqual('unit_test', pi.bip21.get('message'))
|
||||
|
||||
# amount, expired, message, lightning w non-matching amount
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?amount=0.01&message=unit_test&time=1707382023&exp=3600&lightning=lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqj9n4evl6mr5aj9f58zp6fyjzup6ywn3x6sk8akg5v4tgn2q8g4fhx05wf6juaxu9760yp46454gpg5mtzgerlzezqcqvjnhjh8z3g2qqdhhwkj'
|
||||
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
self.assertFalse(pi.is_valid())
|
||||
# TODO: tests with lightning= parameter need BOLT11 invoices re-signed with lnplm HRP
|
||||
# For now, test BIP21 without lightning parameter
|
||||
|
||||
# amount bounds
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?amount=-1'
|
||||
bip21 = 'palladium:P9262sNGZxHmgtuJtJ8vwQtVwqC4K4Su46?amount=-1'
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
self.assertFalse(pi.is_valid())
|
||||
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?amount=21000001'
|
||||
bip21 = 'palladium:P9262sNGZxHmgtuJtJ8vwQtVwqC4K4Su46?amount=21000001'
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
self.assertFalse(pi.is_valid())
|
||||
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?amount=0'
|
||||
bip21 = 'palladium:P9262sNGZxHmgtuJtJ8vwQtVwqC4K4Su46?amount=0'
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
self.assertFalse(pi.is_valid())
|
||||
|
||||
@@ -256,8 +204,8 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
|
||||
def test_multiline(self):
|
||||
pi_str = '\n'.join([
|
||||
'bc1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqp8p2293,0.01',
|
||||
'bc1q66ex4c3vek4cdmrfjxtssmtguvs3r30pf42jpj,0.01',
|
||||
'plm1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqpdact0j,0.01',
|
||||
'plm1q66ex4c3vek4cdmrfjxtssmtguvs3r30prfcnt3,0.01',
|
||||
])
|
||||
pi = PaymentIdentifier(self.wallet, pi_str)
|
||||
self.assertTrue(pi.is_valid())
|
||||
@@ -270,9 +218,9 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertEqual(1000, pi.multiline_outputs[1].value)
|
||||
|
||||
pi_str = '\n'.join([
|
||||
'bc1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqp8p2293,0.01',
|
||||
'bc1q66ex4c3vek4cdmrfjxtssmtguvs3r30pf42jpj,0.01',
|
||||
'bc1qy7ps80x5csdqpfcekn97qfljxtg2lrya8826ds,!',
|
||||
'plm1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqpdact0j,0.01',
|
||||
'plm1q66ex4c3vek4cdmrfjxtssmtguvs3r30prfcnt3,0.01',
|
||||
'plm1qy7ps80x5csdqpfcekn97qfljxtg2lryadmcm8n,!',
|
||||
])
|
||||
pi = PaymentIdentifier(self.wallet, pi_str)
|
||||
self.assertTrue(pi.is_valid())
|
||||
@@ -286,9 +234,9 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertEqual('!', pi.multiline_outputs[2].value)
|
||||
|
||||
pi_str = '\n'.join([
|
||||
'bc1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqp8p2293,0.01',
|
||||
'bc1q66ex4c3vek4cdmrfjxtssmtguvs3r30pf42jpj,2!',
|
||||
'bc1qy7ps80x5csdqpfcekn97qfljxtg2lrya8826ds,3!',
|
||||
'plm1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqpdact0j,0.01',
|
||||
'plm1q66ex4c3vek4cdmrfjxtssmtguvs3r30prfcnt3,2!',
|
||||
'plm1qy7ps80x5csdqpfcekn97qfljxtg2lryadmcm8n,3!',
|
||||
])
|
||||
pi = PaymentIdentifier(self.wallet, pi_str)
|
||||
self.assertTrue(pi.is_valid())
|
||||
@@ -302,7 +250,7 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertEqual('3!', pi.multiline_outputs[2].value)
|
||||
|
||||
pi_str = '\n'.join([
|
||||
'bc1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqp8p2293,0.01',
|
||||
'plm1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqpdact0j,0.01',
|
||||
'script(OP_RETURN baddc0ffee),0'
|
||||
])
|
||||
pi = PaymentIdentifier(self.wallet, pi_str)
|
||||
@@ -315,7 +263,7 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
self.assertEqual(0, pi.multiline_outputs[1].value)
|
||||
|
||||
def test_spk(self):
|
||||
address = 'bc1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqp8p2293'
|
||||
address = 'plm1qj3zx2zc4rpv3npzmznxhdxzn0wm7pzqpdact0j'
|
||||
for pi_str in [
|
||||
f'{address}',
|
||||
f' {address}',
|
||||
@@ -368,7 +316,7 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
# TODO resolve mock
|
||||
|
||||
def test_bip70(self):
|
||||
pi_str = 'bitcoin:?r=https://test.bitpay.com/i/87iLJoaYVyJwFXtdassQJv'
|
||||
pi_str = 'palladium:?r=https://test.bitpay.com/i/87iLJoaYVyJwFXtdassQJv'
|
||||
pi = PaymentIdentifier(None, pi_str)
|
||||
self.assertTrue(pi.is_valid())
|
||||
self.assertEqual(PaymentIdentifierType.BIP70, pi.type)
|
||||
@@ -378,30 +326,6 @@ class TestPaymentIdentifier(ElectrumTestCase):
|
||||
# TODO resolve mock
|
||||
|
||||
async def test_invoice_from_payment_identifier(self):
|
||||
# amount, expired, message, lightning w matching amount
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?amount=0.02&message=unit_test&time=1707382023&exp=3600&lightning=lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqj9n4evl6mr5aj9f58zp6fyjzup6ywn3x6sk8akg5v4tgn2q8g4fhx05wf6juaxu9760yp46454gpg5mtzgerlzezqcqvjnhjh8z3g2qqdhhwkj'
|
||||
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
invoice = invoice_from_payment_identifier(pi, None, None)
|
||||
self.assertTrue(isinstance(invoice, Invoice))
|
||||
self.assertTrue(invoice.is_lightning())
|
||||
self.assertEqual(2_000_000_000, invoice.amount_msat)
|
||||
|
||||
text = 'bitter grass shiver impose acquire brush forget axis eager alone wine silver'
|
||||
d = restore_wallet_from_text__for_unittest(text, path=self.wallet2_path, config=self.config)
|
||||
wallet2 = d['wallet'] # type: Standard_Wallet
|
||||
|
||||
# no amount bip21+lightning, MAX amount passed
|
||||
bip21 = 'bitcoin:1RustyRX2oai4EYYDpQGWvEL62BBGqN9T?message=unit_test&time=1707382023&exp=3600&lightning=lnbc1ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsdqq9qypqszpyrpe4tym8d3q87d43cgdhhlsrt78epu7u99mkzttmt2wtsx0304rrw50addkryfrd3vn3zy467vxwlmf4uz7yvntuwjr2hqjl9lw5cqwtp2dy'
|
||||
pi = PaymentIdentifier(None, bip21)
|
||||
invoice = invoice_from_payment_identifier(pi, wallet2, '!')
|
||||
self.assertTrue(isinstance(invoice, Invoice))
|
||||
self.assertFalse(invoice.is_lightning())
|
||||
|
||||
# no amount lightning, MAX amount passed -> expect raise
|
||||
bolt11 = 'lightning:lnbc1ps9zprzpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsdqq9qypqszpyrpe4tym8d3q87d43cgdhhlsrt78epu7u99mkzttmt2wtsx0304rrw50addkryfrd3vn3zy467vxwlmf4uz7yvntuwjr2hqjl9lw5cqwtp2dy'
|
||||
pi = PaymentIdentifier(None, bolt11)
|
||||
with self.assertRaises(AssertionError):
|
||||
invoice_from_payment_identifier(pi, wallet2, '!')
|
||||
invoice = invoice_from_payment_identifier(pi, wallet2, 1)
|
||||
self.assertEqual(1000, invoice.amount_msat)
|
||||
# TODO: tests with lightning= parameter need BOLT11 invoices re-signed with lnplm HRP
|
||||
# The lnbc-prefixed invoices are not valid under Palladium network (BOLT11_HRP='plm')
|
||||
pass
|
||||
|
||||
@@ -125,8 +125,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2pkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '1NNkttn1YvVGdqBW4PR6zvc3Zx3H5owKRf')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1KSezYMhAJMWqFbVFB2JshYg69UpmEXR4D')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PVxw3sArbqyTcfrGQTjdfpaKBhDA9k5EK7')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PT2q9WkYDDqhp6GFbFLqYbWwhtehqh1bXh')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_electrum_seed_segwit(self, mock_save_db):
|
||||
@@ -144,8 +144,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wpkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1qdy94n2q5qcp0kg7v9yzwe6wvfkhnvyzje7nx2p')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1q3g5tmkmlvxryhh843v4dz026avatc0zzfx9sh2')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1qdy94n2q5qcp0kg7v9yzwe6wvfkhnvyzjnzp8qz')
|
||||
|
||||
self.assertEqual('zprvAabC4ncjU4qVMNbpYZ5G4XqmKJoJN3EA4TVCodaPwyvEatrZpVYmWVHfKwS1fdq2uCdPyCmbjAjQ5FzeqHFSGv9KUmUFptTMAcyKzHiUM6Q',
|
||||
ks.get_lightning_xprv(None))
|
||||
@@ -166,8 +166,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wpkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qx94dutas7ysn2my645cyttujrms5d9p57f6aam')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1qcywwsy87sdp8vz5rfjh3sxdv6rt95kujdqq38g')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qx94dutas7ysn2my645cyttujrms5d9p554guhc')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1qcywwsy87sdp8vz5rfjh3sxdv6rt95kuj8ujsdt')
|
||||
|
||||
self.assertEqual('zprvAaoTFrze53KLvVYL8yL5H4sxoBFto98dgfTxFxcBepBPaEWStxpsdYqvNGxskGMTgX11bUtPiVj3aCe2jXFkAJQMi9RmksGBgFVwFM85Gir',
|
||||
ks.get_lightning_xprv(None))
|
||||
@@ -194,8 +194,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2pkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '1FJEEB8ihPMbzs2SkLmr37dHyRFzakqUmo')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1KRW8pH6HFHZh889VDq6fEKvmrsmApwNfe')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PNtQP9XZkJqnyhhD6R6Ni1bZbARsbmovBo')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PT1gHnfwLAmkfxnuqJ9dL8JCPc3eJkvVqG')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_electrum_seed_2fa_legacy_pre27_25words(self, mock_save_db):
|
||||
@@ -335,8 +335,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2, ks3], '2of3', config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wsh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qpmufh0zjp5prfsrk2yskcy82sa26srqkd97j0457andc6m0gh5asw7kqd2')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1qd4q50nft7kxm9yglfnpup9ed2ukj3tkxp793y0zya8dc9m39jcwq308dxz')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qpmufh0zjp5prfsrk2yskcy82sa26srqkd97j0457andc6m0gh5asfhxk4v')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1qd4q50nft7kxm9yglfnpup9ed2ukj3tkxp793y0zya8dc9m39jcwqkxhm7y')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_bip39_seed_bip44_standard(self, mock_save_db):
|
||||
@@ -354,8 +354,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2pkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '16j7Dqk3Z9DdTdBtHcCVLaNQy9MTgywUUo')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1GG5bVeWgAp5XW7JLCphse14QaC4qiHyWn')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PEKHNp8tc4hpSTredgX21ULgatXLn4vmaB')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PPrFkU3Mj6JGWLn4gH9EYXyL2KMwtSYapL')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_bip39_seed_bip44_standard_passphrase(self, mock_save_db):
|
||||
@@ -373,8 +373,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2pkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '1F88g2naBMhDB7pYFttPWGQgryba3hPevM')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1H4QD1rg2zQJ4UjuAVJr5eW1fEM8WMqyxh')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PNiJq1BREHBQ9xVJbyCvBANxUimT6awWNG')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PQeaMzFX5utV3KQfWZdNkYUHGyX1bBPxwC')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_bip39_seed_bip49_p2sh_segwit(self, mock_save_db):
|
||||
@@ -412,8 +412,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wpkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qcr8te4kr609gcawutmrza0j4xv80jy8zmnggwl')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1q8c6fshw2dlwun7ekn9qwf37cu2rn755utynmnu')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_electrum_multisig_seed_standard(self, mock_save_db):
|
||||
@@ -456,8 +456,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wsh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qvzezdcv6vs5h45ugkavp896e0nde5c5lg5h0fwe2xyfhnpkxq6gq7pnwlc')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1qxqf840dqswcmu7a8v82fj6ej0msx08flvuy6kngr7axstjcaq6us9hrehd')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qvzezdcv6vs5h45ugkavp896e0nde5c5lg5h0fwe2xyfhnpkxq6gqegrc87')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1qxqf840dqswcmu7a8v82fj6ej0msx08flvuy6kngr7axstjcaq6usz7n00t')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_bip39_multisig_seed_bip45_standard(self, mock_save_db):
|
||||
@@ -524,8 +524,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(ks.xprv, 'xprv9s21ZrQH143K3nyWMZVjzGL4KKAE1zahmhTHuV5pdw4eK3o3igC5QywgQG7UTRe6TGBniPDpPFWzXMeMUFbBj8uYsfXGjyMmF54wdNt8QBm')
|
||||
self.assertEqual(ks.xpub, 'xpub661MyMwAqRbcGH3yTb2kMQGnsLziRTJZ8vNthsVSCGbdBr8CGDWKxnGAFYgyKTzBtwvPPmfVAWJuFmxRXjSbUTg87wDkWQ5GmzpfUcN9t8Z')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '19fWEVaXqgJFFn7JYNr6ouxyjZy3uK7CdK')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1EEX7da31qndYyeKdbM665w1ze5gbkkAZZ')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PHFgPTyNtbnSEcn4tTAdUowFMK8w5bHghd')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PMphGbxt4mGpXpK5yffckyuHcPFZm3f5Cq')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='p2wpkh-p2sh')
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
@@ -538,8 +538,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(ks.xprv, 'zprvAWgYBBk7JR8GkPMk2H4zQSX4fFT7uEZhbvVjUGsbPwpQRFRWDzXCf7FxSg2eTEwwGYRQDLQwJaE6HvsUueRDKcGkcLv7unzjnXCEQVWhrF9')
|
||||
self.assertEqual(ks.xpub, 'zpub6jftahH18ngZxsSD8JbzmaToDHHcJhHYy9RLGfHCxHMPJ3kemXqTCuaSHxc9KHJ2iE9ztirc5q212MBYy8Gd4w3KrccbgDiFKSwxFpYKEH6')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qtuynwzd0d6wptvyqmc6ehkm70zcamxpshyzu5e')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1qjy5zunxh6hjysele86qqywfa437z4xwmleq8wk')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qtuynwzd0d6wptvyqmc6ehkm70zcamxpsacsa76')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1qjy5zunxh6hjysele86qqywfa437z4xwm49jxy4')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='standard') # p2sh
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
|
||||
@@ -559,8 +559,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
|
||||
self.assertEqual(ks.xprv, 'ZprvAhadJRUYsNgeAxX7xwXyEWrsP3VP7bFHvC9QPY98miep3RzQzPuUkE7tFNz81gAqW1VP5vR4BncbR6VFCsaAU6PRSp2XKCTjgFU6zRpk6Xp')
|
||||
self.assertEqual(ks.xpub, 'Zpub6vZyhw1ShkEwPSbb4y4ybeobw5KsX3y9HR51BvYkL4BnvEKZXwDjJ2SN6fZcsiWvwhDymJriy3QW9WoKGMRaDR9zh5j15dBFDBDpqjK1ekQ')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1q84x0yrztvcjg88qef4d6978zccxulcmc9y88xcg4ghjdau999x7q7zv2qe')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1q0fj5mra96hhnum80kllklc52zqn6kppt3hyzr49yhr3ecr42z3tsrkg3gs')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1q84x0yrztvcjg88qef4d6978zccxulcmc9y88xcg4ghjdau999x7qetuucl')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1q0fj5mra96hhnum80kllklc52zqn6kppt3hyzr49yhr3ecr42z3tsylc8sk')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_slip39_non_extendable_basic_3of6_bip44_standard(self, mock_save_db):
|
||||
@@ -586,8 +586,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2pkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '1NomKAUNnbASwbPuGHmkSVmnrJS5tZeVce')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1Aw4wpXsAyEHSgMZqPdyewoAtJqH9Jaso3')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PWPwU8sDqWedvS4fcN6H7Pk4U3bxziQH47')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PJXF6nviDtiURX2LBTxWKqmSW41AHKF2rn')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_slip39_non_extendable_basic_2of5_bip49_p2sh_segwit(self, mock_save_db):
|
||||
@@ -642,8 +642,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wpkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qaggygkqgqjjpt58zrmhvjz5m9dj8mjshw0lpgu')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1q8l6hcvlczu4mtjcnlwhczw7vdxnvwccpjl3cwz')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qaggygkqgqjjpt58zrmhvjz5m9dj8mjshyndqzl')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1q8l6hcvlczu4mtjcnlwhczw7vdxnvwccpcrreyp')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_slip39_non_extendable_groups_256bit_bip49_p2sh_segwit(self, mock_save_db):
|
||||
@@ -698,8 +698,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2pkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '1N4hqJRTVqUbwT5WCbbsQSwKRPPPzG1TSo')
|
||||
self.assertEqual(w.get_change_addresses()[0], '1FW3QQzbYRSUoNDDYGWPvSCoom8fBhPC9k')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'PVeszGpJYkxnvHkGYfvQ5Lub38ZHBeXhPo')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'PP6DZPPSbLvfnCsytLpvbLB5RWJYLNBJwM')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_slip39_extendable_basic_2of5_bip49_p2sh_segwit(self, mock_save_db):
|
||||
@@ -754,8 +754,8 @@ class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wpkh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'bc1qs2svwhfz47qv9qju2waa6prxzv5f522fc4p06t')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'bc1qmjq5nenac3vjwltldk5qsq4yd8mttw2dpkmx06')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'plm1qs2svwhfz47qv9qju2waa6prxzv5f522fjfnwsg')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'plm1qmjq5nenac3vjwltldk5qsq4yd8mttw2dt2f89e')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_slip39_extendable_groups_256bit_bip49_p2sh_segwit(self, mock_save_db):
|
||||
@@ -810,8 +810,8 @@ class TestWalletKeystoreAddressIntegrityForTestnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
|
||||
self.assertEqual(w.txin_type, 'p2wsh-p2sh')
|
||||
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '2MzsfTfTGomPRne6TkctMmoDj6LwmVkDrMt')
|
||||
self.assertEqual(w.get_change_addresses()[0], '2NFp9w8tbYYP9Ze2xQpeYBJQjx3gbXymHX7')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'oQVohsJwJ9rTYXoSmduYVeB17V5MtqAeyV')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'ofSJBLkG2vrBKXjwRqfiu9N1yBpBv3kpch')
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_bip32_extended_version_bytes(self, mock_save_db):
|
||||
@@ -834,43 +834,43 @@ class TestWalletKeystoreAddressIntegrityForTestnet(ElectrumTestCase):
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(ks.xprv, 'tprv8ZgxMBicQKsPecD328MF9ux3dSaSFWci7FNQmuWH7uZ86eY8i3XpvjK8KSH8To2QphiZiUqaYc6nzDC6bTw8YCB9QJjaQL5pAApN4z7vh2B')
|
||||
self.assertEqual(ks.xpub, 'tpubD6NzVbkrYhZ4Y5Epun1qZKcACU6NQqocgYyC4RYaYBMWw8nuLSMR7DvzVamkqxwRgrTJ1MBMhc8wwxT2vbHqMu8RBXy4BvjWMxR5EdZroxE')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'mpBTXYfWehjW2tavFwpUdqBJbZZkup13k2')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'mtkUQgf1psDtL67wMAKTv19LrdgPWy6GDQ')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'tFb7HHS81b9X7ppJef9aPqXtfdgrHG9JXx')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'tLA8ARRdBkduR2MKjseZg1VvvhoUti3UzY')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='p2wpkh-p2sh')
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(ks.xprv, 'uprv8tXDerPXZ1QsVuQ9rV8sN13YoQitC8cD2MtdZJQAVuw19kMMxhhPYnyGLeEiThgLELqNTxS91GTLsVofKAM9LRrkGeRzzEuJRtt1Tcostr7')
|
||||
self.assertEqual(ks.xpub, 'upub57Wa4MvRPNyAiPUcxWfsj8zHMSZNbbL4PapEMgon4FTz2YgWWF1e6bHkBvpDKk2Rg2Zy9LsonXFFbv7jNeCZ5kdKWv8UkfcoxpdjJrZuBX6')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '2MuzNWpcHrXyvPVKzEGT7Xrwp8uEnXXjWnK')
|
||||
self.assertEqual(w.get_change_addresses()[0], '2MzTzY5VcGLwce7YmdEwjXhgQD7LYEKLJTm')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'oKcWm2TxLvSx9P2yFHUJFhu6A3NNtLazwf')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'oQ68nHMGkjQeQ1FkeFxvFYdgEFU8d5iKdw')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='p2wpkh')
|
||||
w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
|
||||
self.assertEqual(ks.xprv, 'vprv9DMUxX4ShgxMMCbGgqvVa693yNsL8kbhwUQrLhJ3svJtCrAbDMrxArdQMrCJTcLFdyxBDS2hTvotknRE2rmA8fYM8z8Ra9inhcwerEsG6Ev')
|
||||
self.assertEqual(ks.xpub, 'vpub5SLqN2bLY4WeZgfjnsTVwE5nXQhpYDKZJhLT95hfSFqs5eVjkuBCiewtD8moKegM5fgmtpUNFBboVCjJ6LcZszJvPFpuLaSJEYhNhUAnrCS')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'tb1qtuynwzd0d6wptvyqmc6ehkm70zcamxpsaze002')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'tb1qjy5zunxh6hjysele86qqywfa437z4xwm4lm549')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'tplm1qtuynwzd0d6wptvyqmc6ehkm70zcamxps22n5ds')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'tplm1qjy5zunxh6hjysele86qqywfa437z4xwmzh30hl')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='standard') # p2sh
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
|
||||
self.assertEqual(ks.xprv, 'tprv8ZgxMBicQKsPecD328MF9ux3dSaSFWci7FNQmuWH7uZ86eY8i3XpvjK8KSH8To2QphiZiUqaYc6nzDC6bTw8YCB9QJjaQL5pAApN4z7vh2B')
|
||||
self.assertEqual(ks.xpub, 'tpubD6NzVbkrYhZ4Y5Epun1qZKcACU6NQqocgYyC4RYaYBMWw8nuLSMR7DvzVamkqxwRgrTJ1MBMhc8wwxT2vbHqMu8RBXy4BvjWMxR5EdZroxE')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '2N6czpsRwQ3d8AHZPNbztf5NotzEsaZmVQ8')
|
||||
self.assertEqual(w.get_change_addresses()[0], '2NDgwz4CoaSzdSAQdrCcLFWsJaVowCNgiPA')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'oWF955HbtS69vBGNPd25NvL5v8NTv86aGu')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'odK6EG4U4qTfC47csDdWyMpabdwXc1nZeu')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='p2wsh-p2sh')
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
|
||||
self.assertEqual(ks.xprv, 'Uprv95RJn67y7xyEvUZXo9brC5PMXCm9QVHoLdYJUZfhsgmQmvvGj75fduqC9MCC28uETouMLYSFtUqqzfRRcPW6UuyR77YQPeNJKd9t3XutF8b')
|
||||
self.assertEqual(ks.xpub, 'Upub5JQfBberxLXY8xdzuB8rZDL65Ebdox1ehrTuGx5KS2JPejFRGePvBi9fzdmgtBFKuVdx1vsvfjdkj5jVfsMWEEjzMPEtA55orYubtrCZmRr')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], '2NBZQ25GC3ipaF13ZY3UT8i2xnDuS17pJqx')
|
||||
self.assertEqual(w.get_change_addresses()[0], '2NDmUgLVX8vKvcJ4FQ37GSUre6QtBzKkb6k')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'obBYGH7rY7HbztkYZ4VdrYzEoN32Q3q34v')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'odPcvYMBdJnxNBmER48TAKov7Z1nQHv33T')
|
||||
|
||||
ks = create_keystore_from_bip32seed(xtype='p2wsh')
|
||||
w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
|
||||
self.assertEqual(ks.xprv, 'Vprv16YtLrHXxePM6noKqtFtMtmUgBE9bEpF3fPLmpvuPksssLostujtdHBwqhEeVuzESz22UY8hyPx9ed684SQpCmUKSVhpxPFbvVNY7qnviNR')
|
||||
self.assertEqual(ks.xpub, 'Vpub5dEvVGKn7251zFq7jXvUmJRbFCk5ka19cxz84LyCp2gGhq4eXJZUomop1qjGt5uFK8kkmQUV8PzJcNM4PZmX2URbDiwJjyuJ8GyFHRrEmmG')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'tb1q84x0yrztvcjg88qef4d6978zccxulcmc9y88xcg4ghjdau999x7qf2696k')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'tb1q0fj5mra96hhnum80kllklc52zqn6kppt3hyzr49yhr3ecr42z3ts5777jl')
|
||||
self.assertEqual(w.get_receiving_addresses()[0], 'tplm1q84x0yrztvcjg88qef4d6978zccxulcmc9y88xcg4ghjdau999x7qjycz82')
|
||||
self.assertEqual(w.get_change_addresses()[0], 'tplm1q0fj5mra96hhnum80kllklc52zqn6kppt3hyzr49yhr3ecr42z3ts0sue0r')
|
||||
|
||||
|
||||
class TestWalletSending(ElectrumTestCase):
|
||||
@@ -1301,7 +1301,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', 2500000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -1588,7 +1588,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', 2500000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -1768,7 +1768,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1q7rl9cxr85962ztnsze089zs8ycv52hk43f3m9n', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1q7rl9cxr85962ztnsze089zs8ycv52hk4xpmq8f', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -1829,7 +1829,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -1893,7 +1893,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx1, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -1964,7 +1964,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx1, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2_500_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', 2_500_000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -2003,7 +2003,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
|
||||
# create new tx (output should be batched with existing!)
|
||||
# no new input will be needed. just a new output, and change decreased.
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qy6xmdj96v5dzt3j08hgc05yk3kltqsnmw4r6ry', 2_500_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qy6xmdj96v5dzt3j08hgc05yk3kltqsnmeafpp7', 2_500_000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(20000), base_tx=tx)
|
||||
tx.set_rbf(True)
|
||||
@@ -2034,7 +2034,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
|
||||
# create new tx (output should be batched with existing!)
|
||||
# new input will be needed!
|
||||
outputs = [PartialTxOutput.from_address_and_value('2NCVwbmEpvaXKHpXUGJfJr9iB5vtRN3vcut', 6_000_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oc85qy6VQxzM3iETHKgVZzfT7521q47Eae', 6_000_000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(100000), base_tx=tx)
|
||||
tx.set_rbf(True)
|
||||
@@ -2213,7 +2213,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
funding_txid = funding_tx.txid()
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
dest_addr = "tb1qtzhwpufqr5dwztdaysfqnwlf9m29uwdkq8zm9w"
|
||||
dest_addr = "tplm1qtzhwpufqr5dwztdaysfqnwlf9m29uwdkh0gq85"
|
||||
# first payment to dest_addr
|
||||
outputs1 = [PartialTxOutput.from_address_and_value(dest_addr, 200_000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
@@ -2326,9 +2326,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
else:
|
||||
raise Exception("unexpected txid")
|
||||
|
||||
privkeys = ['93NQ7CFbwTPyKDJLXe97jczw33fiLijam2SCZL3Uinz1NSbHrTu',]
|
||||
privkeys = ['p2pkh:9aUJvuS7aGDbULbd2v56zkbKgsXCjzDbMFZvTj3pdH6DGLwHALW',]
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1q3ws2p0qjk5vrravv065xqlnkckvzcpclk79eu2'
|
||||
dest_addr = 'tplm1q3ws2p0qjk5vrravv065xqlnkckvzcpclpk0z7s'
|
||||
tx = await sweep(privkeys, network=network, to_address=dest_addr, fee_policy=FixedFeePolicy(5000), locktime=1325785, tx_version=1)
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
@@ -2351,9 +2351,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
else:
|
||||
raise Exception("unexpected txid")
|
||||
|
||||
privkeys = ['cUygTZe4jZLVwE4G44NznCPTeGvgsgassqucUHkAJxGC71Rst2kH',]
|
||||
privkeys = ['p2pkh:erFmc9QTY1zhXWGYuGhHWyuFdE98ENvWUushRZHgAcKacJYPt3fW',]
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1q5uy5xjcn55gwdkmghht8yp3vwz3088f6e3e0em'
|
||||
dest_addr = 'tplm1q5uy5xjcn55gwdkmghht8yp3vwz3088f6wen5mp'
|
||||
tx = await sweep(privkeys, network=network, to_address=dest_addr, fee_policy=FixedFeePolicy(5000), locktime=2420006, tx_version=2)
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
@@ -2376,9 +2376,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
else:
|
||||
raise Exception("unexpected txid")
|
||||
|
||||
privkeys = ['p2pkh:91gxDahzHiJ63HXmLP7pvZrkF8i5gKBXk4VqWfhbhJjtf6Ni5NU',]
|
||||
privkeys = ['p2pkh:9Yns3HtVvX7iCQq3qf3pBhT8txZa5afYLHdZR4hwbnr6Z4a7kuA',]
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1q3ws2p0qjk5vrravv065xqlnkckvzcpclk79eu2'
|
||||
dest_addr = 'tplm1q3ws2p0qjk5vrravv065xqlnkckvzcpclpk0z7s'
|
||||
tx = await sweep(privkeys, network=network, to_address=dest_addr, fee_policy=FixedFeePolicy(5000), locktime=2420010, tx_version=2)
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
@@ -2401,9 +2401,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
else:
|
||||
raise Exception("unexpected txid")
|
||||
|
||||
privkeys = ['p2pkh:cN3LiXmurmGRF5xngYd8XS2ZsP2KeXFUh4SH7wpC8uJJzw52JPq1',]
|
||||
privkeys = ['p2pkh:ejKRs7YJfDvcqNB5XkwRGDYMrLEm1Db7J8QN5DMhzZMhWEKfDiet',]
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1q782f750ekkxysp2rrscr6yknmn634e2pv8lktu'
|
||||
dest_addr = 'tplm1q782f750ekkxysp2rrscr6yknmn634e2pm04dfx'
|
||||
tx = await sweep(privkeys, network=network, to_address=dest_addr, fee_policy=FixedFeePolicy(1000), locktime=2420010, tx_version=2)
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
@@ -2426,9 +2426,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
else:
|
||||
raise Exception("unexpected txid")
|
||||
|
||||
privkeys = ['p2wpkh-p2sh:cQMRGsiEsFX5YoxVZaMEzBruAkCWnoFf1SG7SRm2tLHDEN165TrA',]
|
||||
privkeys = ['p2wpkh-p2sh:emdWRTUdfiBH96AnQnfXiyNh9hQx9VbHcWECPhJYjzLbjf6KZv9s',]
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1qu7n2tzm90a3f29kvxlhzsc7t40ddk075ut5w44'
|
||||
dest_addr = 'tplm1qu7n2tzm90a3f29kvxlhzsc7t40ddk075tr74h0'
|
||||
tx = await sweep(privkeys, network=network, to_address=dest_addr, fee_policy=FixedFeePolicy(500), locktime=2420010, tx_version=2)
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
@@ -2451,9 +2451,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
else:
|
||||
raise Exception("unexpected txid")
|
||||
|
||||
privkeys = ['p2wpkh:cV2BvgtpLNX328m4QrhqycBGA6EkZUFfHM9kKjVXjfyD53uNfC4q',]
|
||||
privkeys = ['p2wpkh:erJH5GfD8qBEcQyMG528iPh493TBvAbHtR7qH133bL2baM3tMA7q',]
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1qhuy2e45lrdcp9s4ezeptx5kwxcnahzgpar9scc'
|
||||
dest_addr = 'tplm1qhuy2e45lrdcp9s4ezeptx5kwxcnahzgp2t0t6z'
|
||||
tx = await sweep(privkeys, network=network, to_address=dest_addr, fee_policy=FixedFeePolicy(500), locktime=2420010, tx_version=2)
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
@@ -2488,7 +2488,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet2.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# wallet1 creates tx1, with output back to himself
|
||||
outputs = [PartialTxOutput.from_address_and_value("tb1qhye4wfp26kn0l7ynpn5a4hvt539xc3zf0n76t3", 10_000_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value("tplm1qhye4wfp26kn0l7ynpn5a4hvt539xc3zfcm5pft", 10_000_000)]
|
||||
tx1 = wallet1.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), tx_version=2, rbf=True)
|
||||
tx1.locktime = 1607022
|
||||
partial_tx1 = tx1.serialize_as_bytes().hex()
|
||||
@@ -2500,7 +2500,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
partial_tx1)
|
||||
|
||||
# wallet2 creates tx2, with output back to himself
|
||||
outputs = [PartialTxOutput.from_address_and_value("tb1qufnj5k2rrsnpjq7fg6d2pq3q9um6skdyyehw5m", 10_000_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value("tplm1qufnj5k2rrsnpjq7fg6d2pq3q9um6skdyn3a4kp", 10_000_000)]
|
||||
tx2 = wallet2.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), tx_version=2, rbf=True)
|
||||
tx2.locktime = 1607023
|
||||
partial_tx2 = tx2.serialize_as_bytes().hex()
|
||||
@@ -2573,7 +2573,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet_2of2.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qfrlx5pza9vmez6vpx7swt8yp0nmgz3qa7jjkuf', 100_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qfrlx5pza9vmez6vpx7swt8yp0nmgz3qaf6cd7n', 100_000)]
|
||||
coins = wallet_2of2.get_spendable_coins(domain=None)
|
||||
tx = wallet_2of2.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -2588,9 +2588,9 @@ class TestWalletSending(ElectrumTestCase):
|
||||
self.assertTrue(tx.is_segwit())
|
||||
self.assertEqual('652c1a903a659c9fabb9caf4a2281a9fbcc59cd598bf6edc88cd60f940c2352c', tx.txid())
|
||||
|
||||
self.assertEqual('tb1qxq5crk6yadw66rdt8xr3xj5ctvmq4c3z0fl85yx0ar8l6ga6ehysk0rjrk', tx.inputs()[0].address)
|
||||
self.assertEqual('tb1qfrlx5pza9vmez6vpx7swt8yp0nmgz3qa7jjkuf', tx.outputs()[0].address)
|
||||
self.assertEqual('tb1qadpg5z77egkpkde34mdcrsz3s3tgwk5ew4w3wlfqf4j3dk8kkvrs3t3mn0', tx.outputs()[1].address)
|
||||
self.assertEqual('tplm1qxq5crk6yadw66rdt8xr3xj5ctvmq4c3z0fl85yx0ar8l6ga6ehysdpp472', tx.inputs()[0].address)
|
||||
self.assertEqual('tplm1qfrlx5pza9vmez6vpx7swt8yp0nmgz3qaf6cd7n', tx.outputs()[0].address)
|
||||
self.assertEqual('tplm1qadpg5z77egkpkde34mdcrsz3s3tgwk5ew4w3wlfqf4j3dk8kkvrs29nuwn', tx.outputs()[1].address)
|
||||
|
||||
# check that wallet_frost does not mistakenly think tx is related to it in any way
|
||||
tx.add_info_from_wallet(wallet_frost)
|
||||
@@ -2634,7 +2634,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('miFLSDZBXUo4on8PGhTRTAufUn4mP61uoH', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('t9ezBxKntND5tiMmfQnXDBGFYrBri26CCm', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -2679,7 +2679,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', 2500000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -2744,7 +2744,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N1VTMMFb91SH9SNRAkT7z8otP5eZEct4KL', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oR7bbZ7FdPuJuL5QBmUJhymAQDn9jrKXe5', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -2866,7 +2866,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create tx1
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qsfcddwf7yytl62e3catwv8hpl2hs9e36g2cqxl', 100000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qsfcddwf7yytl62e3catwv8hpl2hs9e36lzjmy9', 100000)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(190))
|
||||
tx.set_rbf(True)
|
||||
@@ -2879,7 +2879,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.add_transaction(tx)
|
||||
|
||||
# create tx2, which spends from unsigned tx1
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qq0lm9esmq6pfjc3jls7v6twy93lnqcs85wlth3', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qq0lm9esmq6pfjc3jls7v6twy93lnqcs8rx4s4t', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -2902,7 +2902,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
config=self.config, gap_limit=3)
|
||||
|
||||
with self.subTest(msg="no coins to use as inputs, max output value, zero fee"):
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qsfcddwf7yytl62e3catwv8hpl2hs9e36g2cqxl', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qsfcddwf7yytl62e3catwv8hpl2hs9e36lzjmy9', '!')]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
with self.assertRaises(NotEnoughFunds):
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(0))
|
||||
@@ -2914,7 +2914,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
with self.subTest(msg="funded wallet, zero output value, zero fee"):
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qsfcddwf7yytl62e3catwv8hpl2hs9e36g2cqxl', 0)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qsfcddwf7yytl62e3catwv8hpl2hs9e36lzjmy9', 0)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(0))
|
||||
self.assertEqual(1, len(tx.inputs()))
|
||||
@@ -2938,7 +2938,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
self.assertEqual(2, len(wallet.get_spendable_coins(nonlocal_only=False)))
|
||||
|
||||
# create payment_tx that spends utxo1 and creates a change txo
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qrxrp08s5d4cgudlmyfasyme9rgxc7n6z29g2m9', 200_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qrxrp08s5d4cgudlmyfasyme9rgxc7n6zadz3el', 200_000)]
|
||||
coins = wallet.get_spendable_coins()
|
||||
payment_tx = wallet.make_unsigned_transaction(coins=[coins[0]], outputs=outputs, fee_policy=FixedFeePolicy(0))
|
||||
payment_txid = payment_tx.txid()
|
||||
@@ -2976,7 +2976,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
funding_tx1 = Transaction('02000000000101bf03f2d37ae084d729e5685d64988c92e8a98cb73062802646dfbb10d77e88410000000000fdffffff02a03007000000000016001443a24a730a7ddd2ce4da777a949a9e87c6ad870920a107000000000016001447597395323a834378d7577d848187684d0d70fe0247304402200e6f1898a0681c4ff1f5995b357c3388ca53fcf56760e0d14d4ea72c48d1134b0220683b8e5045743c087d488dfc5f8c5b7369ff92f611595eaba0dbb0c0009c816e0121021bd313412fad3802801f6c45321a10c7bf35603bf8571aa263ece764d1ab7ef1a2434300')
|
||||
wallet.adb.receive_tx_callback(funding_tx1, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
# create payment_tx that spends utxo1 and creates a change txo
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qrxrp08s5d4cgudlmyfasyme9rgxc7n6z29g2m9', 200_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qrxrp08s5d4cgudlmyfasyme9rgxc7n6zadz3el', 200_000)]
|
||||
coins = wallet.get_spendable_coins()
|
||||
payment_tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(0))
|
||||
payment_txid = payment_tx.txid()
|
||||
@@ -2991,7 +2991,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_imported_wallet_usechange_off(self, mock_save_db):
|
||||
wallet = restore_wallet_from_text__for_unittest(
|
||||
"p2wpkh:cVcwSp488C8Riguq55Tuktgi6TpzuyLdDwUxkBDBz3yzV7FW4af2 p2wpkh:cPWyoPvnv2hiyyxbhMkhX3gPEENzB6DqoP9bbR8SDTg5njK5SL9n",
|
||||
"p2wpkh:eru2bPpWvendJy87vHnCVgCW5R3SGfgFq1T3hSkhqi3NzQUw1Vav p2wpkh:eko4wyhBiVMvaGAtYa4zFqCBDBbRXnZUQT7gYgfx57jUJ2Xd49cb",
|
||||
path='if_this_exists_mocking_failed_648151893',
|
||||
config=self.config)['wallet'] # type: Abstract_Wallet
|
||||
|
||||
@@ -3005,7 +3005,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
# (they send it back to the "from address")
|
||||
self.assertFalse(wallet.use_change)
|
||||
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjqchza3v', 49646)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjq0lgxnk', 49646)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(1000))
|
||||
tx.set_rbf(True)
|
||||
@@ -3014,8 +3014,8 @@ class TestWalletSending(ElectrumTestCase):
|
||||
|
||||
# check that change is sent back to the "from address"
|
||||
self.assertEqual(2, len(tx.outputs()))
|
||||
self.assertTrue(tx.output_value_for_address("tb1q0fj7pxa3m2q2hlr964zn3z3wvx4t03ep5fgnhy") > 0)
|
||||
self.assertEqual(49646, tx.output_value_for_address("tb1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjqchza3v"))
|
||||
self.assertTrue(tx.output_value_for_address("tplm1q0fj7pxa3m2q2hlr964zn3z3wvx4t03eprpzg47") > 0)
|
||||
self.assertEqual(49646, tx.output_value_for_address("tplm1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjq0lgxnk"))
|
||||
|
||||
self.assertEqual("70736274ff0100710200000001ce010c0cab95cde544f713771916613a1a84c8787bbc95321854410b212aed9b0100000000fdffffff02cac00000000000001600147a65e09bb1da80abfc65d545388a2e61aab7c721eec100000000000016001405424089c64d39d9a498b6e1c8e646327431b240c4951e000001011fa0860100000000001600147a65e09bb1da80abfc65d545388a2e61aab7c7210100de02000000000101c6edaaf0157020a38de8b07810b22ffe331d5b79c83b680dad24da15c572ae7d0000000000fdffffff026080010000000000160014eabbd791df76eeeaa3ed273cac4e1dde3be295cca0860100000000001600147a65e09bb1da80abfc65d545388a2e61aab7c7210247304402203cb8b2f84ed4fb8de5f51a07b2159bc0d8d474e5dba0f77cc66ab641cf48621b022076fb3c6b4bc76aa06dd29ebe1dd081c063cdbd2949ffcf4ab4bd8bddae6c948b0121029f16b602a6b3c738b66a03dd5133abe810169a377bbc2fdf5c5363f59b8d9bdec3951e00000000",
|
||||
tx.serialize_as_bytes().hex())
|
||||
@@ -3027,7 +3027,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_imported_wallet_usechange_on(self, mock_save_db):
|
||||
wallet = restore_wallet_from_text__for_unittest(
|
||||
"p2wpkh:cVcwSp488C8Riguq55Tuktgi6TpzuyLdDwUxkBDBz3yzV7FW4af2 p2wpkh:cPWyoPvnv2hiyyxbhMkhX3gPEENzB6DqoP9bbR8SDTg5njK5SL9n",
|
||||
"p2wpkh:eru2bPpWvendJy87vHnCVgCW5R3SGfgFq1T3hSkhqi3NzQUw1Vav p2wpkh:eko4wyhBiVMvaGAtYa4zFqCBDBbRXnZUQT7gYgfx57jUJ2Xd49cb",
|
||||
path='if_this_exists_mocking_failed_648151893',
|
||||
config=self.config)['wallet'] # type: Abstract_Wallet
|
||||
|
||||
@@ -3040,7 +3040,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
# instead of sending the change back to the "from address", we want it sent to another unused address
|
||||
wallet.use_change = True
|
||||
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjqchza3v', 49646)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjq0lgxnk', 49646)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(1000))
|
||||
tx.set_rbf(True)
|
||||
@@ -3049,8 +3049,8 @@ class TestWalletSending(ElectrumTestCase):
|
||||
|
||||
# check that change is sent to another unused imported address
|
||||
self.assertEqual(2, len(tx.outputs()))
|
||||
self.assertTrue(tx.output_value_for_address("tb1qetcgdwuzlpdnt5fmzxxdpczjhadz06cynpttpv") > 0)
|
||||
self.assertEqual(49646, tx.output_value_for_address("tb1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjqchza3v"))
|
||||
self.assertTrue(tx.output_value_for_address("tplm1qetcgdwuzlpdnt5fmzxxdpczjhadz06cyyfpsrk") > 0)
|
||||
self.assertEqual(49646, tx.output_value_for_address("tplm1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjq0lgxnk"))
|
||||
|
||||
self.assertEqual("70736274ff0100710200000001ce010c0cab95cde544f713771916613a1a84c8787bbc95321854410b212aed9b0100000000fdffffff02cac0000000000000160014caf086bb82f85b35d13b118cd0e052bf5a27eb04eec100000000000016001405424089c64d39d9a498b6e1c8e646327431b240c4951e000001011fa0860100000000001600147a65e09bb1da80abfc65d545388a2e61aab7c7210100de02000000000101c6edaaf0157020a38de8b07810b22ffe331d5b79c83b680dad24da15c572ae7d0000000000fdffffff026080010000000000160014eabbd791df76eeeaa3ed273cac4e1dde3be295cca0860100000000001600147a65e09bb1da80abfc65d545388a2e61aab7c7210247304402203cb8b2f84ed4fb8de5f51a07b2159bc0d8d474e5dba0f77cc66ab641cf48621b022076fb3c6b4bc76aa06dd29ebe1dd081c063cdbd2949ffcf4ab4bd8bddae6c948b0121029f16b602a6b3c738b66a03dd5133abe810169a377bbc2fdf5c5363f59b8d9bdec3951e00000000",
|
||||
tx.serialize_as_bytes().hex())
|
||||
@@ -3062,7 +3062,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_imported_wallet_usechange_on__no_more_unused_addresses(self, mock_save_db):
|
||||
wallet = restore_wallet_from_text__for_unittest(
|
||||
"p2wpkh:cVcwSp488C8Riguq55Tuktgi6TpzuyLdDwUxkBDBz3yzV7FW4af2 p2wpkh:cPWyoPvnv2hiyyxbhMkhX3gPEENzB6DqoP9bbR8SDTg5njK5SL9n",
|
||||
"p2wpkh:eru2bPpWvendJy87vHnCVgCW5R3SGfgFq1T3hSkhqi3NzQUw1Vav p2wpkh:eko4wyhBiVMvaGAtYa4zFqCBDBbRXnZUQT7gYgfx57jUJ2Xd49cb",
|
||||
path='if_this_exists_mocking_failed_648151893',
|
||||
config=self.config)['wallet'] # type: Abstract_Wallet
|
||||
|
||||
@@ -3085,7 +3085,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
# (except all our addresses are used! so we expect change sent back to "from address")
|
||||
wallet.use_change = True
|
||||
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjqchza3v', 49646)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjq0lgxnk', 49646)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
tx = wallet.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(1000))
|
||||
tx.set_rbf(True)
|
||||
@@ -3094,8 +3094,8 @@ class TestWalletSending(ElectrumTestCase):
|
||||
|
||||
# check that change is sent back to the "from address"
|
||||
self.assertEqual(2, len(tx.outputs()))
|
||||
self.assertTrue(tx.output_value_for_address("tb1q0fj7pxa3m2q2hlr964zn3z3wvx4t03ep5fgnhy") > 0)
|
||||
self.assertEqual(49646, tx.output_value_for_address("tb1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjqchza3v"))
|
||||
self.assertTrue(tx.output_value_for_address("tplm1q0fj7pxa3m2q2hlr964zn3z3wvx4t03eprpzg47") > 0)
|
||||
self.assertEqual(49646, tx.output_value_for_address("tplm1qq4pypzwxf5uanfyckmsu3ejxxf6rrvjq0lgxnk"))
|
||||
|
||||
self.assertEqual("70736274ff0100710200000001ce010c0cab95cde544f713771916613a1a84c8787bbc95321854410b212aed9b0100000000fdffffff02cac00000000000001600147a65e09bb1da80abfc65d545388a2e61aab7c721eec100000000000016001405424089c64d39d9a498b6e1c8e646327431b240c4951e000001011fa0860100000000001600147a65e09bb1da80abfc65d545388a2e61aab7c7210100de02000000000101c6edaaf0157020a38de8b07810b22ffe331d5b79c83b680dad24da15c572ae7d0000000000fdffffff026080010000000000160014eabbd791df76eeeaa3ed273cac4e1dde3be295cca0860100000000001600147a65e09bb1da80abfc65d545388a2e61aab7c7210247304402203cb8b2f84ed4fb8de5f51a07b2159bc0d8d474e5dba0f77cc66ab641cf48621b022076fb3c6b4bc76aa06dd29ebe1dd081c063cdbd2949ffcf4ab4bd8bddae6c948b0121029f16b602a6b3c738b66a03dd5133abe810169a377bbc2fdf5c5363f59b8d9bdec3951e00000000",
|
||||
tx.serialize_as_bytes().hex())
|
||||
@@ -3128,18 +3128,18 @@ class TestWalletSending(ElectrumTestCase):
|
||||
{txi.prevout.to_str() for txi in wallet.get_spendable_coins()})
|
||||
self.assertEqual(
|
||||
{'52e669a20a26c8b3df5b41e5e6309b18bcde8e1ad7ea17a18f63b6dc6c8becc0:1'},
|
||||
{txi.prevout.to_str() for txi in wallet.get_spendable_coins(["tb1q6n99dl96mx8mfh90m3tn5awk5mllkzdh25dw7z"])})
|
||||
{txi.prevout.to_str() for txi in wallet.get_spendable_coins(["tplm1q6n99dl96mx8mfh90m3tn5awk5mllkzdhau84uc"])})
|
||||
|
||||
utxo1 = "c36a6e1cd54df108e69574f70bc9b88dc13beddc70cfad9feb7f8f6593255d4a:1"
|
||||
utxo2 = "52e669a20a26c8b3df5b41e5e6309b18bcde8e1ad7ea17a18f63b6dc6c8becc0:1"
|
||||
|
||||
# test freezing an address
|
||||
with self.subTest(msg="freeze_address"):
|
||||
wallet.set_frozen_state_of_addresses(["tb1q6n99dl96mx8mfh90m3tn5awk5mllkzdh25dw7z"], freeze=True)
|
||||
wallet.set_frozen_state_of_addresses(["tplm1q6n99dl96mx8mfh90m3tn5awk5mllkzdhau84uc"], freeze=True)
|
||||
self.assertEqual(
|
||||
{utxo1},
|
||||
{txi.prevout.to_str() for txi in wallet.get_spendable_coins()})
|
||||
wallet.set_frozen_state_of_addresses(["tb1q6n99dl96mx8mfh90m3tn5awk5mllkzdh25dw7z"], freeze=False)
|
||||
wallet.set_frozen_state_of_addresses(["tplm1q6n99dl96mx8mfh90m3tn5awk5mllkzdhau84uc"], freeze=False)
|
||||
self.assertEqual(
|
||||
{utxo1, utxo2},
|
||||
{txi.prevout.to_str() for txi in wallet.get_spendable_coins()})
|
||||
@@ -3187,7 +3187,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
self.assertEqual('98c039c9b528a8edf2c64e295bb50cf773ddbf418c98119ef54c31b60e73c322', funding_txid)
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
outputs = [PartialTxOutput.from_address_and_value("tb1q0ezagv55krljkz9973fryeyczhj3dnlsgr02g7", 123456)]
|
||||
outputs = [PartialTxOutput.from_address_and_value("tplm1q0ezagv55krljkz9973fryeyczhj3dnlslt932y", 123456)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
|
||||
# create spending tx
|
||||
@@ -3258,7 +3258,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
self.assertEqual('c70d83827d09b334bb373738be25c93dbe7dd37186d09bb10cae80704da06f91', funding_txid)
|
||||
wallet.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
outputs = [PartialTxOutput.from_address_and_value("tb1q0ezagv55krljkz9973fryeyczhj3dnlsgr02g7", 123456)]
|
||||
outputs = [PartialTxOutput.from_address_and_value("tplm1q0ezagv55krljkz9973fryeyczhj3dnlslt932y", 123456)]
|
||||
coins = wallet.get_spendable_coins(domain=None)
|
||||
|
||||
# create spending tx
|
||||
@@ -3326,7 +3326,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
wallet1b.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# cosignerA creates and signs the tx
|
||||
outputs = [PartialTxOutput.from_address_and_value("tb1qgacvp0zvgtk3etggjayuezrc2mkql8veshv4xw", 200_000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value("tplm1qgacvp0zvgtk3etggjayuezrc2mkql8ve8lxwy5", 200_000)]
|
||||
coins = wallet1a.get_spendable_coins(domain=None)
|
||||
tx = wallet1a.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(5000))
|
||||
tx.set_rbf(True)
|
||||
@@ -3421,7 +3421,7 @@ class TestWalletSending(ElectrumTestCase):
|
||||
self.assertEqual('9d221a69ca3997cbeaf5624d723e7dc5f829b1023078c177d37bdae95f37c539', funding_tx.txid())
|
||||
wallet1.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qgacvp0zvgtk3etggjayuezrc2mkql8veshv4xw', '!')]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qgacvp0zvgtk3etggjayuezrc2mkql8ve8lxwy5', '!')]
|
||||
coins = wallet1.get_spendable_coins(domain=None)
|
||||
tx = wallet1.make_unsigned_transaction(coins=coins, outputs=outputs, fee_policy=FixedFeePolicy(1000))
|
||||
self.assertEqual(2, len(tx.inputs()))
|
||||
@@ -3481,7 +3481,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qyw3c0rvn6kk2c688y3dygvckn57525y8qnxt3a', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qyw3c0rvn6kk2c688y3dygvckn57525y8hmvsn8', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1446655
|
||||
tx.version = 1
|
||||
@@ -3529,7 +3529,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qp0mv2sxsyxxfj5gl0332f9uyez93su9c7zs9ky', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -3584,7 +3584,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qp0mv2sxsyxxfj5gl0332f9uyez93su9c7zs9ky', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325341
|
||||
tx.version = 1
|
||||
@@ -3629,7 +3629,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qp0mv2sxsyxxfj5gl0332f9uyez93su9c7zs9ky', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325341
|
||||
tx.version = 1
|
||||
@@ -3687,7 +3687,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qp0mv2sxsyxxfj5gl0332f9uyez93su9cf26757', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qp0mv2sxsyxxfj5gl0332f9uyez93su9c7zs9ky', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325341
|
||||
tx.version = 1
|
||||
@@ -3735,9 +3735,9 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_sending_offline_wif_online_addr_p2pkh(self, mock_save_db): # compressed pubkey
|
||||
wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
|
||||
wallet_offline.import_private_key('p2pkh:cQDxbmQfwRV3vP1mdnVHq37nJekHLsuD3wdSQseBRA2ct4MFk5Pq', password=None)
|
||||
wallet_offline.import_private_key('p2pkh:emW3kMB4jt9FWfE4UzoaZpdaHbxihaEqf1bXN9BhGp61PMWdMwCc', password=None)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('mg2jk6S5WGDhUPA8mLSxDLWpUoQnX1zzoG')
|
||||
wallet_online.import_address('t7SPVqCgs9diZKPXA3n3yLsQYsXsti7pTj')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('01000000000101197a89cff51096b9dd4214cdee0eb90cb27a25477e739521d728a679724042730100000000fdffffff048096980000000000160014dab37af8fefbbb31887a0a5f9b2698f4a7b45f6a80969800000000001976a91405a20074ef7eb42c7c6fcd4f499faa699742783288ac809698000000000017a914b808938a8007bc54509cd946944c479c0fa6554f87131b2c0400000000160014a04dfdb9a9aeac3b3fada6f43c2a66886186e2440247304402204f5dbb9dda65eab26179f1ca7c37c8baf028153815085dd1bbb2b826296e3b870220379fcd825742d6e2bdff772f347b629047824f289a5499a501033f6c3495594901210363c9c98740fe0455c646215cea9b13807b758791c8af7b74e62968bef57ff8ae1e391400')
|
||||
@@ -3746,7 +3746,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtu40n4p', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -3772,9 +3772,9 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_sending_offline_wif_online_addr_p2wpkh_p2sh(self, mock_save_db):
|
||||
wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
|
||||
wallet_offline.import_private_key('p2wpkh-p2sh:cU9hVzhpvfn91u2zTVn8uqF2ymS7ucYH8V5TmsTDmuyMHgRk9WsJ', password=None)
|
||||
wallet_offline.import_private_key('p2wpkh-p2sh:eqRneaUDj8SLcBFHJi6ReckpxieZGJsujZ3Yj8zjda2jnyfEWwHj', password=None)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('2NA2JbUVK7HGWUCK5RXSVNHrkgUYF8d9zV8')
|
||||
wallet_online.import_address('oZeSqgLybfjYE624SYTg68p2hcfqZBHnCz')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('01000000000101197a89cff51096b9dd4214cdee0eb90cb27a25477e739521d728a679724042730100000000fdffffff048096980000000000160014dab37af8fefbbb31887a0a5f9b2698f4a7b45f6a80969800000000001976a91405a20074ef7eb42c7c6fcd4f499faa699742783288ac809698000000000017a914b808938a8007bc54509cd946944c479c0fa6554f87131b2c0400000000160014a04dfdb9a9aeac3b3fada6f43c2a66886186e2440247304402204f5dbb9dda65eab26179f1ca7c37c8baf028153815085dd1bbb2b826296e3b870220379fcd825742d6e2bdff772f347b629047824f289a5499a501033f6c3495594901210363c9c98740fe0455c646215cea9b13807b758791c8af7b74e62968bef57ff8ae1e391400')
|
||||
@@ -3783,7 +3783,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtu40n4p', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -3812,9 +3812,9 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_sending_offline_wif_online_addr_p2wpkh(self, mock_save_db):
|
||||
wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
|
||||
wallet_offline.import_private_key('p2wpkh:cPuQzcNEgbeYZ5at9VdGkCwkPA9r34gvEVJjuoz384rTfYpahfe7', password=None)
|
||||
wallet_offline.import_private_key('p2wpkh:emBW9C8dV4Jk9MoAzhwZUzTYN7NHPm2YqZGps5XYyiurAqv4fMeC', password=None)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('tb1qm2eh4787lwanrzr6pf0ekf5c7jnmghm2y9k529')
|
||||
wallet_online.import_address('tplm1qm2eh4787lwanrzr6pf0ekf5c7jnmghm2ndu0gl')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('01000000000101197a89cff51096b9dd4214cdee0eb90cb27a25477e739521d728a679724042730100000000fdffffff048096980000000000160014dab37af8fefbbb31887a0a5f9b2698f4a7b45f6a80969800000000001976a91405a20074ef7eb42c7c6fcd4f499faa699742783288ac809698000000000017a914b808938a8007bc54509cd946944c479c0fa6554f87131b2c0400000000160014a04dfdb9a9aeac3b3fada6f43c2a66886186e2440247304402204f5dbb9dda65eab26179f1ca7c37c8baf028153815085dd1bbb2b826296e3b870220379fcd825742d6e2bdff772f347b629047824f289a5499a501033f6c3495594901210363c9c98740fe0455c646215cea9b13807b758791c8af7b74e62968bef57ff8ae1e391400')
|
||||
@@ -3823,7 +3823,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtu40n4p', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -3850,13 +3850,13 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
async def test_signing_mixed_input_script_types(self, mock_save_db):
|
||||
"""Create a tx that spends mixed non-segwit and segwit UTXOs, and try to offline-sign that."""
|
||||
wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
|
||||
wallet_offline.import_private_key('p2pkh:cRd5PRVPgArr1eyrcGLKUAULM3EY3Zhseo5Xs8afkeA9UrtMdEFk', password=None)
|
||||
wallet_offline.import_private_key('p2wpkh-p2sh:cRoYFk7m2nKFxkhQNd81HTUdpK9qBvRHcVmMSzeiFyzyNB712srM', password=None)
|
||||
wallet_offline.import_private_key('p2wpkh:cTKEUyG8Q8t1GmBzy2jc9b9C6XPM5x2kE2xwapAAtkvKjdUXGgXA', password=None)
|
||||
wallet_offline.import_private_key('p2pkh:enuAY1FnUdX3bwC9TUecCwz8KzSyQG3WFs3cpQ8BcJDXzA8hwPLB', password=None)
|
||||
wallet_offline.import_private_key('p2wpkh-p2sh:eo5dQKt9qEyTZ2uhDqSJ2EzRoGNGYckvDZjSQGCE7e4MsUGPL43E', password=None)
|
||||
wallet_offline.import_private_key('p2wpkh:epbKdZ2XCbYCs3QHpF3ttNez5UbnSeNNq6w2Y5hgkQyiEvdYt6Fu', password=None)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('myfTqNq3cyxECtTR5uQukdZos7UfXa3vFU')
|
||||
wallet_online.import_address('2N9BwLxhmiWuRHyTtZk6L52jJEtkukfGTo2')
|
||||
wallet_online.import_address('tb1qkyrls8xvh8ynyrwly89kqu5y8yhf3znnx920t9')
|
||||
wallet_online.import_address('tR57b7beysNFHpgoUck1WdvPwBbkz99Hka')
|
||||
wallet_online.import_address('oYp5bAZSCuNT3sAsam7WnsgaG2tWD3KvFJ')
|
||||
wallet_online.import_address('tplm1qkyrls8xvh8ynyrwly89kqu5y8yhf3znn3dq5fl')
|
||||
|
||||
# bootstrap wallet_online (funding each address separately)
|
||||
funding_tx1 = Transaction('02000000000102a96b792a0872e5d669d503607beb823c99add690bb7c3df794d4b9539228fd8f0000000000fdffffff1306475c0380fe15237a5e800ff8adb415e32526cf284569619e43435e528bfd0000000000fdffffff02e878010000000000160014b32ed4fc9f845698d440cc2bb84a4c4443877309a0860100000000001976a914c70e40272d54659ce757b1a8b20091a26c2d404588ac02473044022048c4436152bf294fea37c89b2d9fca334ca56eb33147acd79a0f712e742edccc022058397bd3c91c8c82318c2dde32dce0c028e1f8d7dc77e394b867498b0195025c0121025635408bbafc2e28981744b28d96beda9582cac0dc49262c7fb2d6d8259c60a10247304402205f50a5cfee40eae71b1a8ceaf7d27347155a50fd0173662a37f86a0884894cbd022040c2ae5eb75a9c23b28200f8be4de576d1ae71b0c1ed3a5f5691b460fb96b05f0121031a95e3afc00c3be5f9c170b1bd0192f5c673741fd641c12490d8b646dd85cb036dfa4800')
|
||||
@@ -3867,7 +3867,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx3, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1qjy38fmma9vj0tl4y9u3hj0lhj03p860c70ss06', "!")]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1qjy38fmma9vj0tl4y9u3hj0lhj03p860cf86tdq', "!")]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 4782701
|
||||
tx.version = 2
|
||||
@@ -3901,7 +3901,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
config=self.config
|
||||
)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('mg2jk6S5WGDhUPA8mLSxDLWpUoQnX1zzoG')
|
||||
wallet_online.import_address('t7SPVqCgs9diZKPXA3n3yLsQYsXsti7pTj')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('01000000000101197a89cff51096b9dd4214cdee0eb90cb27a25477e739521d728a679724042730100000000fdffffff048096980000000000160014dab37af8fefbbb31887a0a5f9b2698f4a7b45f6a80969800000000001976a91405a20074ef7eb42c7c6fcd4f499faa699742783288ac809698000000000017a914b808938a8007bc54509cd946944c479c0fa6554f87131b2c0400000000160014a04dfdb9a9aeac3b3fada6f43c2a66886186e2440247304402204f5dbb9dda65eab26179f1ca7c37c8baf028153815085dd1bbb2b826296e3b870220379fcd825742d6e2bdff772f347b629047824f289a5499a501033f6c3495594901210363c9c98740fe0455c646215cea9b13807b758791c8af7b74e62968bef57ff8ae1e391400')
|
||||
@@ -3910,7 +3910,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtu40n4p', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -3945,7 +3945,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
config=self.config
|
||||
)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('2NA2JbUVK7HGWUCK5RXSVNHrkgUYF8d9zV8')
|
||||
wallet_online.import_address('oZeSqgLybfjYE624SYTg68p2hcfqZBHnCz')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('01000000000101197a89cff51096b9dd4214cdee0eb90cb27a25477e739521d728a679724042730100000000fdffffff048096980000000000160014dab37af8fefbbb31887a0a5f9b2698f4a7b45f6a80969800000000001976a91405a20074ef7eb42c7c6fcd4f499faa699742783288ac809698000000000017a914b808938a8007bc54509cd946944c479c0fa6554f87131b2c0400000000160014a04dfdb9a9aeac3b3fada6f43c2a66886186e2440247304402204f5dbb9dda65eab26179f1ca7c37c8baf028153815085dd1bbb2b826296e3b870220379fcd825742d6e2bdff772f347b629047824f289a5499a501033f6c3495594901210363c9c98740fe0455c646215cea9b13807b758791c8af7b74e62968bef57ff8ae1e391400')
|
||||
@@ -3954,7 +3954,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtu40n4p', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -3986,7 +3986,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
config=self.config
|
||||
)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('tb1qm2eh4787lwanrzr6pf0ekf5c7jnmghm2y9k529')
|
||||
wallet_online.import_address('tplm1qm2eh4787lwanrzr6pf0ekf5c7jnmghm2ndu0gl')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('01000000000101197a89cff51096b9dd4214cdee0eb90cb27a25477e739521d728a679724042730100000000fdffffff048096980000000000160014dab37af8fefbbb31887a0a5f9b2698f4a7b45f6a80969800000000001976a91405a20074ef7eb42c7c6fcd4f499faa699742783288ac809698000000000017a914b808938a8007bc54509cd946944c479c0fa6554f87131b2c0400000000160014a04dfdb9a9aeac3b3fada6f43c2a66886186e2440247304402204f5dbb9dda65eab26179f1ca7c37c8baf028153815085dd1bbb2b826296e3b870220379fcd825742d6e2bdff772f347b629047824f289a5499a501033f6c3495594901210363c9c98740fe0455c646215cea9b13807b758791c8af7b74e62968bef57ff8ae1e391400')
|
||||
@@ -3995,7 +3995,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('tb1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtta9ghm', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('tplm1quk7ahlhr3qmjndy0uvu9y9hxfesrtahtu40n4p', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325340
|
||||
tx.version = 1
|
||||
@@ -4040,7 +4040,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
config=self.config
|
||||
)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('2N4z38eTKcWTZnfugCCfRyXtXWMLnn8HDfw')
|
||||
wallet_online.import_address('oUcBNrJz6tvbYZcfDDgchNqoXVUPEJ9khn')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('010000000001016207d958dc46508d706e4cd7d3bc46c5c2b02160e2578e5fad2efafc3927050301000000171600147a4fc8cdc1c2cf7abbcd88ef6d880e59269797acfdffffff02809698000000000017a91480c2353f6a7bc3c71e99e062655b19adb3dd2e48870d0916020000000017a914703f83ef20f3a52d908475dcad00c5144164d5a2870247304402203b1a5cb48cadeee14fa6c7bbf2bc581ca63104762ec5c37c703df778884cc5b702203233fa53a2a0bfbd85617c636e415da72214e359282cce409019319d031766c50121021112c01a48cc7ea13cba70493c6bffebb3e805df10ff4611d2bf559d26e25c04bf391400')
|
||||
@@ -4049,7 +4049,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2MuCQQHJNnrXzQzuqfUCfAwAjPqpyEHbgue', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oJpYeVA3HF12AtcpgVDqtn81QyxZetnfsX', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325503
|
||||
tx.version = 1
|
||||
@@ -4107,7 +4107,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
config=self.config
|
||||
)
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('2MsHQRm1pNi6VsmXYRxYMcCTdPu7Xa1RyFe')
|
||||
wallet_online.import_address('oGuYfxsUs6ZXdfEXSyZYL3QuR3F815FBgk')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('0100000000010118d494d28e5c3bf61566ca0313e22c3b561b888a317d689cc8b47b947adebd440000000017160014aec84704ea8508ddb94a3c6e53f0992d33a2a529fdffffff020f0925000000000017a91409f7aae0265787a02de22839d41e9c927768230287809698000000000017a91400698bd11c38f887f17c99846d9be96321fbf989870247304402206b906369f4075ebcfc149f7429dcfc34e11e1b7bbfc85d1185d5e9c324be0d3702203ce7fc12fd3131920fbcbb733250f05dbf7d03e18a4656232ee69d5c54dd46bd0121028a4b697a37f3f57f6e53f90db077fa9696095b277454fda839c211d640d48649c0391400')
|
||||
@@ -4116,7 +4116,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2N8CtJRwxb2GCaiWWdSHLZHHLoZy53CCyxf', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oXq2Ydod5QjELcDVeTJXH8Ecpi6fR4j4fn', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325504
|
||||
tx.version = 1
|
||||
@@ -4177,7 +4177,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
)
|
||||
# ^ third seed: hedgehog sunset update estate number jungle amount piano friend donate upper wool
|
||||
wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
|
||||
wallet_online.import_address('tb1q83p6eqxkuvq4eumcha46crpzg4nj84s9p0hnynkxg8nhvfzqcc7q4erju6')
|
||||
wallet_online.import_address('tplm1q83p6eqxkuvq4eumcha46crpzg4nj84s9p0hnynkxg8nhvfzqcc7qwhp4px')
|
||||
|
||||
# bootstrap wallet_online
|
||||
funding_tx = Transaction('0100000000010132352f6459e847e65e56aa05cbd7b9ee67be90b40d8f92f6f11e9bfaa11399c501000000171600142e5d579693b2a7679622935df94d9f3c84909b24fdffffff0280969800000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c83717d010000000017a91441b772909ad301b41b76f4a3c5058888a7fe6f9a8702483045022100de54689f74b8efcce7fdc91e40761084686003bcd56c886ee97e75a7e803526102204dea51ae5e7d01bd56a8c336c64841f7fe02a8b101fa892e13f2d079bb14e6bf012102024e2f73d632c49f4b821ccd3b6da66b155427b1e5b1c4688cefd5a4b4bfa404c1391400')
|
||||
@@ -4186,7 +4186,7 @@ class TestWalletOfflineSigning(ElectrumTestCase):
|
||||
wallet_online.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# create unsigned tx
|
||||
outputs = [PartialTxOutput.from_address_and_value('2MyoZVy8T1t94yLmyKu8DP1SmbWvnxbkwRA', 2500000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value('oPRhkAz7WGc6jEUxLv9Q6rQ3cf4PPnRJy2', 2500000)]
|
||||
tx = wallet_online.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), rbf=True)
|
||||
tx.locktime = 1325505
|
||||
tx.version = 1
|
||||
@@ -4410,23 +4410,23 @@ class TestWalletHistory_EvilGapLimit(ElectrumTestCase):
|
||||
# txn A is an external incoming txn paying to addr (3) and (15)
|
||||
# txn B is an external incoming txn paying to addr (4) and (25)
|
||||
# txn C is an internal transfer txn from addr (25) -- to -- (1) and (25)
|
||||
w.adb.receive_history_callback('tb1qgh5c088he4d559wl0hw27hrdeg8p2z96pefn4q', # HD index 1
|
||||
w.adb.receive_history_callback('tplm1qgh5c088he4d559wl0hw27hrdeg8p2z96k3rgh6', # HD index 1
|
||||
[('268fce617aaaa4847835c2212b984d7b7741fdab65de22813288341819bc5656', 1316917)],
|
||||
{})
|
||||
w.synchronize()
|
||||
w.adb.receive_history_callback('tb1qm0ejr6g964zt2jux5te7m9ds43n28hdsdz9ull', # HD index 3
|
||||
w.adb.receive_history_callback('tplm1qm0ejr6g964zt2jux5te7m9ds43n28hds6208a9', # HD index 3
|
||||
[('511a35e240f4c8855de4c548dad932d03611a37e94e9203fdb6fc79911fe1dd4', 1316912)],
|
||||
{})
|
||||
w.synchronize()
|
||||
w.adb.receive_history_callback('tb1qj4pnq958k89zcem3342lhcgyz0rnmhkzl6x0cl', # HD index 4
|
||||
w.adb.receive_history_callback('tplm1qj4pnq958k89zcem3342lhcgyz0rnmhkzgjv569', # HD index 4
|
||||
[('fde0b68938709c4979827caa576e9455ded148537fdb798fd05680da64dc1b4f', 1316917)],
|
||||
{})
|
||||
w.synchronize()
|
||||
w.adb.receive_history_callback('tb1q3pyjwpm8wxgvquak240mprfhaydmkawcsl25je', # HD index 15
|
||||
w.adb.receive_history_callback('tplm1q3pyjwpm8wxgvquak240mprfhaydmkawc8hq0sr', # HD index 15
|
||||
[('511a35e240f4c8855de4c548dad932d03611a37e94e9203fdb6fc79911fe1dd4', 1316912)],
|
||||
{})
|
||||
w.synchronize()
|
||||
w.adb.receive_history_callback('tb1qr0qjp99ygawul0eylxfqmt7alygye22mj33vej', # HD index 25
|
||||
w.adb.receive_history_callback('tplm1qr0qjp99ygawul0eylxfqmt7alygye22m9emhmg', # HD index 25
|
||||
[('fde0b68938709c4979827caa576e9455ded148537fdb798fd05680da64dc1b4f', 1316917),
|
||||
('268fce617aaaa4847835c2212b984d7b7741fdab65de22813288341819bc5656', 1316917)],
|
||||
{})
|
||||
@@ -4511,7 +4511,7 @@ class TestWalletHistory_HelperFns(ElectrumTestCase):
|
||||
wallet1.adb.receive_tx_callback(funding_tx, tx_height=TX_HEIGHT_UNCONFIRMED)
|
||||
|
||||
# wallet1 -> wallet2
|
||||
outputs = [PartialTxOutput.from_address_and_value("2MuUcGmQ2mLN3vjTuqDSgZpk4LPKDsuPmhN", 165000)]
|
||||
outputs = [PartialTxOutput.from_address_and_value("oK6kWyFhFiq5gdAtrETsHfhLMXSpMuWRZd", 165000)]
|
||||
tx = wallet1.make_unsigned_transaction(outputs=outputs, fee_policy=FixedFeePolicy(5000), tx_version=1, rbf=False)
|
||||
self.assertEqual(
|
||||
"wsh(sortedmulti(2,[b2e35a7d/1h]tpubD9aPYLPPYw8MxU3cD57LwpV5v7GomHxdv62MSbPcRkp47zwXx69ACUFsKrj8xzuzRrij9FWVhfvkvNqtqsr8ZtefkDsGZ9GLuHzoS6bXyk1/0/0,[53b77ddb/1h]tpubD8spLJysN7v7V1KHvkZ7AwjnXShKafopi7Vu3Ahs2S46FxBPTode8DgGxDo55k4pJvETGScZFwnM5f2Y31EUjteJdhxR73sjr9ieydgah2U/0/0,[43067d63/1h]tpubD8khd1g1tzFeKeaU59QV811hyvhwn9KDfy5sqFJ5m2wJLw6rUt4AZviqutRPXTUAK4SpU2we3y2WBP916Ma8Em4qFGcbYkFvXVfpGYV3oZR/0/0))",
|
||||
@@ -4569,7 +4569,7 @@ class TestImportedWallet(ElectrumTestCase):
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
async def test_importing_and_deleting_addresses(self, mock_save_db):
|
||||
w = restore_wallet_from_text__for_unittest(
|
||||
"tb1q7648a2pm2se425lvun0g3vlf4ahmflcthegz63",
|
||||
"tplm1q7648a2pm2se425lvun0g3vlf4ahmflctq3zect",
|
||||
path='if_this_exists_mocking_failed_648151893',
|
||||
config=self.config)['wallet'] # type: Abstract_Wallet
|
||||
self.assertEqual(1, len(w.get_addresses()))
|
||||
@@ -4579,7 +4579,7 @@ class TestImportedWallet(ElectrumTestCase):
|
||||
|
||||
with self.assertRaises(UnrelatedTransactionException):
|
||||
w.adb.add_transaction(Transaction(self.transactions["314385a9f24457098de9fe5cb3893cc408b9f66085268457b82050c988c97908"]))
|
||||
w.import_address("tb1qsyzgpwa0vg2940u5t6l97etuvedr5dejpf9tdy")
|
||||
w.import_address("tplm1qsyzgpwa0vg2940u5t6l97etuvedr5dejkp0s07")
|
||||
self.assertEqual(2, len(w.get_addresses()))
|
||||
self.assertEqual(2, len(w.db.transactions))
|
||||
self.assertEqual(0, sum(w.get_balance()))
|
||||
@@ -4588,7 +4588,7 @@ class TestImportedWallet(ElectrumTestCase):
|
||||
self.assertEqual(3, len(w.db.transactions))
|
||||
self.assertEqual(0, sum(w.get_balance()))
|
||||
|
||||
w.delete_address("tb1q7648a2pm2se425lvun0g3vlf4ahmflcthegz63")
|
||||
w.delete_address("tplm1q7648a2pm2se425lvun0g3vlf4ahmflctq3zect")
|
||||
self.assertEqual(2, len(w.db.transactions))
|
||||
self.assertEqual(
|
||||
{"54de13f7ee4853dc1a281c0e7132efb95330f7ceebc1dbce76fdf34c28028f14", "314385a9f24457098de9fe5cb3893cc408b9f66085268457b82050c988c97908"},
|
||||
@@ -4596,5 +4596,5 @@ class TestImportedWallet(ElectrumTestCase):
|
||||
self.assertEqual(0, sum(w.get_balance()))
|
||||
|
||||
with self.assertRaises(UserFacingException) as ctx:
|
||||
w.delete_address("tb1qsyzgpwa0vg2940u5t6l97etuvedr5dejpf9tdy")
|
||||
w.delete_address("tplm1qsyzgpwa0vg2940u5t6l97etuvedr5dejkp0s07")
|
||||
self.assertTrue("Cannot delete last remaining address" in ctx.exception.args[0])
|
||||
|
||||
@@ -11,6 +11,7 @@ Welcome to the Pallectrum user guide. This document will help you understand and
|
||||
3. [Creating a New Wallet](#3-creating-a-new-wallet)
|
||||
4. [Backing Up Your Seed Phrase](#4-backing-up-your-seed-phrase)
|
||||
5. [Recovering a Wallet from Seed](#5-recovering-a-wallet-from-seed)
|
||||
6. [Troubleshooting](#6-troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
@@ -233,3 +234,45 @@ If you need to restore your wallet (new device, lost wallet file, etc.), you can
|
||||
- Verify the first receiving address matches your original wallet
|
||||
- Never enter your seed phrase on untrusted devices or websites
|
||||
- Use the official Pallectrum application from trusted sources only
|
||||
|
||||
---
|
||||
|
||||
## 6. Troubleshooting
|
||||
|
||||
### Cannot Connect to Server — SSL Certificate Error
|
||||
|
||||
#### Why this happens
|
||||
|
||||
When Pallectrum connects to an Electrum server for the first time, it downloads and saves the server's SSL/TLS certificate locally. On subsequent connections, it compares the stored certificate with the one the server presents. If they do not match, the connection is refused — this is a security mechanism to protect you against man-in-the-middle attacks.
|
||||
|
||||
This becomes a problem with **self-signed certificates**, which are common on personal or community-run servers. Unlike certificates issued by a trusted authority (CA), self-signed certificates are generated directly by the server administrator. They provide encryption, but they are not verified by any third party. When the administrator renews or replaces the certificate (for example, after it expires or following server maintenance), the new certificate no longer matches the one Pallectrum has stored locally, and the connection fails silently.
|
||||
|
||||
**In short:** Pallectrum remembers "this server uses this exact certificate." If the certificate changes — even legitimately — Pallectrum refuses to reconnect until the old cached certificate is deleted.
|
||||
|
||||
#### Symptoms
|
||||
|
||||
- The wallet stays disconnected after selecting a personal or custom server
|
||||
- The status bar shows no connection even though the server is online
|
||||
- The problem started after a server update or maintenance window
|
||||
|
||||
#### Solution
|
||||
|
||||
Delete the locally cached certificate so that Pallectrum can fetch and store the new one on the next connection attempt.
|
||||
|
||||
**On Android / QML interface:**
|
||||
|
||||
1. Open the app and go to **Network** (bottom navigation bar)
|
||||
2. Tap **Server Settings**
|
||||
3. Tap the reset icon (🗑) next to the server address field
|
||||
4. Select **SSL certificates**
|
||||
5. Confirm when prompted
|
||||
6. The app will reconnect automatically and store the new certificate
|
||||
|
||||
**On Desktop (Windows / Linux):**
|
||||
|
||||
1. Open the **Tools** menu → **Network**
|
||||
2. Go to the **Server** tab
|
||||
3. Click **Reset SSL certificates**
|
||||
4. Confirm when prompted
|
||||
|
||||
After resetting, Pallectrum will reconnect to the server and cache the new certificate. If the connection still fails, verify that the server address is correct and that the server is online.
|
||||
|
||||
Reference in New Issue
Block a user