Skip to content

Commit

Permalink
create_multisig_address fn
Browse files Browse the repository at this point in the history
  • Loading branch information
smartgoo committed Dec 8, 2024
1 parent b8b0c32 commit c28205e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 5 deletions.
29 changes: 24 additions & 5 deletions python/examples/transactions/multisig.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
ScriptBuilder,
SighashType,
XPrv,
create_transactions,
address_from_script_public_key,
create_multisig_address,
create_transactions,
kaspa_to_sompi
)

Expand All @@ -33,21 +34,39 @@ async def main():
prv3, pub3 = derive(seed, 2)
print(f'Account 3:\n - prv: {prv3.to_string()}\n - pub: {pub3.to_string()}\n')

##########
# Multisig address creation - from script
# schnorr and ECDSA examples

# schnorr
redeem_script = ScriptBuilder()\
.add_i64(2)\
.add_data(pub1.to_x_only_public_key().to_string())\
.add_data(pub2.to_x_only_public_key().to_string())\
.add_data(pub3.to_x_only_public_key().to_string())\
.add_i64(3)\
.add_op(Opcodes.OpCheckMultiSig)

# TODO ECDSA version
# TODO include create_multisig_address function when available

spk = redeem_script.create_pay_to_script_hash_script()
address = address_from_script_public_key(spk, network="testnet")
print(f"Multisig Address: {address.to_string()}\n")

# ECDSA
# ecdsa_redeem_script = ScriptBuilder()\
# .add_i64(2)\
# .add_data(pub1.to_string())\
# .add_data(pub2.to_string())\
# .add_data(pub3.to_string())\
# .add_i64(3)\
# .add_op(Opcodes.OpCheckMultiSigECDSA)
# ecdsa_spk = ecdsa_redeem_script.create_pay_to_script_hash_script()
# ecdsa_address = address_from_script_public_key(ecdsa_spk, network="testnet")

##########
# Multisig address creation - from kaspa package
# schnorr and ECDSA examples
assert address.to_string() == create_multisig_address(2, [pub1, pub2, pub3], 'testnet').to_string()
# assert ecdsa_address.to_string() == create_multisig_address(2, [pub1, pub2, pub3], 'testnet', True).to_string()

proceed = input("Send funds to address above before proceeding (enter 'y' to proceed): ")
if proceed != 'y':
return
Expand Down
17 changes: 17 additions & 0 deletions python/kaspa.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,23 @@ def sompi_to_kaspa(sompi: int) -> float: ...

def sompi_to_kaspa_string_with_suffix(sompi: int, network: str) -> str: ...

class AccountKind:

def __init__(self, kind: str) -> None: ...

def __str__(self) -> str: ...

def to_string(self) -> str: ...


def create_multisig_address(
minimum_signatures: int,
keys: list[PublicKey],
network_type: str,
ecdsa: Optional[bool] = None,
account_kind: Optional[str] = None,
) -> Address: ...

class PaymentOutput:

def __init__(self, address: Address, amount: int) -> None: ...
Expand Down
2 changes: 2 additions & 0 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ cfg_if::cfg_if! {
m.add_function(wrap_pyfunction!(kaspa_wallet_core::bindings::python::utils::kaspa_to_sompi, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::bindings::python::utils::sompi_to_kaspa, m)?)?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::bindings::python::utils::sompi_to_kaspa_string_with_suffix, m)?)?;
m.add_class::<kaspa_wallet_core::account::AccountKind>()?;
m.add_function(wrap_pyfunction!(kaspa_wallet_core::derivation::create_multisig_address_py, m)?)?;
m.add_class::<kaspa_wallet_core::tx::payment::PaymentOutput>()?;

m.add_class::<kaspa_wallet_keys::derivation_path::DerivationPath>()?;
Expand Down
21 changes: 21 additions & 0 deletions wallet/core/src/account/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
use crate::imports::*;
use fixedstr::*;
#[cfg(feature = "py-sdk")]
use pyo3::prelude::*;
use std::hash::Hash;
use std::str::FromStr;
use workflow_wasm::convert::CastFromJs;
Expand All @@ -15,6 +17,7 @@ use workflow_wasm::convert::CastFromJs;
///
/// @category Wallet SDK
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash, CastFromJs)]
#[cfg_attr(feature = "py-sdk", pyclass)]
#[wasm_bindgen]
pub struct AccountKind(str64);

Expand All @@ -30,6 +33,24 @@ impl AccountKind {
}
}

#[cfg(feature = "py-sdk")]
#[pymethods]
impl AccountKind {
#[new]
pub fn ctor_py(kind: &str) -> PyResult<AccountKind> {
Ok(Self::from_str(kind)?)
}

pub fn __str__(&self) -> String {
self.py_to_string()
}

#[pyo3(name = "to_string")]
pub fn py_to_string(&self) -> String {
self.0.as_str().to_string()
}
}

impl AccountKind {
pub fn as_str(&self) -> &str {
self.0.as_str()
Expand Down
18 changes: 18 additions & 0 deletions wallet/core/src/derivation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use kaspa_consensus_core::network::{NetworkType, NetworkTypeT};
use kaspa_txscript::{
extract_script_pub_key_address, multisig_redeem_script, multisig_redeem_script_ecdsa, pay_to_script_hash_script,
};
#[cfg(feature = "py-sdk")]
use pyo3::prelude::*;

#[derive(Default, Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
pub struct AddressDerivationMeta([u32; 2]);
Expand Down Expand Up @@ -485,6 +487,22 @@ pub fn create_multisig_address_js(
create_address(minimum_signatures, keys.try_into()?, network_type.into(), ecdsa.unwrap_or(false), account_kind)
}

#[cfg(feature = "py-sdk")]
#[pyfunction]
#[pyo3(name = "create_multisig_address")]
#[pyo3(signature = (minimum_signatures, keys, network_type, ecdsa=false, account_kind=None))]
pub fn create_multisig_address_py(
minimum_signatures: usize,
keys: Vec<PublicKey>,
network_type: &str,
ecdsa: Option<bool>,
account_kind: Option<AccountKind>,
) -> PyResult<Address> {
let network_type = NetworkType::from_str(network_type)?;
let keys = keys.iter().map(|pk| pk.try_into()).collect::<Result<Vec<_>, kaspa_wallet_keys::error::Error>>()?;
Ok(create_address(minimum_signatures, keys, network_type.into(), ecdsa.unwrap_or(false), account_kind)?)
}

pub fn create_address(
minimum_signatures: usize,
keys: Vec<secp256k1::PublicKey>,
Expand Down

0 comments on commit c28205e

Please sign in to comment.