@@ -294,6 +294,81 @@ const getRequiredSignersKeyPaths = (
294294 return paths ;
295295} ;
296296
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+
297372/** Check if there are certificates that require DRep credentials and if we own them */
298373export const getDRepCredentialKeyPaths = ( {
299374 dRepKeyHash,
@@ -357,7 +432,8 @@ export const ownSignatureKeyPaths = (
357432 txBody : Cardano . TxBody ,
358433 knownAddresses : GroupedAddress [ ] ,
359434 txInKeyPathMap : TxInKeyPathMap ,
360- dRepKeyHash ?: Crypto . Ed25519KeyHashHex
435+ dRepKeyHash ?: Crypto . Ed25519KeyHashHex ,
436+ scripts ?: Cardano . Script [ ]
361437) : AccountKeyDerivationPath [ ] => {
362438 // TODO: add `proposal_procedure` witnesses.
363439
@@ -368,7 +444,8 @@ export const ownSignatureKeyPaths = (
368444 ...getStakeCredentialKeyPaths ( knownAddresses , txBody ) . derivationPaths ,
369445 ...getDRepCredentialKeyPaths ( { dRepKeyHash, txBody } ) . derivationPaths ,
370446 ...getRequiredSignersKeyPaths ( knownAddresses , txBody . requiredExtraSignatures ) ,
371- ...getVotingProcedureKeyPaths ( { dRepKeyHash, groupedAddresses : knownAddresses , txBody } ) . derivationPaths
447+ ...getVotingProcedureKeyPaths ( { dRepKeyHash, groupedAddresses : knownAddresses , txBody } ) . derivationPaths ,
448+ ...getNativeScriptKeyPaths ( knownAddresses , scripts ) . derivationPaths
372449 ] ,
373450 isEqual
374451 ) ;
0 commit comments