Skip to content

Commit 30330b8

Browse files
committed
Add support for DeSo
- New entries in cryptocurrencies.py; - New {public,private}_key_base58check fields.
1 parent 01aa683 commit 30330b8

File tree

5 files changed

+129
-1
lines changed

5 files changed

+129
-1
lines changed

docs/cryptocurrencies.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,13 @@ This library simplifies the process of generating a new HDWallet's for:
276276
- No
277277
- 116
278278
- m/44'/116'/0'/0/0
279+
* - `DeSo <https://github.com/deso-protocol>`_
280+
- DESO, DESOTEST
281+
- Yes
282+
- Yes
283+
- Yes
284+
- 0
285+
- m/44'/0'/0'/0/0
279286
* - Diamond
280287
- DMD
281288
- Yes

hdwallet/cryptocurrencies.py

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class Cryptocurrency(NestedNamespace):
6363
COIN_TYPE: CoinType
6464

6565
SCRIPT_ADDRESS: int
66-
PUBLIC_KEY_ADDRESS: int
66+
PUBLIC_KEY_ADDRESS: int = 0
67+
PRIVATE_KEY_ADDRESS: int = 0
6768
SEGWIT_ADDRESS: SegwitAddress
6869

6970
EXTENDED_PRIVATE_KEY: ExtendedPrivateKey
@@ -1674,6 +1675,88 @@ class DenariusMainnet(Cryptocurrency):
16741675
WIF_SECRET_KEY = 0x9e
16751676

16761677

1678+
class DeSoMainnet(Cryptocurrency):
1679+
1680+
NAME = "DeSo"
1681+
SYMBOL = "DESO"
1682+
NETWORK = "mainnet"
1683+
SOURCE_CODE = "https://github.com/deso-protocol"
1684+
COIN_TYPE = CoinType({
1685+
"INDEX": 0,
1686+
"HARDENED": True
1687+
})
1688+
1689+
SCRIPT_ADDRESS = 0x05
1690+
PUBLIC_KEY_ADDRESS = 0xCD1400
1691+
PRIVATE_KEY_ADDRESS = 0x350000
1692+
SEGWIT_ADDRESS = SegwitAddress({
1693+
"HRP": "bc",
1694+
"VERSION": 0x00
1695+
})
1696+
1697+
EXTENDED_PRIVATE_KEY = ExtendedPrivateKey({
1698+
"P2PKH": 0x0488ade4,
1699+
"P2SH": 0x0488ade4,
1700+
"P2WPKH": 0x04b2430c,
1701+
"P2WPKH_IN_P2SH": 0x049d7878,
1702+
"P2WSH": 0x02aa7a99,
1703+
"P2WSH_IN_P2SH": 0x0295b005
1704+
})
1705+
EXTENDED_PUBLIC_KEY = ExtendedPublicKey({
1706+
"P2PKH": 0x0488b21e,
1707+
"P2SH": 0x0488b21e,
1708+
"P2WPKH": 0x04b24746,
1709+
"P2WPKH_IN_P2SH": 0x049d7cb2,
1710+
"P2WSH": 0x02aa7ed3,
1711+
"P2WSH_IN_P2SH": 0x0295b43f
1712+
})
1713+
1714+
MESSAGE_PREFIX = "\x18DeSo Signed Message:\n"
1715+
DEFAULT_PATH = f"m/44'/{str(COIN_TYPE)}/0'/0/0"
1716+
WIF_SECRET_KEY = 0x80
1717+
1718+
1719+
class DeSoTestnet(Cryptocurrency):
1720+
1721+
NAME = "DeSo"
1722+
SYMBOL = "DESOTEST"
1723+
NETWORK = "testnet"
1724+
SOURCE_CODE = "https://github.com/deso-protocol"
1725+
COIN_TYPE = CoinType({
1726+
"INDEX": 0,
1727+
"HARDENED": True
1728+
})
1729+
1730+
SCRIPT_ADDRESS = 0x05
1731+
PUBLIC_KEY_ADDRESS = 0x11C200
1732+
PRIVATE_KEY_ADDRESS = 0x4F061B
1733+
SEGWIT_ADDRESS = SegwitAddress({
1734+
"HRP": "bc",
1735+
"VERSION": 0x00
1736+
})
1737+
1738+
EXTENDED_PRIVATE_KEY = ExtendedPrivateKey({
1739+
"P2PKH": 0x0488ade4,
1740+
"P2SH": 0x0488ade4,
1741+
"P2WPKH": 0x04b2430c,
1742+
"P2WPKH_IN_P2SH": 0x049d7878,
1743+
"P2WSH": 0x02aa7a99,
1744+
"P2WSH_IN_P2SH": 0x0295b005
1745+
})
1746+
EXTENDED_PUBLIC_KEY = ExtendedPublicKey({
1747+
"P2PKH": 0x0488b21e,
1748+
"P2SH": 0x0488b21e,
1749+
"P2WPKH": 0x04b24746,
1750+
"P2WPKH_IN_P2SH": 0x049d7cb2,
1751+
"P2WSH": 0x02aa7ed3,
1752+
"P2WSH_IN_P2SH": 0x0295b43f
1753+
})
1754+
1755+
MESSAGE_PREFIX = "\x18DeSo Signed Message:\n"
1756+
DEFAULT_PATH = f"m/44'/{str(COIN_TYPE)}/0'/0/0"
1757+
WIF_SECRET_KEY = 0x80
1758+
1759+
16771760
class DiamondMainnet(Cryptocurrency):
16781761

