Skip to content

Commit

Permalink
Python wallet tx mass and estimate functions (#118)
Browse files Browse the repository at this point in the history
* tx mass wallet fns

* .pyi

* fmt
  • Loading branch information
smartgoo authored Oct 27, 2024
1 parent ef8e872 commit fe65a1c
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 1 deletion.
18 changes: 18 additions & 0 deletions python/kaspa.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,13 @@ class GeneratorSummary:
def final_transaction_id(self) -> Optional[str]: ...


def calculate_transaction_fee(network_id: str, tx: Transaction, minimum_signatures: Optional[int]) -> Optional[int]: ...

def calculate_transaction_mass(network_id: str, tx: Transaction, minimum_signatures: Optional[int]) -> int: ...

def update_transaction_mass(network_id: str, tx: Transaction, minimum_signatures: Optional[int]) -> bool: ...


class PaymentOutput:

def __init__(self, address: Address, amount: int) -> None: ...
Expand Down Expand Up @@ -714,6 +721,17 @@ def create_transactions(
minimum_signatures: Optional[int]
) -> dict: ...

def estimate_transactions(
network_id: str,
entries: list[dict],
outputs: list[dict],
change_address: Address,
payload: Optional[str],
priority_fee: Optional[int],
priority_entries: Optional[list[dict]],
sig_op_count: Optional[int],
minimum_signatures: Optional[int]
) -> GeneratorSummary: ...

def sign_transaction(tx: Transaction, signer: list[PrivateKey], verify_sig: bool) -> Transaction: ...

Expand Down
4 changes: 4 additions & 0 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ cfg_if::cfg_if! {
m.add_class::<kaspa_wallet_core::python::tx::generator::generator::Generator>()?;
m.add_class::<kaspa_wallet_core::python::tx::generator::pending::PendingTransaction>()?;
m.add_class::<kaspa_wallet_core::python::tx::generator::summary::GeneratorSummary>()?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::tx::mass::calculate_unsigned_transaction_fee, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::tx::mass::calculate_unsigned_transaction_mass, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::tx::mass::update_unsigned_transaction_mass, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::tx::utils::create_transaction_py, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::tx::utils::create_transactions_py, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::tx::utils::estimate_transactions_py, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::utils::kaspa_to_sompi, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::utils::sompi_to_kaspa, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::python::utils::sompi_to_kaspa_string_with_suffix, m)?)?;
Expand Down
51 changes: 51 additions & 0 deletions wallet/core/src/python/tx/mass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::imports::*;
use crate::result::Result;
use crate::tx::{mass, MAXIMUM_STANDARD_TRANSACTION_MASS};
use kaspa_consensus_client::Transaction;
use kaspa_consensus_core::config::params::Params;

#[pyfunction]
pub fn maximum_standard_transaction_mass() -> u64 {
MAXIMUM_STANDARD_TRANSACTION_MASS
}

#[pyfunction]
#[pyo3(name = "calculate_transaction_mass")]
pub fn calculate_unsigned_transaction_mass(network_id: &str, tx: &Transaction, minimum_signatures: Option<u16>) -> Result<u64> {
let network_id = NetworkId::from_str(network_id)?;
let consensus_params = Params::from(network_id);
let network_params = NetworkParams::from(network_id);
let mc = mass::MassCalculator::new(&consensus_params, &network_params);
mc.calc_overall_mass_for_unsigned_client_transaction(tx, minimum_signatures.unwrap_or(1))
}

#[pyfunction]
#[pyo3(name = "update_transaction_mass")]
pub fn update_unsigned_transaction_mass(network_id: &str, tx: &Transaction, minimum_signatures: Option<u16>) -> Result<bool> {
let network_id = NetworkId::from_str(network_id)?;
let consensus_params = Params::from(network_id);
let network_params = NetworkParams::from(network_id);
let mc = mass::MassCalculator::new(&consensus_params, network_params);
let mass = mc.calc_overall_mass_for_unsigned_client_transaction(tx, minimum_signatures.unwrap_or(1))?;
if mass > MAXIMUM_STANDARD_TRANSACTION_MASS {
Ok(false)
} else {
tx.set_mass(mass);
Ok(true)
}
}

#[pyfunction]
#[pyo3(name = "calculate_transaction_fee")]
pub fn calculate_unsigned_transaction_fee(network_id: &str, tx: &Transaction, minimum_signatures: Option<u16>) -> Result<Option<u64>> {
let network_id = NetworkId::from_str(network_id)?;
let consensus_params = Params::from(network_id);
let network_params = NetworkParams::from(network_id);
let mc = mass::MassCalculator::new(&consensus_params, network_params);
let mass = mc.calc_overall_mass_for_unsigned_client_transaction(tx, minimum_signatures.unwrap_or(1))?;
if mass > MAXIMUM_STANDARD_TRANSACTION_MASS {
Ok(None)
} else {
Ok(Some(mc.calc_fee_for_mass(mass)))
}
}
1 change: 1 addition & 0 deletions wallet/core/src/python/tx/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod generator;
pub mod mass;
pub mod utils;
31 changes: 30 additions & 1 deletion wallet/core/src/python/tx/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::imports::*;
use crate::python::tx::generator::{Generator, PendingTransaction};
use crate::python::tx::generator::{Generator, GeneratorSummary, PendingTransaction};
use crate::tx::payment::PaymentOutput;
use kaspa_consensus_client::*;
use kaspa_consensus_core::subnets::SUBNETWORK_ID_NATIVE;
Expand Down Expand Up @@ -79,3 +79,32 @@ pub fn create_transactions_py<'a>(
dict.set_item("summary", &summary)?;
Ok(dict)
}

#[pyfunction]
#[pyo3(name = "estimate_transactions")]
pub fn estimate_transactions_py<'a>(
network_id: String,
entries: Vec<&PyDict>,
outputs: Vec<&PyDict>,
change_address: Address,
payload: Option<PyBinary>,
priority_fee: Option<u64>,
priority_entries: Option<Vec<&PyDict>>,
sig_op_count: Option<u8>,
minimum_signatures: Option<u16>,
) -> PyResult<GeneratorSummary> {
let generator = Generator::ctor(
network_id,
entries,
outputs,
change_address,
payload.map(Into::into),
priority_fee,
priority_entries,
sig_op_count,
minimum_signatures,
)?;

generator.iter().collect::<Result<Vec<_>>>()?;
Ok(generator.summary())
}

0 comments on commit fe65a1c

Please sign in to comment.