From 595b9ffc460809ab46a0029e8f664361a76c630c Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Thu, 13 Jul 2023 16:17:30 -0400 Subject: [PATCH] Release/0.0.4 (#7) * fix mock exports * bump version * add changelog * fix release script * add more changelog --- CHANGELOG.md | 10 +++ README.md | 4 +- VERSION | 2 +- bittensor_wallet/__init__.py | 2 +- bittensor_wallet/mock/utils/__init__.py | 2 + scripts/release/release.sh | 2 +- tests/test.py | 99 ++++++++++++------------- 7 files changed, 66 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2719aa4..ade57a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.0.4 / 2023-07-11 + +## What's Changed +* Oops, fix mock exports by @camfairchild in e43ed72 +* Fix release script version check by @camfairchild in 312f41c + + +**Full Changelog**: https://github.com/opentensor/bittensor-wallet/compare/v0.0.3...v0.0.4 + + ## 0.0.3 / 2023-07-06 ## What's Changed diff --git a/README.md b/README.md index 07dd6e6..491537f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# BittensorWallet - v0.0.3 +# BittensorWallet - v0.0.4 BittensorWallet is a library for managing wallet keypairs, keyfiles, etc. for the [Bittensor Python API](https://github.com/opentensor/bittensor). @@ -7,7 +7,7 @@ The purpose of this repo is to separate the concern of keyfile management from t # Installation This package can be installed from [PyPi.org](https://pypi.org/project/bittensor-wallet/): ```bash -pip install bittensor-wallet==0.0.3 +pip install bittensor-wallet==0.0.4 ``` or via this repo (using [gh-cli](https://cli.github.com/)): ```bash diff --git a/VERSION b/VERSION index 6812f81..05b19b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.3 \ No newline at end of file +0.0.4 \ No newline at end of file diff --git a/bittensor_wallet/__init__.py b/bittensor_wallet/__init__.py index 08b5d74..27ef981 100644 --- a/bittensor_wallet/__init__.py +++ b/bittensor_wallet/__init__.py @@ -17,7 +17,7 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -__version__ = "0.0.3" +__version__ = "0.0.4" __ss58_format__ = 42 # Bittensor ss58 format import argparse diff --git a/bittensor_wallet/mock/utils/__init__.py b/bittensor_wallet/mock/utils/__init__.py index 646e392..69ef1c8 100644 --- a/bittensor_wallet/mock/utils/__init__.py +++ b/bittensor_wallet/mock/utils/__init__.py @@ -14,3 +14,5 @@ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. + +from .utils import get_mock_coldkey, get_mock_hotkey, get_mock_keypair, get_mock_wallet diff --git a/scripts/release/release.sh b/scripts/release/release.sh index c2cc5a4..208b314 100755 --- a/scripts/release/release.sh +++ b/scripts/release/release.sh @@ -52,7 +52,7 @@ if [[ ! -f $VERSION_FILENAME ]]; then exit 1 fi -CODE_VERSION=`grep '__version__\ \=\ ' $CODE_WITH_VERSION | awk '{print $3}' | sed "s/'//g"` +CODE_VERSION=`grep '__version__\ \=\ ' $CODE_WITH_VERSION | awk '{print $3}' | sed "s/'//g" | sed 's/"//g'` VERSION=$(cat $VERSION_FILENAME) if ! [[ "$CODE_VERSION" =~ ^[0-9]+.[0-9]+.[0-9]+$ ]];then diff --git a/tests/test.py b/tests/test.py index 9ceba33..c37fe08 100644 --- a/tests/test.py +++ b/tests/test.py @@ -28,12 +28,13 @@ from bittensor_wallet.wallet_impl import Wallet from bittensor_wallet._keyfile import Keyfile, keyfile from bittensor_wallet._keyfile.keyfile_impl import validate_password, ask_password_to_encrypt, decrypt_keyfile_data, KeyFileError +from bittensor_wallet.mock import MockKeyfile, MockWallet class TestWallet(unittest.TestCase): def test_regen_coldkeypub_from_ss58_addr(self): ss58_address = "5DD26kC2kxajmwfbbZmVmxhrY9VeeyR1Gpzy9i8wxLUg6zxm" - mock_wallet = Wallet() + mock_wallet = MockWallet( name=f"mock", hotkey="mock_hk", path=f"/tmp/mock-wallet-{self.id()}" ) with patch.object(mock_wallet, 'set_coldkeypub') as mock_set_coldkeypub: mock_wallet.regenerate_coldkeypub( ss58_address=ss58_address ) @@ -43,12 +44,12 @@ def test_regen_coldkeypub_from_ss58_addr(self): ss58_address_bad = "5DD26kC2kxajmwfbbZmVmxhrY9VeeyR1Gpzy9i8wxLUg6zx" # 1 character short with pytest.raises(ValueError): - self.mock_wallet.regenerate_coldkeypub(ss58_address=ss58_address_bad) + mock_wallet.regenerate_coldkeypub(ss58_address=ss58_address_bad) def test_regen_coldkeypub_from_hex_pubkey_str(self): pubkey_str = "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f" - mock_wallet = Wallet() + mock_wallet = MockWallet( name=f"mock", hotkey="mock_hk", path=f"/tmp/mock-wallet-{self.id()}" ) with patch.object(mock_wallet, 'set_coldkeypub') as mock_set_coldkeypub: mock_wallet.regenerate_coldkeypub(public_key=pubkey_str) @@ -58,13 +59,13 @@ def test_regen_coldkeypub_from_hex_pubkey_str(self): pubkey_str_bad = "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512" # 1 character short with pytest.raises(ValueError): - self.mock_wallet.regenerate_coldkeypub(ss58_address=pubkey_str_bad) + mock_wallet.regenerate_coldkeypub(ss58_address=pubkey_str_bad) def test_regen_coldkeypub_from_hex_pubkey_bytes(self): pubkey_str = "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f" pubkey_bytes = bytes.fromhex(pubkey_str[2:]) # Remove 0x from beginning - mock_wallet = Wallet() + mock_wallet = MockWallet( name=f"mock", hotkey="mock_hk", path=f"/tmp/mock-wallet-{self.id()}" ) with patch.object(mock_wallet, 'set_coldkeypub') as mock_set_coldkeypub: mock_wallet.regenerate_coldkeypub(public_key=pubkey_bytes) @@ -73,7 +74,7 @@ def test_regen_coldkeypub_from_hex_pubkey_bytes(self): self.assertEqual(keypair.public_key, pubkey_bytes) def test_regen_coldkeypub_no_pubkey(self): - mock_wallet = Wallet() + mock_wallet = MockWallet( name=f"mock", hotkey="mock_hk", path=f"/tmp/mock-wallet-{self.id()}" ) with pytest.raises(ValueError): # Must provide either public_key or ss58_address @@ -83,7 +84,7 @@ def test_regen_coldkey_from_hex_seed_str(self): ss58_addr = "5D5cwd8DX6ij7nouVcoxDuWtJfiR1BnzCkiBVTt7DU8ft5Ta" seed_str = "0x659c024d5be809000d0d93fe378cfde020846150b01c49a201fc2a02041f7636" - mock_wallet = Wallet() + mock_wallet = MockWallet( name=f"mock", hotkey="mock_hk", path=f"/tmp/mock-wallet-{self.id()}" ) with patch.object(mock_wallet, 'set_coldkey') as mock_set_coldkey: mock_wallet.regenerate_coldkey(seed=seed_str) @@ -100,8 +101,8 @@ def test_regen_hotkey_from_hex_seed_str(self): ss58_addr = "5D5cwd8DX6ij7nouVcoxDuWtJfiR1BnzCkiBVTt7DU8ft5Ta" seed_str = "0x659c024d5be809000d0d93fe378cfde020846150b01c49a201fc2a02041f7636" - mock_wallet = Wallet() - with patch.object(self.mock_wallet, 'set_hotkey') as mock_set_hotkey: + mock_wallet = MockWallet( name=f"mock", hotkey="mock_hk", path=f"/tmp/mock-wallet-{self.id()}" ) + with patch.object(mock_wallet, 'set_hotkey') as mock_set_hotkey: mock_wallet.regenerate_hotkey(seed=seed_str) mock_set_hotkey.assert_called_once() @@ -126,60 +127,60 @@ def tearDown(self) -> None: shutil.rmtree(self.root_path) def create_keyfile(self): - keyfile = keyfile(path=os.path.join(self.root_path, "keyfile")) + _keyfile = keyfile(path=os.path.join(self.root_path, "keyfile")) mnemonic = Keypair.generate_mnemonic(12) alice = Keypair.create_from_mnemonic(mnemonic) - keyfile.set_keypair(alice, encrypt=True, overwrite=True, password='thisisafakepassword') + _keyfile.set_keypair(alice, encrypt=True, overwrite=True, password='thisisafakepassword') bob = Keypair.create_from_uri('/Bob') - keyfile.set_keypair(bob, encrypt=True, overwrite=True, password='thisisafakepassword') + _keyfile.set_keypair(bob, encrypt=True, overwrite=True, password='thisisafakepassword') return keyfile def test_create(self): - keyfile = keyfile(path=os.path.join(self.root_path, "keyfile")) + _keyfile = keyfile(path=os.path.join(self.root_path, "keyfile")) mnemonic = Keypair.generate_mnemonic( 12 ) alice = Keypair.create_from_mnemonic(mnemonic) - keyfile.set_keypair(alice, encrypt=True, overwrite=True, password = 'thisisafakepassword') - assert keyfile.is_readable() - assert keyfile.is_writable() - assert keyfile.is_encrypted() - keyfile.decrypt( password = 'thisisafakepassword' ) - assert not keyfile.is_encrypted() - keyfile.encrypt( password = 'thisisafakepassword' ) - assert keyfile.is_encrypted() + _keyfile.set_keypair(alice, encrypt=True, overwrite=True, password = 'thisisafakepassword') + assert _keyfile.is_readable() + assert _keyfile.is_writable() + assert _keyfile.is_encrypted() + _keyfile.decrypt( password = 'thisisafakepassword' ) + assert not _keyfile.is_encrypted() + _keyfile.encrypt( password = 'thisisafakepassword' ) + assert _keyfile.is_encrypted() str(keyfile) - keyfile.decrypt( password = 'thisisafakepassword' ) - assert not keyfile.is_encrypted() + _keyfile.decrypt( password = 'thisisafakepassword' ) + assert not _keyfile.is_encrypted() str(keyfile) - assert keyfile.get_keypair( password = 'thisisafakepassword' ).ss58_address == alice.ss58_address - assert keyfile.get_keypair( password = 'thisisafakepassword' ).private_key == alice.private_key - assert keyfile.get_keypair( password = 'thisisafakepassword' ).public_key == alice.public_key + assert _keyfile.get_keypair( password = 'thisisafakepassword' ).ss58_address == alice.ss58_address + assert _keyfile.get_keypair( password = 'thisisafakepassword' ).private_key == alice.private_key + assert _keyfile.get_keypair( password = 'thisisafakepassword' ).public_key == alice.public_key bob = Keypair.create_from_uri ('/Bob') - keyfile.set_keypair(bob, encrypt=True, overwrite=True, password = 'thisisafakepassword') - assert keyfile.get_keypair( password = 'thisisafakepassword' ).ss58_address == bob.ss58_address - assert keyfile.get_keypair( password = 'thisisafakepassword' ).public_key == bob.public_key + _keyfile.set_keypair(bob, encrypt=True, overwrite=True, password = 'thisisafakepassword') + assert _keyfile.get_keypair( password = 'thisisafakepassword' ).ss58_address == bob.ss58_address + assert _keyfile.get_keypair( password = 'thisisafakepassword' ).public_key == bob.public_key repr(keyfile) def test_legacy_coldkey(self): legacy_filename = os.path.join(self.root_path, "coldlegacy_keyfile") - keyfile = keyfile (path = legacy_filename) - keyfile.make_dirs() + _keyfile = keyfile (path = legacy_filename) + _keyfile.make_dirs() keyfile_data = b'0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f' with open(legacy_filename, "wb") as keyfile_obj: keyfile_obj.write( keyfile_data ) - assert keyfile.keyfile_data == keyfile_data - keyfile.encrypt( password = 'this is the fake password' ) - keyfile.decrypt( password = 'this is the fake password' ) + assert _keyfile.keyfile_data == keyfile_data + _keyfile.encrypt( password = 'this is the fake password' ) + _keyfile.decrypt( password = 'this is the fake password' ) keypair_bytes = b'{"accountId": "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f", "publicKey": "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f", "secretPhrase": null, "secretSeed": null, "ss58Address": "5DD26kC2kxajmwfbbZmVmxhrY9VeeyR1Gpzy9i8wxLUg6zxm"}' - assert keyfile.keyfile_data == keypair_bytes - assert keyfile.get_keypair().ss58_address == "5DD26kC2kxajmwfbbZmVmxhrY9VeeyR1Gpzy9i8wxLUg6zxm" - assert "0x" + keyfile.get_keypair().public_key.hex() == "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f" + assert _keyfile.keyfile_data == keypair_bytes + assert _keyfile.get_keypair().ss58_address == "5DD26kC2kxajmwfbbZmVmxhrY9VeeyR1Gpzy9i8wxLUg6zxm" + assert "0x" + _keyfile.get_keypair().public_key.hex() == "0x32939b6abc4d81f02dff04d2b8d1d01cc8e71c5e4c7492e4fa6a238cdca3512f" def test_validate_password(self): assert validate_password(None) == False @@ -219,23 +220,21 @@ def test_user_interface(self): assert ask_password_to_encrypt() == 'asdury3294y' def test_overwriting(self): - keyfile = keyfile (path = os.path.join(self.root_path, "keyfile")) + _keyfile = keyfile (path = os.path.join(self.root_path, "keyfile")) alice = Keypair.create_from_uri ('/Alice') - keyfile.set_keypair(alice, encrypt=True, overwrite=True, password = 'thisisafakepassword') + _keyfile.set_keypair(alice, encrypt=True, overwrite=True, password = 'thisisafakepassword') bob = Keypair.create_from_uri ('/Bob') with pytest.raises(KeyFileError) as pytest_wrapped_e: with patch('builtins.input', return_value = 'n'): - keyfile.set_keypair(bob, encrypt=True, overwrite=False, password = 'thisisafakepassword') + _keyfile.set_keypair(bob, encrypt=True, overwrite=False, password = 'thisisafakepassword') def test_keyfile_mock(self): - file = keyfile( _mock = True ) - assert file.exists_on_device() - assert not file.is_encrypted() - assert file.is_readable() - assert file.data - assert file.keypair - file.set_keypair( keypair = Keypair.create_from_mnemonic( mnemonic = Keypair.generate_mnemonic() )) - - def test_keyfile_mock_func(self): - file = keyfile.mock() + with patch('bittensor_wallet._keyfile.keyfile.__new__', return_value=MockKeyfile(path='/tmp/test-wallet/keyfile')): + file = keyfile( ) + assert file.exists_on_device() + assert not file.is_encrypted() + assert file.is_readable() + assert file.data + assert file.keypair + file.set_keypair( keypair = Keypair.create_from_mnemonic( mnemonic = Keypair.generate_mnemonic() ))