kon-cli/src/tx/send.rs

81 lines
2.7 KiB
Rust

use anyhow::Result;
use minicbor::encode;
use pallas_addresses::{Address, ShelleyAddress, ShelleyDelegationPart};
use pallas_primitives::{
conway::{
PostAlonzoTransactionOutput, TransactionBody, TransactionInput, TransactionOutput, Tx,
Value, WitnessSet,
},
Coin, Nullable, Set,
};
use crate::{cardano::cardano::Cardano, wallet::Wallet};
use super::{
context::TxContext,
plutus::{
build_transaction, default_transaction_body, default_witness_set, expect_post_alonzo,
from_network, into_outputs, value_subtract_lovelace, BuildParams,
},
};
pub async fn send<T>(ctx: TxContext<T>, target: Vec<(Address, u64)>) -> Result<String>
where
T: Cardano,
{
let available_utxos = ctx.available_utxos().await.unwrap();
let wallet_address = ctx.wallet_address();
let mut tx = build_transaction(
&ctx.build_parameters().await,
&available_utxos,
|fee, ex_units| {
let inputs = available_utxos
.iter()
.map(|u| u.input.clone())
.collect::<Vec<TransactionInput>>();
let x = expect_post_alonzo(&available_utxos[0].output);
let mut outputs = target
.iter()
.map(|tup| PostAlonzoTransactionOutput {
address: tup.0.to_vec().into(),
value: Value::Coin(tup.1 * 1_000_000),
datum_option: None,
script_ref: None,
})
.collect::<Vec<PostAlonzoTransactionOutput>>();
outputs.push(
// Change
PostAlonzoTransactionOutput {
address: wallet_address.to_vec().into(),
value: value_subtract_lovelace(x.value.clone(), fee).expect("not enough fuel"),
datum_option: None,
script_ref: None,
},
);
// ----- Put it all together
Tx {
transaction_body: TransactionBody {
inputs: Set::from(inputs),
network_id: Some(from_network(ctx.cardano.network_id())),
outputs: into_outputs(outputs),
fee,
..default_transaction_body()
},
transaction_witness_set: WitnessSet {
..default_witness_set()
},
success: true,
auxiliary_data: Nullable::Null,
}
},
);
ctx.wallet.sign(&mut tx);
let mut serialized_tx = Vec::new();
println!("{:?}", tx);
encode(&tx, &mut serialized_tx).unwrap();
let tx_hash = ctx.cardano.submit(serialized_tx).await?;
Ok(tx_hash)
}