diff --git a/consensus/client/src/transaction.rs b/consensus/client/src/transaction.rs index 4d7b5236e..f748f208d 100644 --- a/consensus/client/src/transaction.rs +++ b/consensus/client/src/transaction.rs @@ -299,13 +299,13 @@ impl Transaction { inputs: Vec, outputs: Vec, lock_time: u64, - subnetwork_id: String, + subnetwork_id: PyBinary, gas: u64, payload: PyBinary, mass: u64, ) -> PyResult { - let subnetwork_id = Vec::from_hex(&subnetwork_id) - .map_err(|err| PyException::new_err(format!("subnetwork_id decode error: {}", err)))? + let subnetwork_id: SubnetworkId = subnetwork_id + .data .as_slice() .try_into() .map_err(|err| PyException::new_err(format!("subnetwork_id conversion error: {}", err)))?; diff --git a/consensus/client/src/utils.rs b/consensus/client/src/utils.rs index c3bd0b3da..a486b8d91 100644 --- a/consensus/client/src/utils.rs +++ b/consensus/client/src/utils.rs @@ -57,7 +57,7 @@ pub fn address_from_script_public_key(script_public_key: &ScriptPublicKeyT, netw #[pyfunction] #[pyo3(name = "address_from_script_public_key")] pub fn address_from_script_public_key_py(script_public_key: &ScriptPublicKey, network: &str) -> PyResult
{ - match standard::extract_script_pub_key_address(script_public_key, network.try_into()?) { + match standard::extract_script_pub_key_address(script_public_key, NetworkType::from_str(network)?.try_into()?) { Ok(address) => Ok(address), Err(err) => Err(pyo3::exceptions::PyException::new_err(format!("{}", err))), } diff --git a/consensus/core/src/network.rs b/consensus/core/src/network.rs index 5c2213293..0c7c8ef86 100644 --- a/consensus/core/src/network.rs +++ b/consensus/core/src/network.rs @@ -183,6 +183,13 @@ impl From for JsValue { } } +#[cfg(feature = "py-sdk")] +impl From for PyErr { + fn from(value: NetworkIdError) -> PyErr { + PyException::new_err(value.to_string()) + } +} + /// /// NetworkId is a unique identifier for a kaspa network instance. /// It is composed of a network type and an optional suffix. diff --git a/python/examples/addresses.py b/python/examples/addresses.py index 2f47b3b0b..77f6f8ef5 100644 --- a/python/examples/addresses.py +++ b/python/examples/addresses.py @@ -28,14 +28,14 @@ def demo_generate_address_from_public_key_hex_string(): def demo_generate_address_from_private_key_hex_string(): private_key = PrivateKey("b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef") print("\nGiven private key b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef") - print(private_key.to_keypair().to_address("kaspa").to_string()) + print(private_key.to_keypair().to_address("mainnet").to_string()) def demo_generate_random(): keypair = Keypair.random() print("\nRandom Generation") print(keypair.private_key) print(keypair.public_key) - print(keypair.to_address("kaspa").to_string()) + print(keypair.to_address("mainnet").to_string()) if __name__ == "__main__": demo_generate_address_from_public_key_hex_string() diff --git a/python/examples/rpc_calls.py b/python/examples/rpc_calls.py index ca6c533ba..828c0f768 100644 --- a/python/examples/rpc_calls.py +++ b/python/examples/rpc_calls.py @@ -4,7 +4,7 @@ async def main(): - client = RpcClient(resolver=Resolver(), network="testnet", network_suffix=11) + client = RpcClient(resolver=Resolver(), network_id="testnet-11") await client.connect() ### diff --git a/python/examples/rpc_subscriptions.py b/python/examples/rpc_subscriptions.py index bdaedd5f8..e4873c8d2 100644 --- a/python/examples/rpc_subscriptions.py +++ b/python/examples/rpc_subscriptions.py @@ -32,7 +32,7 @@ async def rpc_subscriptions(client: RpcClient): await client.unsubscribe_new_block_template() async def main(): - client = RpcClient(resolver=Resolver(), network="testnet", network_suffix=10) + client = RpcClient(resolver=Resolver(), network_id="testnet-11") await client.connect() print(f"Client is connected: {client.is_connected}") diff --git a/python/examples/transactions/krc20_deploy.py b/python/examples/transactions/krc20_deploy.py index 82c0ec0d3..522b2f749 100644 --- a/python/examples/transactions/krc20_deploy.py +++ b/python/examples/transactions/krc20_deploy.py @@ -44,7 +44,7 @@ async def main(): script.add_op(Opcodes.OpEndIf) print(f'Script: {script.to_string()}') - p2sh_address = address_from_script_public_key(script.create_pay_to_script_hash_script(), 'kaspatest') + p2sh_address = address_from_script_public_key(script.create_pay_to_script_hash_script(), 'testnet') print(f'P2SH Address: {p2sh_address.to_string()}') utxos = await client.get_utxos_by_addresses(request={'addresses': [address]}) diff --git a/python/kaspa.pyi b/python/kaspa.pyi index 20dfc1928..3a0ad8e3e 100644 --- a/python/kaspa.pyi +++ b/python/kaspa.pyi @@ -918,16 +918,16 @@ class Resolver: def urls(self) -> list[str]: ... - def get_node(self, encoding: str, network: str, network_suffix: Optional[int]) -> dict: ... + def get_node(self, encoding: str, network_id: Optional[str]) -> dict: ... - def get_url(self, encoding: str, network: str, network_suffix: Optional[int]) -> str: ... + def get_url(self, encoding: str, network_id: Optional[str]) -> str: ... - def connect(self, encoding: str, network: str, network_suffix: Optional[int]) -> RpcClient: ... + def connect(self, encoding: str, network_id: Optional[str]) -> RpcClient: ... class RpcClient: - def __init__(self, resolver: Optional[Resolver], url: Optional[str], encoding: Optional[str], network: Optional[str], network_suffix: Optional[str]) -> None: ... + def __init__(self, resolver: Optional[Resolver], url: Optional[str], encoding: Optional[str], network_id: Optional[str]) -> None: ... @property def url(self) -> str: ... @@ -937,7 +937,7 @@ class RpcClient: def set_resolver(self, Resolver) -> None: ... - def set_network_id(self, network: str, network_suffix: Optional[int]) -> None: ... + def set_network_id(self, network_id: Optional[str]) -> None: ... @property def is_connected(self) -> bool: ... diff --git a/rpc/wrpc/python/src/client.rs b/rpc/wrpc/python/src/client.rs index b6eb4e2a2..766a5a130 100644 --- a/rpc/wrpc/python/src/client.rs +++ b/rpc/wrpc/python/src/client.rs @@ -1,4 +1,4 @@ -use crate::resolver::{into_network_id, Resolver}; +use crate::resolver::Resolver; use ahash::AHashMap; use futures::*; use kaspa_addresses::Address; @@ -157,12 +157,10 @@ impl RpcClient { resolver: Option, url: Option, encoding: Option, - network: Option, - network_suffix: Option, + network_id: Option, ) -> PyResult { let encoding = WrpcEncoding::from_str(&encoding.unwrap_or("borsh".to_string())).unwrap(); - let network = network.unwrap_or(String::from("mainnet")); - let network_id = into_network_id(&network, network_suffix)?; + let network_id = NetworkId::from_str(&network_id.unwrap_or(String::from("mainnet")))?; Ok(Self::new(resolver, url, Some(encoding), Some(network_id))?) } @@ -182,8 +180,8 @@ impl RpcClient { Ok(()) } - fn set_network_id(&self, network: String, network_suffix: Option) -> PyResult<()> { - let network_id = into_network_id(&network, network_suffix)?; + fn set_network_id(&self, network_id: String) -> PyResult<()> { + let network_id = NetworkId::from_str(&network_id)?; self.inner.client.set_network_id(&network_id)?; Ok(()) } diff --git a/rpc/wrpc/python/src/resolver.rs b/rpc/wrpc/python/src/resolver.rs index 65abfdf18..69d131a51 100644 --- a/rpc/wrpc/python/src/resolver.rs +++ b/rpc/wrpc/python/src/resolver.rs @@ -1,7 +1,6 @@ -use kaspa_consensus_core::network::{NetworkId, NetworkType}; +use kaspa_consensus_core::network::NetworkId; use kaspa_python_macros::py_async; use kaspa_wrpc_client::{Resolver as NativeResolver, WrpcEncoding}; -use pyo3::exceptions::PyException; use pyo3::prelude::*; use std::{str::FromStr, sync::Arc}; @@ -36,11 +35,9 @@ impl Resolver { self.resolver.urls().unwrap_or_default().into_iter().map(|url| (*url).clone()).collect::>() } - fn get_node(&self, py: Python, encoding: String, network: String, network_suffix: Option) -> PyResult> { + fn get_node(&self, py: Python, encoding: String, network_id: &str) -> PyResult> { let encoding = WrpcEncoding::from_str(encoding.as_str()).unwrap(); - - // TODO find better way of accepting NetworkId type from Python - let network_id = into_network_id(&network, network_suffix)?; + let network_id = NetworkId::from_str(network_id)?; let resolver = self.resolver.clone(); py_async! {py, async move { @@ -51,11 +48,9 @@ impl Resolver { }} } - fn get_url(&self, py: Python, encoding: String, network: String, network_suffix: Option) -> PyResult> { + fn get_url(&self, py: Python, encoding: String, network_id: &str) -> PyResult> { let encoding = WrpcEncoding::from_str(encoding.as_str()).unwrap(); - - // TODO find better way of accepting NetworkId type from Python - let network_id = into_network_id(&network, network_suffix)?; + let network_id = NetworkId::from_str(network_id)?; let resolver = self.resolver.clone(); py_async! {py, async move { @@ -72,13 +67,3 @@ impl From for NativeResolver { resolver.resolver } } - -pub fn into_network_id(network: &str, network_suffix: Option) -> Result { - let network_type = NetworkType::from_str(network).map_err(|_| PyErr::new::("Invalid network type"))?; - NetworkId::try_from(network_type).or_else(|_| { - network_suffix.map_or_else( - || Err(PyErr::new::("Network suffix required for this network")), - |suffix| Ok(NetworkId::with_suffix(network_type, suffix)), - ) - }) -} diff --git a/wallet/core/src/python/tx/utils.rs b/wallet/core/src/python/tx/utils.rs index 66c4f4a58..f9c6a75ba 100644 --- a/wallet/core/src/python/tx/utils.rs +++ b/wallet/core/src/python/tx/utils.rs @@ -49,7 +49,7 @@ pub fn create_transaction_py( #[pyo3(name = "create_transactions")] pub fn create_transactions_py<'a>( py: Python<'a>, - network_id: String, // TODO this is wrong + network_id: String, entries: Vec<&PyDict>, outputs: Vec<&PyDict>, change_address: Address, diff --git a/wallet/keys/src/imports.rs b/wallet/keys/src/imports.rs index d87648315..08acec2d6 100644 --- a/wallet/keys/src/imports.rs +++ b/wallet/keys/src/imports.rs @@ -15,6 +15,8 @@ pub use borsh::{BorshDeserialize, BorshSerialize}; pub use js_sys::Array; pub use kaspa_addresses::{Address, Version as AddressVersion}; pub use kaspa_bip32::{ChildNumber, ExtendedPrivateKey, ExtendedPublicKey, SecretKey}; +#[cfg(feature = "py-sdk")] +pub use kaspa_consensus_core::network::NetworkType; pub use kaspa_consensus_core::network::{NetworkId, NetworkTypeT}; pub use kaspa_utils::hex::*; pub use kaspa_wasm_core::types::*; diff --git a/wallet/keys/src/keypair.rs b/wallet/keys/src/keypair.rs index 5ac665cf4..b341c86c3 100644 --- a/wallet/keys/src/keypair.rs +++ b/wallet/keys/src/keypair.rs @@ -122,14 +122,14 @@ impl Keypair { #[pyo3(name = "to_address")] pub fn to_address_py(&self, network: &str) -> PyResult
{ let payload = &self.xonly_public_key.serialize(); - let address = Address::new(network.try_into()?, AddressVersion::PubKey, payload); + let address = Address::new(NetworkType::from_str(network)?.try_into()?, AddressVersion::PubKey, payload); Ok(address) } #[pyo3(name = "to_address_ecdsa")] pub fn to_address_ecdsa_py(&self, network: &str) -> PyResult
{ let payload = &self.public_key.serialize(); - let address = Address::new(network.try_into()?, AddressVersion::PubKeyECDSA, payload); + let address = Address::new(NetworkType::from_str(network)?.try_into()?, AddressVersion::PubKeyECDSA, payload); Ok(address) } diff --git a/wallet/keys/src/privatekey.rs b/wallet/keys/src/privatekey.rs index bcf4e20b4..4661a264b 100644 --- a/wallet/keys/src/privatekey.rs +++ b/wallet/keys/src/privatekey.rs @@ -118,7 +118,7 @@ impl PrivateKey { let public_key = secp256k1::PublicKey::from_secret_key_global(&self.inner); let (x_only_public_key, _) = public_key.x_only_public_key(); let payload = x_only_public_key.serialize(); - let address = Address::new(network.try_into()?, AddressVersion::PubKey, &payload); + let address = Address::new(NetworkType::from_str(network)?.try_into()?, AddressVersion::PubKey, &payload); Ok(address) } @@ -126,7 +126,7 @@ impl PrivateKey { pub fn to_address_ecdsa_py(&self, network: &str) -> PyResult
{ let public_key = secp256k1::PublicKey::from_secret_key_global(&self.inner); let payload = public_key.serialize(); - let address = Address::new(network.try_into()?, AddressVersion::PubKeyECDSA, &payload); + let address = Address::new(NetworkType::from_str(network)?.try_into()?, AddressVersion::PubKeyECDSA, &payload); Ok(address) } diff --git a/wallet/keys/src/publickey.rs b/wallet/keys/src/publickey.rs index b619522c1..9657795a3 100644 --- a/wallet/keys/src/publickey.rs +++ b/wallet/keys/src/publickey.rs @@ -305,14 +305,14 @@ impl XOnlyPublicKey { #[pyo3(name = "to_address")] pub fn to_address_py(&self, network: &str) -> PyResult
{ let payload = &self.inner.serialize(); - let address = Address::new(network.try_into()?, AddressVersion::PubKey, payload); + let address = Address::new(NetworkType::from_str(network)?.try_into()?, AddressVersion::PubKey, payload); Ok(address) } #[pyo3(name = "to_address_ecdsa")] pub fn to_address_ecdsa_py(&self, network: &str) -> PyResult
{ let payload = &self.inner.serialize(); - let address = Address::new(network.try_into()?, AddressVersion::PubKeyECDSA, payload); + let address = Address::new(NetworkType::from_str(network)?.try_into()?, AddressVersion::PubKeyECDSA, payload); Ok(address) }