support THORChain address generation
Example:
$ mmgen-addrgen --coin=rune 1-10
Testing:
$ test/tooltest2.py -q --coin=rune
$ test/modtest.py -v bip_hd.multicoin
This commit is contained in:
parent
427834255e
commit
ba3b40c5b6
14 changed files with 135 additions and 5 deletions
|
|
@ -50,6 +50,7 @@ class MMGenAddrType(HiliteStr, InitErrors, MMGenObject):
|
|||
'C': ati('compressed','std', True, 'p2pkh', 'p2pkh', 'wif', (), 'Compressed P2PKH address'),
|
||||
'S': ati('segwit', 'std', True, 'segwit', 'p2sh', 'wif', (), 'Segwit P2SH-P2WPKH address'),
|
||||
'B': ati('bech32', 'std', True, 'bech32', 'bech32', 'wif', (), 'Native Segwit (Bech32) address'),
|
||||
'X': ati('bech32x', 'std', True, 'p2pkh', 'bech32', 'wif', (), 'Cross-chain Bech32 address'),
|
||||
'E': ati('ethereum', 'std', False,'ethereum','p2pkh', 'privkey', ('wallet_passwd',),'Ethereum address'),
|
||||
'Z': ati('zcash_z','zcash_z',False,'zcash_z', 'zcash_z', 'wif', ('viewkey',), 'Zcash z-address'),
|
||||
'M': ati('monero', 'monero', False,'monero', 'monero', 'spendkey',('viewkey','wallet_passwd'),'Monero address'),
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ def AddrGenerator(cfg, proto, addr_type):
|
|||
'compressed': 'btc',
|
||||
'segwit': 'btc',
|
||||
'bech32': 'btc',
|
||||
'bech32x': 'xchain',
|
||||
'monero': 'xmr',
|
||||
'ethereum': 'eth',
|
||||
'zcash_z': 'zec',
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ def check_privkey(key_int):
|
|||
|
||||
class BipHDConfig(Lockable):
|
||||
|
||||
supported_coins = ('btc', 'eth', 'doge', 'ltc', 'bch')
|
||||
supported_coins = ('btc', 'eth', 'doge', 'ltc', 'bch', 'rune')
|
||||
|
||||
def __init__(self, base_cfg, coin, *, network, addr_type, from_path, no_path_checks):
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ def parse_data():
|
|||
|
||||
return out
|
||||
|
||||
# RUNE derivation is SLIP-10, not BIP-44, but we treat them as equivalent
|
||||
|
||||
_data_in = """
|
||||
|
||||
[defaults]
|
||||
|
|
@ -105,6 +107,7 @@ IDX CHAIN CURVE NW ADDR_CLS VB_PRV VB_PUB VB_WIF VB_ADDR DFL_PA
|
|||
784 SUI edw m Sui x x - - 0'/0'/0' Sui
|
||||
818 VET x m Eth x x - - x VeChain Token
|
||||
888 NEO nist m Neo x x - spec x NEO
|
||||
931 RUNE x m BechP2PKH x x - h:thor x THORChain
|
||||
996 OKT x m Okex x x - - x OKChain Token
|
||||
1023 ONE x m One x x - - x HARMONY-ONE (Legacy)
|
||||
1024 ONT nist m Neo x x - spec x Ontology
|
||||
|
|
@ -896,7 +899,6 @@ IDX CHAIN NAME
|
|||
921 AVN - Avian Network
|
||||
925 DIP - Dipper Network
|
||||
928 GHM - HermitMatrixNetwork
|
||||
931 RUNE - THORChain (RUNE)
|
||||
941 --- - reserved
|
||||
945 UNLOCK - Jasiri protocol
|
||||
955 LTP - LifetionCoin
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
15.1.dev37
|
||||
15.1.dev38
|
||||
|
|
|
|||
63
mmgen/proto/rune/params.py
Executable file
63
mmgen/proto/rune/params.py
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# MMGen Wallet, a terminal-based cryptocurrency wallet
|
||||
# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
|
||||
# Licensed under the GNU General Public License, Version 3:
|
||||
# https://www.gnu.org/licenses
|
||||
# Public project repositories:
|
||||
# https://github.com/mmgen/mmgen-wallet
|
||||
# https://gitlab.com/mmgen/mmgen-wallet
|
||||
|
||||
"""
|
||||
proto.rune.params: THORChain protocol
|
||||
"""
|
||||
|
||||
from ...protocol import CoinProtocol, decoded_addr, _nw
|
||||
from ...addr import CoinAddr
|
||||
from ...contrib import bech32
|
||||
|
||||
from ..btc.params import mainnet as btc_mainnet
|
||||
|
||||
class mainnet(CoinProtocol.Secp256k1):
|
||||
mod_clsname = 'THORChain'
|
||||
network_names = _nw('mainnet', 'stagenet', 'testnet')
|
||||
mmtypes = ('X',)
|
||||
preferred_mmtypes = ('X',)
|
||||
dfl_mmtype = 'X'
|
||||
coin_amt = 'UniAmt'
|
||||
max_tx_fee = 1 # TODO
|
||||
caps = ()
|
||||
mmcaps = ()
|
||||
base_proto = 'THORChain'
|
||||
base_proto_coin = 'RUNE'
|
||||
base_coin = 'RUNE'
|
||||
bech32_hrp = 'thor'
|
||||
sign_mode = 'standalone'
|
||||
avg_bdi = 6 # TODO
|
||||
address_reuse_ok = False
|
||||
|
||||
wif_ver_num = btc_mainnet.wif_ver_num
|
||||
coin_cfg_opts = btc_mainnet.coin_cfg_opts
|
||||
encode_wif = btc_mainnet.encode_wif
|
||||
decode_wif = btc_mainnet.decode_wif
|
||||
|
||||
def decode_addr(self, addr):
|
||||
hrp, data = bech32.bech32_decode(addr)
|
||||
assert hrp == self.bech32_hrp, f'{hrp!r}: invalid bech32 hrp (should be {self.bech32_hrp!r})'
|
||||
return decoded_addr(
|
||||
bytes(bech32.convertbits(data, 5, 8)),
|
||||
None,
|
||||
'bech32') if data else False
|
||||
|
||||
def encode_addr_bech32x(self, pubhash):
|
||||
return CoinAddr(
|
||||
self,
|
||||
bech32.bech32_encode(
|
||||
hrp = self.bech32_hrp,
|
||||
data = bech32.convertbits(list(pubhash), 8, 5)))
|
||||
|
||||
class stagenet(mainnet):
|
||||
bech32_hrp = 'sthor'
|
||||
|
||||
class testnet(stagenet): # testnet is deprecated
|
||||
bech32_hrp = 'tthor'
|
||||
22
mmgen/proto/xchain/addrgen.py
Executable file
22
mmgen/proto/xchain/addrgen.py
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# MMGen Wallet, a terminal-based cryptocurrency wallet
|
||||
# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
|
||||
# Licensed under the GNU General Public License, Version 3:
|
||||
# https://www.gnu.org/licenses
|
||||
# Public project repositories:
|
||||
# https://github.com/mmgen/mmgen-wallet
|
||||
# https://gitlab.com/mmgen/mmgen-wallet
|
||||
|
||||
"""
|
||||
proto.xchain.addrgen: Cross-chain address generation classes for the MMGen suite
|
||||
"""
|
||||
|
||||
from ...addrgen import addr_generator, check_data
|
||||
from ..btc.common import hash160
|
||||
|
||||
class bech32x(addr_generator.base):
|
||||
|
||||
@check_data
|
||||
def to_addr(self, data):
|
||||
return self.proto.encode_addr_bech32x(hash160(data.pubkey))
|
||||
|
|
@ -46,7 +46,8 @@ class CoinProtocol(MMGenObject):
|
|||
'eth': proto_info('Ethereum', 4),
|
||||
'etc': proto_info('EthereumClassic', 4),
|
||||
'zec': proto_info('Zcash', 2),
|
||||
'xmr': proto_info('Monero', 4)
|
||||
'xmr': proto_info('Monero', 4),
|
||||
'rune': proto_info('THORChain', 2)
|
||||
}
|
||||
|
||||
class Base(Lockable):
|
||||
|
|
|
|||
|
|
@ -165,6 +165,8 @@ class tool_cmd(tool_cmd_base):
|
|||
return self.proto.pubhash2segwitaddr(pubhash)
|
||||
elif self.mmtype.name == 'bech32':
|
||||
return self.proto.pubhash2bech32addr(pubhash)
|
||||
elif self.mmtype.name == 'bech32x':
|
||||
return self.proto.encode_addr_bech32x(pubhash)
|
||||
else:
|
||||
return self.proto.pubhash2addr(pubhash, self.mmtype.addr_fmt)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ packages =
|
|||
mmgen.proto.eth.tx
|
||||
mmgen.proto.eth.tw
|
||||
mmgen.proto.ltc
|
||||
mmgen.proto.rune
|
||||
mmgen.proto.secp256k1
|
||||
mmgen.proto.xchain
|
||||
mmgen.proto.xmr
|
||||
mmgen.proto.zec
|
||||
mmgen.swap
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ vectors_multicoin = {
|
|||
'bch_compressed': 'bitcoincash:qpqpcllprftg4s0chdgkpxhxv23wfymq3gj7n0a9vw',
|
||||
'bsc_smart': '0x373731f4d885Fc7Da05498F9f0804a87A14F891b',
|
||||
'bnb_beacon': 'bnb179c3ymltqm4utlp089zxqeta5dvn48a305rhe5',
|
||||
'rune': 'thor1nr6fye3nznyn20m5w6fey6w8a8l4q599cdqmpc',
|
||||
}
|
||||
|
||||
def wif2addr(cfg, wif):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
# MMGen address file
|
||||
#
|
||||
# This file is editable.
|
||||
# Everything following a hash symbol '#' is a comment and ignored by MMGen.
|
||||
# A text label of 80 screen cells or less may be added to the right of each
|
||||
# address, and it will be appended to the tracking wallet label upon import.
|
||||
# The label may contain any printable ASCII symbol.
|
||||
#
|
||||
# Address data checksum for 98831F3A-RUNE-X[1,31-33,500-501,1010-1011]: 00C6 1930 557F 5E99
|
||||
# Record this value to a secure location.
|
||||
98831F3A RUNE:BECH32X {
|
||||
1 thor137aqwpky5muxw7rvrdy6kxegt838k04xp4rnge
|
||||
31 thor1w758u285uqv5h3wuksylvxtahql9tjsdllurug
|
||||
32 thor18srpqhu8q8ppp4zc3zje3yp5lf3jpmq8hu4phh
|
||||
33 thor16hgd6g3cutx8dhslvdgxljss4w7prq32u9x20y
|
||||
500 thor14q7m5jyajjnlqgccu3vh2dx0m2323558faxlz6
|
||||
501 thor1gyaexk8l3rvt7vsfd693y33ate989r64ak65gk
|
||||
1010 thor1g95knu2elqt8l0d5vcyf0hyuspn4mhsjrym8g9
|
||||
1011 thor12f6lgkjy7amxdz7eznv33xypvzux9kxslkqvzq
|
||||
}
|
||||
|
|
@ -299,9 +299,10 @@ init_tests() {
|
|||
e $tooltest2_py --coin=eth --token=mm1
|
||||
e $tooltest2_py --coin=eth --token=mm1 --testnet=1
|
||||
e $tooltest2_py --coin=etc
|
||||
t $tooltest2_py --coin=rune
|
||||
- $tooltest2_py --fork # run once with --fork so commands are actually executed
|
||||
"
|
||||
[ "$SKIP_ALT_DEP" ] && t_tool2_skip='a e' # skip ETH,ETC: txview requires py_ecc
|
||||
[ "$SKIP_ALT_DEP" ] && t_tool2_skip='a e t' # skip ETH,ETC: txview requires py_ecc
|
||||
|
||||
d_tool="'mmgen-tool' utility (all supported coins)"
|
||||
t_tool="
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ eth_pubhex2 = '9166c289b9f905e55f9e3df9f69d7f356b4a22095f894f4715714aa4b56606aff
|
|||
xmr_pubhex1 = '1ed49357e217e79dab3c5503822f2bdb561e302e24476ee6ff33242c7551d4e78944790c0cfa9998c2f196061be89b2b8387f9d397db20ea8e049899cdc947d1'
|
||||
zec_pubhex1 = 'e6a4edbff547f21bcc2a825b6cf70f06e266a452d2da9d6dc5c1da3d99d7e996f488704dcdfe8d92cafe47772b3f692a98d59de1e99e00ff815f64ae59910f0c'
|
||||
|
||||
rune_addr1 = 'thor1xptlvmwaymaxa7pxkr2u5pn7c0508stcr9tw2z'
|
||||
|
||||
tests = {
|
||||
'Mnemonic': {
|
||||
'hex2mn': (
|
||||
|
|
@ -407,6 +409,9 @@ tests = {
|
|||
([btc_addr5], pubhash1),
|
||||
([btc_addr6], pubhash2),
|
||||
],
|
||||
'rune_mainnet': [
|
||||
([rune_addr1], pubhash2),
|
||||
],
|
||||
},
|
||||
'eth_checksummed_addr': {
|
||||
'eth_mainnet': [
|
||||
|
|
@ -423,6 +428,9 @@ tests = {
|
|||
['--type=segwit'], 'segwit'),
|
||||
([pubhash2], btc_addr6, ['--type=bech32'], 'bech32'),
|
||||
],
|
||||
'rune_mainnet': [
|
||||
([pubhash2], rune_addr1, ['--type=X'], 'bech32x'),
|
||||
],
|
||||
},
|
||||
'addr2scriptpubkey': {
|
||||
'btc_mainnet': [
|
||||
|
|
@ -665,6 +673,12 @@ tests = {
|
|||
'E97A D796 B495 E8BC'
|
||||
),
|
||||
],
|
||||
'rune_mainnet': [
|
||||
(
|
||||
['test/ref/thorchain/98831F3A-RUNE-X[1,31-33,500-501,1010-1011].addrs'],
|
||||
'00C6 1930 557F 5E99'
|
||||
),
|
||||
],
|
||||
},
|
||||
'viewkeyaddrfile_chksum': {
|
||||
'xmr_mainnet': [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue