use crate::transaction::auth::Authorization;
use crate::transaction::auth::MultiHashMode;
use crate::transaction::auth::MultiSpendingCondition;
use crate::transaction::auth::SingleHashMode;
use crate::transaction::auth::SingleSpendingCondition;
use crate::transaction::AnchorMode;
use crate::transaction::Error;
use crate::transaction::PostConditionMode;
use crate::transaction::PostConditions;
use crate::transaction::StacksTransaction;
use crate::transaction::TokenTransferPayload;
use crate::transaction::TransactionSigner;
use crate::Network;
use crate::StacksPrivateKey;
use crate::StacksPublicKey;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct STXTokenTransfer {
transaction: StacksTransaction,
sender_key: StacksPrivateKey,
}
impl STXTokenTransfer {
pub fn new<T: Network>(
recipient: impl Into<String>,
sender_key: StacksPrivateKey,
amount: u64,
fee: u64,
nonce: u64,
network: impl AsRef<T>,
anchor_mode: AnchorMode,
memo: impl Into<String>,
post_condition_mode: PostConditionMode,
post_conditions: PostConditions,
sponsored: bool,
) -> Result<Self, Error> {
let network = network.as_ref();
let public_key = sender_key.public_key(&secp256k1::Secp256k1::new());
let payload = TokenTransferPayload::new(recipient, amount, memo)?;
let condition = SingleSpendingCondition::new(fee, nonce, public_key, SingleHashMode::P2PKH);
let auth = if sponsored {
Authorization::Sponsored(condition, SingleSpendingCondition::new_empty())
} else {
Authorization::Standard(condition)
};
let transaction = StacksTransaction::new(
network.version(),
network.chain_id(),
auth,
anchor_mode,
post_condition_mode,
post_conditions,
payload,
);
Ok(Self {
transaction,
sender_key,
})
}
pub fn sign(mut self) -> Result<StacksTransaction, Error> {
let mut signer = TransactionSigner::new(&mut self.transaction)?;
signer.sign_origin(&self.sender_key)?;
Ok(self.transaction)
}
pub fn set_fee(&mut self, fee: u64) {
self.transaction.set_fee(fee);
}
pub fn set_nonce(&mut self, nonce: u64) {
self.transaction.set_nonce(nonce);
}
pub fn byte_length(&self) -> Result<u64, Error> {
self.transaction.clone().byte_length()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct STXTokenTransferMultiSig {
transaction: StacksTransaction,
signer_keys: Vec<StacksPrivateKey>,
public_keys: Vec<StacksPublicKey>,
signatures: u8,
}
impl STXTokenTransferMultiSig {
pub fn new<T: Network>(
recipient: impl Into<String>,
signer_keys: impl Into<Vec<StacksPrivateKey>>,
public_keys: impl Into<Vec<StacksPublicKey>>,
signatures: u8,
amount: u64,
fee: u64,
nonce: u64,
network: impl AsRef<T>,
anchor_mode: AnchorMode,
memo: impl Into<String>,
post_condition_mode: PostConditionMode,
post_conditions: PostConditions,
sponsored: bool,
) -> Result<Self, Error> {
let network = network.as_ref();
let signer_keys = signer_keys.into();
let public_keys = public_keys.into();
let payload = TokenTransferPayload::new(recipient, amount, memo)?;
let condition =
MultiSpendingCondition::new(nonce, fee, &public_keys, signatures, MultiHashMode::P2SH);
let auth = if sponsored {
Authorization::Sponsored(condition, SingleSpendingCondition::new_empty())
} else {
Authorization::Standard(condition)
};
let transaction = StacksTransaction::new(
network.version(),
network.chain_id(),
auth,
anchor_mode,
post_condition_mode,
post_conditions,
payload,
);
Ok(Self {
transaction,
signer_keys,
public_keys,
signatures,
})
}
pub fn sign(mut self) -> Result<StacksTransaction, Error> {
let secp = secp256k1::Secp256k1::new();
let private_keys = self.signer_keys;
let mut public_keys = self.public_keys.clone();
let mut signer = TransactionSigner::new(&mut self.transaction)?;
for key in private_keys {
let public_key = key.public_key(&secp);
public_keys.retain(|k| k != &public_key);
signer.sign_origin(&key)?;
}
for key in public_keys {
signer.append_origin(&key)?;
}
Ok(self.transaction)
}
pub fn set_fee(&mut self, fee: u64) {
self.transaction.set_fee(fee);
}
pub fn set_nonce(&mut self, nonce: u64) {
self.transaction.set_nonce(nonce);
}
pub fn byte_length(&self) -> Result<u64, Error> {
self.transaction.clone().byte_length()
}
}