@@ -21,6 +21,7 @@ import {
2121 sessionCallSignatureToJson ,
2222} from '../src/session-signature.js'
2323import { RSY } from '../src/signature.js'
24+ import { Extensions } from '../src/index.js'
2425
2526describe ( 'Session Signature' , ( ) => {
2627 // Test data
@@ -446,22 +447,23 @@ describe('Session Signature', () => {
446447 describe ( 'Helper Functions' , ( ) => {
447448 describe ( 'hashCallWithReplayProtection' , ( ) => {
448449 it ( 'should hash call with replay protection parameters' , ( ) => {
449- const result = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
450+ const result = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
450451
451452 expect ( result ) . toMatch ( / ^ 0 x [ 0 - 9 a - f ] { 64 } $ / ) // 32-byte hex string
452453 expect ( Hex . size ( result ) ) . toBe ( 32 )
453454 } )
454455
455456 it ( 'should produce different hashes for different chain IDs' , ( ) => {
456- const hash1 = hashCallWithReplayProtection ( samplePayload , 0 , ChainId . MAINNET )
457- const hash2 = hashCallWithReplayProtection ( samplePayload , 0 , ChainId . POLYGON )
457+ const hash1 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , ChainId . MAINNET )
458+ const hash2 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , ChainId . POLYGON )
458459
459460 expect ( hash1 ) . not . toBe ( hash2 )
460461 } )
461462
462463 it ( 'should produce different hashes for different spaces' , ( ) => {
463- const hash1 = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
464+ const hash1 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
464465 const hash2 = hashCallWithReplayProtection (
466+ testAddress1 ,
465467 { ...samplePayload , space : samplePayload . space + 1n } ,
466468 0 ,
467469 testChainId ,
@@ -471,8 +473,9 @@ describe('Session Signature', () => {
471473 } )
472474
473475 it ( 'should produce different hashes for different nonces' , ( ) => {
474- const hash1 = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
476+ const hash1 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
475477 const hash2 = hashCallWithReplayProtection (
478+ testAddress1 ,
476479 { ...samplePayload , nonce : samplePayload . nonce + 1n } ,
477480 0 ,
478481 testChainId ,
@@ -488,17 +491,51 @@ describe('Session Signature', () => {
488491 }
489492 const payload2 = { ...samplePayload , calls : [ call2 ] }
490493
491- const hash1 = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
492- const hash2 = hashCallWithReplayProtection ( payload2 , 0 , testChainId )
494+ const hash1 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
495+ const hash2 = hashCallWithReplayProtection ( testAddress1 , payload2 , 0 , testChainId )
493496
494497 expect ( hash1 ) . not . toBe ( hash2 )
495498 } )
496499
500+ it ( 'should produce different hashes for different wallets' , ( ) => {
501+ const payload = { ...samplePayload , calls : [ sampleCall , sampleCall ] }
502+
503+ const hash1 = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId )
504+ const hash2 = hashCallWithReplayProtection ( testAddress2 , payload , 0 , testChainId )
505+
506+ expect ( hash1 ) . not . toBe ( hash2 )
507+ } )
508+
509+ it ( 'should NOT produce different hashes for different wallets when using deprecated hash encoding for Dev1 and Dev2' , ( ) => {
510+ // This is ONLY for backward compatibility with Dev1 and Dev2
511+ // This is exploitable and should not be used in practice
512+ const payload = { ...samplePayload , calls : [ sampleCall , sampleCall ] }
513+
514+ const hash1 = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId , Extensions . Dev1 . sessions )
515+ const hash2 = hashCallWithReplayProtection ( testAddress2 , payload , 0 , testChainId , Extensions . Dev2 . sessions )
516+
517+ expect ( hash1 ) . toBe ( hash2 )
518+ } )
519+
520+ it ( 'should produce different hashes for different wallets when using deprecated hash encoding for Dev1/2, Rc3 and latest' , ( ) => {
521+ // This is ONLY for backward compatibility with Rc3
522+ // This is exploitable and should not be used in practice
523+ const payload = { ...samplePayload , calls : [ sampleCall , sampleCall ] }
524+
525+ const hash1 = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId , Extensions . Dev1 . sessions )
526+ const hash2 = hashCallWithReplayProtection ( testAddress2 , payload , 0 , testChainId , Extensions . Rc3 . sessions )
527+ const hash3 = hashCallWithReplayProtection ( testAddress2 , payload , 0 , testChainId )
528+
529+ expect ( hash1 ) . not . toBe ( hash2 )
530+ expect ( hash1 ) . not . toBe ( hash3 )
531+ expect ( hash2 ) . not . toBe ( hash3 )
532+ } )
533+
497534 it ( 'should produce different hashes for same call at different index' , ( ) => {
498535 const payload = { ...samplePayload , calls : [ sampleCall , sampleCall ] }
499536
500- const hash1 = hashCallWithReplayProtection ( payload , 0 , testChainId )
501- const hash2 = hashCallWithReplayProtection ( payload , 1 , testChainId )
537+ const hash1 = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId )
538+ const hash2 = hashCallWithReplayProtection ( testAddress1 , payload , 1 , testChainId )
502539
503540 expect ( hash1 ) . not . toBe ( hash2 )
504541 } )
@@ -508,15 +545,15 @@ describe('Session Signature', () => {
508545 // This is exploitable and should not be used in practice
509546 const payload = { ...samplePayload , calls : [ sampleCall , sampleCall ] }
510547
511- const hash1 = hashCallWithReplayProtection ( payload , 0 , testChainId , true )
512- const hash2 = hashCallWithReplayProtection ( payload , 1 , testChainId , true )
548+ const hash1 = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId , Extensions . Dev1 . sessions )
549+ const hash2 = hashCallWithReplayProtection ( testAddress1 , payload , 1 , testChainId , Extensions . Dev1 . sessions )
513550
514551 expect ( hash1 ) . toBe ( hash2 )
515552 } )
516553
517554 it ( 'should be deterministic' , ( ) => {
518- const hash1 = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
519- const hash2 = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
555+ const hash1 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
556+ const hash2 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
520557
521558 expect ( hash1 ) . toBe ( hash2 )
522559 } )
@@ -527,6 +564,7 @@ describe('Session Signature', () => {
527564 const largeNonce = 2n ** 24n
528565
529566 const result = hashCallWithReplayProtection (
567+ testAddress1 ,
530568 { ...samplePayload , space : largeSpace , nonce : largeNonce } ,
531569 0 ,
532570 largeChainId ,
@@ -535,7 +573,7 @@ describe('Session Signature', () => {
535573 } )
536574
537575 it ( 'should handle zero values' , ( ) => {
538- const result = hashCallWithReplayProtection ( { ...samplePayload , space : 0n , nonce : 0n } , 0 , 0 )
576+ const result = hashCallWithReplayProtection ( testAddress1 , { ...samplePayload , space : 0n , nonce : 0n } , 0 , 0 )
539577 expect ( result ) . toMatch ( / ^ 0 x [ 0 - 9 a - f ] { 64 } $ / )
540578 } )
541579
@@ -546,7 +584,7 @@ describe('Session Signature', () => {
546584 }
547585 const payload = { ...samplePayload , calls : [ callWithEmptyData ] }
548586
549- const result = hashCallWithReplayProtection ( payload , 0 , testChainId )
587+ const result = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId )
550588 expect ( result ) . toMatch ( / ^ 0 x [ 0 - 9 a - f ] { 64 } $ / )
551589 } )
552590
@@ -557,8 +595,8 @@ describe('Session Signature', () => {
557595 }
558596 const payload = { ...samplePayload , calls : [ delegateCall ] }
559597
560- const hash1 = hashCallWithReplayProtection ( samplePayload , 0 , testChainId )
561- const hash2 = hashCallWithReplayProtection ( payload , 0 , testChainId )
598+ const hash1 = hashCallWithReplayProtection ( testAddress1 , samplePayload , 0 , testChainId )
599+ const hash2 = hashCallWithReplayProtection ( testAddress1 , payload , 0 , testChainId )
562600
563601 expect ( hash1 ) . not . toBe ( hash2 )
564602 } )
@@ -735,12 +773,15 @@ describe('Session Signature', () => {
735773 const calls : Payload . Call [ ] = [
736774 sampleCall ,
737775 { ...sampleCall , to : testAddress2 } ,
776+ { ...sampleCall , to : testAddress2 } , // Repeat call
738777 { ...sampleCall , value : 500000000000000000n } ,
739778 ]
740779 const payload = { ...samplePayload , calls : calls }
741780
742781 // Generate hashes for each call
743- const hashes = calls . map ( ( call ) => hashCallWithReplayProtection ( payload , calls . indexOf ( call ) , testChainId ) )
782+ const hashes = calls . map ( ( call ) =>
783+ hashCallWithReplayProtection ( testAddress1 , payload , calls . indexOf ( call ) , testChainId ) ,
784+ )
744785
745786 // All hashes should be valid and different
746787 for ( let i = 0 ; i < hashes . length ; i ++ ) {
0 commit comments