From 35eac4c30f7777896925957973c8386d3145cc1b Mon Sep 17 00:00:00 2001 From: HardlyDifficult Date: Wed, 23 Sep 2026 13:13:06 -0400 Subject: [PATCH 1/6] chore(deps): bump all upgradable pinned dependencies to latest installable Co-authored-by: Cursor --- package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 38b7b813..747ed65f 100644 --- a/package.json +++ b/package.json @@ -62,41 +62,41 @@ "tsc7": "node node_modules/typescript-7/bin/tsc" }, "dependencies": { - "@canton-network/wallet-sdk": "1.5.1", + "@canton-network/wallet-sdk": "1.5.3", "@hardlydifficult/rest-client": "1.0.65", "@hardlydifficult/websocket": "1.0.73", "@stellar/stellar-base": "15.0.0", - "axios": "1.19.0", - "dotenv": "17.4.2", + "axios": "1.20.0", + "dotenv": "18.0.3", "glob": "13.0.6", "openapi-fetch": "0.17.0", "openapi-typescript": "7.13.0", "pino": "10.3.1", - "ws": "8.21.2", - "zod": "4.4.3" + "ws": "8.21.3", + "zod": "4.6.5" }, "devDependencies": { - "@fairmint/canton-dev-tools": "0.1.7", + "@fairmint/canton-dev-tools": "0.1.11", "@types/jest": "30.0.0", - "@types/node": "26.1.2", + "@types/node": "26.6.2", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.62.1", - "@typescript-eslint/parser": "8.62.1", + "@typescript-eslint/eslint-plugin": "8.70.1", + "@typescript-eslint/parser": "8.70.1", "eslint": "9.39.2", "eslint-config-prettier": "10.1.8", "eslint-import-resolver-typescript": "4.4.5", "eslint-plugin-import": "2.32.0", "eslint-plugin-markdown": "5.1.0", "eslint-plugin-unused-imports": "4.4.1", - "jest": "30.4.2", + "jest": "30.5.2", "markdownlint-cli": "0.49.1", - "npm-package-json-lint": "10.4.1", - "prettier": "3.9.6", + "npm-package-json-lint": "11.0.0", + "prettier": "3.9.8", "prettier-plugin-jsdoc": "1.8.1", "prettier-plugin-organize-imports": "4.3.0", "prettier-plugin-packagejson": "3.0.2", "ts-jest": "29.4.12", - "tsx": "4.23.7", + "tsx": "4.23.15", "typescript": "5.9.3", "typescript-7": "npm:typescript@7.0.2" }, From 84883cf5ab6e69c50e47f1f8b68f16f45d74b662 Mon Sep 17 00:00:00 2001 From: HardlyDifficult Date: Wed, 23 Sep 2026 13:35:38 -0400 Subject: [PATCH 2/6] chore(lint): accommodate typescript-eslint 8.70 rule tightening - Scope unbound-method off to test files (jest expect(mock.method) idiom flagged by the tightened rule; mocks never rely on this). - Drop now-redundant eslint-disable comments in three test files. - Fix 4 pre-existing baseline errors: promise-function-async in race-sensitive spots kept non-async with targeted disables (timing verified by unit tests), plus one consistent-type-imports fix. - Remove meaningless void operators in typecheck tests flagged by no-meaningless-void-operator in typescript-eslint 8.69+. Co-authored-by: Cursor --- eslint.config.mjs | 9 ++ .../external-party-onboarding.ts | 1 + .../ledger-contract-by-id.typecheck.ts | 34 ++--- test/typecheck/ledger-dars.typecheck.ts | 2 +- ...ledger-interactive-submission.typecheck.ts | 142 +++++++++--------- test/typecheck/operation-retry.typecheck.ts | 14 +- .../scan-registry-metadata.typecheck.ts | 2 +- .../scan-snapshot-after.typecheck.ts | 12 +- ...obal-domain-connection-config.typecheck.ts | 6 +- ...ator-wallet-list-transactions.typecheck.ts | 16 +- .../validator-wallet-tap.typecheck.ts | 12 +- test/unit/amulet/offers.test.ts | 1 - test/unit/clients/scan-api.test.ts | 1 - .../unit/clients/validator-api-health.test.ts | 1 - .../external-party-lifecycle.test.ts | 1 + .../external-party-onboarding.test.ts | 3 +- 16 files changed, 133 insertions(+), 124 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 71b8413b..bbc6c24e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -201,6 +201,15 @@ const eslintConfig = [ '@typescript-eslint/no-redundant-type-constituents': 'off', }, }, + // typescript-eslint 8.69+ tightened unbound-method to flag bare method + // references like the jest idiom `expect(mock.method)`. Test files never + // rely on `this` for these references, so relax the rule in tests only. + { + files: ['test/**/*'], + rules: { + '@typescript-eslint/unbound-method': 'off', + }, + }, // Prettier config last to override any conflicting rules eslintConfigPrettier, ]; diff --git a/src/utils/external-signing/external-party-onboarding.ts b/src/utils/external-signing/external-party-onboarding.ts index 825be1e6..5fe29b58 100644 --- a/src/utils/external-signing/external-party-onboarding.ts +++ b/src/utils/external-signing/external-party-onboarding.ts @@ -424,6 +424,7 @@ async function readExistingExternalPartyAfterAllocationConflict( const abortError = new ValidationError('Canton external-party conflict reconciliation was aborted', { partyId }); const createAbortError = (): ValidationError => abortError; try { + // eslint-disable-next-line @typescript-eslint/promise-function-async -- non-async arrow preserves rejection timing expected by race tests const partyDetailsResponse = await runWithAbortSignal(signal, createAbortError, () => signal === undefined ? ledgerClient.getPartyDetails({ diff --git a/test/typecheck/ledger-contract-by-id.typecheck.ts b/test/typecheck/ledger-contract-by-id.typecheck.ts index d1e3e87f..a47d1584 100644 --- a/test/typecheck/ledger-contract-by-id.typecheck.ts +++ b/test/typecheck/ledger-contract-by-id.typecheck.ts @@ -102,20 +102,20 @@ createdEvent.offset; void ledgerClient.getContractById(request, exactBodyRetry); void ledgerClient.getContractById(requestWithoutParties, derivedBodyRetry); -void requestWithUnknownField; -void requestWithUndefinedOptional; -void requestWithPlainString; -void requestWithPartyAsContract; -void requestWithContractAsParty; -void createArgument; -void optionalContractKey; -void responseContractId; -void responseWitness; -void responseTemplateId; -void responsePackageId; -void responsePackageName; -void responseInterfaceId; -void responseImplementationPackageId; -void unvalidatedTemplateId; -void nullContractKey; -void invalidCreateArgument; +requestWithUnknownField; +requestWithUndefinedOptional; +requestWithPlainString; +requestWithPartyAsContract; +requestWithContractAsParty; +createArgument; +optionalContractKey; +responseContractId; +responseWitness; +responseTemplateId; +responsePackageId; +responsePackageName; +responseInterfaceId; +responseImplementationPackageId; +unvalidatedTemplateId; +nullContractKey; +invalidCreateArgument; diff --git a/test/typecheck/ledger-dars.typecheck.ts b/test/typecheck/ledger-dars.typecheck.ts index 9abf7630..fdea0239 100644 --- a/test/typecheck/ledger-dars.typecheck.ts +++ b/test/typecheck/ledger-dars.typecheck.ts @@ -37,4 +37,4 @@ void client.validateDar({ darFile: Buffer.from('dar'), synchronizerId: 'sync::on // @ts-expect-error Successful DAR upload responses cannot expose arbitrary properties. const invalidResponse: UploadDarResponse = { packageId: 'unexpected' }; -void invalidResponse; +invalidResponse; diff --git a/test/typecheck/ledger-interactive-submission.typecheck.ts b/test/typecheck/ledger-interactive-submission.typecheck.ts index fdcbbaf5..d4f52201 100644 --- a/test/typecheck/ledger-interactive-submission.typecheck.ts +++ b/test/typecheck/ledger-interactive-submission.typecheck.ts @@ -142,14 +142,14 @@ const prepareResponse: PrepareResponse = { hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V3', }; -void executeAndWaitForTransactionRequest; -void invalidHelperHashingScheme; -void unspecifiedTransactionShape; -void executeAndWaitResponse; -void prepareRequest; -void unspecifiedPrepareHashingScheme; -void unspecifiedCostHintSigningAlgorithm; -void prepareResponse; +executeAndWaitForTransactionRequest; +invalidHelperHashingScheme; +unspecifiedTransactionShape; +executeAndWaitResponse; +prepareRequest; +unspecifiedPrepareHashingScheme; +unspecifiedCostHintSigningAlgorithm; +prepareResponse; const invalidOffsetRequest: ExecuteAndWaitRequest = { ...executeAndWaitRequest, @@ -256,11 +256,11 @@ const invalidExerciseChoiceArgument: ExercisedTransactionEvent['choiceArgument'] // @ts-expect-error Exercise results are JSON values when present. const invalidExerciseResult: ExercisedTransactionEvent['exerciseResult'] = Symbol('invalid'); -void normalizedTraceContext; -void normalizedTraceState; -void nullTraceState; -void rawExternalHashString; -void unvalidatedExternalHash; +normalizedTraceContext; +normalizedTraceState; +nullTraceState; +rawExternalHashString; +unvalidatedExternalHash; type PrepareCommand = PrepareRequest['commands'][number]; type CreateArguments = Extract['CreateCommand']['createArguments']; @@ -329,43 +329,43 @@ const invalidMultiBranchEvent: InteractiveSubmissionEvent = { CreatedEvent: createdEvent, }; -void invalidOffsetRequest; -void invalidHashingSchemeRequest; -void unspecifiedHashingSchemeRequest; -void decodedProtoAny; -void invalidDecodedProtoAny; -void invalidSignatureFormat; -void unspecifiedSignatureFormat; -void invalidSigningAlgorithm; -void unspecifiedSigningAlgorithm; -void emptyTransactionEvents; -void nullContractKey; -void nullInterfaceViewValue; -void createdEventArgument; -void exerciseChoiceArgument; -void exerciseResult; -void invalidCreatedEventArgument; -void invalidExerciseChoiceArgument; -void invalidExerciseResult; -void createArguments; -void exerciseArguments; -void createAndExerciseCreateArguments; -void createAndExerciseChoiceArguments; -void exerciseByKeyContractKey; -void exerciseByKeyChoiceArgument; -void prefetchContractKey; -void invalidCreateArguments; -void invalidExerciseArguments; -void invalidCreateAndExerciseCreateArguments; -void invalidCreateAndExerciseChoiceArguments; -void invalidExerciseByKeyContractKey; -void invalidExerciseByKeyChoiceArgument; -void invalidPrefetchContractKey; -void invalidMultiBranchCommand; -void invalidMultiBranchDeduplication; -void invalidMultiBranchTime; -void invalidMultiBranchIdentifierFilter; -void invalidMultiBranchEvent; +invalidOffsetRequest; +invalidHashingSchemeRequest; +unspecifiedHashingSchemeRequest; +decodedProtoAny; +invalidDecodedProtoAny; +invalidSignatureFormat; +unspecifiedSignatureFormat; +invalidSigningAlgorithm; +unspecifiedSigningAlgorithm; +emptyTransactionEvents; +nullContractKey; +nullInterfaceViewValue; +createdEventArgument; +exerciseChoiceArgument; +exerciseResult; +invalidCreatedEventArgument; +invalidExerciseChoiceArgument; +invalidExerciseResult; +createArguments; +exerciseArguments; +createAndExerciseCreateArguments; +createAndExerciseChoiceArguments; +exerciseByKeyContractKey; +exerciseByKeyChoiceArgument; +prefetchContractKey; +invalidCreateArguments; +invalidExerciseArguments; +invalidCreateAndExerciseCreateArguments; +invalidCreateAndExerciseChoiceArguments; +invalidExerciseByKeyContractKey; +invalidExerciseByKeyChoiceArgument; +invalidPrefetchContractKey; +invalidMultiBranchCommand; +invalidMultiBranchDeduplication; +invalidMultiBranchTime; +invalidMultiBranchIdentifierFilter; +invalidMultiBranchEvent; const invalidPackagePreference: PrepareRequest = { ...prepareRequest, @@ -381,8 +381,8 @@ const incompletePrepareResponse: PrepareResponse = { hashingSchemeVersion: 'HASHING_SCHEME_VERSION_V3', }; -void invalidPackagePreference; -void incompletePrepareResponse; +invalidPackagePreference; +incompletePrepareResponse; type Assert = Condition; type IsRequired = {} extends Pick ? false : true; @@ -510,18 +510,18 @@ const absentPreferredPackage: PreferredPackageVersionResponse = {}; // @ts-expect-error Public responses normalize wire null into an absent optional property. const wireNullPreferredPackage: PreferredPackageVersionResponse = { packagePreference: null }; -void multipleRawPrepareCommands; -void multiplePrepareCommands; +multipleRawPrepareCommands; +multiplePrepareCommands; void ledgerClient.interactiveSubmissionGetPreferredPackageVersion( preferredPackageVersionRequest, preferredPackageVersionOptions ); void ledgerClient.interactiveSubmissionGetPreferredPackages(preferredPackagesRequest, preferredPackagesOptions); -void preferredPackagesRequest; -void preferredPackageVersionRequest; -void preferredPackagesResponse; -void absentPreferredPackage; -void wireNullPreferredPackage; +preferredPackagesRequest; +preferredPackageVersionRequest; +preferredPackagesResponse; +absentPreferredPackage; +wireNullPreferredPackage; // @ts-expect-error Every derived traffic-cost estimate includes its server estimation timestamp. const trafficEstimateWithoutTimestamp: TrafficCostEstimate = { @@ -533,15 +533,15 @@ const trafficEstimateWithoutTimestamp: TrafficCostEstimate = { costInDollars: 0.01, }; -void emptyPartySignatures; -void partyWithoutSignatures; -void emptyRawPartySignatureGroups; -void emptyRawSignatures; -void emptyRawPrepareCommands; -void emptyRawActAs; -void emptyPrepareCommands; -void emptyActAsParties; -void trafficEstimateWithoutTimestamp; -void invalidExecuteExactBodyOptions; -void invalidExecuteAndWaitExactBodyOptions; -void invalidExecuteAndWaitForTransactionExactBodyOptions; +emptyPartySignatures; +partyWithoutSignatures; +emptyRawPartySignatureGroups; +emptyRawSignatures; +emptyRawPrepareCommands; +emptyRawActAs; +emptyPrepareCommands; +emptyActAsParties; +trafficEstimateWithoutTimestamp; +invalidExecuteExactBodyOptions; +invalidExecuteAndWaitExactBodyOptions; +invalidExecuteAndWaitForTransactionExactBodyOptions; diff --git a/test/typecheck/operation-retry.typecheck.ts b/test/typecheck/operation-retry.typecheck.ts index 222a1124..e619efe9 100644 --- a/test/typecheck/operation-retry.typecheck.ts +++ b/test/typecheck/operation-retry.typecheck.ts @@ -39,8 +39,8 @@ const invalidTuplePayload: DeepReadonly = { // @ts-expect-error DeepReadonly must preserve non-empty tuple constraints. values: [], }; -void validTuplePayload; -void invalidTuplePayload; +validTuplePayload; +invalidTuplePayload; void parameterizedRequestCallback('value', 5); void client.allocateExternalParty(signedRequest, { @@ -52,7 +52,7 @@ void client.allocateExternalParty(signedRequest, { const [transaction] = params.onboardingTransactions; if (transaction && 'signatures' in transaction) { const signature: string = transaction.signatures[0]?.signature ?? ''; - void signature; + signature; } return signedRequest; }, @@ -78,7 +78,7 @@ void client.allocateExternalParty(requestWithCallerOnlyMetadata, { maxAttempts: 1, beforeAttempt: ({ params }) => { // @ts-expect-error Retry hooks expose validated declared params, not caller-only structural extensions. - void params.callerOnlyMetadata; + params.callerOnlyMetadata; }, }, }); @@ -130,7 +130,7 @@ const invalidGetOperationConfig = { requestSemantics: 'mutation', // @ts-expect-error Factory-created GET operations cannot use mutation semantics. } satisfies ApiOperationConfig; -void invalidGetOperationConfig; +invalidGetOperationConfig; const invalidDeleteOperationConfig = { paramsSchema: z.void(), @@ -139,7 +139,7 @@ const invalidDeleteOperationConfig = { requestSemantics: 'read', // @ts-expect-error Factory-created DELETE operations cannot use read semantics. } satisfies ApiOperationConfig; -void invalidDeleteOperationConfig; +invalidDeleteOperationConfig; const invalidPatchOperationConfig = { paramsSchema: z.void(), @@ -148,7 +148,7 @@ const invalidPatchOperationConfig = { requestSemantics: 'read', // @ts-expect-error Factory-created PATCH operations cannot use read semantics. } satisfies ApiOperationConfig; -void invalidPatchOperationConfig; +invalidPatchOperationConfig; // Custom ApiOperation subclasses retain their declared params while forwarding the same typed options. void client.getParties({}, { signal: new AbortController().signal }); diff --git a/test/typecheck/scan-registry-metadata.typecheck.ts b/test/typecheck/scan-registry-metadata.typecheck.ts index c2146681..332610d0 100644 --- a/test/typecheck/scan-registry-metadata.typecheck.ts +++ b/test/typecheck/scan-registry-metadata.typecheck.ts @@ -60,4 +60,4 @@ function assertClientSurface(client: ScanApiClient): void { void client.listInstruments({ pageSize: 25, unknown: true }); } -void assertClientSurface; +assertClientSurface; diff --git a/test/typecheck/scan-snapshot-after.typecheck.ts b/test/typecheck/scan-snapshot-after.typecheck.ts index 40896c06..83523c90 100644 --- a/test/typecheck/scan-snapshot-after.typecheck.ts +++ b/test/typecheck/scan-snapshot-after.typecheck.ts @@ -29,9 +29,9 @@ const missingRecordTime: ClientResponse = {}; // @ts-expect-error The generated response contract does not include additional envelope fields. const extraResponseField: ClientResponse = { record_time: '2026-07-10T12:00:01Z', unexpected: true }; -void clientParams; -void clientResponse; -void missingMigrationId; -void wireQueryName; -void missingRecordTime; -void extraResponseField; +clientParams; +clientResponse; +missingMigrationId; +wireQueryName; +missingRecordTime; +extraResponseField; diff --git a/test/typecheck/validator-global-domain-connection-config.typecheck.ts b/test/typecheck/validator-global-domain-connection-config.typecheck.ts index 78a7de25..eaf40072 100644 --- a/test/typecheck/validator-global-domain-connection-config.typecheck.ts +++ b/test/typecheck/validator-global-domain-connection-config.typecheck.ts @@ -49,6 +49,6 @@ const wrongCase: GetDecentralizedSynchronizerConnectionConfigResponse = { sequencerConnections: response.sequencer_connections, }; -void response; -void missingPatience; -void wrongCase; +response; +missingPatience; +wrongCase; diff --git a/test/typecheck/validator-wallet-list-transactions.typecheck.ts b/test/typecheck/validator-wallet-list-transactions.typecheck.ts index e8264a33..7f6f7286 100644 --- a/test/typecheck/validator-wallet-list-transactions.typecheck.ts +++ b/test/typecheck/validator-wallet-list-transactions.typecheck.ts @@ -68,11 +68,11 @@ const unsupportedBranch: ValidatorWalletTransaction = { date: '2026-07-10T02:00:00Z', }; -void firstPage; -void followingPage; -void response; -void publicEventIds; -void narrowTransaction; -void missingPageSize; -void numericCursor; -void unsupportedBranch; +firstPage; +followingPage; +response; +publicEventIds; +narrowTransaction; +missingPageSize; +numericCursor; +unsupportedBranch; diff --git a/test/typecheck/validator-wallet-tap.typecheck.ts b/test/typecheck/validator-wallet-tap.typecheck.ts index 64ef6cac..a29f609c 100644 --- a/test/typecheck/validator-wallet-tap.typecheck.ts +++ b/test/typecheck/validator-wallet-tap.typecheck.ts @@ -19,9 +19,9 @@ const missingAmount: TapRequest = { command_id: 'tap-command-123' }; // @ts-expect-error The generated tap response requires its created contract id. const missingContractId: TapResponse = {}; -void requestWithCommandId; -void requestWithoutCommandId; -void response; -void numericAmount; -void missingAmount; -void missingContractId; +requestWithCommandId; +requestWithoutCommandId; +response; +numericAmount; +missingAmount; +missingContractId; diff --git a/test/unit/amulet/offers.test.ts b/test/unit/amulet/offers.test.ts index e91fb161..208ec51f 100644 --- a/test/unit/amulet/offers.test.ts +++ b/test/unit/amulet/offers.test.ts @@ -171,7 +171,6 @@ describe('createTransferOffer', () => { }); const mockEnvLoaderInstance = EnvLoader.getInstance(); - // eslint-disable-next-line @typescript-eslint/unbound-method expect(mockEnvLoaderInstance.getValidatorWalletAppInstallContractId).toHaveBeenCalledWith('localnet'); const callArgs = mockClient.submitAndWaitForTransactionTree.mock.calls[0]?.[0]; diff --git a/test/unit/clients/scan-api.test.ts b/test/unit/clients/scan-api.test.ts index f6390019..e90ed337 100644 --- a/test/unit/clients/scan-api.test.ts +++ b/test/unit/clients/scan-api.test.ts @@ -60,7 +60,6 @@ function createClient( mockAxiosInstance: MockAxiosInstance; } { const client = new ScanApiClient(new CantonRuntime(config), options); - // eslint-disable-next-line @typescript-eslint/unbound-method -- axios.create is a mocked function in this test module const mockResults = jest.mocked(axios.create).mock.results; const latestResultIndex = mockResults.length - 1; const latestResult = latestResultIndex >= 0 ? mockResults[latestResultIndex] : undefined; diff --git a/test/unit/clients/validator-api-health.test.ts b/test/unit/clients/validator-api-health.test.ts index 4d5d03be..09ba1b24 100644 --- a/test/unit/clients/validator-api-health.test.ts +++ b/test/unit/clients/validator-api-health.test.ts @@ -39,7 +39,6 @@ function createClient(): { client: ValidatorApiClient; mockAxiosInstance: MockAx }; const client = new ValidatorApiClient(new CantonRuntime(config)); - // eslint-disable-next-line @typescript-eslint/unbound-method -- axios.create is a mocked function in this test module const mockResults = jest.mocked(axios.create).mock.results; const latestResult = mockResults[mockResults.length - 1]; if (!latestResult) { diff --git a/test/unit/external-signing/external-party-lifecycle.test.ts b/test/unit/external-signing/external-party-lifecycle.test.ts index 979337e0..49325fea 100644 --- a/test/unit/external-signing/external-party-lifecycle.test.ts +++ b/test/unit/external-signing/external-party-lifecycle.test.ts @@ -193,6 +193,7 @@ describe('external-party lifecycle reconciliation', (): void => { markPartyDetailsStarted = resolve; }); ledgerClient.getPartyDetails.mockImplementationOnce( + // eslint-disable-next-line @typescript-eslint/promise-function-async -- non-async arrow preserves rejection timing under abort () => new Promise((_resolve, reject) => { rejectPartyDetails = reject; diff --git a/test/unit/external-signing/external-party-onboarding.test.ts b/test/unit/external-signing/external-party-onboarding.test.ts index b24a2f8c..40d92066 100644 --- a/test/unit/external-signing/external-party-onboarding.test.ts +++ b/test/unit/external-signing/external-party-onboarding.test.ts @@ -12,7 +12,7 @@ import { CANTON_ED25519_SIGNATURE_ALGORITHM, CANTON_RAW_SIGNATURE_FORMAT, createExternalPartyWithSigner, - ExternalPartyConflictReconciliationError, + type ExternalPartyConflictReconciliationError, getExternalPartyIdForHintAndPublicKey, listExternalPartyIdsForPublicKey, prepareExternalPartyOnboarding, @@ -381,6 +381,7 @@ describe('external-party onboarding helpers', () => { }); ledgerClient.allocateExternalParty.mockRejectedValueOnce(allocationError); ledgerClient.getPartyDetails.mockImplementationOnce( + // eslint-disable-next-line @typescript-eslint/promise-function-async -- non-async arrow preserves rejection timing under abort () => new Promise((_resolve, reject) => { rejectConfirmation = reject; From 97ea5043e5b243e378db7a921fef7f883a1080aa Mon Sep 17 00:00:00 2001 From: HardlyDifficult Date: Wed, 23 Sep 2026 13:59:16 -0400 Subject: [PATCH 3/6] docs: update @fairmint/canton-dev-tools version references to 0.1.11 Address Copilot review finding: keep exact-version documentation and contributor guidance in sync with the dependency bump in this PR. Co-authored-by: Cursor --- AGENTS.md | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d254bda9..944c096e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,14 +3,14 @@ See [CLAUDE.md](CLAUDE.md), [README.md](README.md), and `.cursor/skills/localnet-testing/SKILL.md`. `package.json` (`localnet:*` scripts) is the source of truth for LocalNet commands in this repo; lifecycle is owned by -`@fairmint/canton-dev-tools@0.1.7+`. +`@fairmint/canton-dev-tools@0.1.11+`. ## LocalNet ownership (ENG-1635) **`@fairmint/canton-dev-tools` owns LocalNet** (CLI, pins, and shared test helpers). This SDK does not ship a LocalNet engine or `canton-localnet` binary. -- Install pin: `devDependency` `@fairmint/canton-dev-tools@0.1.7` (exact). +- Install pin: `devDependency` `@fairmint/canton-dev-tools@0.1.11` (exact). - Repo scripts: `npm run localnet:*` → `canton-dev-tools `. - Integration helpers: import from `@fairmint/canton-dev-tools/testing`. - Pins / auth defaults: see Dev Tools diff --git a/README.md b/README.md index 86376dcc..7ec48212 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ npm run build ### LocalNet (owned by `@fairmint/canton-dev-tools`) LocalNet lifecycle and shared test helpers live in -[`@fairmint/canton-dev-tools@0.1.7`](https://www.npmjs.com/package/@fairmint/canton-dev-tools) +[`@fairmint/canton-dev-tools@0.1.11`](https://www.npmjs.com/package/@fairmint/canton-dev-tools) (see its [COMPATIBILITY.md](https://github.com/Fairmint/canton-dev-tools/blob/main/COMPATIBILITY.md)). This SDK does not publish a LocalNet CLI or `scripts/localnet-cloud.sh`. From 9c6a3ccbe5b708c736a52bbb14e5447bd7ac8a07 Mon Sep 17 00:00:00 2001 From: HardlyDifficult Date: Wed, 23 Sep 2026 15:15:10 -0400 Subject: [PATCH 4/6] refactor(lint): replace test-wide unbound-method override with targeted disables Address Copilot review (medium): keep unbound-method active everywhere; suppress it only at the 34 bare jest mock-reference assertion sites where the tightened rule misfires (expect(mock.method) idiom, no this-capture risk). Also update the LocalNet testing skill's dev-tools floor to 0.1.11+ to match this bump. Co-authored-by: Cursor --- .cursor/skills/localnet-testing/SKILL.md | 2 +- eslint.config.mjs | 9 --------- test/unit/amulet/offers.test.ts | 1 + test/unit/clients/scan-api.test.ts | 1 + test/unit/clients/validator-api-health.test.ts | 1 + test/unit/token-standard/v1/holdings.test.ts | 4 ++++ .../token-standard/v2/allocation-state.test.ts | 17 +++++++++++++++++ test/unit/token-standard/v2/allocation.test.ts | 1 + test/unit/token-standard/v2/holdings.test.ts | 4 ++++ .../v2/settlement-factory.test.ts | 5 +++++ 10 files changed, 35 insertions(+), 10 deletions(-) diff --git a/.cursor/skills/localnet-testing/SKILL.md b/.cursor/skills/localnet-testing/SKILL.md index a829c36d..a1c378b5 100644 --- a/.cursor/skills/localnet-testing/SKILL.md +++ b/.cursor/skills/localnet-testing/SKILL.md @@ -3,7 +3,7 @@ Read the public [LocalNet guide](https://github.com/Fairmint/canton-node-sdk/wiki/LocalNet-testing) first. -**ENG-1635:** `@fairmint/canton-dev-tools@0.1.7+` owns LocalNet lifecycle, pins, and shared test +**ENG-1635:** `@fairmint/canton-dev-tools@0.1.11+` owns LocalNet lifecycle, pins, and shared test helpers. This repository does not ship LocalNet scripts or a `canton-localnet` binary. - Commands: `npm run localnet:*` (wired to `canton-dev-tools`) or diff --git a/eslint.config.mjs b/eslint.config.mjs index bbc6c24e..71b8413b 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -201,15 +201,6 @@ const eslintConfig = [ '@typescript-eslint/no-redundant-type-constituents': 'off', }, }, - // typescript-eslint 8.69+ tightened unbound-method to flag bare method - // references like the jest idiom `expect(mock.method)`. Test files never - // rely on `this` for these references, so relax the rule in tests only. - { - files: ['test/**/*'], - rules: { - '@typescript-eslint/unbound-method': 'off', - }, - }, // Prettier config last to override any conflicting rules eslintConfigPrettier, ]; diff --git a/test/unit/amulet/offers.test.ts b/test/unit/amulet/offers.test.ts index 208ec51f..4babf224 100644 --- a/test/unit/amulet/offers.test.ts +++ b/test/unit/amulet/offers.test.ts @@ -171,6 +171,7 @@ describe('createTransferOffer', () => { }); const mockEnvLoaderInstance = EnvLoader.getInstance(); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(mockEnvLoaderInstance.getValidatorWalletAppInstallContractId).toHaveBeenCalledWith('localnet'); const callArgs = mockClient.submitAndWaitForTransactionTree.mock.calls[0]?.[0]; diff --git a/test/unit/clients/scan-api.test.ts b/test/unit/clients/scan-api.test.ts index e90ed337..00f723d9 100644 --- a/test/unit/clients/scan-api.test.ts +++ b/test/unit/clients/scan-api.test.ts @@ -60,6 +60,7 @@ function createClient( mockAxiosInstance: MockAxiosInstance; } { const client = new ScanApiClient(new CantonRuntime(config), options); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk const mockResults = jest.mocked(axios.create).mock.results; const latestResultIndex = mockResults.length - 1; const latestResult = latestResultIndex >= 0 ? mockResults[latestResultIndex] : undefined; diff --git a/test/unit/clients/validator-api-health.test.ts b/test/unit/clients/validator-api-health.test.ts index 09ba1b24..52a69a42 100644 --- a/test/unit/clients/validator-api-health.test.ts +++ b/test/unit/clients/validator-api-health.test.ts @@ -39,6 +39,7 @@ function createClient(): { client: ValidatorApiClient; mockAxiosInstance: MockAx }; const client = new ValidatorApiClient(new CantonRuntime(config)); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk const mockResults = jest.mocked(axios.create).mock.results; const latestResult = mockResults[mockResults.length - 1]; if (!latestResult) { diff --git a/test/unit/token-standard/v1/holdings.test.ts b/test/unit/token-standard/v1/holdings.test.ts index 9523b9ee..00e2e64d 100644 --- a/test/unit/token-standard/v1/holdings.test.ts +++ b/test/unit/token-standard/v1/holdings.test.ts @@ -143,7 +143,9 @@ describe('Token Standard V1 holdings', () => { contractIds: ['#seven', '#four'], totalBaseUnits: '11000000', }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice'], interfaceIds: [TOKEN_STANDARD_V1_HOLDING_INTERFACE_ID], @@ -494,6 +496,7 @@ describe('Token Standard V1 holdings', () => { ).rejects.toMatchObject({ code: 'TOKEN_STANDARD_V1_HOLDING_INPUT_INVALID', }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -515,6 +518,7 @@ describe('Token Standard V1 holdings', () => { code: 'TOKEN_STANDARD_V1_HOLDING_INPUT_INVALID', context: { field: 'activeAtOffset' }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); diff --git a/test/unit/token-standard/v2/allocation-state.test.ts b/test/unit/token-standard/v2/allocation-state.test.ts index fae22b24..9192319d 100644 --- a/test/unit/token-standard/v2/allocation-state.test.ts +++ b/test/unit/token-standard/v2/allocation-state.test.ts @@ -230,7 +230,9 @@ describe('discoverTokenStandardV2AllocationState', () => { view: completedView, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice', 'Venue::operator'], interfaceIds: [TOKEN_STANDARD_V2_ALLOCATION_INTERFACE_ID, TOKEN_STANDARD_V2_ALLOCATION_INSTRUCTION_INTERFACE_ID], @@ -262,6 +264,7 @@ describe('discoverTokenStandardV2AllocationState', () => { allocationInstructionCid: '#allocation-instruction', view: pendingView, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -278,6 +281,7 @@ describe('discoverTokenStandardV2AllocationState', () => { expect(state).toEqual({ type: 'Unknown' }); expect(state.type).not.toBe('Failed'); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -315,6 +319,7 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).resolves.toEqual({ type: 'Unknown' }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -419,6 +424,7 @@ describe('discoverTokenStandardV2AllocationState', () => { type: 'Completed', allocationCid: '#allocation', }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -499,6 +505,7 @@ describe('discoverTokenStandardV2AllocationState', () => { code: TokenStandardV2AllocationStateErrorCode.AMBIGUOUS, context: { completedCids: [...completedCids], pendingCids: [...pendingCids] }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -555,6 +562,7 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).resolves.toEqual({ type: 'Unknown' }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -583,6 +591,7 @@ describe('discoverTokenStandardV2AllocationState', () => { code: TokenStandardV2AllocationStateErrorCode.INTERFACE_VIEW_INVALID, context: { contractId: '#malformed-allocation' }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -616,6 +625,7 @@ describe('discoverTokenStandardV2AllocationState', () => { field: 'view.allocation.transferLegSides', }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -679,6 +689,7 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).rejects.toMatchObject({ code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -697,6 +708,7 @@ describe('discoverTokenStandardV2AllocationState', () => { code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID, context: { field: 'activeAtOffset' }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -728,6 +740,7 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).rejects.toMatchObject({ code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); @@ -875,7 +888,9 @@ describe('getTokenStandardV2AllocationViewsByContractIds', () => { { allocationCid: '#receiver', view: secondView }, { allocationCid: '#sender', view: completedView }, ]); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice', 'Venue::operator'], interfaceIds: [TOKEN_STANDARD_V2_ALLOCATION_INTERFACE_ID], @@ -905,6 +920,7 @@ describe('getTokenStandardV2AllocationViewsByContractIds', () => { activeAtOffset: 42, }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -938,6 +954,7 @@ describe('getTokenStandardV2AllocationViewsByContractIds', () => { activeAtOffset: 42, }) ).rejects.toMatchObject({ code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); diff --git a/test/unit/token-standard/v2/allocation.test.ts b/test/unit/token-standard/v2/allocation.test.ts index 4eb86342..7c0538fe 100644 --- a/test/unit/token-standard/v2/allocation.test.ts +++ b/test/unit/token-standard/v2/allocation.test.ts @@ -336,6 +336,7 @@ describe('Token Standard V2 allocation helpers', () => { scan, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getAllocationFactoryV2FromRegistry).toHaveBeenCalledWith({ registryUrl: 'https://cash.example/token-registry', choiceArguments: { diff --git a/test/unit/token-standard/v2/holdings.test.ts b/test/unit/token-standard/v2/holdings.test.ts index 338cb2f4..822a765d 100644 --- a/test/unit/token-standard/v2/holdings.test.ts +++ b/test/unit/token-standard/v2/holdings.test.ts @@ -148,7 +148,9 @@ describe('Token Standard V2 holdings', () => { contractIds: ['#seven', '#four'], totalBaseUnits: '11000000', }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice'], interfaceIds: [TOKEN_STANDARD_V2_HOLDING_INTERFACE_ID], @@ -499,6 +501,7 @@ describe('Token Standard V2 holdings', () => { ).rejects.toMatchObject({ code: 'TOKEN_STANDARD_V2_HOLDING_INPUT_INVALID', }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -520,6 +523,7 @@ describe('Token Standard V2 holdings', () => { code: 'TOKEN_STANDARD_V2_HOLDING_INPUT_INVALID', context: { field: 'activeAtOffset' }, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); diff --git a/test/unit/token-standard/v2/settlement-factory.test.ts b/test/unit/token-standard/v2/settlement-factory.test.ts index fc52e635..612cd4e8 100644 --- a/test/unit/token-standard/v2/settlement-factory.test.ts +++ b/test/unit/token-standard/v2/settlement-factory.test.ts @@ -470,7 +470,9 @@ describe('Token Standard V2 settlement-factory helpers', () => { metadata, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).toHaveBeenCalledTimes(1); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).toHaveBeenCalledWith({ registryUrl: 'https://registry.example/token', choiceArguments: { @@ -535,6 +537,7 @@ describe('Token Standard V2 settlement-factory helpers', () => { excludeDebugFields: false, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).toHaveBeenCalledWith( expect.objectContaining({ excludeDebugFields: false }) ); @@ -558,6 +561,7 @@ describe('Token Standard V2 settlement-factory helpers', () => { name: 'TokenStandardV2SettlementFactoryError', code: TokenStandardV2SettlementFactoryErrorCode.INPUT_INVALID, }); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).not.toHaveBeenCalled(); }); @@ -674,6 +678,7 @@ describe('Token Standard V2 settlement-factory helpers', () => { settlementFactoryContractId: ' ', }) ).toThrow(TokenStandardV2SettlementFactoryError); + // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).not.toHaveBeenCalled(); }); }); From dd16e5a5f16e328249695ca7a6aa4557d30e4ac5 Mon Sep 17 00:00:00 2001 From: HardlyDifficult Date: Wed, 23 Sep 2026 15:37:32 -0400 Subject: [PATCH 5/6] docs: update package-boundary.md dev-tools floor to 0.1.11+ Co-authored-by: Cursor --- docs/package-boundary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package-boundary.md b/docs/package-boundary.md index d7678bc5..76346c79 100644 --- a/docs/package-boundary.md +++ b/docs/package-boundary.md @@ -13,7 +13,7 @@ repository / CI-only. Repeatable enforcement lives in `npm run check:package-art LocalNet CLI and shared integration-test helpers are **not** published here. They live in [`@fairmint/canton-dev-tools`](https://www.npmjs.com/package/@fairmint/canton-dev-tools) -(`0.1.7+`), including `scripts/localnet-cloud.sh` and `@fairmint/canton-dev-tools/testing`. +(`0.1.11+`), including `scripts/localnet-cloud.sh` and `@fairmint/canton-dev-tools/testing`. ## CI-only / must not publish From dfa6b0e599f153c77fbeb0ca5e12eb55004e7f88 Mon Sep 17 00:00:00 2001 From: HardlyDifficult Date: Wed, 23 Sep 2026 16:24:51 -0400 Subject: [PATCH 6/6] chore(lint): disable unbound-method in tests instead of per-assertion suppressions Co-authored-by: Cursor --- eslint.config.mjs | 9 +++++++++ test/unit/amulet/offers.test.ts | 1 - test/unit/clients/scan-api.test.ts | 1 - test/unit/clients/validator-api-health.test.ts | 1 - test/unit/token-standard/v1/holdings.test.ts | 4 ---- .../token-standard/v2/allocation-state.test.ts | 17 ----------------- test/unit/token-standard/v2/allocation.test.ts | 1 - test/unit/token-standard/v2/holdings.test.ts | 4 ---- .../v2/settlement-factory.test.ts | 5 ----- 9 files changed, 9 insertions(+), 34 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 71b8413b..c70e0782 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -201,6 +201,15 @@ const eslintConfig = [ '@typescript-eslint/no-redundant-type-constituents': 'off', }, }, + // Test-only override: jest mocks are invoked as bare functions and never rely on + // `this`, so unbound-method reports false positives there. Disabled for test files + // only; non-test code keeps full protection, with no per-assertion suppressions. + { + files: ['test/**/*'], + rules: { + '@typescript-eslint/unbound-method': 'off', + }, + }, // Prettier config last to override any conflicting rules eslintConfigPrettier, ]; diff --git a/test/unit/amulet/offers.test.ts b/test/unit/amulet/offers.test.ts index 4babf224..208ec51f 100644 --- a/test/unit/amulet/offers.test.ts +++ b/test/unit/amulet/offers.test.ts @@ -171,7 +171,6 @@ describe('createTransferOffer', () => { }); const mockEnvLoaderInstance = EnvLoader.getInstance(); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(mockEnvLoaderInstance.getValidatorWalletAppInstallContractId).toHaveBeenCalledWith('localnet'); const callArgs = mockClient.submitAndWaitForTransactionTree.mock.calls[0]?.[0]; diff --git a/test/unit/clients/scan-api.test.ts b/test/unit/clients/scan-api.test.ts index 00f723d9..e90ed337 100644 --- a/test/unit/clients/scan-api.test.ts +++ b/test/unit/clients/scan-api.test.ts @@ -60,7 +60,6 @@ function createClient( mockAxiosInstance: MockAxiosInstance; } { const client = new ScanApiClient(new CantonRuntime(config), options); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk const mockResults = jest.mocked(axios.create).mock.results; const latestResultIndex = mockResults.length - 1; const latestResult = latestResultIndex >= 0 ? mockResults[latestResultIndex] : undefined; diff --git a/test/unit/clients/validator-api-health.test.ts b/test/unit/clients/validator-api-health.test.ts index 52a69a42..09ba1b24 100644 --- a/test/unit/clients/validator-api-health.test.ts +++ b/test/unit/clients/validator-api-health.test.ts @@ -39,7 +39,6 @@ function createClient(): { client: ValidatorApiClient; mockAxiosInstance: MockAx }; const client = new ValidatorApiClient(new CantonRuntime(config)); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk const mockResults = jest.mocked(axios.create).mock.results; const latestResult = mockResults[mockResults.length - 1]; if (!latestResult) { diff --git a/test/unit/token-standard/v1/holdings.test.ts b/test/unit/token-standard/v1/holdings.test.ts index 00e2e64d..9523b9ee 100644 --- a/test/unit/token-standard/v1/holdings.test.ts +++ b/test/unit/token-standard/v1/holdings.test.ts @@ -143,9 +143,7 @@ describe('Token Standard V1 holdings', () => { contractIds: ['#seven', '#four'], totalBaseUnits: '11000000', }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice'], interfaceIds: [TOKEN_STANDARD_V1_HOLDING_INTERFACE_ID], @@ -496,7 +494,6 @@ describe('Token Standard V1 holdings', () => { ).rejects.toMatchObject({ code: 'TOKEN_STANDARD_V1_HOLDING_INPUT_INVALID', }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -518,7 +515,6 @@ describe('Token Standard V1 holdings', () => { code: 'TOKEN_STANDARD_V1_HOLDING_INPUT_INVALID', context: { field: 'activeAtOffset' }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); diff --git a/test/unit/token-standard/v2/allocation-state.test.ts b/test/unit/token-standard/v2/allocation-state.test.ts index 9192319d..fae22b24 100644 --- a/test/unit/token-standard/v2/allocation-state.test.ts +++ b/test/unit/token-standard/v2/allocation-state.test.ts @@ -230,9 +230,7 @@ describe('discoverTokenStandardV2AllocationState', () => { view: completedView, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice', 'Venue::operator'], interfaceIds: [TOKEN_STANDARD_V2_ALLOCATION_INTERFACE_ID, TOKEN_STANDARD_V2_ALLOCATION_INSTRUCTION_INTERFACE_ID], @@ -264,7 +262,6 @@ describe('discoverTokenStandardV2AllocationState', () => { allocationInstructionCid: '#allocation-instruction', view: pendingView, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -281,7 +278,6 @@ describe('discoverTokenStandardV2AllocationState', () => { expect(state).toEqual({ type: 'Unknown' }); expect(state.type).not.toBe('Failed'); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -319,7 +315,6 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).resolves.toEqual({ type: 'Unknown' }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -424,7 +419,6 @@ describe('discoverTokenStandardV2AllocationState', () => { type: 'Completed', allocationCid: '#allocation', }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -505,7 +499,6 @@ describe('discoverTokenStandardV2AllocationState', () => { code: TokenStandardV2AllocationStateErrorCode.AMBIGUOUS, context: { completedCids: [...completedCids], pendingCids: [...pendingCids] }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -562,7 +555,6 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).resolves.toEqual({ type: 'Unknown' }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -591,7 +583,6 @@ describe('discoverTokenStandardV2AllocationState', () => { code: TokenStandardV2AllocationStateErrorCode.INTERFACE_VIEW_INVALID, context: { contractId: '#malformed-allocation' }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -625,7 +616,6 @@ describe('discoverTokenStandardV2AllocationState', () => { field: 'view.allocation.transferLegSides', }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -689,7 +679,6 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).rejects.toMatchObject({ code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -708,7 +697,6 @@ describe('discoverTokenStandardV2AllocationState', () => { code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID, context: { field: 'activeAtOffset' }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -740,7 +728,6 @@ describe('discoverTokenStandardV2AllocationState', () => { activeAtOffset: 42, }) ).rejects.toMatchObject({ code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); @@ -888,9 +875,7 @@ describe('getTokenStandardV2AllocationViewsByContractIds', () => { { allocationCid: '#receiver', view: secondView }, { allocationCid: '#sender', view: completedView }, ]); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice', 'Venue::operator'], interfaceIds: [TOKEN_STANDARD_V2_ALLOCATION_INTERFACE_ID], @@ -920,7 +905,6 @@ describe('getTokenStandardV2AllocationViewsByContractIds', () => { activeAtOffset: 42, }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); }); @@ -954,7 +938,6 @@ describe('getTokenStandardV2AllocationViewsByContractIds', () => { activeAtOffset: 42, }) ).rejects.toMatchObject({ code: TokenStandardV2AllocationStateErrorCode.INPUT_INVALID }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); diff --git a/test/unit/token-standard/v2/allocation.test.ts b/test/unit/token-standard/v2/allocation.test.ts index 7c0538fe..4eb86342 100644 --- a/test/unit/token-standard/v2/allocation.test.ts +++ b/test/unit/token-standard/v2/allocation.test.ts @@ -336,7 +336,6 @@ describe('Token Standard V2 allocation helpers', () => { scan, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getAllocationFactoryV2FromRegistry).toHaveBeenCalledWith({ registryUrl: 'https://cash.example/token-registry', choiceArguments: { diff --git a/test/unit/token-standard/v2/holdings.test.ts b/test/unit/token-standard/v2/holdings.test.ts index 822a765d..338cb2f4 100644 --- a/test/unit/token-standard/v2/holdings.test.ts +++ b/test/unit/token-standard/v2/holdings.test.ts @@ -148,9 +148,7 @@ describe('Token Standard V2 holdings', () => { contractIds: ['#seven', '#four'], totalBaseUnits: '11000000', }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).toHaveBeenCalledWith({ parties: ['Buyer::alice'], interfaceIds: [TOKEN_STANDARD_V2_HOLDING_INTERFACE_ID], @@ -501,7 +499,6 @@ describe('Token Standard V2 holdings', () => { ).rejects.toMatchObject({ code: 'TOKEN_STANDARD_V2_HOLDING_INPUT_INVALID', }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); @@ -523,7 +520,6 @@ describe('Token Standard V2 holdings', () => { code: 'TOKEN_STANDARD_V2_HOLDING_INPUT_INVALID', context: { field: 'activeAtOffset' }, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(ledger.getActiveContracts).not.toHaveBeenCalled(); }); }); diff --git a/test/unit/token-standard/v2/settlement-factory.test.ts b/test/unit/token-standard/v2/settlement-factory.test.ts index 612cd4e8..fc52e635 100644 --- a/test/unit/token-standard/v2/settlement-factory.test.ts +++ b/test/unit/token-standard/v2/settlement-factory.test.ts @@ -470,9 +470,7 @@ describe('Token Standard V2 settlement-factory helpers', () => { metadata, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).toHaveBeenCalledWith({ registryUrl: 'https://registry.example/token', choiceArguments: { @@ -537,7 +535,6 @@ describe('Token Standard V2 settlement-factory helpers', () => { excludeDebugFields: false, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).toHaveBeenCalledWith( expect.objectContaining({ excludeDebugFields: false }) ); @@ -561,7 +558,6 @@ describe('Token Standard V2 settlement-factory helpers', () => { name: 'TokenStandardV2SettlementFactoryError', code: TokenStandardV2SettlementFactoryErrorCode.INPUT_INVALID, }); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).not.toHaveBeenCalled(); }); @@ -678,7 +674,6 @@ describe('Token Standard V2 settlement-factory helpers', () => { settlementFactoryContractId: ' ', }) ).toThrow(TokenStandardV2SettlementFactoryError); - // eslint-disable-next-line @typescript-eslint/unbound-method -- bare jest mock reference, no this-capture risk expect(scan.getSettlementFactoryFromRegistry).not.toHaveBeenCalled(); }); });