1- import { toEthereumAddress , toUserIdRaw , SigningUtil } from '@streamr/utils'
1+ import { toEthereumAddress } from '@streamr/utils'
22import { Lifecycle , scoped } from 'tsyringe'
33import { ERC1271ContractFacade } from '../contracts/ERC1271ContractFacade'
4+ import { DestroySignal } from '../DestroySignal'
45import { StreamMessage } from '../protocol/StreamMessage'
56import { StreamrClientError } from '../StreamrClientError'
6- import { createLegacySignaturePayload } from './createLegacySignaturePayload'
77import { createSignaturePayload } from './createSignaturePayload'
8+ import { SignatureValidationContext } from './SignatureValidationContext'
9+ // This import will be swapped to BrowserSignatureValidation.mts in browser builds
10+ import SignatureValidation from './ServerSignatureValidation'
811import { SignatureType } from '@streamr/trackerless-network'
9- import { IDENTITY_MAPPING } from '../identity/IdentityMapping'
10-
11- // Lookup structure SignatureType -> SigningUtil
12- const signingUtilBySignatureType : Record < number , SigningUtil > = Object . fromEntries (
13- IDENTITY_MAPPING . map ( ( idMapping ) => [ idMapping . signatureType , SigningUtil . getInstance ( idMapping . keyType ) ] )
14- )
15-
16- const evmSigner = SigningUtil . getInstance ( 'ECDSA_SECP256K1_EVM' )
1712
1813@scoped ( Lifecycle . ContainerScoped )
1914export class SignatureValidator {
2015 private readonly erc1271ContractFacade : ERC1271ContractFacade
16+ private validationContext : SignatureValidationContext | undefined
2117
22- constructor ( erc1271ContractFacade : ERC1271ContractFacade ) {
18+ constructor (
19+ erc1271ContractFacade : ERC1271ContractFacade ,
20+ destroySignal : DestroySignal
21+ ) {
2322 this . erc1271ContractFacade = erc1271ContractFacade
23+ destroySignal . onDestroy . listen ( ( ) => this . destroy ( ) )
24+ }
25+
26+ private getValidationContext ( ) : SignatureValidationContext {
27+ if ( ! this . validationContext ) {
28+ this . validationContext = new SignatureValidation ( )
29+ }
30+ return this . validationContext
2431 }
2532
2633 /**
@@ -41,36 +48,33 @@ export class SignatureValidator {
4148 }
4249
4350 private async validate ( streamMessage : StreamMessage ) : Promise < boolean > {
44- const signingUtil = signingUtilBySignatureType [ streamMessage . signatureType ]
45-
46- // Common case
47- if ( signingUtil ) {
48- return signingUtil . verifySignature (
49- toUserIdRaw ( streamMessage . getPublisherId ( ) ) ,
50- createSignaturePayload ( streamMessage ) ,
51- streamMessage . signature
52- )
53- }
54-
55- // Special handling: different payload computation, same SigningUtil
56- if ( streamMessage . signatureType === SignatureType . ECDSA_SECP256K1_LEGACY ) {
57- return evmSigner . verifySignature (
58- // publisherId is hex encoded Ethereum address string
59- toUserIdRaw ( streamMessage . getPublisherId ( ) ) ,
60- createLegacySignaturePayload ( streamMessage ) ,
61- streamMessage . signature
62- )
63- }
64-
65- // Special handling: check signature with ERC-1271 contract facade
6651 if ( streamMessage . signatureType === SignatureType . ERC_1271 ) {
6752 return this . erc1271ContractFacade . isValidSignature (
68- toEthereumAddress ( streamMessage . getPublisherId ( ) ) ,
53+ toEthereumAddress ( streamMessage . messageId . publisherId ) ,
6954 createSignaturePayload ( streamMessage ) ,
7055 streamMessage . signature
7156 )
7257 }
58+ const result = await this . getValidationContext ( ) . validateSignature ( streamMessage )
59+ switch ( result . type ) {
60+ case 'valid' :
61+ return true
62+ case 'invalid' :
63+ return false
64+ case 'error' :
65+ throw new Error ( result . message )
66+ default :
67+ throw new Error ( `Unknown signature validation result type: ${ result . type } ` )
68+ }
69+ }
7370
74- throw new Error ( `Cannot validate message signature, unsupported signatureType: "${ streamMessage . signatureType } "` )
71+ /**
72+ * Cleanup worker resources when the validator is no longer needed.
73+ */
74+ destroy ( ) : void {
75+ if ( this . validationContext ) {
76+ this . validationContext . destroy ( )
77+ this . validationContext = undefined
78+ }
7579 }
7680}
0 commit comments