partner_chains_cardano_offchain/reserve/
create.rs1use super::ReserveData;
19use crate::{
20 await_tx::AwaitTx,
21 cardano_keys::CardanoPaymentSigningKey,
22 csl::{
23 Costs, MultiAssetExt, OgmiosUtxoExt, Script, TransactionBuilderExt, TransactionContext,
24 TransactionExt, TransactionOutputAmountBuilderExt, get_builder_config,
25 },
26 governance::GovernanceData,
27 multisig::{MultiSigSmartContractResult, submit_or_create_tx_to_sign},
28 scripts_data::ReserveScripts,
29};
30use cardano_serialization_lib::{
31 JsError, MultiAsset, Transaction, TransactionBuilder, TransactionOutput,
32 TransactionOutputBuilder,
33};
34use ogmios_client::{
35 query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId},
36 query_network::QueryNetwork,
37 transactions::Transactions,
38};
39use partner_chains_plutus_data::reserve::{
40 ReserveDatum, ReserveImmutableSettings, ReserveMutableSettings, ReserveStats,
41};
42use sidechain_domain::{AssetId, PolicyId, UtxoId};
43
44pub async fn create_reserve_utxo<
46 T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId,
47 A: AwaitTx,
48>(
49 parameters: ReserveParameters,
50 genesis_utxo: UtxoId,
51 payment_key: &CardanoPaymentSigningKey,
52 client: &T,
53 await_tx: &A,
54) -> anyhow::Result<MultiSigSmartContractResult> {
55 let payment_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, &payment_ctx, client).await?;
58
59 submit_or_create_tx_to_sign(
60 &governance,
61 payment_ctx,
62 |costs, ctx| create_reserve_tx(¶meters, &reserve, &governance, costs, &ctx),
63 "Create Reserve",
64 client,
65 await_tx,
66 )
67 .await
68}
69
70pub struct ReserveParameters {
72 pub total_accrued_function_script_hash: PolicyId,
74 pub token: AssetId,
76 pub initial_deposit: u64,
78}
79
80impl From<&ReserveParameters> for ReserveDatum {
81 fn from(value: &ReserveParameters) -> Self {
82 ReserveDatum {
83 immutable_settings: ReserveImmutableSettings { t0: 0, token: value.token.clone() },
87 mutable_settings: ReserveMutableSettings {
88 total_accrued_function_asset_name: value.total_accrued_function_script_hash.clone(),
89 initial_incentive: 0,
92 },
93 stats: ReserveStats { token_total_amount_transferred: 0 },
94 }
95 }
96}
97
98fn create_reserve_tx(
99 parameters: &ReserveParameters,
100 reserve: &ReserveData,
101 governance: &GovernanceData,
102 costs: Costs,
103 ctx: &TransactionContext,
104) -> anyhow::Result<Transaction> {
105 let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?);
106
107 tx_builder.add_mint_one_script_token_using_reference_script(
108 &Script::Plutus(reserve.scripts.auth_policy.clone()),
109 &reserve.auth_policy_version_utxo.to_csl_tx_input(),
110 &costs,
111 )?;
112 tx_builder.add_output(&reserve_validator_output(parameters, &reserve.scripts, ctx)?)?;
113
114 let gov_tx_input = governance.utxo_id_as_tx_input();
115 tx_builder.add_mint_one_script_token_using_reference_script(
116 &governance.policy.script(),
117 &gov_tx_input,
118 &costs,
119 )?;
120 tx_builder.add_script_reference_input(
121 &reserve.validator_version_utxo.to_csl_tx_input(),
122 reserve.scripts.validator.bytes.len(),
123 );
124 Ok(tx_builder.balance_update_and_build(ctx)?.remove_native_script_witnesses())
125}
126
127fn reserve_validator_output(
129 parameters: &ReserveParameters,
130 scripts: &ReserveScripts,
131 ctx: &TransactionContext,
132) -> Result<TransactionOutput, JsError> {
133 let amount_builder = TransactionOutputBuilder::new()
134 .with_address(&scripts.validator.address(ctx.network))
135 .with_plutus_data(&ReserveDatum::from(parameters).into())
136 .next()?;
137 let ma = MultiAsset::new()
138 .with_asset_amount(&scripts.auth_policy.empty_name_asset(), 1u64)?
139 .with_asset_amount(¶meters.token, parameters.initial_deposit)?;
140
141 amount_builder.with_minimum_ada_and_asset(&ma, ctx)?.build()
142}