16791762
NAME = "Diamond"

hdwallet/hdwallet.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ def __init__(self, symbol: str = "BTC", cryptocurrency: Any = None,
112112
self._private_key: Optional[bytes] = None
113113
self._public_key: Optional[str] = None
114114
self._chain_code: Optional[bytes] = None
115+
116+
self._private_key_base58check: Optional[str] = None
117+
self._public_key_base58check: Optional[str] = None
118+
115119
self._depth: int = 0
116120
self._index: int = 0
117121

@@ -211,6 +215,8 @@ def from_seed(self, seed: str) -> "HDWallet":
211215
if self._use_default_path:
212216
self.from_path(path=self._cryptocurrency.DEFAULT_PATH)
213217
self._public_key = self.compressed()
218+
self._public_key_base58check = self.public_key_base58check()
219+
self._private_key_base58check = self.private_key_base58check()
214220
if self._from_class:
215221
self.from_path(path=self._path_class)
216222
return self
@@ -251,6 +257,8 @@ def from_root_xprivate_key(self, xprivate_key: str, strict: bool = True) -> "HDW
251257
if self._from_class:
252258
self.from_path(path=self._path_class)
253259
self._public_key = self.compressed()
260+
self._public_key_base58check = self.public_key_base58check()
261+
self._private_key_base58check = self.private_key_base58check()
254262
return self
255263

256264
def from_root_xpublic_key(self, xpublic_key: str, strict: bool = True) -> "HDWallet":
@@ -289,6 +297,7 @@ def from_root_xpublic_key(self, xpublic_key: str, strict: bool = True) -> "HDWal
289297
if self._from_class:
290298
self.from_path(path=self._path_class)
291299
self._public_key = self.compressed()
300+
self._public_key_base58check = self.public_key_base58check()
292301
return self
293302

294303
def from_xprivate_key(self, xprivate_key: str) -> "HDWallet":
@@ -317,6 +326,8 @@ def from_xprivate_key(self, xprivate_key: str) -> "HDWallet":
317326
self._key = ecdsa.SigningKey.from_string(_deserialize_xprivate_key[5], curve=SECP256k1)
318327
self._verified_key = self._key.get_verifying_key()
319328
self._public_key = self.compressed()
329+
self._public_key_base58check = self.public_key_base58check()
330+
self._private_key_base58check = self.private_key_base58check()
320331
return self
321332

322333
def from_xpublic_key(self, xpublic_key: str) -> "HDWallet":
@@ -346,6 +357,7 @@ def from_xpublic_key(self, xpublic_key: str) -> "HDWallet":
346357
_deserialize_xpublic_key[5], curve=SECP256k1
347358
)
348359
self._public_key = self.compressed()
360+
self._public_key_base58check = self.public_key_base58check()
349361
return self
350362

351363
def from_wif(self, wif: str) -> "HDWallet":
@@ -372,6 +384,8 @@ def from_wif(self, wif: str) -> "HDWallet":
372384
self._key = ecdsa.SigningKey.from_string(self._private_key, curve=SECP256k1)
373385
self._verified_key = self._key.get_verifying_key()
374386
self._public_key = self.compressed()
387+
self._public_key_base58check = self.public_key_base58check()
388+
self._private_key_base58check = self.private_key_base58check()
375389
return self
376390

