partner_chains_cardano_offchain/reserve/
handover.rs1use super::{ReserveUtxo, TokenAmount, reserve_utxo_input_with_validator_script_reference};
22use crate::{
23 await_tx::AwaitTx,
24 cardano_keys::CardanoPaymentSigningKey,
25 csl::{
26 AssetIdExt, CostStore, Costs, OgmiosUtxoExt, Script, TransactionBuilderExt,
27 TransactionContext, TransactionExt, TransactionOutputAmountBuilderExt, get_builder_config,
28 unit_plutus_data,
29 },
30 governance::GovernanceData,
31 multisig::{MultiSigSmartContractResult, submit_or_create_tx_to_sign},
32 reserve::ReserveData,
33 scripts_data::ReserveScripts,
34};
35use cardano_serialization_lib::*;
36use ogmios_client::{
37 query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId},
38 query_network::QueryNetwork,
39 transactions::Transactions,
40 types::OgmiosUtxo,
41};
42use partner_chains_plutus_data::reserve::ReserveRedeemer;
43use sidechain_domain::UtxoId;
44
45pub async fn handover_reserve<
47 T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId,
48 A: AwaitTx,
49>(
50 genesis_utxo: UtxoId,
51 payment_key: &CardanoPaymentSigningKey,
52 client: &T,
53 await_tx: &A,
54) -> anyhow::Result<MultiSigSmartContractResult> {
55 let ctx = TransactionContext::for_payment_key(payment_key, client).await?;
56 let governance = GovernanceData::get(genesis_utxo, client).await?;
57 let reserve = ReserveData::get(genesis_utxo, &ctx, client).await?;
58
59 let ref reserve_utxo @ ReserveUtxo { ref utxo, .. } =
60 reserve.get_reserve_utxo(&ctx, client).await?;
61 let amount = get_amount_to_release(reserve_utxo);
62
63 submit_or_create_tx_to_sign(
64 &governance,
65 ctx,
66 |costs, ctx| build_tx(&amount, utxo, &reserve, &governance, costs, &ctx),
67 "Handover Reserve",
68 client,
69 await_tx,
70 )
71 .await
72}
73
74fn get_amount_to_release(reserve_utxo: &ReserveUtxo) -> TokenAmount {
75 let token = reserve_utxo.datum.immutable_settings.token.clone();
76 let amount = reserve_utxo.utxo.get_asset_amount(&token);
77 TokenAmount { token, amount }
78}
79
80fn build_tx(
81 handover_amount: &TokenAmount,
82 reserve_utxo: &OgmiosUtxo,
83 reserve: &ReserveData,
84 governance: &GovernanceData,
85 costs: Costs,
86 ctx: &TransactionContext,
87) -> anyhow::Result<Transaction> {
88 let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?);
89
90 let reserve_auth_policy_spend_cost = costs.get_one_spend();
91
92 tx_builder.add_mint_one_script_token_using_reference_script(
94 &governance.policy.script(),
95 &governance.utxo_id_as_tx_input(),
96 &costs,
97 )?;
98
99 tx_builder.set_inputs(&reserve_utxo_input_with_validator_script_reference(
101 reserve_utxo,
102 reserve,
103 ReserveRedeemer::Handover,
104 &reserve_auth_policy_spend_cost,
105 )?);
106
107 tx_builder.add_mint_script_token_using_reference_script(
109 &Script::Plutus(reserve.scripts.auth_policy.clone()),
110 &reserve.auth_policy_version_utxo.to_csl_tx_input(),
111 &Int::new_i32(-1),
112 &costs,
113 )?;
114
115 tx_builder.add_output(&illiquid_supply_validator_output(
116 handover_amount,
117 &reserve.scripts,
118 ctx,
119 )?)?;
120 tx_builder.add_script_reference_input(
121 &reserve.illiquid_circulation_supply_validator_version_utxo.to_csl_tx_input(),
122 reserve.scripts.illiquid_circulation_supply_validator.bytes.len(),
123 );
124 Ok(tx_builder.balance_update_and_build(ctx)?.remove_native_script_witnesses())
125}
126
127fn illiquid_supply_validator_output(
129 output_value: &TokenAmount,
130 scripts: &ReserveScripts,
131 ctx: &TransactionContext,
132) -> Result<TransactionOutput, JsError> {
133 let tx_output_builder = TransactionOutputBuilder::new()
134 .with_address(&scripts.illiquid_circulation_supply_validator.address(ctx.network));
135 if output_value.amount > 0 {
136 let ma = output_value.token.to_multi_asset(output_value.amount)?;
137 let amount_builder = tx_output_builder
138 .with_plutus_data(&illiquid_supply_validator_redeemer())
139 .next()?;
140 amount_builder.with_minimum_ada_and_asset(&ma, ctx)?.build()
141 } else {
142 let amount_builder = tx_output_builder.next()?;
145 amount_builder.with_minimum_ada(ctx)?.build()
146 }
147}
148
149fn illiquid_supply_validator_redeemer() -> PlutusData {
150 unit_plutus_data()
151}