No project description provided
Project description
Bittensor Wallet SDK
Install
There are a few ways to install Bittensor
- From source for usage:
$ git clone https://github.com/opentensor/btwallet.git
$ python3 -m pip install -e bittensor_wallet/
- From source for development needs:
$ git clone https://github.com/opentensor/btwallet.git
$ python3 -m venv venv # create env
$ source venv/bin/activate # activate env
$ pip install bittensor-wallet # install bittensor-wallet
$ python3 -m pip install -e .[dev] # installs dependencies for development and testing
- From PyPI (currently unavailable):
$ python3 -m venv venv # create env
$ source venv/bin/activate # activate env
$ pip install bittensor-wallet # install bittensor-wallet
To test your installation using python
from bittensor_wallet import Wallet
# creates wallet with name `default`
wallet = Wallet()
wallet.create()
If you want to pass arguments to the class other than the default, use the following:
name (str): The name of the wallet, used to identify it among possibly multiple wallets.
hotkey (str): String identifier for the hotkey.
path (str): File system path where wallet keys are stored.
config (Config): Bittensor configuration object.
To use your own config, you can do it like this:
from bittensor_wallet.config import Config
config = Config()
Rust
Rust Development
To build and test the Rust components of the project, you can use the following commands:
maturin develop
- Builds the project.cargo test
- Runs the tests.cargo run
- Runs the project.cargo doc --open
- Generates the documentation and opens it in the browser.cargo fmt
- Formats the code.cargo clippy
- Runs the linter.cargo clippy --fix
- Fixes the code.
Using the Rust components in Python
from bittensor_wallet import config, errors, keyfile, keypair, utils, wallet
print(utils.SS58_FORMAT)
myconf = config.Config()
print(myconf)
mywallet = wallet.Wallet(config=myconf)
print(mywallet)
try:
mywallet.unlock_coldkey()
mywallet.unlock_coldkeypub()
mywallet.unlock_hotkey()
except errors.KeyFileError:
print("Failed unlocking.")
keypair::KeyPair
Tests for Keypair
from bittensor_wallet import Keypair as WKeypair
from substrateinterface import Keypair as SKeypair
kps = SKeypair.create_from_mnemonic("stool feel open east woman high can denial forget screen trust salt")
kpw = WKeypair.create_from_mnemonic("stool feel open east woman high can denial forget screen trust salt")
assert kps.ss58_address == kpw.ss58_address
assert kps.seed_hex == kpw.seed_hex
assert kps.public_key == kpw.public_key
assert kps.private_key == kpw.private_key
kps = SKeypair.create_from_seed("0x023d5fbd7981676587a9f7232aeae1087ac7c265f9658fb643b6f5e61961dfbf")
kpw = WKeypair.create_from_seed("0x023d5fbd7981676587a9f7232aeae1087ac7c265f9658fb643b6f5e61961dfbf")
assert kps.ss58_address == kpw.ss58_address
assert kps.seed_hex == kpw.seed_hex
assert kps.public_key == kpw.public_key
assert kps.private_key == kpw.private_key
# substrateinterface has a bug -> can't create the KP without `ss58_format` passed
kps = SKeypair.create_from_private_key("0x2b400f61c21cbaad4d5cb2dcbb4ef4fcdc238b98d04d48c6d2a451ebfd306c0eed845edcc69b0a19a6905afed0dd84c16ebd0f458928f2e91a6b67b95fc0b42f", ss58_format=42)
kpw = WKeypair.create_from_private_key("0x2b400f61c21cbaad4d5cb2dcbb4ef4fcdc238b98d04d48c6d2a451ebfd306c0eed845edcc69b0a19a6905afed0dd84c16ebd0f458928f2e91a6b67b95fc0b42f")
assert kps.ss58_address == kpw.ss58_address
assert kps.seed_hex == kpw.seed_hex
assert kps.public_key == kpw.public_key
assert kps.private_key == kpw.private_key
kps = SKeypair.create_from_uri("//Alice")
kpw = WKeypair.create_from_uri("//Alice")
assert kps.ss58_address == kpw.ss58_address
assert kps.seed_hex == kpw.seed_hex
assert kps.public_key == kpw.public_key
assert kps.private_key == kpw.private_key
# substrateinterface has a bug -> can't create the KP without `ss58_format` passed
from_private_key_new_kps = SKeypair(public_key=kps.public_key.hex(), ss58_format=42)
from_private_key_new_kpw = WKeypair(public_key=kps.public_key.hex())
assert from_private_key_new_kps.ss58_address == from_private_key_new_kpw.ss58_address
assert from_private_key_new_kps.seed_hex == from_private_key_new_kpw.seed_hex
assert from_private_key_new_kps.public_key == from_private_key_new_kpw.public_key
assert from_private_key_new_kps.private_key == from_private_key_new_kpw.private_key
from_address_kps = SKeypair(ss58_address="5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY")
from_address_kpw = WKeypair(ss58_address="5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY")
assert from_address_kps.ss58_address == from_address_kpw.ss58_address
assert from_address_kps.seed_hex == from_address_kpw.seed_hex
assert from_address_kps.public_key == from_address_kpw.public_key
assert from_address_kps.private_key == from_address_kpw.private_key
# check signature
assert kps.verify("asd", kpw.sign("asd")) == True
# check verify
assert kpw.verify("asd", kps.sign("asd")) == Tru
# check create_from_encrypted_json
from substrateinterface.base import Keypair as S_Keypair
from bittensor_wallet import Keypair as W_Keypair
data = '{"encoded":"Z1yzxASuj21ej3CANbZKc3ibDaOpQPMahTT0qkniyZgAgAAAAQAAAAgAAACSDgflXWKXrX36EmX9XcA6cRpkN+oZX30/9FhtNP17krIG/yHLKmDnL1km1W/nZ+BpC7Qid6IuBvbZeboFyewFeXsKtcoY/bRY6nx/cLB5BND9WpXXS6Enf4RXAX7vPu/BY+o2z7VwPaXyFARfyPTiqJKqLDJWm3W5ZlvK0ks8FBv66mWEBYc+lLx8jvuzDNkdD3pnV3G802OwwHTy","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"address":"5CuByUQBWZci5AtXonuHHhcbRL3yxM5xDdJsTNaYN3vPDY6f","meta":{"genesisHash":null,"name":"test","whenCreated":1727395683981}}'
passphrase = "Password123"
skp = S_Keypair.create_from_encrypted_json(data, passphrase)
wkp = W_Keypair.create_from_encrypted_json(data, passphrase)
assert skp.ss58_format == wkp.ss58_format
assert skp.private_key == wkp.private_key
assert skp.private_key.hex() == wkp.private_key.hex()
assert skp.public_key == wkp.public_key
assert skp.public_key.hex() == wkp.public_key.hex()
Check signature and verify with ScaleBytes
from scalecodec.base import ScaleBytes
from bittensor_wallet import Keypair as WKeypair
from substrateinterface import Keypair as SKeypair
kps = SKeypair.create_from_uri("//Alice")
kpw = WKeypair.create_from_uri("//Alice")
message = ScaleBytes(b"my message")
# cross check
assert kps.verify(message, kpw.sign(message)) == True
assert kpw.verify(message, kps.sign(message)) == True
# itself check
assert kpw.verify(message, kpw.sign(message)) == True
assert kps.verify(message, kps.sign(message)) == True
utils.rs
Tests for utils' functions
# check utils functions
from bittensor_wallet import get_ss58_format, is_valid_ss58_address, is_valid_ed25519_pubkey, is_valid_bittensor_address_or_public_key
# check get_ss58_format
assert get_ss58_format("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") == 42
# check is_valid_ss58_address
assert is_valid_ss58_address("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") == True
assert is_valid_ss58_address("blabla") == False
# check is_valid_ed25519_pubkey
assert is_valid_ed25519_pubkey("a"*64) == True
assert is_valid_ed25519_pubkey("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") == False
assert is_valid_ed25519_pubkey("0x86eb46a3f42935d901acc3b8910ca301d969b76cfc2a80f0eac733a8eda7ed24") == True
assert is_valid_ed25519_pubkey("86eb46a3f42935d901acc3b8910ca301d969b76cfc2a80f0eac733a8eda7ed24") == True
assert is_valid_ed25519_pubkey("") == False
try:
is_valid_ed25519_pubkey()
except TypeError:
# TypeError: is_valid_ed25519_pubkey() missing 1 required positional argument: 'public_key'
...
# check is_valid_bittensor_address_or_public_key
assert is_valid_bittensor_address_or_public_key("blabla") == False
assert is_valid_bittensor_address_or_public_key("a"*64) == False
assert is_valid_bittensor_address_or_public_key(b"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") == False
assert is_valid_bittensor_address_or_public_key("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") == True
assert is_valid_bittensor_address_or_public_key(100) == False
keyfile.rs
Tests for keyfile.rs functions
Test serialization and deserialization
from bittensor_wallet import Keyfile, Keypair, serialized_keypair_to_keyfile_data, deserialize_keypair_from_keyfile_data
kp = Keypair.create_from_mnemonic("stool feel open east woman high can denial forget screen trust salt")
kf_data = serialized_keypair_to_keyfile_data(kp)
assert isinstance(kf_data, bytes)
kp_2 = deserialize_keypair_from_keyfile_data(kf_data)
assert isinstance(kp_2, Keypair)
assert kp.ss58_address == kp_2.ss58_address
assert kp.seed_hex == kp_2.seed_hex
assert kp.public_key == kp_2.public_key
assert kp.private_key == kp_2.private_key
Test Keyfile encrypt and decrypt
# test keyfile encryption and decryption
from bittensor_wallet import Keyfile
#KF is an already encrypted key
kf = Keyfile("/Users/daniel/.bittensor/wallets/game_wallet/coldkey", name="default")
assert kf.data[:5] == b"$NACL"
kf.decrypt("testing")
#Decrypt data...
assert kf.data[1:13] == b'"publicKey":'
kf.encrypt("testing")
#Encryption data...
assert kf.data[:5] == b"$NACL"
Test Keyfile validate_password and ask_password
from bittensor_wallet import validate_password, ask_password
ask_password()
#Specify password for key encryption: {password specified here}
validate_password("test")
# False, Password not strong enough
validate_password("asdf45as6d4f52asd6f54")
# True
Test Keyfile keyfile_data_is_encrypted and keyfile_data_encryption_method
from bittensor_wallet import Keyfile, keyfile_data_is_encrypted, keyfile_data_encryption_method
#KF is an already encrypted key NACL
kf = Keyfile("/Users/daniel/.bittensor/wallets/game_wallet/coldkey", name="default")
assert keyfile_data_is_encrypted(kf.data) == True
assert keyfile_data_encryption_method(kf.data) == 'NaCl'
Test Keyfile legacy_encrypt_keyfile_data and keyfile_data_encryption_method
from bittensor_wallet import Keyfile, keyfile_data_is_encrypted, keyfile_data_encryption_method, legacy_encrypt_keyfile_data
#KF is an already encrypted key NACL
kf = Keyfile("/Users/daniel/.bittensor/wallets/validator/coldkey", name="default")
assert keyfile_data_is_encrypted(kf.data) == False
legacy_enc_kf_data = legacy_encrypt_keyfile_data(kf.data, "testing")
# :exclamation_mark: Encrypting key with legacy encryption method...
assert keyfile_data_encryption_method(legacy_enc_kf_data) == 'Ansible Vault'
Test Keyfile get_coldkey_password_from_environment
import os
from bittensor_wallet import get_coldkey_password_from_environment
assert get_coldkey_password_from_environment("some-pw") == None
os.environ["BT_COLD_PW_SOME_PW"] = "SOMEPASSWORD"
assert get_coldkey_password_from_environment("some-pw") == "SOMEPASSWORD"
Test Keyfile encrypt_keyfile_data and decrypt_keyfile_data
from bittensor_wallet import Keyfile, decrypt_keyfile_data, encrypt_keyfile_data, keyfile_data_is_encrypted
kf = Keyfile("/Users/daniel/.bittensor/wallets/validator/coldkey", name="default")
assert keyfile_data_is_encrypted(kf.data) == False
encrypted_kf_data = encrypt_keyfile_data(kf.data, "somePassword")
#Encryption data...
assert keyfile_data_is_encrypted(encrypted_kf_data) == True
decrypted_kf_data = decrypt_keyfile_data(encrypted_kf_data, "somePassword")
#Decrypt data...
assert decrypted_kf_data == kf.data
Tests for keyfile::Keyfile
Test Keyfile is_encrypted, decrypt, encrypt and check_and_update_encryption
from bittensor_wallet import Keyfile, Keypair
kf = Keyfile("/Users/daniel/.bittensor/wallets/newkeyfile", name="default")
kp = Keypair.create_from_mnemonic("stool feel open east woman high can denial forget screen trust salt")
kf.set_keypair(kp, False, False)
assert kf.is_encrypted() == False
kf.encrypt("somepassword")
#Encryption data...
assert kf.is_encrypted() == True
kf.decrypt("somepassword")
#Decrypt data...
assert kf.is_encrypted() == False
kf.check_and_update_encryption(True, True)
#Keyfile is not encrypted.
#False
Test Keyfile make_dirs, is_writable, is_readable, get_keypair and exists_on_device
from bittensor_wallet import Keyfile, Keypair
kf = Keyfile("/Users/daniel/.bittensor/wallets/newkeyfile", name="default")
kp = Keypair.create_from_mnemonic("stool feel open east woman high can denial forget screen trust salt")
kf.set_keypair(kp, False, False)
assert kf.exists_on_device() == False
assert kf.is_writable() == False
assert kf.is_readable() == False
kf.make_dirs()
assert kf.exists_on_device() == True
assert kf.is_writable() == True
assert kf.is_readable() == True
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
bittensor_wallet-2.0.0a4.tar.gz
(62.7 kB
view hashes)
Built Distributions
Close
Hashes for bittensor_wallet-2.0.0a4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12c9eab6b9031ab51af90a834e0d012c5ce7ffe2bed270d19bc3f14097887495 |
|
MD5 | ab1694c03260e85c05531ae96a6ae7c2 |
|
BLAKE2b-256 | 92a45623c31490d9c21d7f39f998149a14fae13afb2da66f8072f15761243a83 |
Close
Hashes for bittensor_wallet-2.0.0a4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1c04af9a748a4b3ec5f43fbaa9df4d5523b3887d03b44ea79b609a419c7a3d39 |
|
MD5 | b19fbfc58435d329fa448d73c56dbee6 |
|
BLAKE2b-256 | 9756e3280a8b7563ea5b23ddced9f3c2793a2034064f003c4cce7cdeeeb6fd8b |
Close
Hashes for bittensor_wallet-2.0.0a4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 97440c884bc7a5afe7491e83f8dfc99d36a0865eaddf56b2b52f065755a506f6 |
|
MD5 | 7651064dbec39adb74d76fecfa2fe5ac |
|
BLAKE2b-256 | 28e92d9ef4b38a2971a14e9042446a89415e352cf40e1d2302b8dcc498db8962 |
Close
Hashes for bittensor_wallet-2.0.0a4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 342aa46cd8d1321c2b4059a6ec2f887450f5d413fe138df44dc10d8156be413e |
|
MD5 | 805162c37453dc901cf49ff2e864f7cd |
|
BLAKE2b-256 | a730230e38979085ac66b5339816ff75a64e4dfd3a9955b8925143ad86769e9a |
Close
Hashes for bittensor_wallet-2.0.0a4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 977c0acc4b0afe1cdfd1500e976be2e82c07a0b5968b32d36a28e1442c3a8eb2 |
|
MD5 | a583f6cdbc613cf1f93c11b8ae0c9c2f |
|
BLAKE2b-256 | 20764c5bb3f6cf872cbd237f6e24fb18b4459afc21473fe391768dd3d9bfd1e9 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 74b55a5b51149032e73b4950ae8191f5bcb10c22248d6834e2a1b7f21e3c6f86 |
|
MD5 | 4b2c2cf7007f55ccde4209f3cc11f6a4 |
|
BLAKE2b-256 | 1ca7881f6476b13747fb025da367e641f89a4b9e50131f1c8d772acf7f89597a |
Close
Hashes for bittensor_wallet-2.0.0a4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 59133a3448151a50659fb33ed2593f3a550ca0b957cd837dbf1c613778d6829c |
|
MD5 | 6b4495d5b65c71bd2f18e4543e045056 |
|
BLAKE2b-256 | f568b8e2d3783dc7a66a8f24b5d89d8020646c72b178181b314547830bbc1fc1 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a2c0977833aee1cc33b918cbd1849d8f8c03ad0cea6727f3e5ab2daf605a8301 |
|
MD5 | f1456122f8d2161cc22f93f617f0f6c8 |
|
BLAKE2b-256 | 3e707515707f8d4df4b15ea1e7d3bb6b536524e7ce7ad1ec3549cf0cf53d7762 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b1af73811ff45019e253ca3a2ed9099d4533445db1e4a9cdae1e842bcd541204 |
|
MD5 | a0e67dbeb848e86010f75159cfffb494 |
|
BLAKE2b-256 | 38bad58c4ddc49d7c0dafaad0c496cbdbd4e41349f36a1f3e5e5a5fd79713220 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9f89c6590c9cceb8118ed9b6408b92e5eac8ba7ca67e448c4de330058d22f7d8 |
|
MD5 | 5e988937cf537b7daa1417bf4566d948 |
|
BLAKE2b-256 | 093eca9f115d7eed5ec4e61e66ca2ad6b9bad953439490b2119f87fcdc766de5 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c3648243302fcf3bcd6bf46370cf85fa44545468b958220337897a0fab8a3dbf |
|
MD5 | bde85684be8f847ddba408a60bb44313 |
|
BLAKE2b-256 | b7ef20ce289727b1b08ec16f1578a59a76e9babff777250680bfabc1a2f8a79a |
Close
Hashes for bittensor_wallet-2.0.0a4-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d9806cc8d6cbcd200229982ee4a46e22ee2188b572807a14e67c21ce99e6a834 |
|
MD5 | a75331cd9b20c96de90cb6028713497a |
|
BLAKE2b-256 | cdb33b43a9cef25cb0b5f96ff09c9e2793343193ab7cff111ab99d077b98e495 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ec8636a20ed902bad0249614bbb7872cdcea6ff1e8592a7f5fed43da3846a23b |
|
MD5 | 1ded6ec3f0dea423f5b4d7e6a3d9443c |
|
BLAKE2b-256 | a85d3518f8c35fe5c1d4b8349d77d9b0e463e5204fc55ad6da9c2f7f82b60063 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 20484c72a893a9b43efc24dc1be93cab900f253bc045737a0cb64616d2633d38 |
|
MD5 | fc719c9cba6733ef6f83a10fc6c963c1 |
|
BLAKE2b-256 | 26423e2aa4b492a700193dfa19b5458275aa06959f87ab2bae4d9f4579725687 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0a549abb914589c315540172c695cadaf5ff7f9fd83a02ddf918b8bbda0c8506 |
|
MD5 | dd4a7d211846df9422f06f12137a9471 |
|
BLAKE2b-256 | faa34693cd3f82e6a6169843ff7f8e72d9fd35ce784e76982061db80c9ff163e |
Close
Hashes for bittensor_wallet-2.0.0a4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3753d2556bc3117aaf9c6ea05ce24e761db6de8f6a81c9304e803ea00d607580 |
|
MD5 | 2c0769711fadf5c9c1ab2c2b68846e6c |
|
BLAKE2b-256 | 0b9daf09fdfef3122d11b02dd479ac76229f6edab139d13e264d786e0415fa92 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9e61b8614c7f06719f516351a40e8078492ee04239ef0304ec62e9a7175576dd |
|
MD5 | 332e94579333bfac3f8276bd796470a5 |
|
BLAKE2b-256 | 704fe42e7faa9e16dc316fe06fa559896306301350074f9d1e9db11d425854f3 |
Close
Hashes for bittensor_wallet-2.0.0a4-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0f154f765e519eb268f9495b6fe530245337c4fa0b7108a441d8c1dc879f3f84 |
|
MD5 | a0d1c542f09e8de1e0979b487362ded3 |
|
BLAKE2b-256 | 498ce6bab6f43c159af0365081824703bf9ab08e42139bbbf0709da2f22c23a2 |