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 { token: value.token.clone() },
84 mutable_settings: ReserveMutableSettings {
85 total_accrued_function_asset_name: value.total_accrued_function_script_hash.clone(),
86 initial_incentive: 0,
89 },
90 stats: ReserveStats { token_total_amount_transferred: 0 },
91 }
92 }
93}
94
95fn create_reserve_tx(
96 parameters: &ReserveParameters,
97 reserve: &ReserveData,
98 governance: &GovernanceData,
99 costs: Costs,
100 ctx: &TransactionContext,
101) -> anyhow::Result<Transaction> {
102 let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?);
103
104 tx_builder.add_mint_one_script_token_using_reference_script(
105 &Script::Plutus(reserve.scripts.auth_policy.clone()),
106 &reserve.auth_policy_version_utxo.to_csl_tx_input(),
107 &costs,
108 )?;
109 tx_builder.add_output(&reserve_validator_output(parameters, &reserve.scripts, ctx)?)?;
110
111 let gov_tx_input = governance.utxo_id_as_tx_input();
112 tx_builder.add_mint_one_script_token_using_reference_script(
113 &governance.policy.script(),
114 &gov_tx_input,
115 &costs,
116 )?;
117 tx_builder.add_script_reference_input(
118 &reserve.validator_version_utxo.to_csl_tx_input(),
119 reserve.scripts.validator.bytes.len(),
120 );
121 Ok(tx_builder.balance_update_and_build(ctx)?.remove_native_script_witnesses())
122}
123
124fn reserve_validator_output(
126 parameters: &ReserveParameters,
127 scripts: &ReserveScripts,
128 ctx: &TransactionContext,
129) -> Result<TransactionOutput, JsError> {
130 let amount_builder = TransactionOutputBuilder::new()
131 .with_address(&scripts.validator.address(ctx.network))
132 .with_plutus_data(&ReserveDatum::from(parameters).into())
133 .next()?;
134 let ma = MultiAsset::new()
135 .with_asset_amount(&scripts.auth_policy.empty_name_asset(), 1u64)?
136 .with_asset_amount(¶meters.token, parameters.initial_deposit)?;
137
138 amount_builder.with_minimum_ada_and_asset(&ma, ctx)?.build()
139}