From 639cd94dcb418f1668aaa4e25dedbdce108d21ca Mon Sep 17 00:00:00 2001 From: wakiyamap Date: Sun, 2 May 2021 05:54:58 +0900 Subject: [PATCH 1/2] add signet support --- electrum/commands.py | 1 + electrum/constants.py | 18 +++++++++++++++++- electrum/gui/qt/main_window.py | 4 +++- electrum/lnaddr.py | 6 ++++++ electrum/servers_signet.json | 14 ++++++++++++++ electrum/simple_config.py | 3 +++ electrum/trampoline.py | 10 ++++++++-- electrum/util.py | 19 ++++++++++++++++++- run_electrum | 2 ++ 9 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 electrum/servers_signet.json diff --git a/electrum/commands.py b/electrum/commands.py index 3159f4ed5..b17bb540b 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -1400,6 +1400,7 @@ def add_global_options(parser): group.add_argument("--testnet", action="store_true", dest="testnet", default=False, help="Use Testnet") group.add_argument("--regtest", action="store_true", dest="regtest", default=False, help="Use Regtest") group.add_argument("--simnet", action="store_true", dest="simnet", default=False, help="Use Simnet") + group.add_argument("--signet", action="store_true", dest="signet", default=False, help="Use Signet") group.add_argument("-o", "--offline", action="store_true", dest="offline", default=False, help="Run offline") def add_wallet_option(parser): diff --git a/electrum/constants.py b/electrum/constants.py index 6e5f7435e..b31654e1b 100644 --- a/electrum/constants.py +++ b/electrum/constants.py @@ -60,6 +60,7 @@ class AbstractNet: class BitcoinMainnet(AbstractNet): + NET_NAME = "mainnet" TESTNET = False WIF_PREFIX = 0x80 ADDRTYPE_P2PKH = 0 @@ -98,6 +99,7 @@ class BitcoinMainnet(AbstractNet): class BitcoinTestnet(AbstractNet): + NET_NAME = "testnet" TESTNET = True WIF_PREFIX = 0xef ADDRTYPE_P2PKH = 111 @@ -134,6 +136,7 @@ class BitcoinTestnet(AbstractNet): class BitcoinRegtest(BitcoinTestnet): + NET_NAME = "regtest" SEGWIT_HRP = "bcrt" GENESIS = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206" DEFAULT_SERVERS = read_json('servers_regtest.json', {}) @@ -143,6 +146,7 @@ class BitcoinRegtest(BitcoinTestnet): class BitcoinSimnet(BitcoinTestnet): + NET_NAME = "simnet" WIF_PREFIX = 0x64 ADDRTYPE_P2PKH = 0x3f ADDRTYPE_P2SH = 0x7b @@ -153,9 +157,22 @@ class BitcoinSimnet(BitcoinTestnet): LN_DNS_SEEDS = [] +class BitcoinSignet(BitcoinTestnet): + + NET_NAME = "signet" + GENESIS = "00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6" + DEFAULT_SERVERS = read_json('servers_signet.json', {}) + CHECKPOINTS = [] + LN_DNS_SEEDS = [] + + # don't import net directly, import the module instead (so that net is singleton) net = BitcoinMainnet +def set_signet(): + global net + net = BitcoinSignet + def set_simnet(): global net net = BitcoinSimnet @@ -168,7 +185,6 @@ def set_testnet(): global net net = BitcoinTestnet - def set_regtest(): global net net = BitcoinRegtest diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index 7a607caab..ac39a4884 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -540,7 +540,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): self.setGeometry(100, 100, 840, 400) def watching_only_changed(self): - name = "Electrum Testnet" if constants.net.TESTNET else "Electrum" + name = "Electrum" + if constants.net.TESTNET: + name += " " + constants.net.NET_NAME.capitalize() title = '%s %s - %s' % (name, ELECTRUM_VERSION, self.wallet.basename()) extra = [self.wallet.db.get('wallet_type', '?')] diff --git a/electrum/lnaddr.py b/electrum/lnaddr.py index 3d2549b63..b9c944122 100644 --- a/electrum/lnaddr.py +++ b/electrum/lnaddr.py @@ -178,6 +178,9 @@ def pull_tagged(stream): return (CHARSET[tag], stream.read(length * 5), stream) def lnencode(addr: 'LnAddr', privkey) -> str: + # see https://github.com/lightningnetwork/lightning-rfc/pull/844 + if constants.net.NET_NAME == "signet": + addr.currency += "s" if addr.amount: amount = addr.currency + shorten_amount(addr.amount) else: @@ -366,6 +369,9 @@ class SerializableKey: def lndecode(invoice: str, *, verbose=False, expected_hrp=None) -> LnAddr: if expected_hrp is None: expected_hrp = constants.net.SEGWIT_HRP + # see https://github.com/lightningnetwork/lightning-rfc/pull/844 + if constants.net.NET_NAME == "signet": + expected_hrp += "s" decoded_bech32 = bech32_decode(invoice, ignore_long_length=True) hrp = decoded_bech32.hrp data = decoded_bech32.data diff --git a/electrum/servers_signet.json b/electrum/servers_signet.json new file mode 100644 index 000000000..134e2682a --- /dev/null +++ b/electrum/servers_signet.json @@ -0,0 +1,14 @@ +{ + "127.0.0.1": { + "pruning": "-", + "s": "51002", + "t": "51001", + "version": "1.2" + }, + "signet-electrumx.wakiyamap.dev": { + "pruning": "-", + "s": "50002", + "t": "50001", + "version": "1.4" + } +} diff --git a/electrum/simple_config.py b/electrum/simple_config.py index 3ab248da7..96e313096 100644 --- a/electrum/simple_config.py +++ b/electrum/simple_config.py @@ -128,6 +128,9 @@ class SimpleConfig(Logger): elif self.get('simnet'): path = os.path.join(path, 'simnet') make_dir(path, allow_symlink=False) + elif self.get('signet'): + path = os.path.join(path, 'signet') + make_dir(path, allow_symlink=False) self.logger.info(f"electrum directory {path}") return path diff --git a/electrum/trampoline.py b/electrum/trampoline.py index 07eed3ce8..f49f6fbda 100644 --- a/electrum/trampoline.py +++ b/electrum/trampoline.py @@ -63,11 +63,17 @@ TRAMPOLINE_NODES_TESTNET = { 'endurance': LNPeerAddr(host='34.250.234.192', port=9735, pubkey=bytes.fromhex('03933884aaf1d6b108397e5efe5c86bcf2d8ca8d2f700eda99db9214fc2712b134')), } +TRAMPOLINE_NODES_SIGNET = { + 'wakiyamap.dev': LNPeerAddr(host='signet-electrumx.wakiyamap.dev', port=9735, pubkey=bytes.fromhex('02dadf6c28f3284d591cd2a4189d1530c1ff82c07059ebea150a33ab76e7364b4a')), +} + def hardcoded_trampoline_nodes(): - if constants.net in (constants.BitcoinMainnet,): + if constants.net.NET_NAME == "mainnet": return TRAMPOLINE_NODES_MAINNET - if constants.net in (constants.BitcoinTestnet,): + if constants.net.NET_NAME == "testnet": return TRAMPOLINE_NODES_TESTNET + if constants.net.NET_NAME == "signet": + return TRAMPOLINE_NODES_SIGNET return {} def trampolines_by_id(): diff --git a/electrum/util.py b/electrum/util.py index 8fb9ca0d6..263b1003c 100644 --- a/electrum/util.py +++ b/electrum/util.py @@ -804,12 +804,29 @@ testnet_block_explorers = { {'tx': 'tx/', 'addr': 'address/'}), } +signet_block_explorers = { + 'bc-2.jp': ('https://explorer.bc-2.jp/', + {'tx': 'tx/', 'addr': 'address/'}), + 'mempool.space': ('https://mempool.space/signet/', + {'tx': 'tx/', 'addr': 'address/'}), + 'bitcoinexplorer.org': ('https://signet.bitcoinexplorer.org/', + {'tx': 'tx/', 'addr': 'address/'}), + 'wakiyamap.dev': ('https://signet-explorer.wakiyamap.dev/', + {'tx': 'tx/', 'addr': 'address/'}), + 'system default': ('blockchain:/', + {'tx': 'tx/', 'addr': 'address/'}), +} + _block_explorer_default_api_loc = {'tx': 'tx/', 'addr': 'address/'} def block_explorer_info(): from . import constants - return mainnet_block_explorers if not constants.net.TESTNET else testnet_block_explorers + if constants.net.NET_NAME == "testnet": + return testnet_block_explorers + elif constants.net.NET_NAME == "signet": + return signet_block_explorers + return mainnet_block_explorers def block_explorer(config: 'SimpleConfig') -> Optional[str]: diff --git a/run_electrum b/run_electrum index c44650a3a..a00c7a1f6 100755 --- a/run_electrum +++ b/run_electrum @@ -366,6 +366,8 @@ def main(): constants.set_regtest() elif config.get('simnet'): constants.set_simnet() + elif config.get('signet'): + constants.set_signet() cmdname = config.get('cmd') From 9f4d7ec6d1ef26094d0e9683f3088cf929dd0850 Mon Sep 17 00:00:00 2001 From: wakiyamap Date: Sat, 8 May 2021 11:53:58 +0900 Subject: [PATCH 2/2] Add net.BOLT11_HRP --- electrum/constants.py | 5 +++++ electrum/lnaddr.py | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/electrum/constants.py b/electrum/constants.py index b31654e1b..0ea93d319 100644 --- a/electrum/constants.py +++ b/electrum/constants.py @@ -66,6 +66,7 @@ class BitcoinMainnet(AbstractNet): ADDRTYPE_P2PKH = 0 ADDRTYPE_P2SH = 5 SEGWIT_HRP = "bc" + BOLT11_HRP = SEGWIT_HRP GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" DEFAULT_PORTS = {'t': '50001', 's': '50002'} DEFAULT_SERVERS = read_json('servers.json', {}) @@ -105,6 +106,7 @@ class BitcoinTestnet(AbstractNet): ADDRTYPE_P2PKH = 111 ADDRTYPE_P2SH = 196 SEGWIT_HRP = "tb" + BOLT11_HRP = SEGWIT_HRP GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943" DEFAULT_PORTS = {'t': '51001', 's': '51002'} DEFAULT_SERVERS = read_json('servers_testnet.json', {}) @@ -138,6 +140,7 @@ class BitcoinRegtest(BitcoinTestnet): NET_NAME = "regtest" SEGWIT_HRP = "bcrt" + BOLT11_HRP = SEGWIT_HRP GENESIS = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206" DEFAULT_SERVERS = read_json('servers_regtest.json', {}) CHECKPOINTS = [] @@ -151,6 +154,7 @@ class BitcoinSimnet(BitcoinTestnet): ADDRTYPE_P2PKH = 0x3f ADDRTYPE_P2SH = 0x7b SEGWIT_HRP = "sb" + BOLT11_HRP = SEGWIT_HRP GENESIS = "683e86bd5c6d110d91b94b97137ba6bfe02dbbdb8e3dff722a669b5d69d77af6" DEFAULT_SERVERS = read_json('servers_regtest.json', {}) CHECKPOINTS = [] @@ -160,6 +164,7 @@ class BitcoinSimnet(BitcoinTestnet): class BitcoinSignet(BitcoinTestnet): NET_NAME = "signet" + BOLT11_HRP = "tbs" GENESIS = "00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6" DEFAULT_SERVERS = read_json('servers_signet.json', {}) CHECKPOINTS = [] diff --git a/electrum/lnaddr.py b/electrum/lnaddr.py index b9c944122..b6a797e9c 100644 --- a/electrum/lnaddr.py +++ b/electrum/lnaddr.py @@ -180,7 +180,7 @@ def pull_tagged(stream): def lnencode(addr: 'LnAddr', privkey) -> str: # see https://github.com/lightningnetwork/lightning-rfc/pull/844 if constants.net.NET_NAME == "signet": - addr.currency += "s" + addr.currency = constants.net.BOLT11_HRP if addr.amount: amount = addr.currency + shorten_amount(addr.amount) else: @@ -371,7 +371,7 @@ def lndecode(invoice: str, *, verbose=False, expected_hrp=None) -> LnAddr: expected_hrp = constants.net.SEGWIT_HRP # see https://github.com/lightningnetwork/lightning-rfc/pull/844 if constants.net.NET_NAME == "signet": - expected_hrp += "s" + expected_hrp = constants.net.BOLT11_HRP decoded_bech32 = bech32_decode(invoice, ignore_long_length=True) hrp = decoded_bech32.hrp data = decoded_bech32.data