From af9f58ef4719f6072ee08e3ff7db134ac640df79 Mon Sep 17 00:00:00 2001 From: thinktanktom Date: Tue, 17 Feb 2026 14:44:46 +0530 Subject: [PATCH 1/2] feat(node): migrate @noble/curves from v1 to v2 Resolves #1109 --- node/jest.config.js | 10 ++++- node/package-lock.json | 29 +++++++++----- node/package.json | 9 ++++- node/src/blockevents.test.ts | 22 ++++++----- node/src/blockeventsbuilder.ts | 8 ++-- node/src/blockeventsrequest.ts | 8 ++-- node/src/chaincodeevent.ts | 2 +- node/src/chaincodeevents.test.ts | 14 +++---- node/src/chaincodeeventsbuilder.ts | 8 ++-- node/src/chaincodeeventsrequest.ts | 8 ++-- node/src/checkpointer.d.ts | 2 +- node/src/checkpointers.test.ts | 8 ++-- node/src/checkpointers.ts | 6 +-- node/src/client.test.ts | 6 +-- node/src/client.ts | 10 ++--- node/src/commit.ts | 8 ++-- node/src/commiterror.ts | 2 +- node/src/commitstatuserror.ts | 2 +- node/src/contract.ts | 12 +++--- node/src/dependency.test.ts | 2 +- node/src/endorseerror.ts | 2 +- node/src/eventsbuilder.ts | 2 +- node/src/filecheckpointer.ts | 4 +- node/src/gateway.test.ts | 4 +- node/src/gateway.ts | 24 ++++++------ node/src/hash/hashes.test.ts | 2 +- node/src/hash/hashes.ts | 2 +- node/src/identity/ecdsa.ts | 15 ++++---- node/src/identity/hsmsigner.test.ts | 10 ++--- node/src/identity/hsmsigner.ts | 10 ++--- node/src/identity/signers.test.ts | 2 +- node/src/identity/signers.ts | 6 +-- node/src/index.ts | 60 ++++++++++++++--------------- node/src/inmemorycheckpointer.ts | 4 +- node/src/network.test.ts | 6 +-- node/src/network.ts | 20 ++++++---- node/src/offlinesign.test.ts | 12 +++--- node/src/proposal.test.ts | 12 +++--- node/src/proposal.ts | 10 ++--- node/src/proposalbuilder.ts | 8 ++-- node/src/signingidentity.test.ts | 6 +-- node/src/signingidentity.ts | 10 ++--- node/src/submiterror.ts | 2 +- node/src/submittedtransaction.ts | 2 +- node/src/testutils.test.ts | 4 +- node/src/transaction.test.ts | 16 ++++---- node/src/transaction.ts | 12 +++--- node/src/transactioncontext.ts | 4 +- node/src/transactionparser.ts | 2 +- node/tsconfig.json | 2 + 50 files changed, 241 insertions(+), 210 deletions(-) diff --git a/node/jest.config.js b/node/jest.config.js index e0afc89cd..bba01bce9 100644 --- a/node/jest.config.js +++ b/node/jest.config.js @@ -1,6 +1,12 @@ -module.exports = { +export default { roots: ['/src'], - preset: 'ts-jest', + extensionsToTreatAsEsm: ['.ts'], + moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { useESM: true }], + '^.+\\.js$': ['ts-jest', { useESM: true }], + }, + transformIgnorePatterns: ['node_modules/(?!(@noble)/)'], testEnvironment: 'node', collectCoverage: true, collectCoverageFrom: ['**/*.[jt]s?(x)', '!**/*.d.ts'], diff --git a/node/package-lock.json b/node/package-lock.json index 0c56fa5fb..7d1a059d7 100644 --- a/node/package-lock.json +++ b/node/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@grpc/grpc-js": "^1.14.0", "@hyperledger/fabric-protos": "^0.3.0", - "@noble/curves": "^1.9.4", + "@noble/curves": "^2.0.0", "google-protobuf": "^3.21.0" }, "devDependencies": { @@ -82,6 +82,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz", "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1539,27 +1540,27 @@ } }, "node_modules/@noble/curves": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.4.tgz", - "integrity": "sha512-2bKONnuM53lINoDrSmK8qP8W271ms7pygDhZt4SiLOoLwBtoHqeCFi6RG42V8zd3mLHuJFhU/Bmaqo4nX0/kBw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", + "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "@noble/hashes": "2.0.1" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", + "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -1942,6 +1943,7 @@ "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.55.0", @@ -2147,6 +2149,7 @@ "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.55.0", "@typescript-eslint/types": "8.55.0", @@ -2949,6 +2952,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3193,6 +3197,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -3547,6 +3552,7 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4452,6 +4458,7 @@ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "30.2.0", "@jest/types": "30.2.0", @@ -6311,6 +6318,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -6516,6 +6524,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/node/package.json b/node/package.json index e4d631299..d7e4f6d7b 100644 --- a/node/package.json +++ b/node/package.json @@ -4,6 +4,13 @@ "description": "Hyperledger Fabric Gateway client API for Node", "main": "dist/index.js", "types": "dist/index.d.ts", + "type": "module", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, "engines": { "node": ">=20.9.0" }, @@ -35,7 +42,7 @@ "dependencies": { "@grpc/grpc-js": "^1.14.0", "@hyperledger/fabric-protos": "^0.3.0", - "@noble/curves": "^1.9.4", + "@noble/curves": "^2.0.0", "google-protobuf": "^3.21.0" }, "optionalDependencies": { diff --git a/node/src/blockevents.test.ts b/node/src/blockevents.test.ts index d7e31a381..8a04e8e25 100644 --- a/node/src/blockevents.test.ts +++ b/node/src/blockevents.test.ts @@ -6,20 +6,24 @@ import { CallOptions, Metadata, ServiceError, status } from '@grpc/grpc-js'; import { common, ledger, msp, orderer, peer } from '@hyperledger/fabric-protos'; -import { CloseableAsyncIterable } from '.'; -import { BlockEventsOptions } from './blockeventsbuilder'; -import { BlockAndPrivateDataEventsRequest, BlockEventsRequest, FilteredBlockEventsRequest } from './blockeventsrequest'; -import * as checkpointers from './checkpointers'; -import { Gateway, InternalConnectOptions, assertDefined, internalConnect } from './gateway'; -import { GatewayError } from './gatewayerror'; -import { Identity } from './identity/identity'; -import { Network } from './network'; +import { CloseableAsyncIterable } from './index.js'; +import { BlockEventsOptions } from './blockeventsbuilder.js'; +import { + BlockAndPrivateDataEventsRequest, + BlockEventsRequest, + FilteredBlockEventsRequest, +} from './blockeventsrequest.js'; +import * as checkpointers from './checkpointers.js'; +import { Gateway, InternalConnectOptions, assertDefined, internalConnect } from './gateway.js'; +import { GatewayError } from './gatewayerror.js'; +import { Identity } from './identity/identity.js'; +import { Network } from './network.js'; import { DuplexStreamResponseStub, MockGatewayGrpcClient, newDuplexStreamResponse, readElements, -} from './testutils.test'; +} from './testutils.test.js'; function assertStartPositionToBeSpecified(seekInfo: orderer.SeekInfo, blockNumber: number): void { const start = seekInfo.getStart(); diff --git a/node/src/blockeventsbuilder.ts b/node/src/blockeventsbuilder.ts index 26bd90519..e67d51718 100644 --- a/node/src/blockeventsbuilder.ts +++ b/node/src/blockeventsbuilder.ts @@ -13,10 +13,10 @@ import { BlockEventsRequestImpl, FilteredBlockEventsRequest, FilteredBlockEventsRequestImpl, -} from './blockeventsrequest'; -import { GatewayClient } from './client'; -import { EventsBuilder, EventsOptions } from './eventsbuilder'; -import { SigningIdentity } from './signingidentity'; +} from './blockeventsrequest.js'; +import { GatewayClient } from './client.js'; +import { EventsBuilder, EventsOptions } from './eventsbuilder.js'; +import { SigningIdentity } from './signingidentity.js'; function seekLargestBlockNumber(): orderer.SeekPosition { const largestBlockNumber = new orderer.SeekSpecified(); diff --git a/node/src/blockeventsrequest.ts b/node/src/blockeventsrequest.ts index a9e6565b3..62019f26a 100644 --- a/node/src/blockeventsrequest.ts +++ b/node/src/blockeventsrequest.ts @@ -6,10 +6,10 @@ import { CallOptions } from '@grpc/grpc-js'; import { common, peer } from '@hyperledger/fabric-protos'; -import { CloseableAsyncIterable, GatewayClient } from './client'; -import { assertDefined } from './gateway'; -import { Signable } from './signable'; -import { SigningIdentity } from './signingidentity'; +import { CloseableAsyncIterable, GatewayClient } from './client.js'; +import { assertDefined } from './gateway.js'; +import { Signable } from './signable.js'; +import { SigningIdentity } from './signingidentity.js'; /** * Delivers block events. diff --git a/node/src/chaincodeevent.ts b/node/src/chaincodeevent.ts index 503f9a927..bbc14f27c 100644 --- a/node/src/chaincodeevent.ts +++ b/node/src/chaincodeevent.ts @@ -5,7 +5,7 @@ */ import { gateway, peer } from '@hyperledger/fabric-protos'; -import { CloseableAsyncIterable } from './client'; +import { CloseableAsyncIterable } from './client.js'; /** * Chaincode event emitted by a transaction function. diff --git a/node/src/chaincodeevents.test.ts b/node/src/chaincodeevents.test.ts index 5b0506ad7..cfc9ab487 100644 --- a/node/src/chaincodeevents.test.ts +++ b/node/src/chaincodeevents.test.ts @@ -6,13 +6,13 @@ import { CallOptions, Metadata, ServiceError, status } from '@grpc/grpc-js'; import { gateway as gatewayproto, orderer, peer } from '@hyperledger/fabric-protos'; -import { ChaincodeEvent } from './chaincodeevent'; -import * as checkpointers from './checkpointers'; -import { Gateway, InternalConnectOptions, internalConnect } from './gateway'; -import { GatewayError } from './gatewayerror'; -import { Identity } from './identity/identity'; -import { Network } from './network'; -import { MockGatewayGrpcClient, newServerStreamResponse, readElements } from './testutils.test'; +import { ChaincodeEvent } from './chaincodeevent.js'; +import * as checkpointers from './checkpointers.js'; +import { Gateway, InternalConnectOptions, internalConnect } from './gateway.js'; +import { GatewayError } from './gatewayerror.js'; +import { Identity } from './identity/identity.js'; +import { Network } from './network.js'; +import { MockGatewayGrpcClient, newServerStreamResponse, readElements } from './testutils.test.js'; function assertDecodeChaincodeEventsRequest( signedRequest: gatewayproto.SignedChaincodeEventsRequest, diff --git a/node/src/chaincodeeventsbuilder.ts b/node/src/chaincodeeventsbuilder.ts index 23908e203..fd38b8c23 100644 --- a/node/src/chaincodeeventsbuilder.ts +++ b/node/src/chaincodeeventsbuilder.ts @@ -5,10 +5,10 @@ */ import { gateway } from '@hyperledger/fabric-protos'; -import { ChaincodeEventsRequest, ChaincodeEventsRequestImpl } from './chaincodeeventsrequest'; -import { GatewayClient } from './client'; -import { EventsBuilder, EventsOptions } from './eventsbuilder'; -import { SigningIdentity } from './signingidentity'; +import { ChaincodeEventsRequest, ChaincodeEventsRequestImpl } from './chaincodeeventsrequest.js'; +import { GatewayClient } from './client.js'; +import { EventsBuilder, EventsOptions } from './eventsbuilder.js'; +import { SigningIdentity } from './signingidentity.js'; /** * Options used when requesting chaincode events. diff --git a/node/src/chaincodeeventsrequest.ts b/node/src/chaincodeeventsrequest.ts index 0b3444dc7..74e530c33 100644 --- a/node/src/chaincodeeventsrequest.ts +++ b/node/src/chaincodeeventsrequest.ts @@ -6,10 +6,10 @@ import { CallOptions } from '@grpc/grpc-js'; import { gateway } from '@hyperledger/fabric-protos'; -import { ChaincodeEvent, newChaincodeEvents } from './chaincodeevent'; -import { CloseableAsyncIterable, GatewayClient } from './client'; -import { Signable } from './signable'; -import { SigningIdentity } from './signingidentity'; +import { ChaincodeEvent, newChaincodeEvents } from './chaincodeevent.js'; +import { CloseableAsyncIterable, GatewayClient } from './client.js'; +import { Signable } from './signable.js'; +import { SigningIdentity } from './signingidentity.js'; /** * Delivers events emitted by transaction functions in a specific chaincode. diff --git a/node/src/checkpointer.d.ts b/node/src/checkpointer.d.ts index c00e9db64..38db51e83 100644 --- a/node/src/checkpointer.d.ts +++ b/node/src/checkpointer.d.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ChaincodeEvent } from './chaincodeevent'; +import { ChaincodeEvent } from './chaincodeevent.js'; /** * Used to get the checkpointed state. diff --git a/node/src/checkpointers.test.ts b/node/src/checkpointers.test.ts index 7db78dec4..08c0224f1 100644 --- a/node/src/checkpointers.test.ts +++ b/node/src/checkpointers.test.ts @@ -6,10 +6,10 @@ import { promises as fs } from 'node:fs'; import * as path from 'node:path'; -import { ChaincodeEvent } from './chaincodeevent'; -import { Checkpointer } from './checkpointer'; -import * as checkpointers from './checkpointers'; -import { createTempDir } from './testutils.test'; +import { ChaincodeEvent } from './chaincodeevent.js'; +import { Checkpointer } from './checkpointer.js'; +import * as checkpointers from './checkpointers.js'; +import { createTempDir } from './testutils.test.js'; /* eslint-disable jest/expect-expect */ diff --git a/node/src/checkpointers.ts b/node/src/checkpointers.ts index 26b37c8e3..6355535e9 100644 --- a/node/src/checkpointers.ts +++ b/node/src/checkpointers.ts @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Checkpointer } from './checkpointer'; -import { FileCheckPointer } from './filecheckpointer'; -import { InMemoryCheckPointer } from './inmemorycheckpointer'; +import { Checkpointer } from './checkpointer.js'; +import { FileCheckPointer } from './filecheckpointer.js'; +import { InMemoryCheckPointer } from './inmemorycheckpointer.js'; /** * Create a checkpointer that uses the specified file to store persistent state. diff --git a/node/src/client.test.ts b/node/src/client.test.ts index b316e605c..266580470 100644 --- a/node/src/client.test.ts +++ b/node/src/client.test.ts @@ -6,9 +6,9 @@ import * as grpc from '@grpc/grpc-js'; import { common, gateway } from '@hyperledger/fabric-protos'; -import { GatewayClient, newGatewayClient } from './client'; -import { GatewayError } from './gatewayerror'; -import { MockGatewayGrpcClient } from './testutils.test'; +import { GatewayClient, newGatewayClient } from './client.js'; +import { GatewayError } from './gatewayerror.js'; +import { MockGatewayGrpcClient } from './testutils.test.js'; describe('client', () => { describe('throws GatewayError on gRPC error', () => { diff --git a/node/src/client.ts b/node/src/client.ts index aeb54e316..9945edae1 100644 --- a/node/src/client.ts +++ b/node/src/client.ts @@ -7,11 +7,11 @@ import { CallOptions, ClientUnaryCall, Metadata, requestCallback, ServiceError } from '@grpc/grpc-js'; import { common, gateway, peer } from '@hyperledger/fabric-protos'; import { Message } from 'google-protobuf'; -import { CommitStatusError } from './commitstatuserror'; -import { EndorseError } from './endorseerror'; -import { ConnectOptions } from './gateway'; -import { GatewayError, newGatewayError } from './gatewayerror'; -import { SubmitError } from './submiterror'; +import { CommitStatusError } from './commitstatuserror.js'; +import { EndorseError } from './endorseerror.js'; +import { ConnectOptions } from './gateway.js'; +import { GatewayError, newGatewayError } from './gatewayerror.js'; +import { SubmitError } from './submiterror.js'; export const evaluateMethod = '/gateway.Gateway/Evaluate'; export const endorseMethod = '/gateway.Gateway/Endorse'; diff --git a/node/src/commit.ts b/node/src/commit.ts index 2fe688087..a6df0301c 100644 --- a/node/src/commit.ts +++ b/node/src/commit.ts @@ -6,10 +6,10 @@ import { CallOptions } from '@grpc/grpc-js'; import { gateway } from '@hyperledger/fabric-protos'; -import { GatewayClient } from './client'; -import { Signable } from './signable'; -import { SigningIdentity } from './signingidentity'; -import { Status, StatusCode } from './status'; +import { GatewayClient } from './client.js'; +import { Signable } from './signable.js'; +import { SigningIdentity } from './signingidentity.js'; +import { Status, StatusCode } from './status.js'; /** * Allows access to information about a transaction that is committed to the ledger. diff --git a/node/src/commiterror.ts b/node/src/commiterror.ts index 9d4acb49a..394c3d41c 100644 --- a/node/src/commiterror.ts +++ b/node/src/commiterror.ts @@ -5,7 +5,7 @@ */ import { peer } from '@hyperledger/fabric-protos'; -import { Status, StatusNames } from './status'; +import { Status, StatusNames } from './status.js'; /** * CommitError is thrown to indicate that a transaction committed with an unsuccessful status code. diff --git a/node/src/commitstatuserror.ts b/node/src/commitstatuserror.ts index cf9a8aea5..3574ce2fb 100644 --- a/node/src/commitstatuserror.ts +++ b/node/src/commitstatuserror.ts @@ -5,7 +5,7 @@ */ import { ServiceError } from '@grpc/grpc-js'; -import { ErrorDetail, GatewayError } from './gatewayerror'; +import { ErrorDetail, GatewayError } from './gatewayerror.js'; /** * CommitStatusError is thrown when a failure occurs obtaining the commit status of a transaction. diff --git a/node/src/contract.ts b/node/src/contract.ts index 1e7f9a4c8..7f6c38356 100644 --- a/node/src/contract.ts +++ b/node/src/contract.ts @@ -4,12 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { GatewayClient } from './client'; -import { newCommitError } from './commiterror'; -import { Proposal } from './proposal'; -import { ProposalBuilder, ProposalOptions } from './proposalbuilder'; -import { SigningIdentity } from './signingidentity'; -import { SubmittedTransaction } from './submittedtransaction'; +import { GatewayClient } from './client.js'; +import { newCommitError } from './commiterror.js'; +import { Proposal } from './proposal.js'; +import { ProposalBuilder, ProposalOptions } from './proposalbuilder.js'; +import { SigningIdentity } from './signingidentity.js'; +import { SubmittedTransaction } from './submittedtransaction.js'; /** * Represents a smart contract, and allows applications to: diff --git a/node/src/dependency.test.ts b/node/src/dependency.test.ts index 14652bb77..02ade8010 100644 --- a/node/src/dependency.test.ts +++ b/node/src/dependency.test.ts @@ -6,7 +6,7 @@ import { generateKeyPairSync } from 'node:crypto'; import { dirname, sep as pathSeparator } from 'node:path'; -import type { signers as SignersType } from '.'; +import type { signers as SignersType } from './index.js'; function isLoaded(moduleName: string): boolean { const moduleFile = require.resolve(moduleName); diff --git a/node/src/endorseerror.ts b/node/src/endorseerror.ts index 4d14f7a0b..38fe64089 100644 --- a/node/src/endorseerror.ts +++ b/node/src/endorseerror.ts @@ -5,7 +5,7 @@ */ import { ServiceError } from '@grpc/grpc-js'; -import { ErrorDetail, GatewayError } from './gatewayerror'; +import { ErrorDetail, GatewayError } from './gatewayerror.js'; /** * EndorseError is thrown when a failure occurs endorsing a transaction proposal. diff --git a/node/src/eventsbuilder.ts b/node/src/eventsbuilder.ts index d5ad06316..e88acd1fd 100644 --- a/node/src/eventsbuilder.ts +++ b/node/src/eventsbuilder.ts @@ -5,7 +5,7 @@ */ import { orderer } from '@hyperledger/fabric-protos'; -import { Checkpoint } from './checkpointer'; +import { Checkpoint } from './checkpointer.js'; /** * Options used when requesting events. diff --git a/node/src/filecheckpointer.ts b/node/src/filecheckpointer.ts index 18a5ecad6..e99162025 100644 --- a/node/src/filecheckpointer.ts +++ b/node/src/filecheckpointer.ts @@ -5,8 +5,8 @@ */ import fs from 'node:fs'; -import { ChaincodeEvent } from './chaincodeevent'; -import { Checkpointer } from './checkpointer'; +import { ChaincodeEvent } from './chaincodeevent.js'; +import { Checkpointer } from './checkpointer.js'; /** * Interface to store checkpointer state during file read write operations . diff --git a/node/src/gateway.test.ts b/node/src/gateway.test.ts index 4c0aa7303..9c6246aef 100644 --- a/node/src/gateway.test.ts +++ b/node/src/gateway.test.ts @@ -5,8 +5,8 @@ */ import * as grpc from '@grpc/grpc-js'; -import { connect, ConnectOptions } from './gateway'; -import { Identity } from './identity/identity'; +import { connect, ConnectOptions } from './gateway.js'; +import { Identity } from './identity/identity.js'; describe('Gateway', () => { let identity: Identity; diff --git a/node/src/gateway.ts b/node/src/gateway.ts index 707a685cb..26c9036c6 100644 --- a/node/src/gateway.ts +++ b/node/src/gateway.ts @@ -16,7 +16,7 @@ import { requestCallback, } from '@grpc/grpc-js'; import { common, gateway, peer } from '@hyperledger/fabric-protos'; -import { ChaincodeEventsRequest, Commit, Proposal, Transaction } from '.'; +import { ChaincodeEventsRequest, Commit, Proposal, Transaction } from './index.js'; import { BlockAndPrivateDataEventsRequest, BlockAndPrivateDataEventsRequestImpl, @@ -24,17 +24,17 @@ import { BlockEventsRequestImpl, FilteredBlockEventsRequest, FilteredBlockEventsRequestImpl, -} from './blockeventsrequest'; -import { ChaincodeEventsRequestImpl } from './chaincodeeventsrequest'; -import { GatewayClient, GatewayGrpcClient, newGatewayClient } from './client'; -import { CommitImpl } from './commit'; -import { Hash } from './hash/hash'; -import { Identity } from './identity/identity'; -import { Signer } from './identity/signer'; -import { Network, NetworkImpl } from './network'; -import { ProposalImpl } from './proposal'; -import { SigningIdentity } from './signingidentity'; -import { TransactionImpl } from './transaction'; +} from './blockeventsrequest.js'; +import { ChaincodeEventsRequestImpl } from './chaincodeeventsrequest.js'; +import { GatewayClient, GatewayGrpcClient, newGatewayClient } from './client.js'; +import { CommitImpl } from './commit.js'; +import { Hash } from './hash/hash.js'; +import { Identity } from './identity/identity.js'; +import { Signer } from './identity/signer.js'; +import { Network, NetworkImpl } from './network.js'; +import { ProposalImpl } from './proposal.js'; +import { SigningIdentity } from './signingidentity.js'; +import { TransactionImpl } from './transaction.js'; /** * Interface describing the public API of the gRPC [Client](https://grpc.github.io/grpc/node/grpc.Client.html) class, diff --git a/node/src/hash/hashes.test.ts b/node/src/hash/hashes.test.ts index 8f8297b2c..4722aee52 100644 --- a/node/src/hash/hashes.test.ts +++ b/node/src/hash/hashes.test.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import * as hashes from './hashes'; +import * as hashes from './hashes.js'; describe('hashes', () => { Object.entries(hashes).forEach(([name, hash]) => { diff --git a/node/src/hash/hashes.ts b/node/src/hash/hashes.ts index 2cdc7967b..343641a60 100644 --- a/node/src/hash/hashes.ts +++ b/node/src/hash/hashes.ts @@ -5,7 +5,7 @@ */ import { createHash } from 'node:crypto'; -import { Hash } from './hash'; +import { Hash } from './hash.js'; /** * Returns the input message unchanged. This can be used if the signing implementation requires the full message bytes, diff --git a/node/src/identity/ecdsa.ts b/node/src/identity/ecdsa.ts index 552f41ee8..4c018e9b1 100644 --- a/node/src/identity/ecdsa.ts +++ b/node/src/identity/ecdsa.ts @@ -4,13 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { CurveFn } from '@noble/curves/abstract/weierstrass'; -import { p256 } from '@noble/curves/nist'; -import { p384 } from '@noble/curves/nist'; +import { p256, p384 } from '@noble/curves/nist.js'; import { KeyObject } from 'node:crypto'; -import { Signer } from './signer'; +import { Signer } from './signer.js'; -const namedCurves: Record = { +type Curve = typeof p256; +const namedCurves: Record = { 'P-256': p256, 'P-384': p384, }; @@ -28,12 +27,12 @@ export function newECPrivateKeySigner(key: KeyObject): Signer { const privateKey = Buffer.from(d, 'base64url'); return (digest) => { - const signature = curve.sign(digest, privateKey, { lowS: true }); - return Promise.resolve(signature.toBytes('der')); + const signature = curve.sign(digest, privateKey, { lowS: true, prehash: false, format: 'der' }); + return Promise.resolve(signature); }; } -function getCurve(name: string): CurveFn { +function getCurve(name: string): Curve { const curve = namedCurves[name]; if (!curve) { throw new Error(`Unsupported curve: ${name}`); diff --git a/node/src/identity/hsmsigner.test.ts b/node/src/identity/hsmsigner.test.ts index 1ad3b9359..bb775d5d7 100644 --- a/node/src/identity/hsmsigner.test.ts +++ b/node/src/identity/hsmsigner.test.ts @@ -4,11 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { p256 } from '@noble/curves/nist'; +import { p256 } from '@noble/curves/nist.js'; import { createHash } from 'node:crypto'; import { Mechanism, Pkcs11Error, SessionInfo, SlotInfo, Template, TokenInfo } from 'pkcs11js'; -import { HSMSignerOptions } from './hsmsigner'; -import { newHSMSignerFactory } from './signers'; +import { HSMSignerOptions } from './hsmsigner.js'; +import { newHSMSignerFactory } from './signers.js'; const CKO_PRIVATE_KEY = 179; const CKA_ID = 54; @@ -212,7 +212,7 @@ describe('When using an HSM Signer', () => { }); pkcs11Stub.C_SignInit = jest.fn(); pkcs11Stub.C_SignAsync = jest.fn((session, digest, buffer) => { - const signature = p256.sign(digest, privateKey).toBytes('compact'); + const signature = p256.sign(digest, privateKey, { format: 'compact', prehash: false }); signature.forEach((b, i) => buffer.writeUInt8(b, i)); // Return buffer of exactly signature length regardless of supplied buffer size const result = buffer.subarray(0, signature.length); @@ -372,7 +372,7 @@ describe('When using an HSM Signer', () => { const { signer } = hsmSignerFactory.newSigner(hsmOptions); const signature = await signer(digest); - const valid = p256.verify(signature, digest, publicKey); + const valid = p256.verify(signature, digest, publicKey, { format: 'der', prehash: false }); expect(valid).toBe(true); expect(pkcs11Stub.C_SignInit).toHaveBeenCalledWith(mockSession, { mechanism: CKM_ECDSA }, mockPrivateKeyHandle); diff --git a/node/src/identity/hsmsigner.ts b/node/src/identity/hsmsigner.ts index 9185587ee..b695ce85b 100644 --- a/node/src/identity/hsmsigner.ts +++ b/node/src/identity/hsmsigner.ts @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { p256 } from '@noble/curves/nist'; +import { p256 } from '@noble/curves/nist.js'; import * as pkcs11js from 'pkcs11js'; -import { Signer } from './signer'; +import { Signer } from './signer.js'; export interface HSMSignerOptions { /** @@ -99,11 +99,11 @@ export class HSMSignerFactoryImpl implements HSMSignerFactory { const compactSignature = await pkcs11.C_SignAsync( session, Buffer.from(digest), - // EC signatures have length of 2n according to the PKCS11 spec: - // https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html Buffer.alloc(p256.Point.Fn.BYTES * 2), ); - return p256.Signature.fromBytes(compactSignature, 'compact').normalizeS().toBytes('der'); + const sig = p256.Signature.fromBytes(compactSignature, 'compact'); + const normalizedSig = sig.hasHighS() ? new p256.Signature(sig.r, p256.Point.CURVE().n - sig.s) : sig; + return normalizedSig.toBytes('der'); }, close: () => { pkcs11.C_CloseSession(session); diff --git a/node/src/identity/signers.test.ts b/node/src/identity/signers.test.ts index 1f46ac0f5..9ccd04980 100644 --- a/node/src/identity/signers.test.ts +++ b/node/src/identity/signers.test.ts @@ -5,7 +5,7 @@ */ import { createHash, generateKeyPairSync, verify } from 'node:crypto'; -import { newPrivateKeySigner } from './signers'; +import { newPrivateKeySigner } from './signers.js'; describe('signers', () => { it('throws for public key', () => { diff --git a/node/src/identity/signers.ts b/node/src/identity/signers.ts index ccf44d42d..91acee170 100644 --- a/node/src/identity/signers.ts +++ b/node/src/identity/signers.ts @@ -5,9 +5,9 @@ */ import { KeyObject, sign } from 'node:crypto'; -import { newECPrivateKeySigner } from './ecdsa'; -import { HSMSignerFactory, type HSMSignerFactoryImpl as HSMSignerFactoryImplType } from './hsmsigner'; -import { Signer } from './signer'; +import { newECPrivateKeySigner } from './ecdsa.js'; +import { HSMSignerFactory, type HSMSignerFactoryImpl as HSMSignerFactoryImplType } from './hsmsigner.js'; +import { Signer } from './signer.js'; /** * Create a new signing implementation that uses the supplied private key to sign messages. diff --git a/node/src/index.ts b/node/src/index.ts index 1d795b480..759e123e6 100644 --- a/node/src/index.ts +++ b/node/src/index.ts @@ -4,37 +4,37 @@ * SPDX-License-Identifier: Apache-2.0 */ -export { type BlockEventsOptions } from './blockeventsbuilder'; +export { type BlockEventsOptions } from './blockeventsbuilder.js'; export { type BlockAndPrivateDataEventsRequest, type BlockEventsRequest, type FilteredBlockEventsRequest, -} from './blockeventsrequest'; -export { type ChaincodeEvent } from './chaincodeevent'; -export { type ChaincodeEventsOptions } from './chaincodeeventsbuilder'; -export { type ChaincodeEventsRequest } from './chaincodeeventsrequest'; -export { type Checkpoint, type Checkpointer } from './checkpointer'; -export * as checkpointers from './checkpointers'; -export { type CloseableAsyncIterable } from './client'; -export { type Commit } from './commit'; -export { CommitError } from './commiterror'; -export { CommitStatusError } from './commitstatuserror'; -export { type Contract } from './contract'; -export { EndorseError } from './endorseerror'; -export { type EventsOptions } from './eventsbuilder'; -export { type ConnectOptions, type Gateway, type GrpcClient, connect } from './gateway'; -export { type ErrorDetail, GatewayError } from './gatewayerror'; -export { type Hash } from './hash/hash'; -export * as hash from './hash/hashes'; -export { type HSMSigner, type HSMSignerFactory, type HSMSignerOptions } from './identity/hsmsigner'; -export { type Identity } from './identity/identity'; -export { type Signer } from './identity/signer'; -export * as signers from './identity/signers'; -export { type Network } from './network'; -export { type Proposal } from './proposal'; -export { type ProposalOptions } from './proposalbuilder'; -export { type Signable } from './signable'; -export { type Status, StatusCode } from './status'; -export { type SubmitError } from './submiterror'; -export { type SubmittedTransaction } from './submittedtransaction'; -export { type Transaction } from './transaction'; +} from './blockeventsrequest.js'; +export { type ChaincodeEvent } from './chaincodeevent.js'; +export { type ChaincodeEventsOptions } from './chaincodeeventsbuilder.js'; +export { type ChaincodeEventsRequest } from './chaincodeeventsrequest.js'; +export { type Checkpoint, type Checkpointer } from './checkpointer.js'; +export * as checkpointers from './checkpointers.js'; +export { type CloseableAsyncIterable } from './client.js'; +export { type Commit } from './commit.js'; +export { CommitError } from './commiterror.js'; +export { CommitStatusError } from './commitstatuserror.js'; +export { type Contract } from './contract.js'; +export { EndorseError } from './endorseerror.js'; +export { type EventsOptions } from './eventsbuilder.js'; +export { type ConnectOptions, type Gateway, type GrpcClient, connect } from './gateway.js'; +export { type ErrorDetail, GatewayError } from './gatewayerror.js'; +export { type Hash } from './hash/hash.js'; +export * as hash from './hash/hashes.js'; +export { type HSMSigner, type HSMSignerFactory, type HSMSignerOptions } from './identity/hsmsigner.js'; +export { type Identity } from './identity/identity.js'; +export { type Signer } from './identity/signer.js'; +export * as signers from './identity/signers.js'; +export { type Network } from './network.js'; +export { type Proposal } from './proposal.js'; +export { type ProposalOptions } from './proposalbuilder.js'; +export { type Signable } from './signable.js'; +export { type Status, StatusCode } from './status.js'; +export { type SubmitError } from './submiterror.js'; +export { type SubmittedTransaction } from './submittedtransaction.js'; +export { type Transaction } from './transaction.js'; diff --git a/node/src/inmemorycheckpointer.ts b/node/src/inmemorycheckpointer.ts index e49e8130e..1e6ec7d0a 100644 --- a/node/src/inmemorycheckpointer.ts +++ b/node/src/inmemorycheckpointer.ts @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Checkpointer } from './checkpointer'; -import { ChaincodeEvent } from './chaincodeevent'; +import { Checkpointer } from './checkpointer.js'; +import { ChaincodeEvent } from './chaincodeevent.js'; /** * In-memory checkpointer class used to persist checkpointer state in memory. diff --git a/node/src/network.test.ts b/node/src/network.test.ts index 221ec8827..5a70502c6 100644 --- a/node/src/network.test.ts +++ b/node/src/network.test.ts @@ -5,9 +5,9 @@ */ import * as grpc from '@grpc/grpc-js'; -import { connect, ConnectOptions } from './gateway'; -import { Identity } from './identity/identity'; -import { Network } from './network'; +import { connect, ConnectOptions } from './gateway.js'; +import { Identity } from './identity/identity.js'; +import { Network } from './network.js'; describe('Network', () => { let network: Network; diff --git a/node/src/network.ts b/node/src/network.ts index d4bc41277..3b6e870f2 100644 --- a/node/src/network.ts +++ b/node/src/network.ts @@ -11,14 +11,18 @@ import { BlockEventsBuilderOptions, BlockEventsOptions, FilteredBlockEventsBuilder, -} from './blockeventsbuilder'; -import { BlockAndPrivateDataEventsRequest, BlockEventsRequest, FilteredBlockEventsRequest } from './blockeventsrequest'; -import { ChaincodeEvent } from './chaincodeevent'; -import { ChaincodeEventsBuilder, ChaincodeEventsOptions } from './chaincodeeventsbuilder'; -import { ChaincodeEventsRequest } from './chaincodeeventsrequest'; -import { CloseableAsyncIterable, GatewayClient } from './client'; -import { Contract, ContractImpl } from './contract'; -import { SigningIdentity } from './signingidentity'; +} from './blockeventsbuilder.js'; +import { + BlockAndPrivateDataEventsRequest, + BlockEventsRequest, + FilteredBlockEventsRequest, +} from './blockeventsrequest.js'; +import { ChaincodeEvent } from './chaincodeevent.js'; +import { ChaincodeEventsBuilder, ChaincodeEventsOptions } from './chaincodeeventsbuilder.js'; +import { ChaincodeEventsRequest } from './chaincodeeventsrequest.js'; +import { CloseableAsyncIterable, GatewayClient } from './client.js'; +import { Contract, ContractImpl } from './contract.js'; +import { SigningIdentity } from './signingidentity.js'; /** * Network represents a network of nodes that are members of a specific Fabric channel. The Network can be used to diff --git a/node/src/offlinesign.test.ts b/node/src/offlinesign.test.ts index 105bd8828..eda4741b3 100644 --- a/node/src/offlinesign.test.ts +++ b/node/src/offlinesign.test.ts @@ -5,12 +5,12 @@ */ import { common, gateway as gatewayproto, peer } from '@hyperledger/fabric-protos'; -import { Contract } from './contract'; -import { Gateway, InternalConnectOptions, internalConnect } from './gateway'; -import { Identity } from './identity/identity'; -import { Network } from './network'; -import { undefinedSignerMessage } from './signingidentity'; -import { asString, MockGatewayGrpcClient, newDuplexStreamResponse, newEndorseResponse } from './testutils.test'; +import { Contract } from './contract.js'; +import { Gateway, InternalConnectOptions, internalConnect } from './gateway.js'; +import { Identity } from './identity/identity.js'; +import { Network } from './network.js'; +import { undefinedSignerMessage } from './signingidentity.js'; +import { asString, MockGatewayGrpcClient, newDuplexStreamResponse, newEndorseResponse } from './testutils.test.js'; describe('Offline sign', () => { const expectedResult = 'TX_RESULT'; diff --git a/node/src/proposal.test.ts b/node/src/proposal.test.ts index 97c045771..c0a978713 100644 --- a/node/src/proposal.test.ts +++ b/node/src/proposal.test.ts @@ -6,12 +6,12 @@ import { CallOptions, Metadata, ServiceError, status } from '@grpc/grpc-js'; import { common, gateway as gatewayproto, msp, peer } from '@hyperledger/fabric-protos'; -import { Contract } from './contract'; -import { EndorseError } from './endorseerror'; -import { Gateway, assertDefined, internalConnect } from './gateway'; -import { Identity } from './identity/identity'; -import { Network } from './network'; -import { asString, MockGatewayGrpcClient, newEndorseResponse } from './testutils.test'; +import { Contract } from './contract.js'; +import { EndorseError } from './endorseerror.js'; +import { Gateway, assertDefined, internalConnect } from './gateway.js'; +import { Identity } from './identity/identity.js'; +import { Network } from './network.js'; +import { asString, MockGatewayGrpcClient, newEndorseResponse } from './testutils.test.js'; function assertDecodeEvaluateRequest(request: gatewayproto.EvaluateRequest): peer.Proposal { let proposalBytes = request.getProposedTransaction()?.getProposalBytes_asU8(); diff --git a/node/src/proposal.ts b/node/src/proposal.ts index c3149eead..8c564a89c 100644 --- a/node/src/proposal.ts +++ b/node/src/proposal.ts @@ -6,11 +6,11 @@ import { CallOptions } from '@grpc/grpc-js'; import { common, gateway, peer } from '@hyperledger/fabric-protos'; -import { GatewayClient } from './client'; -import { assertDefined } from './gateway'; -import { Signable } from './signable'; -import { SigningIdentity } from './signingidentity'; -import { Transaction, TransactionImpl } from './transaction'; +import { GatewayClient } from './client.js'; +import { assertDefined } from './gateway.js'; +import { Signable } from './signable.js'; +import { SigningIdentity } from './signingidentity.js'; +import { Transaction, TransactionImpl } from './transaction.js'; /** * Proposal represents a transaction proposal that can be sent to peers for endorsement or evaluated as a query. diff --git a/node/src/proposalbuilder.ts b/node/src/proposalbuilder.ts index 0691b9d76..6caef2b0a 100644 --- a/node/src/proposalbuilder.ts +++ b/node/src/proposalbuilder.ts @@ -6,10 +6,10 @@ import { common, gateway, peer } from '@hyperledger/fabric-protos'; import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; -import { GatewayClient } from './client'; -import { Proposal, ProposalImpl } from './proposal'; -import { SigningIdentity } from './signingidentity'; -import { TransactionContext } from './transactioncontext'; +import { GatewayClient } from './client.js'; +import { Proposal, ProposalImpl } from './proposal.js'; +import { SigningIdentity } from './signingidentity.js'; +import { TransactionContext } from './transactioncontext.js'; /** * Options used when evaluating or endorsing a transaction proposal. diff --git a/node/src/signingidentity.test.ts b/node/src/signingidentity.test.ts index b9f0fd37d..5603c05df 100644 --- a/node/src/signingidentity.test.ts +++ b/node/src/signingidentity.test.ts @@ -5,9 +5,9 @@ */ import { msp } from '@hyperledger/fabric-protos'; -import { Identity } from './identity/identity'; -import { Signer } from './identity/signer'; -import { SigningIdentity } from './signingidentity'; +import { Identity } from './identity/identity.js'; +import { Signer } from './identity/signer.js'; +import { SigningIdentity } from './signingidentity.js'; describe('SigningIdentity', () => { let identity: Identity; diff --git a/node/src/signingidentity.ts b/node/src/signingidentity.ts index 40f248e2f..1ad7a7df5 100644 --- a/node/src/signingidentity.ts +++ b/node/src/signingidentity.ts @@ -5,11 +5,11 @@ */ import { msp } from '@hyperledger/fabric-protos'; -import { ConnectOptions } from './gateway'; -import { Hash } from './hash/hash'; -import { sha256 } from './hash/hashes'; -import { Identity } from './identity/identity'; -import { Signer } from './identity/signer'; +import { ConnectOptions } from './gateway.js'; +import { Hash } from './hash/hash.js'; +import { sha256 } from './hash/hashes.js'; +import { Identity } from './identity/identity.js'; +import { Signer } from './identity/signer.js'; export const undefinedSignerMessage = 'No signing implementation'; diff --git a/node/src/submiterror.ts b/node/src/submiterror.ts index e0562cfa5..159a5a061 100644 --- a/node/src/submiterror.ts +++ b/node/src/submiterror.ts @@ -5,7 +5,7 @@ */ import { ServiceError } from '@grpc/grpc-js'; -import { ErrorDetail, GatewayError } from './gatewayerror'; +import { ErrorDetail, GatewayError } from './gatewayerror.js'; /** * SubmitError is thrown when a failure occurs submitting an endorsed transaction to the orderer. diff --git a/node/src/submittedtransaction.ts b/node/src/submittedtransaction.ts index b48426028..2b10f10c7 100644 --- a/node/src/submittedtransaction.ts +++ b/node/src/submittedtransaction.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Commit, CommitImpl, CommitImplOptions } from './commit'; +import { Commit, CommitImpl, CommitImplOptions } from './commit.js'; /** * Allows access to the transaction result and its commit status on the ledger. diff --git a/node/src/testutils.test.ts b/node/src/testutils.test.ts index 7ebd94dc3..0d799153e 100644 --- a/node/src/testutils.test.ts +++ b/node/src/testutils.test.ts @@ -22,8 +22,8 @@ import { endorseMethod, evaluateMethod, submitMethod, -} from './client'; -import { assertDefined } from './gateway'; +} from './client.js'; +import { assertDefined } from './gateway.js'; /* eslint-disable jest/no-export */ diff --git a/node/src/transaction.test.ts b/node/src/transaction.test.ts index 1d70d4a74..93bdb3199 100644 --- a/node/src/transaction.test.ts +++ b/node/src/transaction.test.ts @@ -6,14 +6,14 @@ import { CallOptions, Metadata, ServiceError, status } from '@grpc/grpc-js'; import { gateway as gatewayproto, peer } from '@hyperledger/fabric-protos'; -import { CommitError } from './commiterror'; -import { CommitStatusError } from './commitstatuserror'; -import { Contract } from './contract'; -import { Gateway, internalConnect, InternalConnectOptions } from './gateway'; -import { Identity } from './identity/identity'; -import { Network } from './network'; -import { SubmitError } from './submiterror'; -import { asString, MockGatewayGrpcClient, newEndorseResponse } from './testutils.test'; +import { CommitError } from './commiterror.js'; +import { CommitStatusError } from './commitstatuserror.js'; +import { Contract } from './contract.js'; +import { Gateway, internalConnect, InternalConnectOptions } from './gateway.js'; +import { Identity } from './identity/identity.js'; +import { Network } from './network.js'; +import { SubmitError } from './submiterror.js'; +import { asString, MockGatewayGrpcClient, newEndorseResponse } from './testutils.test.js'; describe('Transaction', () => { const expectedResult = 'TX_RESULT'; diff --git a/node/src/transaction.ts b/node/src/transaction.ts index 07c7ac907..e9c51359e 100644 --- a/node/src/transaction.ts +++ b/node/src/transaction.ts @@ -6,12 +6,12 @@ import { CallOptions } from '@grpc/grpc-js'; import { common, gateway } from '@hyperledger/fabric-protos'; -import { GatewayClient } from './client'; -import { assertDefined } from './gateway'; -import { Signable } from './signable'; -import { SigningIdentity } from './signingidentity'; -import { SubmittedTransaction, SubmittedTransactionImpl } from './submittedtransaction'; -import { parseTransactionEnvelope } from './transactionparser'; +import { GatewayClient } from './client.js'; +import { assertDefined } from './gateway.js'; +import { Signable } from './signable.js'; +import { SigningIdentity } from './signingidentity.js'; +import { SubmittedTransaction, SubmittedTransactionImpl } from './submittedtransaction.js'; +import { parseTransactionEnvelope } from './transactionparser.js'; /** * Represents an endorsed transaction that can be submitted to the orderer for commit to the ledger. diff --git a/node/src/transactioncontext.ts b/node/src/transactioncontext.ts index 408cd0d2e..773c0a436 100644 --- a/node/src/transactioncontext.ts +++ b/node/src/transactioncontext.ts @@ -6,8 +6,8 @@ import { common } from '@hyperledger/fabric-protos'; import { randomBytes } from 'node:crypto'; -import { sha256 } from './hash/hashes'; -import { SigningIdentity } from './signingidentity'; +import { sha256 } from './hash/hashes.js'; +import { SigningIdentity } from './signingidentity.js'; export class TransactionContext { readonly #transactionId: string; diff --git a/node/src/transactionparser.ts b/node/src/transactionparser.ts index a06d9babc..621987233 100644 --- a/node/src/transactionparser.ts +++ b/node/src/transactionparser.ts @@ -6,7 +6,7 @@ import { common, peer } from '@hyperledger/fabric-protos'; import { inspect } from 'node:util'; -import { assertDefined } from './gateway'; +import { assertDefined } from './gateway.js'; export function parseTransactionEnvelope(envelope: common.Envelope): { channelName: string; diff --git a/node/tsconfig.json b/node/tsconfig.json index f9c9ff5d9..2f5b6c86f 100644 --- a/node/tsconfig.json +++ b/node/tsconfig.json @@ -2,6 +2,8 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler", "declaration": true, "declarationMap": true, "erasableSyntaxOnly": true, From 6901b18250130ba5838558999ffefce3ac74b2b2 Mon Sep 17 00:00:00 2001 From: thinktanktom Date: Tue, 17 Feb 2026 17:24:24 +0530 Subject: [PATCH 2/2] fix: address review comments from maintainer --- node/src/blockeventsbuilder.ts | 3 +++ node/src/identity/hsmsigner.ts | 11 ++++++++--- node/src/proposalbuilder.ts | 3 +++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/node/src/blockeventsbuilder.ts b/node/src/blockeventsbuilder.ts index e67d51718..d752910c3 100644 --- a/node/src/blockeventsbuilder.ts +++ b/node/src/blockeventsbuilder.ts @@ -5,6 +5,9 @@ */ import { common, orderer } from '@hyperledger/fabric-protos'; +// google-protobuf has no package exports field, so deep path imports are +// unresolvable under node18 module resolution. Disable unsafe rules for this import. +// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; import { BlockAndPrivateDataEventsRequest, diff --git a/node/src/identity/hsmsigner.ts b/node/src/identity/hsmsigner.ts index b695ce85b..97c000da9 100644 --- a/node/src/identity/hsmsigner.ts +++ b/node/src/identity/hsmsigner.ts @@ -99,11 +99,16 @@ export class HSMSignerFactoryImpl implements HSMSignerFactory { const compactSignature = await pkcs11.C_SignAsync( session, Buffer.from(digest), + // EC signatures have length of 2n according to the PKCS11 spec: + // https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html Buffer.alloc(p256.Point.Fn.BYTES * 2), ); - const sig = p256.Signature.fromBytes(compactSignature, 'compact'); - const normalizedSig = sig.hasHighS() ? new p256.Signature(sig.r, p256.Point.CURVE().n - sig.s) : sig; - return normalizedSig.toBytes('der'); + let signature = p256.Signature.fromBytes(compactSignature, 'compact'); + if (signature.hasHighS()) { + signature = new p256.Signature(signature.r, p256.Point.CURVE().n - signature.s); + } + + return signature.toBytes('der'); }, close: () => { pkcs11.C_CloseSession(session); diff --git a/node/src/proposalbuilder.ts b/node/src/proposalbuilder.ts index 6caef2b0a..90c8b9596 100644 --- a/node/src/proposalbuilder.ts +++ b/node/src/proposalbuilder.ts @@ -5,6 +5,9 @@ */ import { common, gateway, peer } from '@hyperledger/fabric-protos'; +// google-protobuf has no package exports field, so deep path imports are +// unresolvable under node18 module resolution. Disable unsafe rules for this import. +// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; import { GatewayClient } from './client.js'; import { Proposal, ProposalImpl } from './proposal.js';