11use crate :: crypto;
22use crate :: error:: Error ;
33use crate :: storage;
4- use crate :: types:: { HTLCStatus , HashAlgorithm , HTLC } ;
4+ use crate :: types:: { HTLCStatus , HashAlgorithm , HTLC , MultiSigConfig } ;
55use soroban_sdk:: { Address , Bytes , BytesN , Env } ;
66
77/// Creates a new HTLC using SHA256 as the hash algorithm (default, Bitcoin-compatible).
@@ -12,14 +12,20 @@ pub fn create_htlc(
1212 amount : i128 ,
1313 hash_lock : BytesN < 32 > ,
1414 time_lock : u64 ,
15+ multi_sig : Option < MultiSigConfig > ,
1516) -> Result < u64 , Error > {
17+ if storage:: is_paused ( env) {
18+ return Err ( Error :: Paused ) ;
19+ }
20+
1621 create_htlc_with_algorithm (
1722 env,
1823 sender,
1924 receiver,
2025 amount,
2126 hash_lock,
2227 time_lock,
28+ multi_sig,
2329 HashAlgorithm :: SHA256 ,
2430 )
2531}
@@ -35,6 +41,7 @@ pub fn create_htlc_with_algorithm(
3541 amount : i128 ,
3642 hash_lock : BytesN < 32 > ,
3743 time_lock : u64 ,
44+ multi_sig : Option < MultiSigConfig > ,
3845 algorithm : HashAlgorithm ,
3946) -> Result < u64 , Error > {
4047 if amount <= 0 {
@@ -57,6 +64,7 @@ pub fn create_htlc_with_algorithm(
5764 status : HTLCStatus :: Active ,
5865 secret : None ,
5966 created_at : current_time,
67+ multi_sig,
6068 hash_algorithm : algorithm,
6169 } ;
6270
@@ -69,6 +77,10 @@ pub fn create_htlc_with_algorithm(
6977/// Uses the algorithm stored in the HTLC and constant-time comparison
7078/// to prevent timing-based side channel attacks.
7179pub fn claim_htlc ( env : & Env , htlc_id : u64 , secret : Bytes ) -> Result < ( ) , Error > {
80+ if storage:: is_paused ( env) {
81+ return Err ( Error :: Paused ) ;
82+ }
83+
7284 let mut htlc = storage:: read_htlc ( env, htlc_id) . ok_or ( Error :: HTLCNotFound ) ?;
7385
7486 if htlc. status != HTLCStatus :: Active {
@@ -80,6 +92,12 @@ pub fn claim_htlc(env: &Env, htlc_id: u64, secret: Bytes) -> Result<(), Error> {
8092 return Err ( Error :: HTLCExpired ) ;
8193 }
8294
95+ if let Some ( config) = & htlc. multi_sig {
96+ if config. signatures . len ( ) < config. threshold {
97+ return Err ( Error :: ThresholdNotMet ) ;
98+ }
99+ }
100+
83101 // Verify the secret preimage using constant-time comparison to prevent
84102 // timing attacks. Uses the algorithm chosen when the HTLC was created.
85103 if !crypto:: verify_preimage ( env, & secret, & htlc. hash_lock , & htlc. hash_algorithm ) {
@@ -94,6 +112,10 @@ pub fn claim_htlc(env: &Env, htlc_id: u64, secret: Bytes) -> Result<(), Error> {
94112}
95113
96114pub fn refund_htlc ( env : & Env , htlc_id : u64 , sender : & Address ) -> Result < ( ) , Error > {
115+ if storage:: is_paused ( env) {
116+ return Err ( Error :: Paused ) ;
117+ }
118+
97119 let mut htlc = storage:: read_htlc ( env, htlc_id) . ok_or ( Error :: HTLCNotFound ) ?;
98120
99121 if htlc. sender != * sender {
@@ -142,3 +164,29 @@ pub fn get_revealed_secret(env: &Env, htlc_id: u64) -> Result<Option<Bytes>, Err
142164 let htlc = storage:: read_htlc ( env, htlc_id) . ok_or ( Error :: HTLCNotFound ) ?;
143165 Ok ( htlc. secret )
144166}
167+
168+ pub fn sign_htlc ( env : & Env , htlc_id : u64 , signer : & Address ) -> Result < ( ) , Error > {
169+ if storage:: is_paused ( env) {
170+ return Err ( Error :: Paused ) ;
171+ }
172+
173+ let mut htlc = storage:: read_htlc ( env, htlc_id) . ok_or ( Error :: HTLCNotFound ) ?;
174+
175+ if htlc. status != HTLCStatus :: Active {
176+ return Err ( Error :: AlreadyClaimed ) ; // or similar error
177+ }
178+
179+ if let Some ( mut config) = htlc. multi_sig . clone ( ) {
180+ if !config. signers . contains ( signer) {
181+ return Err ( Error :: SignerNotAuthorized ) ;
182+ }
183+ if !config. signatures . contains ( signer) {
184+ config. signatures . push_back ( signer. clone ( ) ) ;
185+ htlc. multi_sig = Some ( config) ;
186+ storage:: write_htlc ( env, htlc_id, & htlc) ;
187+ }
188+ Ok ( ( ) )
189+ } else {
190+ Err ( Error :: SignerNotAuthorized )
191+ }
192+ }
0 commit comments