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