From fc49aa254496766075b6281cc55febb588bc41b8 Mon Sep 17 00:00:00 2001 From: Tarun Vadde Date: Wed, 24 Jun 2026 02:34:16 +0530 Subject: [PATCH] fix(askar): use NativeAskar.instance instead of the deprecated askar export Signed-off-by: Tarun Vadde --- .changeset/askar-native-instance.md | 7 +++++++ packages/askar/package.json | 2 +- packages/askar/src/kms/AskarKeyManagementService.ts | 12 ++++++++---- .../kms/__tests__/AskarKeyManagementService.test.ts | 4 ++-- packages/askar/src/kms/crypto/deriveKey.ts | 6 +++--- .../storage/__tests__/AskarStorageService.test.ts | 8 ++++---- 6 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 .changeset/askar-native-instance.md diff --git a/.changeset/askar-native-instance.md b/.changeset/askar-native-instance.md new file mode 100644 index 0000000000..7733bcd70d --- /dev/null +++ b/.changeset/askar-native-instance.md @@ -0,0 +1,7 @@ +--- +'@credo-ts/askar': minor +--- + +Read the askar native binding via `NativeAskar.instance` instead of the deprecated mutable `askar` export in the KMS (key management and ECDH key derivation). The deprecated binding is populated only when the platform package's side-effect import runs, so an ESM consumer that loads the KMS first snapshots it as `undefined` and key operations fail with `Cannot read properties of undefined (reading 'keyGetJwkSecret')`. `NativeAskar.instance` resolves the binding on each access, so registration order no longer matters. See #2597, #2607. + +This raises the minimum required `@openwallet-foundation/askar-shared` to 0.6.0, where `NativeAskar` was introduced, so the peer dependency range is narrowed to `^0.6.0`. diff --git a/packages/askar/package.json b/packages/askar/package.json index e77a0d7ce3..4ac98a3238 100644 --- a/packages/askar/package.json +++ b/packages/askar/package.json @@ -45,6 +45,6 @@ "typescript": "catalog:" }, "peerDependencies": { - "@openwallet-foundation/askar-shared": "^0.4.3 || ^0.5.0 || ^0.6.0" + "@openwallet-foundation/askar-shared": "^0.6.0" } } diff --git a/packages/askar/src/kms/AskarKeyManagementService.ts b/packages/askar/src/kms/AskarKeyManagementService.ts index 3d90b61395..be9f8b5256 100644 --- a/packages/askar/src/kms/AskarKeyManagementService.ts +++ b/packages/askar/src/kms/AskarKeyManagementService.ts @@ -1,12 +1,12 @@ import { type AgentContext, JsonEncoder, Kms, TypedArrayEncoder, utils } from '@credo-ts/core' import type { JwkProps, KeyEntryObject, Session } from '@openwallet-foundation/askar-shared' import { - askar, CryptoBox, Jwk, Key, KeyAlgorithm, KeyEntryList, + NativeAskar, SignatureAlgorithm, } from '@openwallet-foundation/askar-shared' @@ -681,7 +681,7 @@ export class AskarKeyManagementService implements Kms.KeyManagementService { private keyFromJwk(jwk: Kms.KmsJwkPrivate | Kms.KmsJwkPublic) { const key = new Key( - askar.keyFromJwk({ + NativeAskar.instance.keyFromJwk({ // TODO: the JWK class in JS Askar wrapper is too limiting // so we use this method directly. should update it jwk: new Uint8Array(JsonEncoder.toUint8Array(jwk)) as unknown as Jwk, @@ -717,7 +717,7 @@ export class AskarKeyManagementService implements Kms.KeyManagementService { // so we use this method directly. should update it // We extract alg, as Askar doesn't always use the same algs const { alg, ...jwkSecret } = JsonEncoder.fromUint8Array( - askar.keyGetJwkSecret({ + NativeAskar.instance.keyGetJwkSecret({ localKeyHandle: key.handle, }) ) @@ -733,7 +733,11 @@ export class AskarKeyManagementService implements Kms.KeyManagementService { if (!session.handle) throw Error('Cannot fetch a key with a closed session') // Fetch the key from the session - const handle = await askar.sessionFetchKey({ forUpdate: false, name: keyId, sessionHandle: session.handle }) + const handle = await NativeAskar.instance.sessionFetchKey({ + forUpdate: false, + name: keyId, + sessionHandle: session.handle, + }) if (!handle) return null // Get the key entry diff --git a/packages/askar/src/kms/__tests__/AskarKeyManagementService.test.ts b/packages/askar/src/kms/__tests__/AskarKeyManagementService.test.ts index fc58bf762e..d8105346c2 100644 --- a/packages/askar/src/kms/__tests__/AskarKeyManagementService.test.ts +++ b/packages/askar/src/kms/__tests__/AskarKeyManagementService.test.ts @@ -1,7 +1,7 @@ import { readFileSync } from 'node:fs' import path from 'node:path' import { InjectionSymbols, JsonEncoder, Kms, TypedArrayEncoder } from '@credo-ts/core' -import { AskarError, askar } from '@openwallet-foundation/askar-shared' +import { AskarError, NativeAskar } from '@openwallet-foundation/askar-shared' import { getAgentConfig, getAgentContext } from '../../../../core/tests' import { NodeFileSystem } from '../../../../node/src/NodeFileSystem' import { AskarModuleConfig, AskarMultiWalletDatabaseScheme } from '../../AskarModuleConfig' @@ -17,7 +17,7 @@ const agentContext = getAgentContext({ AskarModuleConfig, new AskarModuleConfig({ multiWalletDatabaseScheme: AskarMultiWalletDatabaseScheme.ProfilePerWallet, - askar, + askar: NativeAskar.instance, store: { id: 'default', key: 'CwNJroKHTSSj3XvE7ZAnuKiTn2C4QkFvxEqfm5rzhNrb', diff --git a/packages/askar/src/kms/crypto/deriveKey.ts b/packages/askar/src/kms/crypto/deriveKey.ts index 57918ad1f1..af82d63dba 100644 --- a/packages/askar/src/kms/crypto/deriveKey.ts +++ b/packages/askar/src/kms/crypto/deriveKey.ts @@ -1,5 +1,5 @@ import { Kms, TypedArrayEncoder } from '@credo-ts/core' -import { askar, Key } from '@openwallet-foundation/askar-shared' +import { Key, NativeAskar } from '@openwallet-foundation/askar-shared' import { jwkEncToAskarAlg } from '../../utils' export const askarSupportedKeyAgreementAlgorithms = [ @@ -47,7 +47,7 @@ export function deriveEncryptionKey(options: { : undefined const derivedKey = new Key( - askar.keyDeriveEcdhEs({ + NativeAskar.instance.keyDeriveEcdhEs({ algId: TypedArrayEncoder.fromUtf8String( keyAgreement.algorithm === 'ECDH-ES' ? encryption.algorithm : keyAgreement.algorithm ), @@ -130,7 +130,7 @@ export function deriveDecryptionKey(options: { : undefined const derivedKey = new Key( - askar.keyDeriveEcdhEs({ + NativeAskar.instance.keyDeriveEcdhEs({ algId: TypedArrayEncoder.fromUtf8String( keyAgreement.algorithm === 'ECDH-ES' ? decryption.algorithm : keyAgreement.algorithm ), diff --git a/packages/askar/src/storage/__tests__/AskarStorageService.test.ts b/packages/askar/src/storage/__tests__/AskarStorageService.test.ts index f9cfd1d008..8cc03c365b 100644 --- a/packages/askar/src/storage/__tests__/AskarStorageService.test.ts +++ b/packages/askar/src/storage/__tests__/AskarStorageService.test.ts @@ -1,7 +1,7 @@ import type { AgentContext, TagsBase } from '@credo-ts/core' import { RecordDuplicateError, RecordNotFoundError, TypedArrayEncoder } from '@credo-ts/core' -import { askar } from '@openwallet-foundation/askar-nodejs' +import { NativeAskar } from '@openwallet-foundation/askar-nodejs' import { TestRecord } from '../../../../core/src/storage/__tests__/TestRecord' import { getAgentConfig, getAgentContext, getAskarStoreConfig } from '../../../../core/tests/helpers' @@ -27,7 +27,7 @@ describe('AskarStorageService', () => { storeManager = new AskarStoreManager( new NodeFileSystem(), new AskarModuleConfig({ - askar, + askar: NativeAskar.instance, store: getAskarStoreConfig('AskarStorageServiceTest', { inMemory: true, }), @@ -70,7 +70,7 @@ describe('AskarStorageService', () => { }) const retrieveRecord = await storeManager.withSession(agentContext, (session) => - askar.sessionFetch({ + NativeAskar.instance.sessionFetch({ category: record.type, name: record.id, // biome-ignore lint/style/noNonNullAssertion: no explanation @@ -96,7 +96,7 @@ describe('AskarStorageService', () => { await storeManager.withSession( agentContext, async (session) => - await askar.sessionUpdate({ + await NativeAskar.instance.sessionUpdate({ category: TestRecord.type, name: 'some-id', // biome-ignore lint/style/noNonNullAssertion: no explanation