Skip to content

Commit d0f7a99

Browse files
committed
feat: complete dig collateral coin utility
1 parent f6cd59b commit d0f7a99

File tree

1 file changed

+101
-50
lines changed

1 file changed

+101
-50
lines changed

src/dig_collateral_coin.rs

Lines changed: 101 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::dig_coin::DigCoin;
22
use crate::error::WalletError;
33
use crate::wallet::DIG_ASSET_ID;
4-
use crate::{Bytes, Bytes32, Coin, CoinSpend, CoinState, P2ParentCoin, Peer, PublicKey};
4+
use crate::{
5+
Bytes, Bytes32, Coin, CoinSpend, CoinState, LineageProof, P2ParentCoin, Peer, PublicKey,
6+
};
57
use chia::puzzles::Memos;
68
use chia::traits::Streamable;
79
use chia_wallet_sdk::driver::{
@@ -13,6 +15,7 @@ use clvmr::Allocator;
1315
use indexmap::indexmap;
1416
use num_bigint::BigInt;
1517

18+
#[derive(Debug, Clone)]
1619
pub struct DigCollateralCoin {
1720
inner: P2ParentCoin,
1821
#[allow(dead_code)]
@@ -22,8 +25,16 @@ pub struct DigCollateralCoin {
2225
}
2326

2427
impl DigCollateralCoin {
28+
pub fn coin(&self) -> Coin {
29+
self.inner.coin
30+
}
31+
32+
pub fn proof(&self) -> LineageProof {
33+
self.inner.proof
34+
}
35+
2536
/// Morphs a DIG store launcher ID into the DIG store collateral coin namespace.
26-
pub fn morph_store_launcher_if_for_collateral(store_launcher_id: Bytes32) -> Bytes32 {
37+
pub fn morph_store_launcher_id_for_collateral(store_launcher_id: Bytes32) -> Bytes32 {
2738
(store_launcher_id, "DIG_STORE_COLLATERAL")
2839
.tree_hash()
2940
.into()
@@ -139,67 +150,62 @@ impl DigCollateralCoin {
139150

140151
/// Uses the specified $DIG to create a collateral coin for the provided DIG store ID (launcher ID)
141152
#[allow(clippy::result_large_err)]
142-
pub fn create(
153+
pub fn create_collateral(
143154
dig_coins: Vec<DigCoin>,
144-
collateral_amount: u64,
155+
amount: u64,
145156
store_id: Bytes32,
146-
mirror_urls: Option<Vec<String>>,
147157
synthetic_key: PublicKey,
148158
fee_coins: Vec<Coin>,
149159
fee: u64,
150160
) -> Result<Vec<CoinSpend>, WalletError> {
151-
let p2_parent_inner_hash = P2ParentCoin::inner_puzzle_hash(Some(DIG_ASSET_ID));
152-
153161
let mut ctx = SpendContext::new();
154162

155-
let morphed_store_id = Self::morph_store_launcher_if_for_collateral(store_id);
156-
157-
let memos = match mirror_urls {
158-
Some(urls) => {
159-
let mut memos_vec = Vec::with_capacity(urls.len() + 1);
160-
memos_vec.push(morphed_store_id.to_vec());
161-
162-
for url in &urls {
163-
memos_vec.push(url.as_bytes().to_vec());
164-
}
165-
166-
let memos_node_ptr = ctx.alloc(&memos_vec)?;
167-
Memos::Some(memos_node_ptr)
168-
}
169-
None => ctx.hint(morphed_store_id)?,
170-
};
171-
172-
let actions = [
173-
Action::fee(fee),
174-
Action::send(
175-
Id::Existing(DIG_ASSET_ID),
176-
p2_parent_inner_hash.into(),
177-
collateral_amount,
178-
memos,
179-
),
180-
];
163+
let morphed_store_id = Self::morph_store_launcher_id_for_collateral(store_id);
164+
let hint = ctx.hint(morphed_store_id)?;
181165

182-
let p2_layer = StandardLayer::new(synthetic_key);
183-
let p2_puzzle_hash: Bytes32 = p2_layer.tree_hash().into();
184-
let mut spends = Spends::new(p2_puzzle_hash);
166+
Self::build_coin_spends(
167+
&mut ctx,
168+
hint,
169+
dig_coins,
170+
amount,
171+
synthetic_key,
172+
fee_coins,
173+
fee,
174+
)
175+
}
185176

186-
// add collateral coins to spends
187-
for dig_coin in dig_coins {
188-
spends.add(dig_coin.cat());
189-
}
177+
#[allow(clippy::result_large_err, clippy::too_many_arguments)]
178+
pub fn create_mirror(
179+
dig_coins: Vec<DigCoin>,
180+
amount: u64,
181+
store_id: Bytes32,
182+
mirror_urls: Vec<String>,
183+
epoch: BigInt,
184+
synthetic_key: PublicKey,
185+
fee_coins: Vec<Coin>,
186+
fee: u64,
187+
) -> Result<Vec<CoinSpend>, WalletError> {
188+
let mut ctx = SpendContext::new();
189+
let morphed_store_id = Self::morph_store_launcher_id_for_mirror(store_id, &epoch);
190+
let mut memos_vec = Vec::with_capacity(mirror_urls.len() + 1);
191+
memos_vec.push(morphed_store_id.to_vec());
190192

191-
// add fee coins to spends
192-
for fee_xch_coin in fee_coins {
193-
spends.add(fee_xch_coin);
193+
for url in &mirror_urls {
194+
memos_vec.push(url.as_bytes().to_vec());
194195
}
195196

196-
let deltas = spends.apply(&mut ctx, &actions)?;
197-
let index_map = indexmap! {p2_puzzle_hash => synthetic_key};
197+
let memos_node_ptr = ctx.alloc(&memos_vec)?;
198+
let memos = Memos::Some(memos_node_ptr);
198199

199-
let _outputs =
200-
spends.finish_with_keys(&mut ctx, &deltas, Relation::AssertConcurrent, &index_map)?;
201-
202-
Ok(ctx.take())
200+
Self::build_coin_spends(
201+
&mut ctx,
202+
memos,
203+
dig_coins,
204+
amount,
205+
synthetic_key,
206+
fee_coins,
207+
fee,
208+
)
203209
}
204210

205211
/// Builds the spend bundle for spending the $DIG collateral coin to de-collateralize
@@ -216,7 +222,7 @@ impl DigCollateralCoin {
216222

217223
if p2_puzzle_hash != self.inner.proof.parent_inner_puzzle_hash {
218224
return Err(WalletError::PuzzleHashMismatch(
219-
"This coin is not owned by this wallet".to_string(),
225+
"Collateral coin controlled by another wallet".to_string(),
220226
));
221227
}
222228

@@ -256,4 +262,49 @@ impl DigCollateralCoin {
256262

257263
Ok(ctx.take())
258264
}
265+
266+
#[allow(clippy::result_large_err)]
267+
fn build_coin_spends(
268+
ctx: &mut SpendContext,
269+
memos: Memos,
270+
dig_coins: Vec<DigCoin>,
271+
amount: u64,
272+
synthetic_key: PublicKey,
273+
fee_coins: Vec<Coin>,
274+
fee: u64,
275+
) -> Result<Vec<CoinSpend>, WalletError> {
276+
let p2_parent_inner_hash = P2ParentCoin::inner_puzzle_hash(Some(DIG_ASSET_ID));
277+
278+
let actions = [
279+
Action::fee(fee),
280+
Action::send(
281+
Id::Existing(DIG_ASSET_ID),
282+
p2_parent_inner_hash.into(),
283+
amount,
284+
memos,
285+
),
286+
];
287+
288+
let p2_layer = StandardLayer::new(synthetic_key);
289+
let p2_puzzle_hash: Bytes32 = p2_layer.tree_hash().into();
290+
let mut spends = Spends::new(p2_puzzle_hash);
291+
292+
// add collateral coins to spends
293+
for dig_coin in dig_coins {
294+
spends.add(dig_coin.cat());
295+
}
296+
297+
// add fee coins to spends
298+
for fee_xch_coin in fee_coins {
299+
spends.add(fee_xch_coin);
300+
}
301+
302+
let deltas = spends.apply(ctx, &actions)?;
303+
let index_map = indexmap! {p2_puzzle_hash => synthetic_key};
304+
305+
let _outputs =
306+
spends.finish_with_keys(ctx, &deltas, Relation::AssertConcurrent, &index_map)?;
307+
308+
Ok(ctx.take())
309+
}
259310
}

0 commit comments

Comments
 (0)