From 707891969889e32c361e203829e403f2e5e0d1af Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 14:46:55 +0200 Subject: [PATCH 01/12] Draft: validation in worker thread --- packages/sdk/package.json | 5 +- .../signature/BrowserSignatureValidation.mts | 38 ++++++++++ .../signature/ServerSignatureValidation.ts | 20 +++++ .../signature/SignatureValidationContext.ts | 12 +++ .../signature/SignatureValidationWorker.ts | 18 +++++ .../sdk/src/signature/SignatureValidator.ts | 74 ++++++++++--------- .../sdk/src/signature/signatureValidation.ts | 72 ++++++++++++++++++ packages/sdk/webpack.config.js | 3 +- 8 files changed, 205 insertions(+), 37 deletions(-) create mode 100644 packages/sdk/src/signature/BrowserSignatureValidation.mts create mode 100644 packages/sdk/src/signature/ServerSignatureValidation.ts create mode 100644 packages/sdk/src/signature/SignatureValidationContext.ts create mode 100644 packages/sdk/src/signature/SignatureValidationWorker.ts create mode 100644 packages/sdk/src/signature/signatureValidation.ts diff --git a/packages/sdk/package.json b/packages/sdk/package.json index e586b916f5..80ed9679ec 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -13,7 +13,9 @@ "script": "./dist/streamr-sdk.web.min.js", "browser": { "./src/utils/persistence/ServerPersistence.ts": "./src/utils/persistence/BrowserPersistence.mts", - "./dist/src/utils/persistence/ServerPersistence.js": "./dist/src/utils/persistence/BrowserPersistence.mjs" + "./dist/src/utils/persistence/ServerPersistence.js": "./dist/src/utils/persistence/BrowserPersistence.mjs", + "./src/signature/ServerSignatureValidation.ts": "./src/signature/BrowserSignatureValidation.mts", + "./dist/src/signature/ServerSignatureValidation.js": "./dist/src/signature/BrowserSignatureValidation.mjs" }, "exports": { "default": { @@ -93,6 +95,7 @@ "#IMPORTANT": "babel-runtime must be in dependencies, not devDependencies", "dependencies": { "@babel/runtime": "^7.28.4", + "comlink": "^4.4.2", "@babel/runtime-corejs3": "^7.28.4", "@noble/post-quantum": "^0.4.1", "@protobuf-ts/runtime": "^2.8.2", diff --git a/packages/sdk/src/signature/BrowserSignatureValidation.mts b/packages/sdk/src/signature/BrowserSignatureValidation.mts new file mode 100644 index 0000000000..771ecf0965 --- /dev/null +++ b/packages/sdk/src/signature/BrowserSignatureValidation.mts @@ -0,0 +1,38 @@ +/** + * Browser implementation of signature validation using Web Worker. + * This offloads CPU-intensive cryptographic operations to a separate thread. + */ +import * as Comlink from 'comlink' +import { SignatureValidationContext } from './SignatureValidationContext.js' +import { SignatureValidationResult } from './signatureValidation.js' +import type { SignatureValidationWorkerApi } from './SignatureValidationWorker.js' +import { StreamMessage } from '../protocol/StreamMessage.js' + +export default class BrowserSignatureValidation implements SignatureValidationContext { + private worker: Worker | null = null + private workerApi: Comlink.Remote | null = null + + private ensureWorker(): Comlink.Remote { + if (!this.workerApi) { + // Webpack 5 handles this pattern automatically, creating a separate chunk for the worker + this.worker = new Worker( + /* webpackChunkName: "signature-worker" */ + new URL('./SignatureValidationWorker.js', import.meta.url) + ) + this.workerApi = Comlink.wrap(this.worker) + } + return this.workerApi + } + + async validateSignature(message: StreamMessage): Promise { + return this.ensureWorker().validateSignature(message) + } + + destroy(): void { + if (this.worker) { + this.worker.terminate() + this.worker = null + } + this.workerApi = null + } +} diff --git a/packages/sdk/src/signature/ServerSignatureValidation.ts b/packages/sdk/src/signature/ServerSignatureValidation.ts new file mode 100644 index 0000000000..fefce283b3 --- /dev/null +++ b/packages/sdk/src/signature/ServerSignatureValidation.ts @@ -0,0 +1,20 @@ +/** + * Node.js implementation of signature validation. + * Runs on the main thread (worker threads can be added later if needed). + */ +import { StreamMessage } from '../protocol/StreamMessage' +import { SignatureValidationContext } from './SignatureValidationContext' +import { SignatureValidationResult, validateSignatureData } from './signatureValidation' + +export default class ServerSignatureValidation implements SignatureValidationContext { + + async validateSignature(message: StreamMessage): Promise { + return validateSignatureData(message) + } + + // eslint-disable-next-line class-methods-use-this + destroy(): void { + // No-op for server implementation + } +} + diff --git a/packages/sdk/src/signature/SignatureValidationContext.ts b/packages/sdk/src/signature/SignatureValidationContext.ts new file mode 100644 index 0000000000..77f8afb4a0 --- /dev/null +++ b/packages/sdk/src/signature/SignatureValidationContext.ts @@ -0,0 +1,12 @@ +/** + * Interface for signature validation backend. + * Browser implementation uses a Web Worker, Node.js runs on main thread. + */ +import { StreamMessage } from '../protocol/StreamMessage' +import { SignatureValidationResult } from './signatureValidation' + +export interface SignatureValidationContext { + validateSignature(message: StreamMessage): Promise + destroy(): void +} + diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts new file mode 100644 index 0000000000..21f14288ca --- /dev/null +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -0,0 +1,18 @@ +/** + * Web Worker for signature validation. + * This worker handles CPU-intensive cryptographic operations off the main thread. + */ +import * as Comlink from 'comlink' +import { validateSignatureData, SignatureValidationResult } from './signatureValidation' +import { StreamMessage } from '../protocol/StreamMessage' + +const workerApi = { + validateSignature: async (data: StreamMessage): Promise => { + return validateSignatureData(data) + } +} + +export type SignatureValidationWorkerApi = typeof workerApi + +Comlink.expose(workerApi) + diff --git a/packages/sdk/src/signature/SignatureValidator.ts b/packages/sdk/src/signature/SignatureValidator.ts index 0c7ba17605..7f7d10f9e1 100644 --- a/packages/sdk/src/signature/SignatureValidator.ts +++ b/packages/sdk/src/signature/SignatureValidator.ts @@ -1,26 +1,33 @@ -import { toEthereumAddress, toUserIdRaw, SigningUtil } from '@streamr/utils' +import { toEthereumAddress } from '@streamr/utils' import { Lifecycle, scoped } from 'tsyringe' import { ERC1271ContractFacade } from '../contracts/ERC1271ContractFacade' +import { DestroySignal } from '../DestroySignal' import { StreamMessage } from '../protocol/StreamMessage' import { StreamrClientError } from '../StreamrClientError' -import { createLegacySignaturePayload } from './createLegacySignaturePayload' import { createSignaturePayload } from './createSignaturePayload' +import { SignatureValidationContext } from './SignatureValidationContext' +// This import will be swapped to BrowserSignatureValidation.mts in browser builds +import SignatureValidation from './ServerSignatureValidation' import { SignatureType } from '@streamr/trackerless-network' -import { IDENTITY_MAPPING } from '../identity/IdentityMapping' - -// Lookup structure SignatureType -> SigningUtil -const signingUtilBySignatureType: Record = Object.fromEntries( - IDENTITY_MAPPING.map((idMapping) => [idMapping.signatureType, SigningUtil.getInstance(idMapping.keyType)]) -) - -const evmSigner = SigningUtil.getInstance('ECDSA_SECP256K1_EVM') @scoped(Lifecycle.ContainerScoped) export class SignatureValidator { private readonly erc1271ContractFacade: ERC1271ContractFacade + private validationContext: SignatureValidationContext | undefined - constructor(erc1271ContractFacade: ERC1271ContractFacade) { + constructor( + erc1271ContractFacade: ERC1271ContractFacade, + destroySignal: DestroySignal + ) { this.erc1271ContractFacade = erc1271ContractFacade + destroySignal.onDestroy.listen(() => this.destroy()) + } + + private getValidationContext(): SignatureValidationContext { + if (!this.validationContext) { + this.validationContext = new SignatureValidation() + } + return this.validationContext } /** @@ -41,36 +48,33 @@ export class SignatureValidator { } private async validate(streamMessage: StreamMessage): Promise { - const signingUtil = signingUtilBySignatureType[streamMessage.signatureType] - - // Common case - if (signingUtil) { - return signingUtil.verifySignature( - toUserIdRaw(streamMessage.getPublisherId()), - createSignaturePayload(streamMessage), - streamMessage.signature - ) - } - - // Special handling: different payload computation, same SigningUtil - if (streamMessage.signatureType === SignatureType.ECDSA_SECP256K1_LEGACY) { - return evmSigner.verifySignature( - // publisherId is hex encoded Ethereum address string - toUserIdRaw(streamMessage.getPublisherId()), - createLegacySignaturePayload(streamMessage), - streamMessage.signature - ) - } - - // Special handling: check signature with ERC-1271 contract facade if (streamMessage.signatureType === SignatureType.ERC_1271) { return this.erc1271ContractFacade.isValidSignature( - toEthereumAddress(streamMessage.getPublisherId()), + toEthereumAddress(streamMessage.messageId.publisherId), createSignaturePayload(streamMessage), streamMessage.signature ) } + const result = await this.getValidationContext().validateSignature(streamMessage) + switch (result.type) { + case 'valid': + return true + case 'invalid': + return false + case 'error': + throw new Error(result.message) + default: + throw new Error(`Unknown signature validation result type: ${result.type}`) + } + } - throw new Error(`Cannot validate message signature, unsupported signatureType: "${streamMessage.signatureType}"`) + /** + * Cleanup worker resources when the validator is no longer needed. + */ + destroy(): void { + if (this.validationContext) { + this.validationContext.destroy() + this.validationContext = undefined + } } } diff --git a/packages/sdk/src/signature/signatureValidation.ts b/packages/sdk/src/signature/signatureValidation.ts new file mode 100644 index 0000000000..0a01f35e4f --- /dev/null +++ b/packages/sdk/src/signature/signatureValidation.ts @@ -0,0 +1,72 @@ +/** + * Core signature validation logic - shared between worker and main thread implementations. + * This file contains pure cryptographic validation functions without any network dependencies. + */ +import { SigningUtil, toUserIdRaw } from '@streamr/utils' +import { SignatureType } from '@streamr/trackerless-network' +import { IDENTITY_MAPPING } from '../identity/IdentityMapping' +import { createSignaturePayload } from './createSignaturePayload' +import { createLegacySignaturePayload } from './createLegacySignaturePayload' +import { StreamMessage } from '../protocol/StreamMessage' + +// Lookup structure SignatureType -> SigningUtil +const signingUtilBySignatureType: Record = Object.fromEntries( + IDENTITY_MAPPING.map((idMapping) => [idMapping.signatureType, SigningUtil.getInstance(idMapping.keyType)]) +) + +const evmSigner = SigningUtil.getInstance('ECDSA_SECP256K1_EVM') + +/** + * Result of signature validation + */ +export type SignatureValidationResult = + | { type: 'valid' } + | { type: 'invalid' } + | { type: 'requires_erc1271' } + | { type: 'error'; message: string } + +/** + * Validate signature using extracted data. + * This is the core validation logic that can be run in a worker. + */ +export async function validateSignatureData(message: StreamMessage): Promise { + try { + const signingUtil = signingUtilBySignatureType[message.signatureType] + // Common case: standard signature types + if (signingUtil) { + const payload = createSignaturePayload({ + messageId: message.messageId, + content: message.content, + messageType: message.messageType, + prevMsgRef: message.prevMsgRef, + newGroupKey: message.newGroupKey, + }) + const isValid = await signingUtil.verifySignature( + toUserIdRaw(message.messageId.publisherId), + payload, + message.signature + ) + return isValid ? { type: 'valid' } : { type: 'invalid' } + } + // Special handling: legacy signature type + if (message.signatureType === SignatureType.ECDSA_SECP256K1_LEGACY) { + const payload = createLegacySignaturePayload({ + messageId: message.messageId, + content: message.content, + encryptionType: message.encryptionType, + prevMsgRef: message.prevMsgRef, + newGroupKey: message.newGroupKey, + }) + const isValid = await evmSigner.verifySignature( + toUserIdRaw(message.messageId.publisherId), + payload, + message.signature + ) + return isValid ? { type: 'valid' } : { type: 'invalid' } + } + return { type: 'error', message: `Unsupported signatureType: "${message.signatureType}"` } + } catch (err) { + return { type: 'error', message: String(err) } + } +} + diff --git a/packages/sdk/webpack.config.js b/packages/sdk/webpack.config.js index d7005da143..d996bbe75d 100644 --- a/packages/sdk/webpack.config.js +++ b/packages/sdk/webpack.config.js @@ -67,7 +67,8 @@ module.exports = (env, argv) => { GIT_BRANCH: gitRevisionPlugin.branch(), }), new webpack.optimize.LimitChunkCountPlugin({ - maxChunks: 1 + // Allow 2 chunks: main bundle + signature validation worker + maxChunks: 2 }) ], performance: { From 9bf8431397d36f643016d31cee4f74d7647ddab2 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 14:51:01 +0200 Subject: [PATCH 02/12] package-lock --- package-lock.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/package-lock.json b/package-lock.json index 8ee7081d6a..d6d7593c82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11578,6 +11578,12 @@ "node": ">= 0.8" } }, + "node_modules/comlink": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz", + "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==", + "license": "Apache-2.0" + }, "node_modules/commander": { "version": "14.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", @@ -29067,6 +29073,7 @@ "@streamr/proto-rpc": "103.2.0", "@streamr/trackerless-network": "103.2.0", "@streamr/utils": "103.2.0", + "comlink": "^4.4.2", "core-js": "^3.47.0", "env-paths": "^2.2.1", "ethers": "^6.13.0", From 19ce5d700ca4c49a9472b8dd58e76852ca6f6d8b Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 14:59:42 +0200 Subject: [PATCH 03/12] DestroySignal to tests --- packages/sdk/test/unit/MessageFactory.test.ts | 3 ++- packages/sdk/test/unit/SignatureValidator.test.ts | 3 ++- packages/sdk/test/unit/messagePipeline.test.ts | 2 +- packages/sdk/test/unit/validateStreamMessage.test.ts | 3 ++- packages/sdk/test/unit/validateStreamMessage2.test.ts | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/sdk/test/unit/MessageFactory.test.ts b/packages/sdk/test/unit/MessageFactory.test.ts index 93c17213a4..2d93a05696 100644 --- a/packages/sdk/test/unit/MessageFactory.test.ts +++ b/packages/sdk/test/unit/MessageFactory.test.ts @@ -16,6 +16,7 @@ import { StreamMessage, StreamMessageType } from './../../src/protocol/StreamMes import { EthereumKeyPairIdentity } from '../../src/identity/EthereumKeyPairIdentity' import { EncryptionType, SignatureType, ContentType } from '@streamr/trackerless-network' import { StrictStreamrClientConfig } from '../../src/Config' +import { DestroySignal } from '../../src/DestroySignal' const CONTENT = { foo: 'bar' } const TIMESTAMP = Date.parse('2001-02-03T04:05:06Z') @@ -58,7 +59,7 @@ describe('MessageFactory', () => { isStreamPublisher: true }), groupKeyQueue: await createGroupKeyQueue(identity, GROUP_KEY), - signatureValidator: new SignatureValidator(opts?.erc1271ContractFacade ?? mock()), + signatureValidator: new SignatureValidator(opts?.erc1271ContractFacade ?? mock(), new DestroySignal()), messageSigner: new MessageSigner(identity), config: { validation: { diff --git a/packages/sdk/test/unit/SignatureValidator.test.ts b/packages/sdk/test/unit/SignatureValidator.test.ts index f303546dea..8b199679b7 100644 --- a/packages/sdk/test/unit/SignatureValidator.test.ts +++ b/packages/sdk/test/unit/SignatureValidator.test.ts @@ -11,6 +11,7 @@ import { StreamrClientError } from './../../src/StreamrClientError' import { MessageID } from './../../src/protocol/MessageID' import { StreamMessage, StreamMessageType } from './../../src/protocol/StreamMessage' import { ContentType, EncryptionType, SignatureType } from '@streamr/trackerless-network' +import { DestroySignal } from '../../src/DestroySignal' describe('SignatureValidator', () => { let erc1271ContractFacade: MockProxy @@ -18,7 +19,7 @@ describe('SignatureValidator', () => { beforeEach(() => { erc1271ContractFacade = mock() - signatureValidator = new SignatureValidator(erc1271ContractFacade) + signatureValidator = new SignatureValidator(erc1271ContractFacade, new DestroySignal()) }) describe('SECP256K1', () => { diff --git a/packages/sdk/test/unit/messagePipeline.test.ts b/packages/sdk/test/unit/messagePipeline.test.ts index ad7c0e5699..5cf75a458a 100644 --- a/packages/sdk/test/unit/messagePipeline.test.ts +++ b/packages/sdk/test/unit/messagePipeline.test.ts @@ -88,7 +88,7 @@ describe('messagePipeline', () => { getStorageNodes: undefined as any, resends: undefined as any, streamRegistry: streamRegistry as any, - signatureValidator: new SignatureValidator(mock()), + signatureValidator: new SignatureValidator(mock(), destroySignal), groupKeyManager: new GroupKeyManager( mock(), groupKeyStore, diff --git a/packages/sdk/test/unit/validateStreamMessage.test.ts b/packages/sdk/test/unit/validateStreamMessage.test.ts index 851521fb8c..e60c253d82 100644 --- a/packages/sdk/test/unit/validateStreamMessage.test.ts +++ b/packages/sdk/test/unit/validateStreamMessage.test.ts @@ -12,6 +12,7 @@ import { validateStreamMessage } from '../../src/utils/validateStreamMessage' import { createMockMessage } from '../test-utils/utils' import { StreamMessage } from './../../src/protocol/StreamMessage' import { StrictStreamrClientConfig } from '../../src/Config' +import { DestroySignal } from '../../src/DestroySignal' const PARTITION_COUNT = 3 @@ -47,7 +48,7 @@ describe('Validator', () => { await validateStreamMessage( msg, streamRegistry as any, - new SignatureValidator(mock()), + new SignatureValidator(mock(), new DestroySignal()), { validation: { permissions: true, diff --git a/packages/sdk/test/unit/validateStreamMessage2.test.ts b/packages/sdk/test/unit/validateStreamMessage2.test.ts index 1b570fe421..cd2cfec32f 100644 --- a/packages/sdk/test/unit/validateStreamMessage2.test.ts +++ b/packages/sdk/test/unit/validateStreamMessage2.test.ts @@ -14,6 +14,7 @@ import { MessageID } from './../../src/protocol/MessageID' import { MessageRef } from './../../src/protocol/MessageRef' import { StreamMessage, StreamMessageType } from './../../src/protocol/StreamMessage' import { StrictStreamrClientConfig } from '../../src/Config' +import { DestroySignal } from '../../src/DestroySignal' const groupKeyRequestToStreamMessage = async ( groupKeyRequest: GroupKeyRequest, @@ -71,7 +72,7 @@ describe('Validator2', () => { isStreamPublisher: (streamId: string, userId: UserID) => isPublisher(userId, streamId), isStreamSubscriber: (streamId: string, userId: UserID) => isSubscriber(userId, streamId) } as any, - new SignatureValidator(mock()), + new SignatureValidator(mock(), new DestroySignal()), { validation: { permissions: true, From c4586b86bdc5ad305687537a0ab1bfbb745bda7b Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 15:09:28 +0200 Subject: [PATCH 04/12] eslint --- packages/sdk/src/signature/ServerSignatureValidation.ts | 1 + packages/sdk/src/signature/SignatureValidator.ts | 7 ++----- packages/sdk/src/signature/signatureValidation.ts | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/sdk/src/signature/ServerSignatureValidation.ts b/packages/sdk/src/signature/ServerSignatureValidation.ts index fefce283b3..ba38835558 100644 --- a/packages/sdk/src/signature/ServerSignatureValidation.ts +++ b/packages/sdk/src/signature/ServerSignatureValidation.ts @@ -8,6 +8,7 @@ import { SignatureValidationResult, validateSignatureData } from './signatureVal export default class ServerSignatureValidation implements SignatureValidationContext { + // eslint-disable-next-line class-methods-use-this async validateSignature(message: StreamMessage): Promise { return validateSignatureData(message) } diff --git a/packages/sdk/src/signature/SignatureValidator.ts b/packages/sdk/src/signature/SignatureValidator.ts index 7f7d10f9e1..bbbf0ac3d9 100644 --- a/packages/sdk/src/signature/SignatureValidator.ts +++ b/packages/sdk/src/signature/SignatureValidator.ts @@ -24,10 +24,7 @@ export class SignatureValidator { } private getValidationContext(): SignatureValidationContext { - if (!this.validationContext) { - this.validationContext = new SignatureValidation() - } - return this.validationContext + return this.validationContext ??= new SignatureValidation() } /** @@ -64,7 +61,7 @@ export class SignatureValidator { case 'error': throw new Error(result.message) default: - throw new Error(`Unknown signature validation result type: ${result.type}`) + throw new Error(`Unknown signature validation result type '${result}'`) } } diff --git a/packages/sdk/src/signature/signatureValidation.ts b/packages/sdk/src/signature/signatureValidation.ts index 0a01f35e4f..8f294f49d5 100644 --- a/packages/sdk/src/signature/signatureValidation.ts +++ b/packages/sdk/src/signature/signatureValidation.ts @@ -22,8 +22,7 @@ const evmSigner = SigningUtil.getInstance('ECDSA_SECP256K1_EVM') export type SignatureValidationResult = | { type: 'valid' } | { type: 'invalid' } - | { type: 'requires_erc1271' } - | { type: 'error'; message: string } + | { type: 'error', message: string } /** * Validate signature using extracted data. From c2a74edabb44064c45098bcfc9834b831eb22f03 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 15:14:40 +0200 Subject: [PATCH 05/12] npm run version --- packages/sdk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 80ed9679ec..008af1e844 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -95,7 +95,6 @@ "#IMPORTANT": "babel-runtime must be in dependencies, not devDependencies", "dependencies": { "@babel/runtime": "^7.28.4", - "comlink": "^4.4.2", "@babel/runtime-corejs3": "^7.28.4", "@noble/post-quantum": "^0.4.1", "@protobuf-ts/runtime": "^2.8.2", @@ -106,6 +105,7 @@ "@streamr/proto-rpc": "103.2.0", "@streamr/trackerless-network": "103.2.0", "@streamr/utils": "103.2.0", + "comlink": "^4.4.2", "core-js": "^3.47.0", "env-paths": "^2.2.1", "ethers": "^6.13.0", From 2dd5dd42968ea5cef0487ad1b8f34489ed58feb6 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 15:55:31 +0200 Subject: [PATCH 06/12] refactors --- .../signature/BrowserSignatureValidation.mts | 25 ++++++++----------- .../signature/SignatureValidationWorker.ts | 9 +++---- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/packages/sdk/src/signature/BrowserSignatureValidation.mts b/packages/sdk/src/signature/BrowserSignatureValidation.mts index 771ecf0965..9e202ffef7 100644 --- a/packages/sdk/src/signature/BrowserSignatureValidation.mts +++ b/packages/sdk/src/signature/BrowserSignatureValidation.mts @@ -9,30 +9,25 @@ import type { SignatureValidationWorkerApi } from './SignatureValidationWorker.j import { StreamMessage } from '../protocol/StreamMessage.js' export default class BrowserSignatureValidation implements SignatureValidationContext { - private worker: Worker | null = null - private workerApi: Comlink.Remote | null = null + private worker: Worker + private workerApi: Comlink.Remote - private ensureWorker(): Comlink.Remote { - if (!this.workerApi) { - // Webpack 5 handles this pattern automatically, creating a separate chunk for the worker - this.worker = new Worker( - /* webpackChunkName: "signature-worker" */ - new URL('./SignatureValidationWorker.js', import.meta.url) - ) - this.workerApi = Comlink.wrap(this.worker) - } - return this.workerApi + constructor() { + // Webpack 5 handles this pattern automatically, creating a separate chunk for the worker + this.worker = new Worker( + /* webpackChunkName: "signature-worker" */ + new URL('./SignatureValidationWorker.js', import.meta.url) + ) + this.workerApi = Comlink.wrap(this.worker) } async validateSignature(message: StreamMessage): Promise { - return this.ensureWorker().validateSignature(message) + return this.workerApi.validateSignature(message) } destroy(): void { if (this.worker) { this.worker.terminate() - this.worker = null } - this.workerApi = null } } diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts index 21f14288ca..173059cbc5 100644 --- a/packages/sdk/src/signature/SignatureValidationWorker.ts +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -6,13 +6,10 @@ import * as Comlink from 'comlink' import { validateSignatureData, SignatureValidationResult } from './signatureValidation' import { StreamMessage } from '../protocol/StreamMessage' -const workerApi = { - validateSignature: async (data: StreamMessage): Promise => { +export class SignatureValidationWorkerApi { + async validateSignature(data: StreamMessage): Promise { return validateSignatureData(data) } } -export type SignatureValidationWorkerApi = typeof workerApi - -Comlink.expose(workerApi) - +Comlink.expose(SignatureValidationWorkerApi) From d6481e2235df8dcabc1e13a4b54c32e762a24b64 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 16:00:14 +0200 Subject: [PATCH 07/12] fix issue with StreamMessage passing --- packages/sdk/src/signature/SignatureValidationWorker.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts index 173059cbc5..015ff016ee 100644 --- a/packages/sdk/src/signature/SignatureValidationWorker.ts +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -6,10 +6,12 @@ import * as Comlink from 'comlink' import { validateSignatureData, SignatureValidationResult } from './signatureValidation' import { StreamMessage } from '../protocol/StreamMessage' -export class SignatureValidationWorkerApi { - async validateSignature(data: StreamMessage): Promise { +const workerApi = { + validateSignature: async (data: StreamMessage): Promise => { return validateSignatureData(data) } } -Comlink.expose(SignatureValidationWorkerApi) +export type SignatureValidationWorkerApi = typeof workerApi + +Comlink.expose(workerApi) From 46a9c6f59869aa58f4996c2f4fe0348ddcca6fa1 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 16:05:48 +0200 Subject: [PATCH 08/12] revert --- packages/sdk/src/signature/SignatureValidationWorker.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts index 015ff016ee..6bbcb971cf 100644 --- a/packages/sdk/src/signature/SignatureValidationWorker.ts +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -1,7 +1,3 @@ -/** - * Web Worker for signature validation. - * This worker handles CPU-intensive cryptographic operations off the main thread. - */ import * as Comlink from 'comlink' import { validateSignatureData, SignatureValidationResult } from './signatureValidation' import { StreamMessage } from '../protocol/StreamMessage' From d31d1c18d5b3313973b958976ddc8453ea1eac35 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 17:44:14 +0200 Subject: [PATCH 09/12] nodejs workers for validation --- .../signature/ServerSignatureValidation.ts | 26 ++++++++++++++----- .../signature/SignatureValidationWorker.ts | 13 +++++++++- .../sdk/test/unit/SignatureValidator.test.ts | 7 ++++- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/sdk/src/signature/ServerSignatureValidation.ts b/packages/sdk/src/signature/ServerSignatureValidation.ts index ba38835558..fda6103d9c 100644 --- a/packages/sdk/src/signature/ServerSignatureValidation.ts +++ b/packages/sdk/src/signature/ServerSignatureValidation.ts @@ -1,16 +1,28 @@ -/** - * Node.js implementation of signature validation. - * Runs on the main thread (worker threads can be added later if needed). - */ +import * as Comlink from 'comlink' +import nodeEndpoint from 'comlink/dist/umd/node-adapter' +import { Worker } from "worker_threads" import { StreamMessage } from '../protocol/StreamMessage' import { SignatureValidationContext } from './SignatureValidationContext' -import { SignatureValidationResult, validateSignatureData } from './signatureValidation' +import { SignatureValidationWorkerApi } from './SignatureValidationWorker' +import { SignatureValidationResult } from './signatureValidation' +import { join } from 'path' export default class ServerSignatureValidation implements SignatureValidationContext { - // eslint-disable-next-line class-methods-use-this + private readonly worker: Worker + private readonly workerApi: Comlink.Remote + constructor() { + const isRunningFromDist = __dirname.includes('/dist/') + const workerPath = isRunningFromDist + ? join(__dirname, 'SignatureValidationWorker.js') + : join(__dirname, '../../dist/src/signature/SignatureValidationWorker.js') + this.worker = new Worker(workerPath) + this.workerApi = Comlink.wrap(nodeEndpoint(this.worker)) + } + async validateSignature(message: StreamMessage): Promise { - return validateSignatureData(message) + console.log('validateSignature', message) + return this.workerApi.validateSignature(message) } // eslint-disable-next-line class-methods-use-this diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts index 6bbcb971cf..7fd6a39561 100644 --- a/packages/sdk/src/signature/SignatureValidationWorker.ts +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -10,4 +10,15 @@ const workerApi = { export type SignatureValidationWorkerApi = typeof workerApi -Comlink.expose(workerApi) +// Detect environment and expose accordingly +if (typeof self !== 'undefined') { + // Browser Web Worker + Comlink.expose(workerApi) +} else { + // Node.js Worker Thread + // eslint-disable-next-line @typescript-eslint/no-require-imports + const { parentPort } = require('worker_threads') + // eslint-disable-next-line @typescript-eslint/no-require-imports + const nodeEndpoint = require('comlink/dist/umd/node-adapter') + Comlink.expose(workerApi, nodeEndpoint(parentPort)) +} diff --git a/packages/sdk/test/unit/SignatureValidator.test.ts b/packages/sdk/test/unit/SignatureValidator.test.ts index 8b199679b7..bebeceb352 100644 --- a/packages/sdk/test/unit/SignatureValidator.test.ts +++ b/packages/sdk/test/unit/SignatureValidator.test.ts @@ -24,7 +24,7 @@ describe('SignatureValidator', () => { describe('SECP256K1', () => { - it('unencrypted message passes signature validation', async () => { + it.only('unencrypted message passes signature validation', async () => { const message = new StreamMessage({ messageId: new MessageID( toStreamID('streamr.eth/foo/bar'), @@ -43,6 +43,11 @@ describe('SignatureValidator', () => { signature: hexToBinary('e53045adef4e01f7fe11d4b3073c6053688912e4db0ee780c189cd0d128c923457e1f6cbc1e47d9cd57e115afa9eb8524288887777c1056d638b193cae112dda1b'), signatureType: SignatureType.ECDSA_SECP256K1_EVM }) + try { + await signatureValidator.assertSignatureIsValid(message) + } catch (error) { + console.log(error) + } await expect(signatureValidator.assertSignatureIsValid(message)).toResolve() }) From 360dfdc40a1cba63c300cadd35bed57e5d151a70 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 18:02:12 +0200 Subject: [PATCH 10/12] most unit tests work now --- .../signature/SignatureValidationWorker.ts | 20 +++++++++++++------ .../sdk/test/unit/SignatureValidator.test.ts | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts index 7fd6a39561..c316201106 100644 --- a/packages/sdk/src/signature/SignatureValidationWorker.ts +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -11,14 +11,22 @@ const workerApi = { export type SignatureValidationWorkerApi = typeof workerApi // Detect environment and expose accordingly -if (typeof self !== 'undefined') { - // Browser Web Worker - Comlink.expose(workerApi) -} else { - // Node.js Worker Thread +// Check for Node.js worker_threads first, since `self` is defined in both environments +// but only browser Web Workers have WorkerGlobalScope with addEventListener +let parentPort: import('worker_threads').MessagePort | null = null +try { // eslint-disable-next-line @typescript-eslint/no-require-imports - const { parentPort } = require('worker_threads') + parentPort = require('worker_threads').parentPort +} catch { + // Not in Node.js environment +} + +if (parentPort) { + // Node.js Worker Thread // eslint-disable-next-line @typescript-eslint/no-require-imports const nodeEndpoint = require('comlink/dist/umd/node-adapter') Comlink.expose(workerApi, nodeEndpoint(parentPort)) +} else { + // Browser Web Worker + Comlink.expose(workerApi) } diff --git a/packages/sdk/test/unit/SignatureValidator.test.ts b/packages/sdk/test/unit/SignatureValidator.test.ts index bebeceb352..7db870af91 100644 --- a/packages/sdk/test/unit/SignatureValidator.test.ts +++ b/packages/sdk/test/unit/SignatureValidator.test.ts @@ -24,7 +24,7 @@ describe('SignatureValidator', () => { describe('SECP256K1', () => { - it.only('unencrypted message passes signature validation', async () => { + it('unencrypted message passes signature validation', async () => { const message = new StreamMessage({ messageId: new MessageID( toStreamID('streamr.eth/foo/bar'), From 494cc2135ef6887fd7d8183f1182e49cf1b1ed50 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 18:23:18 +0200 Subject: [PATCH 11/12] SignatureValidationData --- .../signature/BrowserSignatureValidation.mts | 6 +- .../signature/ServerSignatureValidation.ts | 7 +- .../signature/SignatureValidationWorker.ts | 5 +- .../signature/createLegacySignaturePayload.ts | 7 +- .../src/signature/createSignaturePayload.ts | 28 ++++-- .../sdk/src/signature/signatureValidation.ts | 85 ++++++++++++++----- 6 files changed, 99 insertions(+), 39 deletions(-) diff --git a/packages/sdk/src/signature/BrowserSignatureValidation.mts b/packages/sdk/src/signature/BrowserSignatureValidation.mts index 9e202ffef7..55080d3d46 100644 --- a/packages/sdk/src/signature/BrowserSignatureValidation.mts +++ b/packages/sdk/src/signature/BrowserSignatureValidation.mts @@ -4,7 +4,7 @@ */ import * as Comlink from 'comlink' import { SignatureValidationContext } from './SignatureValidationContext.js' -import { SignatureValidationResult } from './signatureValidation.js' +import { SignatureValidationResult, toSignatureValidationData } from './signatureValidation.js' import type { SignatureValidationWorkerApi } from './SignatureValidationWorker.js' import { StreamMessage } from '../protocol/StreamMessage.js' @@ -22,7 +22,9 @@ export default class BrowserSignatureValidation implements SignatureValidationCo } async validateSignature(message: StreamMessage): Promise { - return this.workerApi.validateSignature(message) + // Convert class instance to plain serializable data before sending to worker + const data = toSignatureValidationData(message) + return this.workerApi.validateSignature(data) } destroy(): void { diff --git a/packages/sdk/src/signature/ServerSignatureValidation.ts b/packages/sdk/src/signature/ServerSignatureValidation.ts index fda6103d9c..552171756e 100644 --- a/packages/sdk/src/signature/ServerSignatureValidation.ts +++ b/packages/sdk/src/signature/ServerSignatureValidation.ts @@ -4,7 +4,7 @@ import { Worker } from "worker_threads" import { StreamMessage } from '../protocol/StreamMessage' import { SignatureValidationContext } from './SignatureValidationContext' import { SignatureValidationWorkerApi } from './SignatureValidationWorker' -import { SignatureValidationResult } from './signatureValidation' +import { SignatureValidationResult, toSignatureValidationData } from './signatureValidation' import { join } from 'path' export default class ServerSignatureValidation implements SignatureValidationContext { @@ -21,8 +21,9 @@ export default class ServerSignatureValidation implements SignatureValidationCon } async validateSignature(message: StreamMessage): Promise { - console.log('validateSignature', message) - return this.workerApi.validateSignature(message) + // Convert class instance to plain serializable data before sending to worker + const data = toSignatureValidationData(message) + return this.workerApi.validateSignature(data) } // eslint-disable-next-line class-methods-use-this diff --git a/packages/sdk/src/signature/SignatureValidationWorker.ts b/packages/sdk/src/signature/SignatureValidationWorker.ts index c316201106..11c8cf1626 100644 --- a/packages/sdk/src/signature/SignatureValidationWorker.ts +++ b/packages/sdk/src/signature/SignatureValidationWorker.ts @@ -1,9 +1,8 @@ import * as Comlink from 'comlink' -import { validateSignatureData, SignatureValidationResult } from './signatureValidation' -import { StreamMessage } from '../protocol/StreamMessage' +import { validateSignatureData, SignatureValidationResult, SignatureValidationData } from './signatureValidation' const workerApi = { - validateSignature: async (data: StreamMessage): Promise => { + validateSignature: async (data: SignatureValidationData): Promise => { return validateSignatureData(data) } } diff --git a/packages/sdk/src/signature/createLegacySignaturePayload.ts b/packages/sdk/src/signature/createLegacySignaturePayload.ts index 3aadd0828e..42c785c2fe 100644 --- a/packages/sdk/src/signature/createLegacySignaturePayload.ts +++ b/packages/sdk/src/signature/createLegacySignaturePayload.ts @@ -1,7 +1,6 @@ import { binaryToHex, binaryToUtf8 } from '@streamr/utils' import { EncryptedGroupKey, EncryptionType } from '@streamr/trackerless-network' -import { MessageID } from '../protocol/MessageID' -import { MessageRef } from '../protocol/MessageRef' +import { MessageIdLike, MessageRefLike } from './createSignaturePayload' const serializeGroupKey = ({ id, data }: EncryptedGroupKey): string => { return JSON.stringify([id, binaryToHex(data)]) @@ -11,10 +10,10 @@ const serializeGroupKey = ({ id, data }: EncryptedGroupKey): string => { * Only to be used for LEGACY_SECP256K1 signature type. */ export const createLegacySignaturePayload = (opts: { - messageId: MessageID + messageId: MessageIdLike content: Uint8Array encryptionType: EncryptionType - prevMsgRef?: MessageRef + prevMsgRef?: MessageRefLike newGroupKey?: EncryptedGroupKey }): Uint8Array => { const prev = ((opts.prevMsgRef !== undefined) ? `${opts.prevMsgRef.timestamp}${opts.prevMsgRef.sequenceNumber}` : '') diff --git a/packages/sdk/src/signature/createSignaturePayload.ts b/packages/sdk/src/signature/createSignaturePayload.ts index 9cfadf7d32..0162139680 100644 --- a/packages/sdk/src/signature/createSignaturePayload.ts +++ b/packages/sdk/src/signature/createSignaturePayload.ts @@ -3,16 +3,34 @@ import { GroupKeyRequest as NewGroupKeyRequest, GroupKeyResponse as NewGroupKeyResponse } from '@streamr/trackerless-network' -import { utf8ToBinary } from '@streamr/utils' -import { MessageID } from '../protocol/MessageID' -import { MessageRef } from '../protocol/MessageRef' +import { StreamID, UserID, utf8ToBinary } from '@streamr/utils' import { StreamMessageType } from '../protocol/StreamMessage' +/** + * Plain data for message ID - accepts class instances or plain objects with the same properties. + */ +export interface MessageIdLike { + streamId: StreamID + streamPartition: number + timestamp: number + sequenceNumber: number + publisherId: UserID + msgChainId: string +} + +/** + * Plain data for message reference - accepts class instances or plain objects with the same properties. + */ +export interface MessageRefLike { + timestamp: number + sequenceNumber: number +} + export const createSignaturePayload = (opts: { - messageId: MessageID + messageId: MessageIdLike content: Uint8Array messageType: StreamMessageType - prevMsgRef?: MessageRef + prevMsgRef?: MessageRefLike newGroupKey?: EncryptedGroupKey }): Uint8Array | never => { const header = Buffer.concat([ diff --git a/packages/sdk/src/signature/signatureValidation.ts b/packages/sdk/src/signature/signatureValidation.ts index 8f294f49d5..e23b73ee1d 100644 --- a/packages/sdk/src/signature/signatureValidation.ts +++ b/packages/sdk/src/signature/signatureValidation.ts @@ -2,12 +2,12 @@ * Core signature validation logic - shared between worker and main thread implementations. * This file contains pure cryptographic validation functions without any network dependencies. */ -import { SigningUtil, toUserIdRaw } from '@streamr/utils' -import { SignatureType } from '@streamr/trackerless-network' +import { SigningUtil, StreamID, toUserIdRaw, UserID } from '@streamr/utils' +import { EncryptedGroupKey, EncryptionType, SignatureType } from '@streamr/trackerless-network' import { IDENTITY_MAPPING } from '../identity/IdentityMapping' -import { createSignaturePayload } from './createSignaturePayload' +import { createSignaturePayload, MessageIdLike, MessageRefLike } from './createSignaturePayload' import { createLegacySignaturePayload } from './createLegacySignaturePayload' -import { StreamMessage } from '../protocol/StreamMessage' +import { StreamMessage, StreamMessageType } from '../protocol/StreamMessage' // Lookup structure SignatureType -> SigningUtil const signingUtilBySignatureType: Record = Object.fromEntries( @@ -24,46 +24,87 @@ export type SignatureValidationResult = | { type: 'invalid' } | { type: 'error', message: string } +/** + * Plain data type for signature validation that can be serialized to a worker. + * This contains only primitive values and simple objects (no class instances). + */ +export interface SignatureValidationData { + messageId: MessageIdLike + prevMsgRef?: MessageRefLike + messageType: StreamMessageType + content: Uint8Array + signature: Uint8Array + signatureType: SignatureType + encryptionType: EncryptionType + newGroupKey?: EncryptedGroupKey +} + +/** + * Extract plain serializable data from a StreamMessage for worker communication. + */ +export function toSignatureValidationData(message: StreamMessage): SignatureValidationData { + return { + messageId: { + streamId: message.messageId.streamId, + streamPartition: message.messageId.streamPartition, + timestamp: message.messageId.timestamp, + sequenceNumber: message.messageId.sequenceNumber, + publisherId: message.messageId.publisherId, + msgChainId: message.messageId.msgChainId, + }, + prevMsgRef: message.prevMsgRef ? { + timestamp: message.prevMsgRef.timestamp, + sequenceNumber: message.prevMsgRef.sequenceNumber, + } : undefined, + messageType: message.messageType, + content: message.content, + signature: message.signature, + signatureType: message.signatureType, + encryptionType: message.encryptionType, + newGroupKey: message.newGroupKey, + } +} + /** * Validate signature using extracted data. * This is the core validation logic that can be run in a worker. */ -export async function validateSignatureData(message: StreamMessage): Promise { +export async function validateSignatureData(data: SignatureValidationData): Promise { try { - const signingUtil = signingUtilBySignatureType[message.signatureType] + const signingUtil = signingUtilBySignatureType[data.signatureType] // Common case: standard signature types if (signingUtil) { const payload = createSignaturePayload({ - messageId: message.messageId, - content: message.content, - messageType: message.messageType, - prevMsgRef: message.prevMsgRef, - newGroupKey: message.newGroupKey, + messageId: data.messageId, + content: data.content, + messageType: data.messageType, + prevMsgRef: data.prevMsgRef, + newGroupKey: data.newGroupKey, }) const isValid = await signingUtil.verifySignature( - toUserIdRaw(message.messageId.publisherId), + toUserIdRaw(data.messageId.publisherId), payload, - message.signature + data.signature ) return isValid ? { type: 'valid' } : { type: 'invalid' } } // Special handling: legacy signature type - if (message.signatureType === SignatureType.ECDSA_SECP256K1_LEGACY) { + if (data.signatureType === SignatureType.ECDSA_SECP256K1_LEGACY) { const payload = createLegacySignaturePayload({ - messageId: message.messageId, - content: message.content, - encryptionType: message.encryptionType, - prevMsgRef: message.prevMsgRef, - newGroupKey: message.newGroupKey, + messageId: data.messageId, + content: data.content, + encryptionType: data.encryptionType, + prevMsgRef: data.prevMsgRef, + newGroupKey: data.newGroupKey, }) const isValid = await evmSigner.verifySignature( - toUserIdRaw(message.messageId.publisherId), + toUserIdRaw(data.messageId.publisherId), payload, - message.signature + data.signature ) return isValid ? { type: 'valid' } : { type: 'invalid' } } - return { type: 'error', message: `Unsupported signatureType: "${message.signatureType}"` } + return { type: 'error', message: `Unsupported signatureType: "${data.signatureType}"` } } catch (err) { return { type: 'error', message: String(err) } } From 4741a1794731d1fa08a8831b991e79b195baa3f2 Mon Sep 17 00:00:00 2001 From: juslesan Date: Mon, 22 Dec 2025 18:33:26 +0200 Subject: [PATCH 12/12] =?UTF-8?q?es=C3=B6int?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/src/signature/ServerSignatureValidation.ts | 3 ++- packages/sdk/src/signature/signatureValidation.ts | 2 +- packages/sdk/test/unit/SignatureValidator.test.ts | 5 ----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/sdk/src/signature/ServerSignatureValidation.ts b/packages/sdk/src/signature/ServerSignatureValidation.ts index 552171756e..4321c1a067 100644 --- a/packages/sdk/src/signature/ServerSignatureValidation.ts +++ b/packages/sdk/src/signature/ServerSignatureValidation.ts @@ -1,6 +1,7 @@ import * as Comlink from 'comlink' +// eslint-disable-next-line no-restricted-imports import nodeEndpoint from 'comlink/dist/umd/node-adapter' -import { Worker } from "worker_threads" +import { Worker } from 'worker_threads' import { StreamMessage } from '../protocol/StreamMessage' import { SignatureValidationContext } from './SignatureValidationContext' import { SignatureValidationWorkerApi } from './SignatureValidationWorker' diff --git a/packages/sdk/src/signature/signatureValidation.ts b/packages/sdk/src/signature/signatureValidation.ts index e23b73ee1d..6f1cd3d348 100644 --- a/packages/sdk/src/signature/signatureValidation.ts +++ b/packages/sdk/src/signature/signatureValidation.ts @@ -2,7 +2,7 @@ * Core signature validation logic - shared between worker and main thread implementations. * This file contains pure cryptographic validation functions without any network dependencies. */ -import { SigningUtil, StreamID, toUserIdRaw, UserID } from '@streamr/utils' +import { SigningUtil, toUserIdRaw } from '@streamr/utils' import { EncryptedGroupKey, EncryptionType, SignatureType } from '@streamr/trackerless-network' import { IDENTITY_MAPPING } from '../identity/IdentityMapping' import { createSignaturePayload, MessageIdLike, MessageRefLike } from './createSignaturePayload' diff --git a/packages/sdk/test/unit/SignatureValidator.test.ts b/packages/sdk/test/unit/SignatureValidator.test.ts index 7db870af91..8b199679b7 100644 --- a/packages/sdk/test/unit/SignatureValidator.test.ts +++ b/packages/sdk/test/unit/SignatureValidator.test.ts @@ -43,11 +43,6 @@ describe('SignatureValidator', () => { signature: hexToBinary('e53045adef4e01f7fe11d4b3073c6053688912e4db0ee780c189cd0d128c923457e1f6cbc1e47d9cd57e115afa9eb8524288887777c1056d638b193cae112dda1b'), signatureType: SignatureType.ECDSA_SECP256K1_EVM }) - try { - await signatureValidator.assertSignatureIsValid(message) - } catch (error) { - console.log(error) - } await expect(signatureValidator.assertSignatureIsValid(message)).toResolve() })