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