partner_chains_cardano_offchain/init_governance/
mod.rs

1use crate::{
2	await_tx::AwaitTx, cardano_keys::CardanoPaymentSigningKey, csl::Costs, csl::key_hash_address,
3	governance::MultiSigParameters,
4};
5use anyhow::anyhow;
6use ogmios_client::{
7	query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId},
8	query_network::QueryNetwork,
9	transactions::Transactions,
10};
11use sidechain_domain::{McTxHash, UtxoId};
12
13#[cfg(test)]
14mod tests;
15
16pub(crate) mod transaction;
17
18#[derive(serde::Serialize)]
19/// Result type of [run_init_governance].
20pub struct InitGovernanceResult {
21	/// Hash of submitted transaction.
22	pub tx_hash: McTxHash,
23	/// Genesis UTxO id identifying Partner Chain.
24	pub genesis_utxo: UtxoId,
25}
26
27/// Initializes multi-signature governance. Initialization spends provided `genesis_utxo_id` or picks one from the `payment_key`.
28/// This UTxO will identify the Partner Chain.
29pub async fn run_init_governance<
30	T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId,
31	A: AwaitTx,
32>(
33	governance_parameters: &MultiSigParameters,
34	payment_key: &CardanoPaymentSigningKey,
35	genesis_utxo_id: Option<UtxoId>,
36	client: &T,
37	await_tx: A,
38) -> anyhow::Result<InitGovernanceResult> {
39	let ctx = crate::csl::TransactionContext::for_payment_key(payment_key, client).await?;
40
41	let own_address = key_hash_address(&ctx.payment_key_hash(), ctx.network);
42	log::info!("✉️ Submitter address: {}", own_address.to_bech32(None).unwrap());
43
44	let own_utxos = ctx.payment_key_utxos.clone();
45	log::info!("💱 {} UTXOs available", own_utxos.len());
46
47	let genesis_utxo = match genesis_utxo_id {
48		None => {
49			log::info!("⚙️ No genesis UTXO provided, will select one automatically...");
50			let utxo = own_utxos.first().ok_or(anyhow!("No UTXOs to choose from"))?.clone();
51			log::info!("☑️ UTXO selected: {}", utxo);
52			utxo
53		},
54		Some(utxo_id) => own_utxos
55			.iter()
56			.find(|utxo| utxo.transaction.id == utxo_id.tx_hash.0 && utxo.index == utxo_id.index.0)
57			.ok_or(anyhow!("Could not find genesis UTXO: {utxo_id}"))?
58			.clone(),
59	};
60
61	let tx = Costs::calculate_costs(
62		|costs| {
63			transaction::init_governance_transaction(
64				governance_parameters,
65				genesis_utxo.clone(),
66				costs,
67				&ctx,
68			)
69		},
70		client,
71	)
72	.await?;
73
74	let signed_transaction = ctx.sign(&tx);
75
76	let result = client.submit_transaction(&signed_transaction.to_bytes()).await?;
77	let tx_id = result.transaction.id;
78	log::info!("✅ Transaction submitted. ID: {}", hex::encode(tx_id));
79	await_tx.await_tx_output(client, UtxoId::new(tx_id, 0)).await?;
80	Ok(InitGovernanceResult { tx_hash: McTxHash(tx_id), genesis_utxo: genesis_utxo.utxo_id() })
81}