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