@@ -3,6 +3,9 @@ pub use bitcoin::address::ParseError as BitcoinParseError;
3
3
use bitcoin:: amount:: ParseAmountError as BitcoinParseAmountError ;
4
4
use bitcoin:: consensus:: encode:: Error as BitcoinEncodeError ;
5
5
use bitcoin:: hex:: DisplayHex ;
6
+ use bitcoin:: psbt:: Error as BitcoinPsbtError ;
7
+ use bitcoin:: psbt:: ExtractTxError as BitcoinExtractTxError ;
8
+ use bitcoin:: psbt:: PsbtParseError as BitcoinPsbtParseError ;
6
9
7
10
#[ derive( Debug , thiserror:: Error , uniffi:: Error ) ]
8
11
pub enum AddressParseError {
@@ -166,3 +169,196 @@ impl From<BitcoinEncodeError> for EncodeError {
166
169
}
167
170
}
168
171
}
172
+
173
+ #[ derive( Debug , thiserror:: Error , uniffi:: Error ) ]
174
+ pub enum PsbtError {
175
+ #[ error( "invalid magic" ) ]
176
+ InvalidMagic ,
177
+ #[ error( "UTXO information is not present in PSBT" ) ]
178
+ MissingUtxo ,
179
+ #[ error( "invalid separator" ) ]
180
+ InvalidSeparator ,
181
+ #[ error( "output index is out of bounds of non witness script output array" ) ]
182
+ PsbtUtxoOutOfBounds ,
183
+ #[ error( "invalid key: {key}" ) ]
184
+ InvalidKey { key : String } ,
185
+ #[ error( "non-proprietary key type found when proprietary key was expected" ) ]
186
+ InvalidProprietaryKey ,
187
+ #[ error( "duplicate key: {key}" ) ]
188
+ DuplicateKey { key : String } ,
189
+ #[ error( "the unsigned transaction has script sigs" ) ]
190
+ UnsignedTxHasScriptSigs ,
191
+ #[ error( "the unsigned transaction has script witnesses" ) ]
192
+ UnsignedTxHasScriptWitnesses ,
193
+ #[ error( "partially signed transactions must have an unsigned transaction" ) ]
194
+ MustHaveUnsignedTx ,
195
+ #[ error( "no more key-value pairs for this psbt map" ) ]
196
+ NoMorePairs ,
197
+ #[ error( "different unsigned transaction" ) ]
198
+ UnexpectedUnsignedTx ,
199
+ #[ error( "non-standard sighash type: {sighash}" ) ]
200
+ NonStandardSighashType { sighash : u32 } ,
201
+ #[ error( "invalid hash when parsing slice: {hash}" ) ]
202
+ InvalidHash { hash : String } ,
203
+ #[ error( "preimage does not match" ) ]
204
+ InvalidPreimageHashPair ,
205
+ #[ error( "combine conflict: {xpub}" ) ]
206
+ CombineInconsistentKeySources { xpub : String } ,
207
+ #[ error( "bitcoin consensus encoding error: {encoding_error}" ) ]
208
+ ConsensusEncoding { encoding_error : String } ,
209
+ #[ error( "PSBT has a negative fee which is not allowed" ) ]
210
+ NegativeFee ,
211
+ #[ error( "integer overflow in fee calculation" ) ]
212
+ FeeOverflow ,
213
+ #[ error( "invalid public key {error_message}" ) ]
214
+ InvalidPublicKey { error_message : String } ,
215
+ #[ error( "invalid secp256k1 public key: {secp256k1_error}" ) ]
216
+ InvalidSecp256k1PublicKey { secp256k1_error : String } ,
217
+ #[ error( "invalid xonly public key" ) ]
218
+ InvalidXOnlyPublicKey ,
219
+ #[ error( "invalid ECDSA signature: {error_message}" ) ]
220
+ InvalidEcdsaSignature { error_message : String } ,
221
+ #[ error( "invalid taproot signature: {error_message}" ) ]
222
+ InvalidTaprootSignature { error_message : String } ,
223
+ #[ error( "invalid control block" ) ]
224
+ InvalidControlBlock ,
225
+ #[ error( "invalid leaf version" ) ]
226
+ InvalidLeafVersion ,
227
+ #[ error( "taproot error" ) ]
228
+ Taproot ,
229
+ #[ error( "taproot tree error: {error_message}" ) ]
230
+ TapTree { error_message : String } ,
231
+ #[ error( "xpub key error" ) ]
232
+ XPubKey ,
233
+ #[ error( "version error: {error_message}" ) ]
234
+ Version { error_message : String } ,
235
+ #[ error( "data not consumed entirely when explicitly deserializing" ) ]
236
+ PartialDataConsumption ,
237
+ #[ error( "I/O error: {error_message}" ) ]
238
+ Io { error_message : String } ,
239
+ #[ error( "other PSBT error" ) ]
240
+ OtherPsbtErr ,
241
+ }
242
+
243
+ impl From < BitcoinPsbtError > for PsbtError {
244
+ fn from ( error : BitcoinPsbtError ) -> Self {
245
+ match error {
246
+ BitcoinPsbtError :: InvalidMagic => PsbtError :: InvalidMagic ,
247
+ BitcoinPsbtError :: MissingUtxo => PsbtError :: MissingUtxo ,
248
+ BitcoinPsbtError :: InvalidSeparator => PsbtError :: InvalidSeparator ,
249
+ BitcoinPsbtError :: PsbtUtxoOutOfbounds => PsbtError :: PsbtUtxoOutOfBounds ,
250
+ BitcoinPsbtError :: InvalidKey ( key) => PsbtError :: InvalidKey {
251
+ key : key. to_string ( ) ,
252
+ } ,
253
+ BitcoinPsbtError :: InvalidProprietaryKey => PsbtError :: InvalidProprietaryKey ,
254
+ BitcoinPsbtError :: DuplicateKey ( key) => PsbtError :: DuplicateKey {
255
+ key : key. to_string ( ) ,
256
+ } ,
257
+ BitcoinPsbtError :: UnsignedTxHasScriptSigs => PsbtError :: UnsignedTxHasScriptSigs ,
258
+ BitcoinPsbtError :: UnsignedTxHasScriptWitnesses => {
259
+ PsbtError :: UnsignedTxHasScriptWitnesses
260
+ }
261
+ BitcoinPsbtError :: MustHaveUnsignedTx => PsbtError :: MustHaveUnsignedTx ,
262
+ BitcoinPsbtError :: NoMorePairs => PsbtError :: NoMorePairs ,
263
+ BitcoinPsbtError :: UnexpectedUnsignedTx { .. } => PsbtError :: UnexpectedUnsignedTx ,
264
+ BitcoinPsbtError :: NonStandardSighashType ( sighash) => {
265
+ PsbtError :: NonStandardSighashType { sighash }
266
+ }
267
+ BitcoinPsbtError :: InvalidHash ( hash) => PsbtError :: InvalidHash {
268
+ hash : hash. to_string ( ) ,
269
+ } ,
270
+ BitcoinPsbtError :: InvalidPreimageHashPair { .. } => PsbtError :: InvalidPreimageHashPair ,
271
+ BitcoinPsbtError :: CombineInconsistentKeySources ( xpub) => {
272
+ PsbtError :: CombineInconsistentKeySources {
273
+ xpub : xpub. to_string ( ) ,
274
+ }
275
+ }
276
+ BitcoinPsbtError :: ConsensusEncoding ( encoding_error) => PsbtError :: ConsensusEncoding {
277
+ encoding_error : encoding_error. to_string ( ) ,
278
+ } ,
279
+ BitcoinPsbtError :: NegativeFee => PsbtError :: NegativeFee ,
280
+ BitcoinPsbtError :: FeeOverflow => PsbtError :: FeeOverflow ,
281
+ BitcoinPsbtError :: InvalidPublicKey ( e) => PsbtError :: InvalidPublicKey {
282
+ error_message : e. to_string ( ) ,
283
+ } ,
284
+ BitcoinPsbtError :: InvalidSecp256k1PublicKey ( e) => {
285
+ PsbtError :: InvalidSecp256k1PublicKey {
286
+ secp256k1_error : e. to_string ( ) ,
287
+ }
288
+ }
289
+ BitcoinPsbtError :: InvalidXOnlyPublicKey => PsbtError :: InvalidXOnlyPublicKey ,
290
+ BitcoinPsbtError :: InvalidEcdsaSignature ( e) => PsbtError :: InvalidEcdsaSignature {
291
+ error_message : e. to_string ( ) ,
292
+ } ,
293
+ BitcoinPsbtError :: InvalidTaprootSignature ( e) => PsbtError :: InvalidTaprootSignature {
294
+ error_message : e. to_string ( ) ,
295
+ } ,
296
+ BitcoinPsbtError :: InvalidControlBlock => PsbtError :: InvalidControlBlock ,
297
+ BitcoinPsbtError :: InvalidLeafVersion => PsbtError :: InvalidLeafVersion ,
298
+ BitcoinPsbtError :: Taproot ( _) => PsbtError :: Taproot ,
299
+ BitcoinPsbtError :: TapTree ( e) => PsbtError :: TapTree {
300
+ error_message : e. to_string ( ) ,
301
+ } ,
302
+ BitcoinPsbtError :: XPubKey ( _) => PsbtError :: XPubKey ,
303
+ BitcoinPsbtError :: Version ( e) => PsbtError :: Version {
304
+ error_message : e. to_string ( ) ,
305
+ } ,
306
+ BitcoinPsbtError :: PartialDataConsumption => PsbtError :: PartialDataConsumption ,
307
+ BitcoinPsbtError :: Io ( e) => PsbtError :: Io {
308
+ error_message : e. to_string ( ) ,
309
+ } ,
310
+ _ => PsbtError :: OtherPsbtErr ,
311
+ }
312
+ }
313
+ }
314
+
315
+ #[ derive( Debug , thiserror:: Error , uniffi:: Error ) ]
316
+ pub enum PsbtParseError {
317
+ #[ error( "error in internal psbt data structure: {error_message}" ) ]
318
+ PsbtEncoding { error_message : String } ,
319
+ #[ error( "error in psbt base64 encoding: {error_message}" ) ]
320
+ Base64Encoding { error_message : String } ,
321
+ }
322
+
323
+ impl From < BitcoinPsbtParseError > for PsbtParseError {
324
+ fn from ( error : BitcoinPsbtParseError ) -> Self {
325
+ match error {
326
+ BitcoinPsbtParseError :: PsbtEncoding ( e) => PsbtParseError :: PsbtEncoding {
327
+ error_message : e. to_string ( ) ,
328
+ } ,
329
+ BitcoinPsbtParseError :: Base64Encoding ( e) => PsbtParseError :: Base64Encoding {
330
+ error_message : e. to_string ( ) ,
331
+ } ,
332
+ _ => {
333
+ unreachable ! ( "this is required because of the non-exhaustive enum in rust-bitcoin" )
334
+ }
335
+ }
336
+ }
337
+ }
338
+
339
+ #[ derive( Debug , thiserror:: Error , uniffi:: Error ) ]
340
+ pub enum ExtractTxError {
341
+ #[ error( "feerate is too high {fee_rate}" ) ]
342
+ AbsurdFeeRate { fee_rate : String } ,
343
+ #[ error( "input[s] are missing information" ) ]
344
+ MissingInputValue ,
345
+ #[ error( "input is less than the output value" ) ]
346
+ SendingTooMuch ,
347
+ #[ error( "other extract tx error" ) ]
348
+ OtherExtractTxErr ,
349
+ }
350
+
351
+ impl From < BitcoinExtractTxError > for ExtractTxError {
352
+ fn from ( error : BitcoinExtractTxError ) -> Self {
353
+ match error {
354
+ BitcoinExtractTxError :: AbsurdFeeRate { fee_rate, .. } => {
355
+ ExtractTxError :: AbsurdFeeRate {
356
+ fee_rate : fee_rate. to_string ( ) ,
357
+ }
358
+ }
359
+ BitcoinExtractTxError :: MissingInputValue { .. } => ExtractTxError :: MissingInputValue ,
360
+ BitcoinExtractTxError :: SendingTooMuch { .. } => ExtractTxError :: SendingTooMuch ,
361
+ _ => ExtractTxError :: OtherExtractTxErr ,
362
+ }
363
+ }
364
+ }
0 commit comments