use tronz_primitives::{Bytes, Trx};
use tronz_provider::{
PendingTransaction, TronProvider,
types::{ContractType, CreateSmartContract, TransactionRequest},
};
use crate::error::{ContractError, Result};
pub struct DeployBuilder<P> {
provider: P,
bytecode: Bytes,
abi: Vec<u8>,
call_value: Trx,
fee_limit: Option<Trx>,
consume_user_resource_percent: i64,
origin_energy_limit: i64,
name: String,
}
impl<P: TronProvider> DeployBuilder<P> {
pub(crate) fn new(provider: P, bytecode: impl Into<Bytes>) -> Self {
Self {
provider,
bytecode: bytecode.into(),
abi: Vec::new(),
call_value: Trx::ZERO,
fee_limit: None,
consume_user_resource_percent: 100,
origin_energy_limit: 10_000_000,
name: String::new(),
}
}
#[inline]
pub fn abi(mut self, abi: impl Into<Vec<u8>>) -> Self {
self.abi = abi.into();
self
}
#[inline]
pub fn value(mut self, trx: Trx) -> Self {
self.call_value = trx;
self
}
#[inline]
pub fn fee_limit(mut self, limit: Trx) -> Self {
self.fee_limit = Some(limit);
self
}
#[inline]
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = name.into();
self
}
#[inline]
pub fn consume_user_resource_percent(mut self, pct: i64) -> Self {
self.consume_user_resource_percent = pct;
self
}
#[inline]
pub fn origin_energy_limit(mut self, limit: i64) -> Self {
self.origin_energy_limit = limit;
self
}
pub async fn send(self) -> Result<PendingTransaction<P>> {
let owner = self
.provider
.signer_address()
.ok_or(ContractError::NoSigner)?;
let mut req = TransactionRequest::default().with_contract(
ContractType::CreateSmartContract(CreateSmartContract {
owner_address: owner,
bytecode: self.bytecode,
abi: self.abi,
call_value: self.call_value,
consume_user_resource_percent: self.consume_user_resource_percent,
origin_energy_limit: self.origin_energy_limit,
name: self.name,
}),
);
if let Some(limit) = self.fee_limit {
req = req.with_fee_limit(limit);
}
self.provider
.send_transaction(req)
.await
.map_err(ContractError::Provider)
}
}