22 * Core signature validation logic - shared between worker and main thread implementations.
33 * This file contains pure cryptographic validation functions without any network dependencies.
44 */
5- import { SigningUtil , toUserIdRaw } from '@streamr/utils'
6- import { SignatureType } from '@streamr/trackerless-network'
5+ import { SigningUtil , StreamID , toUserIdRaw , UserID } from '@streamr/utils'
6+ import { EncryptedGroupKey , EncryptionType , SignatureType } from '@streamr/trackerless-network'
77import { IDENTITY_MAPPING } from '../identity/IdentityMapping'
8- import { createSignaturePayload } from './createSignaturePayload'
8+ import { createSignaturePayload , MessageIdLike , MessageRefLike } from './createSignaturePayload'
99import { createLegacySignaturePayload } from './createLegacySignaturePayload'
10- import { StreamMessage } from '../protocol/StreamMessage'
10+ import { StreamMessage , StreamMessageType } from '../protocol/StreamMessage'
1111
1212// Lookup structure SignatureType -> SigningUtil
1313const signingUtilBySignatureType : Record < number , SigningUtil > = Object . fromEntries (
@@ -24,46 +24,87 @@ export type SignatureValidationResult =
2424 | { type : 'invalid' }
2525 | { type : 'error' , message : string }
2626
27+ /**
28+ * Plain data type for signature validation that can be serialized to a worker.
29+ * This contains only primitive values and simple objects (no class instances).
30+ */
31+ export interface SignatureValidationData {
32+ messageId : MessageIdLike
33+ prevMsgRef ?: MessageRefLike
34+ messageType : StreamMessageType
35+ content : Uint8Array
36+ signature : Uint8Array
37+ signatureType : SignatureType
38+ encryptionType : EncryptionType
39+ newGroupKey ?: EncryptedGroupKey
40+ }
41+
42+ /**
43+ * Extract plain serializable data from a StreamMessage for worker communication.
44+ */
45+ export function toSignatureValidationData ( message : StreamMessage ) : SignatureValidationData {
46+ return {
47+ messageId : {
48+ streamId : message . messageId . streamId ,
49+ streamPartition : message . messageId . streamPartition ,
50+ timestamp : message . messageId . timestamp ,
51+ sequenceNumber : message . messageId . sequenceNumber ,
52+ publisherId : message . messageId . publisherId ,
53+ msgChainId : message . messageId . msgChainId ,
54+ } ,
55+ prevMsgRef : message . prevMsgRef ? {
56+ timestamp : message . prevMsgRef . timestamp ,
57+ sequenceNumber : message . prevMsgRef . sequenceNumber ,
58+ } : undefined ,
59+ messageType : message . messageType ,
60+ content : message . content ,
61+ signature : message . signature ,
62+ signatureType : message . signatureType ,
63+ encryptionType : message . encryptionType ,
64+ newGroupKey : message . newGroupKey ,
65+ }
66+ }
67+
2768/**
2869 * Validate signature using extracted data.
2970 * This is the core validation logic that can be run in a worker.
3071 */
31- export async function validateSignatureData ( message : StreamMessage ) : Promise < SignatureValidationResult > {
72+ export async function validateSignatureData ( data : SignatureValidationData ) : Promise < SignatureValidationResult > {
3273 try {
33- const signingUtil = signingUtilBySignatureType [ message . signatureType ]
74+ const signingUtil = signingUtilBySignatureType [ data . signatureType ]
3475 // Common case: standard signature types
3576 if ( signingUtil ) {
3677 const payload = createSignaturePayload ( {
37- messageId : message . messageId ,
38- content : message . content ,
39- messageType : message . messageType ,
40- prevMsgRef : message . prevMsgRef ,
41- newGroupKey : message . newGroupKey ,
78+ messageId : data . messageId ,
79+ content : data . content ,
80+ messageType : data . messageType ,
81+ prevMsgRef : data . prevMsgRef ,
82+ newGroupKey : data . newGroupKey ,
4283 } )
4384 const isValid = await signingUtil . verifySignature (
44- toUserIdRaw ( message . messageId . publisherId ) ,
85+ toUserIdRaw ( data . messageId . publisherId ) ,
4586 payload ,
46- message . signature
87+ data . signature
4788 )
4889 return isValid ? { type : 'valid' } : { type : 'invalid' }
4990 }
5091 // Special handling: legacy signature type
51- if ( message . signatureType === SignatureType . ECDSA_SECP256K1_LEGACY ) {
92+ if ( data . signatureType === SignatureType . ECDSA_SECP256K1_LEGACY ) {
5293 const payload = createLegacySignaturePayload ( {
53- messageId : message . messageId ,
54- content : message . content ,
55- encryptionType : message . encryptionType ,
56- prevMsgRef : message . prevMsgRef ,
57- newGroupKey : message . newGroupKey ,
94+ messageId : data . messageId ,
95+ content : data . content ,
96+ encryptionType : data . encryptionType ,
97+ prevMsgRef : data . prevMsgRef ,
98+ newGroupKey : data . newGroupKey ,
5899 } )
59100 const isValid = await evmSigner . verifySignature (
60- toUserIdRaw ( message . messageId . publisherId ) ,
101+ toUserIdRaw ( data . messageId . publisherId ) ,
61102 payload ,
62- message . signature
103+ data . signature
63104 )
64105 return isValid ? { type : 'valid' } : { type : 'invalid' }
65106 }
66- return { type : 'error' , message : `Unsupported signatureType: "${ message . signatureType } "` }
107+ return { type : 'error' , message : `Unsupported signatureType: "${ data . signatureType } "` }
67108 } catch ( err ) {
68109 return { type : 'error' , message : String ( err ) }
69110 }
0 commit comments