@@ -2,7 +2,11 @@ use chia::{
22 clvm_utils:: ToTreeHash ,
33 protocol:: { Bytes , Bytes32 , CoinSpend } ,
44} ;
5- use chia_wallet_sdk:: driver:: { Action , ClawbackV2 , Id , SpendContext } ;
5+ use chia_wallet_sdk:: {
6+ driver:: { Action , Cat , CatSpend , ClawbackV2 , Id , SpendContext } ,
7+ prelude:: AssertConcurrentSpend ,
8+ } ;
9+ use sage_database:: { CoinKind , P2Puzzle } ;
610
711use crate :: {
812 wallet:: memos:: { calculate_memos, Hint } ,
@@ -53,6 +57,86 @@ impl Wallet {
5357
5458 Ok ( ctx. take ( ) )
5559 }
60+
61+ pub async fn finalize_clawback (
62+ & self ,
63+ coin_ids : Vec < Bytes32 > ,
64+ fee : u64 ,
65+ ) -> Result < Vec < CoinSpend > , WalletError > {
66+ let mut ctx = SpendContext :: new ( ) ;
67+
68+ for & coin_id in & coin_ids {
69+ let Some ( coin_kind) = self . db . coin_kind ( coin_id) . await ? else {
70+ return Err ( WalletError :: MissingCoin ( coin_id) ) ;
71+ } ;
72+
73+ match coin_kind {
74+ CoinKind :: Xch => {
75+ let Some ( coin) = self . db . xch_coin ( coin_id) . await ? else {
76+ return Err ( WalletError :: MissingXchCoin ( coin_id) ) ;
77+ } ;
78+
79+ let P2Puzzle :: Clawback ( clawback) = self . db . p2_puzzle ( coin. puzzle_hash ) . await ?
80+ else {
81+ return Err ( WalletError :: MissingClawbackInfo ( coin_id) ) ;
82+ } ;
83+
84+ let clawback = ClawbackV2 :: new (
85+ clawback. sender_puzzle_hash ,
86+ clawback. receiver_puzzle_hash ,
87+ clawback. seconds ,
88+ coin. amount ,
89+ false ,
90+ ) ;
91+
92+ clawback. push_through_coin_spend ( & mut ctx, coin) ?;
93+ }
94+ CoinKind :: Cat => {
95+ let Some ( cat) = self . db . cat_coin ( coin_id) . await ? else {
96+ return Err ( WalletError :: MissingCatCoin ( coin_id) ) ;
97+ } ;
98+
99+ let P2Puzzle :: Clawback ( clawback) =
100+ self . db . p2_puzzle ( cat. info . p2_puzzle_hash ) . await ?
101+ else {
102+ return Err ( WalletError :: MissingClawbackInfo ( coin_id) ) ;
103+ } ;
104+
105+ let clawback = ClawbackV2 :: new (
106+ clawback. sender_puzzle_hash ,
107+ clawback. receiver_puzzle_hash ,
108+ clawback. seconds ,
109+ cat. coin . amount ,
110+ true ,
111+ ) ;
112+
113+ let spend = clawback. push_through_spend ( & mut ctx) ?;
114+ Cat :: spend_all ( & mut ctx, & [ CatSpend :: new ( cat, spend) ] ) ?;
115+ }
116+ _ => {
117+ return Err ( WalletError :: UnsupportedClawbackCoinKind ( coin_kind) ) ;
118+ }
119+ }
120+ }
121+
122+ if fee > 0 {
123+ let actions = [ Action :: fee ( fee) ] ;
124+
125+ let mut spends = self . prepare_spends ( & mut ctx, vec ! [ ] , & actions) . await ?;
126+
127+ for & coin_id in & coin_ids {
128+ spends
129+ . conditions
130+ . required
131+ . push ( AssertConcurrentSpend :: new ( coin_id) ) ;
132+ }
133+
134+ let deltas = spends. apply ( & mut ctx, & actions) ?;
135+ self . complete_spends ( & mut ctx, & deltas, spends) . await ?;
136+ }
137+
138+ Ok ( ctx. take ( ) )
139+ }
56140}
57141
58142#[ cfg( test) ]
0 commit comments