@@ -294,6 +294,81 @@ const getRequiredSignersKeyPaths = (
294
294
return paths ;
295
295
} ;
296
296
297
+ const checkStakeCredential = ( address : GroupedAddress , keyHash : Crypto . Ed25519KeyHashHex ) : SignatureCheck =>
298
+ address . stakeKeyDerivationPath &&
299
+ Cardano . RewardAccount . toHash ( address . rewardAccount ) === Crypto . Hash28ByteBase16 . fromEd25519KeyHashHex ( keyHash )
300
+ ? { derivationPaths : [ address . stakeKeyDerivationPath ] , requiresForeignSignatures : false }
301
+ : { derivationPaths : [ ] , requiresForeignSignatures : true } ;
302
+
303
+ const checkPaymentCredential = ( address : GroupedAddress , keyHash : Crypto . Ed25519KeyHashHex ) : SignatureCheck => {
304
+ const paymentCredential = Cardano . Address . fromBech32 ( address . address ) ?. asBase ( ) ?. getPaymentCredential ( ) ;
305
+ return paymentCredential ?. type === Cardano . CredentialType . KeyHash &&
306
+ paymentCredential . hash === Crypto . Hash28ByteBase16 . fromEd25519KeyHashHex ( keyHash )
307
+ ? {
308
+ derivationPaths : [ { index : address . index , role : Number ( address . type ) } ] ,
309
+ requiresForeignSignatures : false
310
+ }
311
+ : { derivationPaths : [ ] , requiresForeignSignatures : true } ;
312
+ } ;
313
+
314
+ const combineSignatureChecks = ( a : SignatureCheck , b : SignatureCheck ) : SignatureCheck => ( {
315
+ derivationPaths : [ ...a . derivationPaths , ...b . derivationPaths ] ,
316
+ requiresForeignSignatures : a . requiresForeignSignatures || b . requiresForeignSignatures
317
+ } ) ;
318
+
319
+ const processSignatureScript = (
320
+ script : Cardano . RequireSignatureScript ,
321
+ groupedAddresses : GroupedAddress [ ]
322
+ ) : SignatureCheck => {
323
+ let signatureCheck : SignatureCheck = { derivationPaths : [ ] , requiresForeignSignatures : false } ;
324
+
325
+ for ( const address of groupedAddresses ) {
326
+ if ( address . stakeKeyDerivationPath ) {
327
+ signatureCheck = checkStakeCredential ( address , script . keyHash ) ;
328
+ }
329
+ signatureCheck = combineSignatureChecks ( signatureCheck , checkPaymentCredential ( address , script . keyHash ) ) ;
330
+ }
331
+
332
+ return signatureCheck ;
333
+ } ;
334
+
335
+ const getNativeScriptKeyPaths = (
336
+ groupedAddresses : GroupedAddress [ ] ,
337
+ nativeScripts ?: Cardano . Script [ ]
338
+ ) : SignatureCheck => {
339
+ const signatureCheck : SignatureCheck = { derivationPaths : [ ] , requiresForeignSignatures : false } ;
340
+ if ( ! nativeScripts ?. length ) return signatureCheck ;
341
+
342
+ const processScript = ( script : Cardano . Script ) : SignatureCheck => {
343
+ if ( ! Cardano . isNativeScript ( script ) ) {
344
+ return { derivationPaths : [ ] , requiresForeignSignatures : false } ;
345
+ }
346
+
347
+ switch ( script . kind ) {
348
+ case Cardano . NativeScriptKind . RequireSignature : {
349
+ return processSignatureScript ( script as Cardano . RequireSignatureScript , groupedAddresses ) ;
350
+ }
351
+ case Cardano . NativeScriptKind . RequireAllOf :
352
+ case Cardano . NativeScriptKind . RequireAnyOf :
353
+ case Cardano . NativeScriptKind . RequireNOf : {
354
+ const scriptWithScripts = script as Cardano . RequireAllOfScript | Cardano . RequireAnyOfScript ;
355
+ return scriptWithScripts . scripts . reduce < SignatureCheck > (
356
+ ( acc , subScript ) => combineSignatureChecks ( acc , processScript ( subScript ) ) ,
357
+ { derivationPaths : [ ] , requiresForeignSignatures : false }
358
+ ) ;
359
+ }
360
+ case Cardano . NativeScriptKind . RequireTimeBefore :
361
+ case Cardano . NativeScriptKind . RequireTimeAfter :
362
+ return { derivationPaths : [ ] , requiresForeignSignatures : false } ;
363
+ }
364
+ } ;
365
+
366
+ return nativeScripts . reduce < SignatureCheck > (
367
+ ( acc , script ) => combineSignatureChecks ( acc , processScript ( script ) ) ,
368
+ signatureCheck
369
+ ) ;
370
+ } ;
371
+
297
372
/** Check if there are certificates that require DRep credentials and if we own them */
298
373
export const getDRepCredentialKeyPaths = ( {
299
374
dRepKeyHash,
@@ -357,7 +432,8 @@ export const ownSignatureKeyPaths = (
357
432
txBody : Cardano . TxBody ,
358
433
knownAddresses : GroupedAddress [ ] ,
359
434
txInKeyPathMap : TxInKeyPathMap ,
360
- dRepKeyHash ?: Crypto . Ed25519KeyHashHex
435
+ dRepKeyHash ?: Crypto . Ed25519KeyHashHex ,
436
+ scripts ?: Cardano . Script [ ]
361
437
) : AccountKeyDerivationPath [ ] => {
362
438
// TODO: add `proposal_procedure` witnesses.
363
439
@@ -368,7 +444,8 @@ export const ownSignatureKeyPaths = (
368
444
...getStakeCredentialKeyPaths ( knownAddresses , txBody ) . derivationPaths ,
369
445
...getDRepCredentialKeyPaths ( { dRepKeyHash, txBody } ) . derivationPaths ,
370
446
...getRequiredSignersKeyPaths ( knownAddresses , txBody . requiredExtraSignatures ) ,
371
- ...getVotingProcedureKeyPaths ( { dRepKeyHash, groupedAddresses : knownAddresses , txBody } ) . derivationPaths
447
+ ...getVotingProcedureKeyPaths ( { dRepKeyHash, groupedAddresses : knownAddresses , txBody } ) . derivationPaths ,
448
+ ...getNativeScriptKeyPaths ( knownAddresses , scripts ) . derivationPaths
372
449
] ,
373
450
isEqual
374
451
) ;
0 commit comments