377391
def from_private_key(self, private_key: str) -> "HDWallet":
@@ -394,6 +408,8 @@ def from_private_key(self, private_key: str) -> "HDWallet":
394408
self._key = ecdsa.SigningKey.from_string(self._private_key, curve=SECP256k1)
395409
self._verified_key = self._key.get_verifying_key()
396410
self._public_key = self.compressed()
411+
self._public_key_base58check = self.public_key_base58check()
412+
self._private_key_base58check = self.private_key_base58check()
397413
return self
398414

399415
def from_public_key(self, public_key: str) -> "HDWallet":
@@ -416,6 +432,7 @@ def from_public_key(self, public_key: str) -> "HDWallet":
416432
unhexlify(public_key), curve=SECP256k1
417433
)
418434
self._public_key = self.compressed()
435+
self._public_key_base58check = self.public_key_base58check()
419436
return self
420437

421438
def from_path(self, path: Union[str, Derivation]) -> "HDWallet":
@@ -521,6 +538,7 @@ def _derive_key_by_index(self, index) -> Optional["HDWallet"]:
521538
)
522539
self._key = ecdsa.SigningKey.from_string(self._private_key, curve=SECP256k1)
523540
self._verified_key = self._key.get_verifying_key()
541+
self._private_key_base58check = self.private_key_base58check()
524542
else:
525543
key_point = S256Point.parse(unhexlify(self.public_key()))
526544
left_point = il_int * G
@@ -730,6 +748,7 @@ def clean_derivation(self) -> "HDWallet":
730748
self._private_key, self._chain_code = self._root_private_key
731749
self._key = ecdsa.SigningKey.from_string(self._private_key, curve=SECP256k1)
732750
self._verified_key = self._key.get_verifying_key()
751+
self._private_key_base58check = self.private_key_base58check()
733752
elif self._root_public_key:
734753
self._path, self._depth, self._parent_fingerprint, self._index = (
735754
"m", 0, b"\0\0\0\0", 0
@@ -847,6 +866,18 @@ def public_key(self, compressed: bool = True, private_key: Optional[str] = None)
847866
return hexlify(ck).decode() if compressed else self.uncompressed(compressed=hexlify(ck).decode())
848867
return self.compressed() if compressed else self.uncompressed()
849868

869+
def public_key_base58check(self) -> str:
870+
return base58.b58encode_check(
871+
_unhexlify(self._cryptocurrency.PUBLIC_KEY_ADDRESS) +
872+
unhexlify(self.public_key())
873+
)
874+
875+
def private_key_base58check(self) -> str:
876+
return base58.b58encode_check(
877+
_unhexlify(self._cryptocurrency.PRIVATE_KEY_ADDRESS) +
878+
unhexlify(self.private_key())
879+
)
880+
850881
def strength(self) -> Optional[int]:
851882
"""
852883
Get Entropy strength.
@@ -1281,6 +1312,8 @@ def dumps(self) -> dict:
12811312
semantic=self.semantic(),
12821313
path=self.path(),
12831314
hash=self.hash(),
1315+
public_key_base58check=self.public_key_base58check(),
1316+
private_key_base58check=self.private_key_base58check(),
12841317
addresses=dict(
12851318
p2pkh=self.p2pkh_address(),
12861319
p2sh=self.p2sh_address(),

hdwallet/symbols.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
DFC = "DFC"
7575
# Denarius
7676
DNR = "DNR"
77+
# DeSo
78+
DESO, DESOTEST = "DESO", "DESOTEST"
7779
# Diamond
7880
DMD = "DMD"
7981
# Digi Byte
@@ -316,6 +318,7 @@
316318
"CRAVE",
317319
"DASH", "DASHTEST",
318320
"ONION",
321+
"DESO", "DESOTEST",
319322
"DFC",
320323
"DNR",
321324
"DMD",

tests/test_symbols.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def test_symbols():
4545
assert ONION == "ONION"
4646
assert DFC == "DFC"
4747
assert DNR == "DNR"
48+
assert DESO == "DESO"
49+
assert DESOTEST == "DESOTEST"
4850
assert DMD == "DMD"
4951
assert DGB == "DGB"
5052
assert DGC == "DGC"

0 commit comments

Comments
 (0)