@credo-ts/askar 0.6.1-pr-2091-20241119140918 → 0.6.2-alpha-20251210145840

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/build/AskarApi.d.mts +68 -0
  2. package/build/AskarApi.d.mts.map +1 -0
  3. package/build/AskarApi.mjs +94 -0
  4. package/build/AskarApi.mjs.map +1 -0
  5. package/build/AskarApiOptions.d.mts +29 -0
  6. package/build/AskarApiOptions.d.mts.map +1 -0
  7. package/build/AskarModule.d.mts +18 -0
  8. package/build/AskarModule.d.mts.map +1 -0
  9. package/build/AskarModule.mjs +61 -0
  10. package/build/AskarModule.mjs.map +1 -0
  11. package/build/AskarModuleConfig.d.mts +125 -0
  12. package/build/AskarModuleConfig.d.mts.map +1 -0
  13. package/build/AskarModuleConfig.mjs +41 -0
  14. package/build/AskarModuleConfig.mjs.map +1 -0
  15. package/build/AskarStorageConfig.d.mts +32 -0
  16. package/build/AskarStorageConfig.d.mts.map +1 -0
  17. package/build/AskarStorageConfig.mjs +11 -0
  18. package/build/AskarStorageConfig.mjs.map +1 -0
  19. package/build/AskarStoreManager.d.mts +109 -0
  20. package/build/AskarStoreManager.d.mts.map +1 -0
  21. package/build/AskarStoreManager.mjs +386 -0
  22. package/build/AskarStoreManager.mjs.map +1 -0
  23. package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs +10 -0
  24. package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs +7 -0
  25. package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs +9 -0
  26. package/build/error/AskarError.d.mts +1 -0
  27. package/build/error/AskarError.mjs +12 -0
  28. package/build/error/AskarError.mjs.map +1 -0
  29. package/build/error/AskarStoreDuplicateError.d.mts +13 -0
  30. package/build/error/AskarStoreDuplicateError.d.mts.map +1 -0
  31. package/build/error/AskarStoreDuplicateError.mjs +12 -0
  32. package/build/error/AskarStoreDuplicateError.mjs.map +1 -0
  33. package/build/error/AskarStoreError.d.mts +13 -0
  34. package/build/error/AskarStoreError.d.mts.map +1 -0
  35. package/build/error/AskarStoreError.mjs +12 -0
  36. package/build/error/AskarStoreError.mjs.map +1 -0
  37. package/build/error/AskarStoreExportPathExistsError.d.mts +13 -0
  38. package/build/error/AskarStoreExportPathExistsError.d.mts.map +1 -0
  39. package/build/error/AskarStoreExportPathExistsError.mjs +12 -0
  40. package/build/error/AskarStoreExportPathExistsError.mjs.map +1 -0
  41. package/build/error/AskarStoreExportUnsupportedError.d.mts +13 -0
  42. package/build/error/AskarStoreExportUnsupportedError.d.mts.map +1 -0
  43. package/build/error/AskarStoreExportUnsupportedError.mjs +12 -0
  44. package/build/error/AskarStoreExportUnsupportedError.mjs.map +1 -0
  45. package/build/error/AskarStoreImportPathExistsError.d.mts +13 -0
  46. package/build/error/AskarStoreImportPathExistsError.d.mts.map +1 -0
  47. package/build/error/AskarStoreImportPathExistsError.mjs +12 -0
  48. package/build/error/AskarStoreImportPathExistsError.mjs.map +1 -0
  49. package/build/error/AskarStoreInvalidKeyError.d.mts +13 -0
  50. package/build/error/AskarStoreInvalidKeyError.d.mts.map +1 -0
  51. package/build/error/AskarStoreInvalidKeyError.mjs +12 -0
  52. package/build/error/AskarStoreInvalidKeyError.mjs.map +1 -0
  53. package/build/error/AskarStoreNotFoundError.d.mts +13 -0
  54. package/build/error/AskarStoreNotFoundError.d.mts.map +1 -0
  55. package/build/error/AskarStoreNotFoundError.mjs +12 -0
  56. package/build/error/AskarStoreNotFoundError.mjs.map +1 -0
  57. package/build/error/index.d.mts +8 -0
  58. package/build/error/index.mjs +8 -0
  59. package/build/index.d.mts +19 -0
  60. package/build/index.mjs +19 -0
  61. package/build/kms/AskarKeyManagementService.d.mts +30 -0
  62. package/build/kms/AskarKeyManagementService.d.mts.map +1 -0
  63. package/build/kms/AskarKeyManagementService.mjs +415 -0
  64. package/build/kms/AskarKeyManagementService.mjs.map +1 -0
  65. package/build/kms/crypto/decrypt.mjs +21 -0
  66. package/build/kms/crypto/decrypt.mjs.map +1 -0
  67. package/build/kms/crypto/deriveKey.mjs +87 -0
  68. package/build/kms/crypto/deriveKey.mjs.map +1 -0
  69. package/build/kms/crypto/encrypt.mjs +24 -0
  70. package/build/kms/crypto/encrypt.mjs.map +1 -0
  71. package/build/kms/crypto/randomBytes.mjs +19 -0
  72. package/build/kms/crypto/randomBytes.mjs.map +1 -0
  73. package/build/storage/AskarStorageService.d.mts +34 -0
  74. package/build/storage/AskarStorageService.d.mts.map +1 -0
  75. package/build/storage/AskarStorageService.mjs +169 -0
  76. package/build/storage/AskarStorageService.mjs.map +1 -0
  77. package/build/storage/index.d.mts +1 -0
  78. package/build/storage/index.mjs +1 -0
  79. package/build/storage/utils.d.mts +8 -0
  80. package/build/storage/utils.d.mts.map +1 -0
  81. package/build/storage/utils.mjs +58 -0
  82. package/build/storage/utils.mjs.map +1 -0
  83. package/build/tenants.mjs +42 -0
  84. package/build/tenants.mjs.map +1 -0
  85. package/build/utils/askarError.d.mts +1 -0
  86. package/build/utils/askarError.mjs +21 -0
  87. package/build/utils/askarError.mjs.map +1 -0
  88. package/build/utils/askarKeyTypes.d.mts +2 -0
  89. package/build/utils/askarKeyTypes.mjs +25 -0
  90. package/build/utils/askarKeyTypes.mjs.map +1 -0
  91. package/build/utils/askarStoreConfig.d.mts +2 -0
  92. package/build/utils/askarStoreConfig.mjs +47 -0
  93. package/build/utils/askarStoreConfig.mjs.map +1 -0
  94. package/build/utils/index.d.mts +4 -0
  95. package/build/utils/index.mjs +4 -0
  96. package/build/utils/transformPrivateKey.d.mts +73 -0
  97. package/build/utils/transformPrivateKey.d.mts.map +1 -0
  98. package/build/utils/transformPrivateKey.mjs +73 -0
  99. package/build/utils/transformPrivateKey.mjs.map +1 -0
  100. package/package.json +21 -29
  101. package/build/AskarModule.d.ts +0 -9
  102. package/build/AskarModule.js +0 -58
  103. package/build/AskarModule.js.map +0 -1
  104. package/build/AskarModuleConfig.d.ts +0 -68
  105. package/build/AskarModuleConfig.js +0 -33
  106. package/build/AskarModuleConfig.js.map +0 -1
  107. package/build/index.d.ts +0 -4
  108. package/build/index.js +0 -16
  109. package/build/index.js.map +0 -1
  110. package/build/secureEnvironment/index.d.ts +0 -1
  111. package/build/secureEnvironment/index.js +0 -18
  112. package/build/secureEnvironment/index.js.map +0 -1
  113. package/build/secureEnvironment/secureEnvironment.d.ts +0 -5
  114. package/build/secureEnvironment/secureEnvironment.js +0 -7
  115. package/build/secureEnvironment/secureEnvironment.js.map +0 -1
  116. package/build/secureEnvironment/secureEnvironment.native.d.ts +0 -1
  117. package/build/secureEnvironment/secureEnvironment.native.js +0 -14
  118. package/build/secureEnvironment/secureEnvironment.native.js.map +0 -1
  119. package/build/storage/AskarStorageService.d.ts +0 -17
  120. package/build/storage/AskarStorageService.js +0 -141
  121. package/build/storage/AskarStorageService.js.map +0 -1
  122. package/build/storage/index.d.ts +0 -1
  123. package/build/storage/index.js +0 -18
  124. package/build/storage/index.js.map +0 -1
  125. package/build/storage/utils.d.ts +0 -15
  126. package/build/storage/utils.js +0 -109
  127. package/build/storage/utils.js.map +0 -1
  128. package/build/utils/askarError.d.ts +0 -14
  129. package/build/utils/askarError.js +0 -20
  130. package/build/utils/askarError.js.map +0 -1
  131. package/build/utils/askarKeyBackend.d.ts +0 -3
  132. package/build/utils/askarKeyBackend.js +0 -15
  133. package/build/utils/askarKeyBackend.js.map +0 -1
  134. package/build/utils/askarKeyTypes.d.ts +0 -8
  135. package/build/utils/askarKeyTypes.js +0 -46
  136. package/build/utils/askarKeyTypes.js.map +0 -1
  137. package/build/utils/askarWalletConfig.d.ts +0 -14
  138. package/build/utils/askarWalletConfig.js +0 -75
  139. package/build/utils/askarWalletConfig.js.map +0 -1
  140. package/build/utils/assertAskarWallet.d.ts +0 -3
  141. package/build/utils/assertAskarWallet.js +0 -14
  142. package/build/utils/assertAskarWallet.js.map +0 -1
  143. package/build/utils/index.d.ts +0 -3
  144. package/build/utils/index.js +0 -20
  145. package/build/utils/index.js.map +0 -1
  146. package/build/wallet/AskarBaseWallet.d.ts +0 -112
  147. package/build/wallet/AskarBaseWallet.js +0 -540
  148. package/build/wallet/AskarBaseWallet.js.map +0 -1
  149. package/build/wallet/AskarProfileWallet.d.ts +0 -24
  150. package/build/wallet/AskarProfileWallet.js +0 -150
  151. package/build/wallet/AskarProfileWallet.js.map +0 -1
  152. package/build/wallet/AskarWallet.d.ts +0 -58
  153. package/build/wallet/AskarWallet.js +0 -342
  154. package/build/wallet/AskarWallet.js.map +0 -1
  155. package/build/wallet/AskarWalletStorageConfig.d.ts +0 -31
  156. package/build/wallet/AskarWalletStorageConfig.js +0 -11
  157. package/build/wallet/AskarWalletStorageConfig.js.map +0 -1
  158. package/build/wallet/JweEnvelope.d.ts +0 -32
  159. package/build/wallet/JweEnvelope.js +0 -55
  160. package/build/wallet/JweEnvelope.js.map +0 -1
  161. package/build/wallet/didcommV1.d.ts +0 -8
  162. package/build/wallet/didcommV1.js +0 -155
  163. package/build/wallet/didcommV1.js.map +0 -1
  164. package/build/wallet/index.d.ts +0 -3
  165. package/build/wallet/index.js +0 -23
  166. package/build/wallet/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AskarKeyManagementService.mjs","names":["key: Key | undefined","askarKey: Key | undefined","lengthToKeyAlg: Record<number, KeyAlgorithm | undefined>","keysToFree: Key[]","encryptionKey: Key | undefined","encryptedKey: Kms.KmsEncryptedKey | undefined","privateJwk","key","decryptionKey: Key | undefined"],"sources":["../../src/kms/AskarKeyManagementService.ts"],"sourcesContent":["import { type AgentContext, type AnyUint8Array, JsonEncoder, Kms, TypedArrayEncoder, utils } from '@credo-ts/core'\nimport type { JwkProps, KeyEntryObject, Session } from '@openwallet-foundation/askar-shared'\nimport {\n askar,\n CryptoBox,\n Jwk,\n Key,\n KeyAlgorithm,\n KeyEntryList,\n SignatureAlgorithm,\n} from '@openwallet-foundation/askar-shared'\n\nimport { AskarStoreManager } from '../AskarStoreManager'\nimport { AskarErrorCode, isAskarError, jwkCrvToAskarAlg, jwkEncToAskarAlg } from '../utils'\nimport { aeadDecrypt } from './crypto/decrypt'\nimport { askarSupportedKeyAgreementAlgorithms, deriveDecryptionKey, deriveEncryptionKey } from './crypto/deriveKey'\nimport { type AskarSupportedEncryptionOptions, aeadEncrypt } from './crypto/encrypt'\nimport { randomBytes } from './crypto/randomBytes'\n\nconst askarSupportedEncryptionAlgorithms = [\n ...(Object.keys(jwkEncToAskarAlg) as Array<keyof typeof jwkEncToAskarAlg>),\n 'XSALSA20-POLY1305',\n] satisfies Array<Kms.KnownJwaContentEncryptionAlgorithm | Kms.KnownJwaKeyEncryptionAlgorithm>\n\nexport class AskarKeyManagementService implements Kms.KeyManagementService {\n public static readonly backend = 'askar'\n public readonly backend = AskarKeyManagementService.backend\n\n private static algToSigType: Partial<Record<Kms.KnownJwaSignatureAlgorithm, SignatureAlgorithm>> = {\n EdDSA: SignatureAlgorithm.EdDSA,\n Ed25519: SignatureAlgorithm.EdDSA,\n ES256K: SignatureAlgorithm.ES256K,\n ES256: SignatureAlgorithm.ES256,\n ES384: SignatureAlgorithm.ES384,\n }\n\n private withSession<Return>(agentContext: AgentContext, callback: (session: Session) => Return) {\n return agentContext.dependencyManager.resolve(AskarStoreManager).withSession(agentContext, callback)\n }\n\n public isOperationSupported(_agentContext: AgentContext, operation: Kms.KmsOperation): boolean {\n if (operation.operation === 'deleteKey') return true\n if (operation.operation === 'randomBytes') return true\n\n if (operation.operation === 'importKey') {\n if (operation.privateJwk.kty === 'EC' || operation.privateJwk.kty === 'OKP') {\n return jwkCrvToAskarAlg[operation.privateJwk.crv] !== undefined\n }\n\n // RSA/oct not supported\n return false\n }\n\n if (operation.operation === 'createKey') {\n if (operation.type.kty === 'EC' || operation.type.kty === 'OKP') {\n return jwkCrvToAskarAlg[operation.type.crv] !== undefined\n }\n\n if (operation.type.kty === 'oct') {\n if (operation.type.algorithm === 'C20P') return true\n\n // TODO: sync with the createKey code\n if (operation.type.algorithm === 'aes') {\n return [128, 256].includes(operation.type.length)\n }\n }\n\n return false\n }\n\n if (operation.operation === 'sign' || operation.operation === 'verify') {\n return AskarKeyManagementService.algToSigType[operation.algorithm] !== undefined\n }\n\n if (operation.operation === 'encrypt') {\n const isSupportedEncryptionAlgorithm = askarSupportedEncryptionAlgorithms.includes(\n operation.encryption.algorithm as (typeof askarSupportedEncryptionAlgorithms)[number]\n )\n if (!isSupportedEncryptionAlgorithm) return false\n if (!operation.keyAgreement) return true\n\n return askarSupportedKeyAgreementAlgorithms.includes(\n operation.keyAgreement.algorithm as (typeof askarSupportedKeyAgreementAlgorithms)[number]\n )\n }\n\n if (operation.operation === 'decrypt') {\n const isSupportedEncryptionAlgorithm = askarSupportedEncryptionAlgorithms.includes(\n operation.decryption.algorithm as (typeof askarSupportedEncryptionAlgorithms)[number]\n )\n if (!isSupportedEncryptionAlgorithm) return false\n if (!operation.keyAgreement) return true\n\n return askarSupportedKeyAgreementAlgorithms.includes(\n operation.keyAgreement.algorithm as (typeof askarSupportedKeyAgreementAlgorithms)[number]\n )\n }\n\n return false\n }\n\n public randomBytes(_agentContext: AgentContext, options: Kms.KmsRandomBytesOptions): Kms.KmsRandomBytesReturn {\n return randomBytes(options.length)\n }\n\n public async getPublicKey(agentContext: AgentContext, keyId: string): Promise<Kms.KmsJwkPublic | null> {\n const key = await this.fetchAskarKey(agentContext, keyId)\n if (!key) return null\n\n return this.publicJwkFromKey(key.key, { kid: keyId })\n }\n\n public async importKey<Jwk extends Kms.KmsJwkPrivate>(\n agentContext: AgentContext,\n options: Kms.KmsImportKeyOptions<Jwk>\n ): Promise<Kms.KmsImportKeyReturn<Jwk>> {\n const { kid } = options.privateJwk\n\n const privateJwk = {\n ...options.privateJwk,\n kid: kid ?? utils.uuid(),\n }\n\n let key: Key | undefined\n try {\n if (privateJwk.kty === 'oct') {\n // TODO: we need to look at how to import symmetric keys, as we need the alg\n // Should we do the same as we do for createKey?\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `importing keys with kty '${privateJwk.kty}'`,\n this.backend\n )\n }\n if (privateJwk.kty === 'EC' || privateJwk.kty === 'OKP') {\n // Throws error if not supported\n this.assertAskarAlgForJwkCrv(privateJwk.kty, privateJwk.crv)\n\n key = Key.fromJwk({ jwk: Jwk.fromJson(privateJwk) })\n }\n\n const _key = key\n if (!_key) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`kty '${privateJwk.kty}'`, this.backend)\n }\n\n await this.withSession(agentContext, (session) => session.insertKey({ name: privateJwk.kid, key: _key }))\n const publicJwk = Kms.publicJwkFromPrivateJwk(privateJwk)\n\n return {\n keyId: privateJwk.kid,\n publicJwk: {\n ...publicJwk,\n kid: privateJwk.kid,\n },\n } as Kms.KmsImportKeyReturn<Jwk>\n } catch (error) {\n if (error instanceof Kms.KeyManagementError) throw error\n\n // Handle case where key already exists\n if (isAskarError(error, AskarErrorCode.Duplicate)) {\n throw new Kms.KeyManagementKeyExistsError(privateJwk.kid, this.backend)\n }\n\n throw new Kms.KeyManagementError('Error importing key', { cause: error })\n } finally {\n key?.handle.free()\n }\n }\n\n public async deleteKey(agentContext: AgentContext, options: Kms.KmsDeleteKeyOptions): Promise<boolean> {\n try {\n await this.withSession(agentContext, (session) => session.removeKey({ name: options.keyId }))\n return true\n } catch (error) {\n // Handle case where key does not exist\n if (isAskarError(error, AskarErrorCode.NotFound)) {\n return false\n }\n\n throw new Kms.KeyManagementError(`Error deleting key with id '${options.keyId}'`, { cause: error })\n }\n }\n\n public async createKey<Type extends Kms.KmsCreateKeyType>(\n agentContext: AgentContext,\n options: Kms.KmsCreateKeyOptions<Type>\n ): Promise<Kms.KmsCreateKeyReturn<Type>> {\n const { type, keyId } = options\n\n // FIXME: we should maybe keep the default keyId as publicKeyBase58 for a while for now, so it doesn't break\n // Or we need a way to query a key based on the public key?\n const kid = keyId ?? utils.uuid()\n let askarKey: Key | undefined\n try {\n if (type.kty === 'EC' || type.kty === 'OKP') {\n const keyAlg = this.assertAskarAlgForJwkCrv(type.kty, type.crv)\n askarKey = Key.generate(keyAlg)\n } else if (type.kty === 'oct') {\n // NOTE: askar is more specific in the intended use of the key at time of generation.\n // We either need to allow for this on a higher level (should be possible using `alg`)\n // but as the keys are the same it's ok to just always pick one and if used for another\n // purpose we can see them as the same.\n if (type.algorithm === 'aes') {\n const lengthToKeyAlg: Record<number, KeyAlgorithm | undefined> = {\n 128: KeyAlgorithm.AesA128Gcm,\n 256: KeyAlgorithm.AesA256Gcm,\n 512: KeyAlgorithm.AesA256CbcHs512,\n }\n\n const keyAlg = lengthToKeyAlg[type.length]\n if (!keyAlg) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `length '${type.length}' for kty '${type.kty}' with algorithm '${type.algorithm}'. Supported length values are ${Object.keys(lengthToKeyAlg).join(', ')}`,\n this.backend\n )\n }\n\n askarKey = Key.generate(keyAlg)\n } else if (type.algorithm === 'C20P') {\n // Both X and non-X variant can be used with the same key\n askarKey = Key.generate(KeyAlgorithm.Chacha20C20P)\n } else {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `algorithm '${type.algorithm}' for kty '${type.kty}'`,\n this.backend\n )\n }\n }\n\n const _key = askarKey\n if (!_key) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`kty '${type.kty}'`, this.backend)\n }\n\n const publicJwk = this.publicJwkFromKey(_key, { kid }) as Kms.KmsCreateKeyReturn<Type>['publicJwk']\n await this.withSession(agentContext, (session) => session.insertKey({ name: kid, key: _key }))\n\n return {\n publicJwk,\n keyId: kid,\n } as Kms.KmsCreateKeyReturn<Type>\n } catch (error) {\n if (error instanceof Kms.KeyManagementError) throw error\n\n // Handle case where key already exists\n if (isAskarError(error, AskarErrorCode.Duplicate)) {\n throw new Kms.KeyManagementKeyExistsError(kid, this.backend)\n }\n\n throw new Kms.KeyManagementError('Error creating key', { cause: error })\n } finally {\n askarKey?.handle.free()\n }\n }\n\n public async sign(agentContext: AgentContext, options: Kms.KmsSignOptions): Promise<Kms.KmsSignReturn> {\n const { keyId, algorithm, data } = options\n\n // 1. Retrieve the key\n const key = await this.getKeyAsserted(agentContext, keyId)\n try {\n const sigType = this.assertedSigTypeForAlg(algorithm)\n // Askar has a bug with loading symmetric keys, but we shouldn't get here as I don't think askar\n // support signing with symmetric keys, and we don't support it (it will be caught by assertedSigTypeForAlg)\n if (!key.key) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`algorithm ${algorithm}`, this.backend)\n }\n\n // TODO: we should extend this with metadata properties (e.g. use, key_ops)\n const publicJwk = this.publicJwkFromKey(key.key, { kid: keyId })\n const privateJwk = this.privateJwkFromKey(key.key, { kid: keyId })\n\n // 2. Validate alg and use for key\n Kms.assertAllowedSigningAlgForKey(privateJwk, algorithm)\n Kms.assertKeyAllowsSign(publicJwk)\n\n // 3. Perform the signing operation\n const signature = key.key.signMessage({\n message: new Uint8Array(data),\n sigType,\n })\n\n return {\n signature: new Uint8Array(signature),\n }\n } catch (error) {\n if (error instanceof Kms.KeyManagementError) throw error\n throw new Kms.KeyManagementError('Error signing with key', { cause: error })\n } finally {\n key.key?.handle.free()\n }\n }\n\n public async verify(agentContext: AgentContext, options: Kms.KmsVerifyOptions): Promise<Kms.KmsVerifyReturn> {\n const { algorithm, data, signature, key: keyInput } = options\n\n // Get askar sig type (and handles unsupported alg)\n const sigType = this.assertedSigTypeForAlg(algorithm)\n\n // Retrieve the key\n let askarKey: Key | undefined\n\n try {\n if (keyInput.keyId) {\n askarKey = (await this.getKeyAsserted(agentContext, keyInput.keyId)).key\n } else if (keyInput.publicJwk?.kty === 'EC' || keyInput.publicJwk?.kty === 'OKP') {\n // Throws error if not supported\n this.assertAskarAlgForJwkCrv(keyInput.publicJwk.kty, keyInput.publicJwk.crv)\n\n askarKey = Key.fromJwk({ jwk: Jwk.fromJson(keyInput.publicJwk as JwkProps) })\n } else {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`kty ${keyInput.publicJwk?.kty}`, this.backend)\n }\n\n // Askar has a bug with loading symmetric keys, but we shouldn't get here as I don't think askar\n // support signing with symmetric keys, and we don't support it (it will be caught by assertedSigTypeForAlg)\n if (!askarKey) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`algorithm ${algorithm}`, this.backend)\n }\n\n const keyId = keyInput.keyId ?? keyInput.publicJwk?.kid\n const publicJwk = this.publicJwkFromKey(askarKey, { kid: keyId })\n\n // For symmetric verificdation we need the private key\n if (publicJwk.kty === 'oct') {\n const privateJwk = this.privateJwkFromKey(askarKey, { kid: keyId })\n\n // 2. Validate alg and use for key\n Kms.assertAllowedSigningAlgForKey(privateJwk, algorithm)\n Kms.assertKeyAllowsVerify(publicJwk)\n } else {\n // 2. Validate alg and use for key\n Kms.assertAllowedSigningAlgForKey(publicJwk, algorithm)\n Kms.assertKeyAllowsVerify(publicJwk)\n }\n\n // 4. Perform the verify operation\n const verified = askarKey.verifySignature({\n message: new Uint8Array(data),\n signature: new Uint8Array(signature),\n sigType,\n })\n if (verified) {\n return {\n verified: true,\n publicJwk: keyInput.keyId\n ? this.publicJwkFromKey(askarKey, { kid: keyId })\n : (keyInput.publicJwk as Kms.KmsJwkPublic),\n }\n }\n\n return {\n verified: false,\n }\n } catch (error) {\n if (error instanceof Kms.KeyManagementError) throw error\n throw new Kms.KeyManagementError('Error verifying with key', { cause: error })\n } finally {\n if (askarKey) askarKey.handle.free()\n }\n }\n\n public async encrypt(agentContext: AgentContext, options: Kms.KmsEncryptOptions): Promise<Kms.KmsEncryptReturn> {\n const { data, encryption, key } = options\n\n Kms.assertSupportedEncryptionAlgorithm(encryption, askarSupportedEncryptionAlgorithms, this.backend)\n\n const keysToFree: Key[] = []\n try {\n let encryptionKey: Key | undefined\n let encryptedKey: Kms.KmsEncryptedKey | undefined\n\n // TODO: we should check if the key allows this operation\n if (key.keyId) {\n encryptionKey = (await this.getKeyAsserted(agentContext, key.keyId)).key\n\n keysToFree.push(encryptionKey)\n } else if (key.privateJwk) {\n if (encryption.algorithm === 'XSALSA20-POLY1305') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `encryption algorithm '${encryption.algorithm}' is only supported in combination with key agreement algorithm '${Kms.KnownJwaKeyAgreementAlgorithms.ECDH_HSALSA20}'`,\n this.backend\n )\n }\n encryptionKey = this.keyFromSecretBytesAndEncryptionAlgorithm(\n TypedArrayEncoder.fromBase64(key.privateJwk.k),\n encryption.algorithm\n )\n keysToFree.push(encryptionKey)\n } else if (key.keyAgreement) {\n Kms.assertAllowedKeyDerivationAlgForKey(key.keyAgreement.externalPublicJwk, key.keyAgreement.algorithm)\n Kms.assertKeyAllowsDerive(key.keyAgreement.externalPublicJwk)\n Kms.assertSupportedKeyAgreementAlgorithm(key.keyAgreement, askarSupportedKeyAgreementAlgorithms, this.backend)\n\n let privateKey = key.keyAgreement.keyId\n ? (await this.getKeyAsserted(agentContext, key.keyAgreement.keyId)).key\n : undefined\n if (privateKey) keysToFree.push(privateKey)\n\n const privateJwk = privateKey ? this.privateJwkFromKey(privateKey) : undefined\n if (privateJwk) {\n Kms.assertJwkAsymmetric(privateJwk, key.keyAgreement.keyId)\n Kms.assertAllowedKeyDerivationAlgForKey(privateJwk, key.keyAgreement.algorithm)\n Kms.assertKeyAllowsDerive(privateJwk)\n\n // Special case, for DIDComm v1 we often use an X25519 for the external key\n // but we use an Ed25519 for our key\n if (key.keyAgreement.algorithm !== 'ECDH-HSALSA20') {\n Kms.assertAsymmetricJwkKeyTypeMatches(privateJwk, key.keyAgreement.externalPublicJwk)\n }\n }\n\n const recipientKey = this.keyFromJwk(key.keyAgreement.externalPublicJwk)\n keysToFree.push(recipientKey)\n\n // Special case to support DIDComm v1\n if (key.keyAgreement.algorithm === 'ECDH-HSALSA20' || encryption.algorithm === 'XSALSA20-POLY1305') {\n if (encryption.algorithm !== 'XSALSA20-POLY1305' || key.keyAgreement.algorithm !== 'ECDH-HSALSA20') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `key agreement algorithm '${key.keyAgreement.algorithm}' with encryption algorithm '${encryption.algorithm}'`,\n this.backend\n )\n }\n\n // anonymous encryption\n if (!privateKey) {\n return {\n encrypted: new Uint8Array(\n CryptoBox.seal({\n recipientKey,\n message: new Uint8Array(data),\n })\n ),\n }\n }\n\n // Special case. For DIDComm v1 we basically use the Ed25519 key also\n // for X25519 operations.\n if (privateKey.algorithm === KeyAlgorithm.Ed25519) {\n privateKey = privateKey.convertkey({ algorithm: KeyAlgorithm.X25519 })\n keysToFree.push(privateKey)\n }\n\n const nonce = new Uint8Array(CryptoBox.randomNonce())\n const encrypted = new Uint8Array(\n CryptoBox.cryptoBox({\n recipientKey,\n senderKey: privateKey,\n message: new Uint8Array(data),\n nonce,\n })\n )\n\n return {\n encrypted,\n iv: nonce,\n }\n }\n\n // This should not happen, but for TS\n if (!privateKey) {\n throw new Kms.KeyManagementError('sender key is required for ECDH-ES key derivation.')\n }\n\n const { contentEncryptionKey, encryptedContentEncryptionKey } = deriveEncryptionKey({\n encryption,\n keyAgreement: key.keyAgreement,\n recipientKey,\n senderKey: privateKey,\n })\n\n encryptionKey = contentEncryptionKey\n keysToFree.push(contentEncryptionKey)\n encryptedKey = encryptedContentEncryptionKey\n } else {\n throw new Kms.KeyManagementError('Unexpected key parameter for encrypt')\n }\n\n if (encryption.algorithm === 'XSALSA20-POLY1305') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `encryption algorithm '${encryption.algorithm}' can only be used with key agreement algorithm ECDH-HSALSA20`,\n this.backend\n )\n }\n\n const privateJwk = this.privateJwkFromKey(encryptionKey)\n Kms.assertKeyAllowsDerive(privateJwk)\n Kms.assertAllowedEncryptionAlgForKey(privateJwk, encryption.algorithm)\n Kms.assertKeyAllowsEncrypt(privateJwk)\n\n const encrypted = aeadEncrypt({\n key: encryptionKey,\n data,\n encryption,\n })\n\n return {\n ...encrypted,\n encryptedKey,\n }\n } catch (error) {\n if (error instanceof Kms.KeyManagementError) throw error\n throw new Kms.KeyManagementError('Error encrypting with key', { cause: error })\n } finally {\n // Clear all keys\n for (const key of keysToFree) {\n key.handle.free()\n }\n }\n }\n\n public async decrypt(agentContext: AgentContext, options: Kms.KmsDecryptOptions): Promise<Kms.KmsDecryptReturn> {\n const { encrypted, decryption, key } = options\n\n Kms.assertSupportedEncryptionAlgorithm(decryption, askarSupportedEncryptionAlgorithms, this.backend)\n\n const keysToFree: Key[] = []\n\n try {\n let decryptionKey: Key | undefined\n\n if (key.keyId) {\n decryptionKey = (await this.getKeyAsserted(agentContext, key.keyId)).key\n keysToFree.push(decryptionKey)\n } else if (key.privateJwk) {\n if (decryption.algorithm === 'XSALSA20-POLY1305') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `decryption algorithm '${decryption.algorithm}' is only supported in combination with key agreement algorithm '${Kms.KnownJwaKeyAgreementAlgorithms.ECDH_HSALSA20}'`,\n this.backend\n )\n }\n decryptionKey = this.keyFromSecretBytesAndEncryptionAlgorithm(\n TypedArrayEncoder.fromBase64(key.privateJwk.k),\n decryption.algorithm\n )\n keysToFree.push(decryptionKey)\n } else if (key.keyAgreement) {\n if (key.keyAgreement.externalPublicJwk) {\n Kms.assertAllowedKeyDerivationAlgForKey(key.keyAgreement.externalPublicJwk, key.keyAgreement.algorithm)\n Kms.assertKeyAllowsDerive(key.keyAgreement.externalPublicJwk)\n }\n Kms.assertSupportedKeyAgreementAlgorithm(key.keyAgreement, askarSupportedKeyAgreementAlgorithms, this.backend)\n\n let privateKey = (await this.getKeyAsserted(agentContext, key.keyAgreement.keyId)).key\n keysToFree.push(privateKey)\n\n const privateJwk = this.privateJwkFromKey(privateKey)\n\n Kms.assertJwkAsymmetric(privateJwk, key.keyAgreement.keyId)\n Kms.assertAllowedKeyDerivationAlgForKey(privateJwk, key.keyAgreement.algorithm)\n Kms.assertKeyAllowsDerive(privateJwk)\n\n // Special case for ECDH-HSALSA as we can have mismatch between keys because of DIDComm v1\n if (key.keyAgreement.externalPublicJwk && key.keyAgreement.algorithm !== 'ECDH-HSALSA20') {\n Kms.assertAsymmetricJwkKeyTypeMatches(privateJwk, key.keyAgreement.externalPublicJwk)\n }\n\n const senderKey = key.keyAgreement.externalPublicJwk\n ? this.keyFromJwk(key.keyAgreement.externalPublicJwk)\n : undefined\n if (senderKey) keysToFree.push(senderKey)\n\n // Special case to support DIDComm v1\n if (key.keyAgreement.algorithm === 'ECDH-HSALSA20' || decryption.algorithm === 'XSALSA20-POLY1305') {\n if (decryption.algorithm !== 'XSALSA20-POLY1305' || key.keyAgreement.algorithm !== 'ECDH-HSALSA20') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `key agreement algorithm '${key.keyAgreement.algorithm}' with encryption algorithm '${decryption.algorithm}'`,\n this.backend\n )\n }\n\n // Special case. For DIDComm v1 we basically use the Ed25519 key also\n // for X25519 operations.\n if (privateKey.algorithm === KeyAlgorithm.Ed25519) {\n privateKey = privateKey.convertkey({ algorithm: KeyAlgorithm.X25519 })\n keysToFree.push(privateKey)\n }\n\n if (!senderKey) {\n // anonymous encryption\n return {\n data: new Uint8Array(\n CryptoBox.sealOpen({\n recipientKey: privateKey,\n ciphertext: new Uint8Array(encrypted),\n })\n ),\n }\n }\n\n if (!decryption.iv) {\n throw new Kms.KeyManagementError(\n `Missing required 'iv' for key agreement algorithm ${key.keyAgreement.algorithm} and encryption algorithm ${decryption.algorithm} with sender key defined.`\n )\n }\n\n const decrypted = new Uint8Array(\n CryptoBox.open({\n recipientKey: privateKey,\n senderKey: senderKey,\n message: new Uint8Array(encrypted),\n nonce: new Uint8Array(decryption.iv),\n })\n )\n\n return {\n data: decrypted,\n }\n }\n\n // This should not happen, but for TS\n if (!senderKey) {\n throw new Kms.KeyManagementError('sender key is required for ECDH-ES key derivation.')\n }\n\n const { contentEncryptionKey } = deriveDecryptionKey({\n decryption,\n keyAgreement: key.keyAgreement,\n recipientKey: privateKey,\n senderKey,\n })\n\n decryptionKey = contentEncryptionKey\n keysToFree.push(contentEncryptionKey)\n } else {\n throw new Kms.KeyManagementError('Unexpected key parameter for decrypt')\n }\n\n if (decryption.algorithm === 'XSALSA20-POLY1305') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `encryption algorithm '${decryption.algorithm}' can only be used with key agreement algorithm ECDH-HSALSA20`,\n this.backend\n )\n }\n\n const privateJwk = this.privateJwkFromKey(decryptionKey)\n Kms.assertKeyAllowsDerive(privateJwk)\n Kms.assertAllowedEncryptionAlgForKey(privateJwk, decryption.algorithm)\n Kms.assertKeyAllowsEncrypt(privateJwk)\n\n const decrypted = aeadDecrypt({\n key: decryptionKey,\n encrypted,\n decryption,\n })\n\n return {\n data: decrypted,\n }\n } catch (error) {\n if (error instanceof Kms.KeyManagementError) throw error\n throw new Kms.KeyManagementError('Error decrypting with key', { cause: error })\n } finally {\n // Clear all keys\n for (const key of keysToFree) {\n key.handle.free()\n }\n }\n }\n\n private assertedSigTypeForAlg(algorithm: Kms.KnownJwaSignatureAlgorithm): SignatureAlgorithm {\n const sigType = AskarKeyManagementService.algToSigType[algorithm]\n if (!sigType) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `signing and verification with algorithm '${algorithm}'`,\n this.backend\n )\n }\n\n return sigType\n }\n\n private assertAskarAlgForJwkCrv(kty: string, crv: Kms.KmsJwkPublicEc['crv'] | Kms.KmsJwkPublicOkp['crv']) {\n const keyAlg = jwkCrvToAskarAlg[crv]\n if (!keyAlg) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`crv '${crv}' for kty '${kty}'`, this.backend)\n }\n\n return keyAlg\n }\n\n private keyFromJwk(jwk: Kms.KmsJwkPrivate | Kms.KmsJwkPublic) {\n const key = new Key(\n askar.keyFromJwk({\n // TODO: the JWK class in JS Askar wrapper is too limiting\n // so we use this method directly. should update it\n jwk: new Uint8Array(JsonEncoder.toBuffer(jwk)) as unknown as Jwk,\n })\n )\n\n return key\n }\n\n private keyFromSecretBytesAndEncryptionAlgorithm(\n secretBytes: AnyUint8Array,\n algorithm: AskarSupportedEncryptionOptions['algorithm']\n ) {\n const askarEncryptionAlgorithm = jwkEncToAskarAlg[algorithm]\n if (!askarEncryptionAlgorithm) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`JWA encryption algorithm '${algorithm}'`, 'askar')\n }\n\n return Key.fromSecretBytes({\n algorithm: askarEncryptionAlgorithm,\n secretKey: new Uint8Array(secretBytes),\n })\n }\n\n private publicJwkFromKey(key: Key, partialJwkPublic?: Partial<Kms.KmsJwkPublic>) {\n return Kms.publicJwkFromPrivateJwk(this.privateJwkFromKey(key, partialJwkPublic))\n }\n\n private privateJwkFromKey(key: Key, partialJwkPrivate?: Partial<Kms.KmsJwkPrivate>) {\n // TODO: once we support additional params we should add these here\n\n // TODO: the JWK class in JS Askar wrapper is too limiting\n // so we use this method directly. should update it\n // We extract alg, as Askar doesn't always use the same algs\n // biome-ignore lint/correctness/noUnusedVariables: no explanation\n const { alg, ...jwkSecret } = JsonEncoder.fromBuffer(\n askar.keyGetJwkSecret({\n localKeyHandle: key.handle,\n })\n )\n\n return {\n ...partialJwkPrivate,\n ...jwkSecret,\n } as Kms.KmsJwkPrivate\n }\n\n private async fetchAskarKey(agentContext: AgentContext, keyId: string): Promise<KeyEntryObject | null> {\n return await this.withSession(agentContext, async (session) => {\n if (!session.handle) throw Error('Cannot fetch a key with a closed session')\n\n // Fetch the key from the session\n const handle = await askar.sessionFetchKey({ forUpdate: false, name: keyId, sessionHandle: session.handle })\n if (!handle) return null\n\n // Get the key entry\n const keyEntryList = new KeyEntryList({ handle })\n const keyEntry = keyEntryList.getEntryByIndex(0)\n\n const keyEntryObject = keyEntry.toJson()\n keyEntryList.handle.free()\n\n return keyEntryObject\n })\n }\n\n private async getKeyAsserted(agentContext: AgentContext, keyId: string) {\n const storageKey = await this.fetchAskarKey(agentContext, keyId)\n if (!storageKey) {\n throw new Kms.KeyManagementKeyNotFoundError(keyId, [this.backend])\n }\n\n return storageKey\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { jwkEncToAskarAlg } from "../../utils/askarKeyTypes.mjs";
2
+ import "../../utils/index.mjs";
3
+ import { Kms } from "@credo-ts/core";
4
+ import { Key } from "@openwallet-foundation/askar-shared";
5
+
6
+ //#region src/kms/crypto/decrypt.ts
7
+ function aeadDecrypt(options) {
8
+ const { key, decryption, encrypted } = options;
9
+ if (!jwkEncToAskarAlg[decryption.algorithm]) throw new Kms.KeyManagementAlgorithmNotSupportedError(`JWA decryption algorithm '${decryption.algorithm}'`, "askar");
10
+ const decrypted = key.aeadDecrypt({
11
+ ciphertext: new Uint8Array(encrypted),
12
+ tag: new Uint8Array(decryption.tag),
13
+ aad: decryption.aad ? new Uint8Array(decryption.aad) : void 0,
14
+ nonce: new Uint8Array(decryption.iv)
15
+ });
16
+ return new Uint8Array(decrypted);
17
+ }
18
+
19
+ //#endregion
20
+ export { aeadDecrypt };
21
+ //# sourceMappingURL=decrypt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrypt.mjs","names":[],"sources":["../../../src/kms/crypto/decrypt.ts"],"sourcesContent":["import { type AnyUint8Array, Kms } from '@credo-ts/core'\nimport { Key } from '@openwallet-foundation/askar-shared'\nimport { jwkEncToAskarAlg } from '../../utils'\n\n// TODO: should we make these methods generic, so they can be reused across backends?\ntype AskarSupportedDecryptionOptions = Kms.KmsDecryptDataDecryption & {\n algorithm: keyof typeof jwkEncToAskarAlg\n}\n\nexport function aeadDecrypt(options: {\n key: Key\n decryption: AskarSupportedDecryptionOptions\n encrypted: AnyUint8Array\n}) {\n const { key, decryption, encrypted } = options\n\n const askarEncryptionAlgorithm = jwkEncToAskarAlg[decryption.algorithm]\n if (!askarEncryptionAlgorithm) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`JWA decryption algorithm '${decryption.algorithm}'`, 'askar')\n }\n\n const decrypted = key.aeadDecrypt({\n ciphertext: new Uint8Array(encrypted),\n tag: new Uint8Array(decryption.tag),\n aad: decryption.aad ? new Uint8Array(decryption.aad) : undefined,\n nonce: new Uint8Array(decryption.iv),\n })\n\n return new Uint8Array(decrypted)\n}\n"],"mappings":";;;;;;AASA,SAAgB,YAAY,SAIzB;CACD,MAAM,EAAE,KAAK,YAAY,cAAc;AAGvC,KAAI,CAD6B,iBAAiB,WAAW,WAE3D,OAAM,IAAI,IAAI,wCAAwC,6BAA6B,WAAW,UAAU,IAAI,QAAQ;CAGtH,MAAM,YAAY,IAAI,YAAY;EAChC,YAAY,IAAI,WAAW,UAAU;EACrC,KAAK,IAAI,WAAW,WAAW,IAAI;EACnC,KAAK,WAAW,MAAM,IAAI,WAAW,WAAW,IAAI,GAAG;EACvD,OAAO,IAAI,WAAW,WAAW,GAAG;EACrC,CAAC;AAEF,QAAO,IAAI,WAAW,UAAU"}
@@ -0,0 +1,87 @@
1
+ import { jwkEncToAskarAlg } from "../../utils/askarKeyTypes.mjs";
2
+ import "../../utils/index.mjs";
3
+ import { Kms, TypedArrayEncoder } from "@credo-ts/core";
4
+ import { Key, askar } from "@openwallet-foundation/askar-shared";
5
+
6
+ //#region src/kms/crypto/deriveKey.ts
7
+ const askarSupportedKeyAgreementAlgorithms = [
8
+ "ECDH-ES",
9
+ "ECDH-ES+A128KW",
10
+ "ECDH-ES+A256KW",
11
+ "ECDH-HSALSA20"
12
+ ];
13
+ function deriveEncryptionKey(options) {
14
+ const { keyAgreement, encryption, senderKey, recipientKey } = options;
15
+ const askarEncryptionAlgorithm = jwkEncToAskarAlg[encryption.algorithm];
16
+ if (!askarEncryptionAlgorithm) throw new Kms.KeyManagementAlgorithmNotSupportedError(`encryption with algorithm '${encryption.algorithm}'`, "askar");
17
+ if (keyAgreement.algorithm === "ECDH-HSALSA20") throw new Kms.KeyManagementAlgorithmNotSupportedError(`derive key for algorithm '${keyAgreement.algorithm}' with encryption algorithm '${encryption.algorithm}'`, "askar");
18
+ const askarKeyWrappingAlgorithm = keyAgreement.algorithm !== "ECDH-ES" ? jwkEncToAskarAlg[keyAgreement.algorithm.replace("ECDH-ES+", "")] : void 0;
19
+ const derivedKey = new Key(askar.keyDeriveEcdhEs({
20
+ algId: TypedArrayEncoder.fromString(keyAgreement.algorithm === "ECDH-ES" ? encryption.algorithm : keyAgreement.algorithm),
21
+ receive: false,
22
+ apv: keyAgreement.apv ? new Uint8Array(keyAgreement.apv) : new Uint8Array([]),
23
+ apu: keyAgreement.apu ? new Uint8Array(keyAgreement.apu) : new Uint8Array([]),
24
+ algorithm: askarKeyWrappingAlgorithm ?? askarEncryptionAlgorithm,
25
+ ephemeralKey: senderKey,
26
+ recipientKey
27
+ }));
28
+ let contentEncryptionKey;
29
+ let encryptedContentEncryptionKey;
30
+ try {
31
+ if (keyAgreement.algorithm !== "ECDH-ES") {
32
+ contentEncryptionKey = Key.generate(askarEncryptionAlgorithm);
33
+ const wrappedKey = derivedKey.wrapKey({ other: contentEncryptionKey });
34
+ encryptedContentEncryptionKey = {
35
+ encrypted: new Uint8Array(wrappedKey.ciphertext),
36
+ iv: new Uint8Array(wrappedKey.nonce),
37
+ tag: new Uint8Array(wrappedKey.tag)
38
+ };
39
+ }
40
+ return {
41
+ contentEncryptionKey: contentEncryptionKey ?? derivedKey,
42
+ encryptedContentEncryptionKey
43
+ };
44
+ } catch (error) {
45
+ if (contentEncryptionKey) contentEncryptionKey.handle.free();
46
+ else derivedKey.handle.free();
47
+ throw error;
48
+ } finally {
49
+ if (contentEncryptionKey) derivedKey.handle.free();
50
+ }
51
+ }
52
+ function deriveDecryptionKey(options) {
53
+ const { keyAgreement, decryption, senderKey, recipientKey } = options;
54
+ const askarEncryptionAlgorithm = jwkEncToAskarAlg[decryption.algorithm];
55
+ if (!askarEncryptionAlgorithm) throw new Kms.KeyManagementAlgorithmNotSupportedError(`decryption with algorithm '${decryption.algorithm}'`, "askar");
56
+ if (keyAgreement.algorithm === "ECDH-HSALSA20") throw new Kms.KeyManagementAlgorithmNotSupportedError(`derive key for algorithm '${keyAgreement.algorithm}' with encryption algorithm '${decryption.algorithm}'`, "askar");
57
+ const askarKeyWrappingAlgorithm = keyAgreement.algorithm !== "ECDH-ES" ? jwkEncToAskarAlg[keyAgreement.algorithm.replace("ECDH-ES+", "")] : void 0;
58
+ const derivedKey = new Key(askar.keyDeriveEcdhEs({
59
+ algId: TypedArrayEncoder.fromString(keyAgreement.algorithm === "ECDH-ES" ? decryption.algorithm : keyAgreement.algorithm),
60
+ receive: true,
61
+ apv: keyAgreement.apv ? new Uint8Array(keyAgreement.apv) : new Uint8Array(),
62
+ apu: keyAgreement.apu ? new Uint8Array(keyAgreement.apu) : new Uint8Array(),
63
+ algorithm: askarKeyWrappingAlgorithm ?? askarEncryptionAlgorithm,
64
+ ephemeralKey: senderKey,
65
+ recipientKey
66
+ }));
67
+ let contentEncryptionKey;
68
+ try {
69
+ if (keyAgreement.algorithm !== "ECDH-ES") contentEncryptionKey = derivedKey.unwrapKey({
70
+ ciphertext: new Uint8Array(keyAgreement.encryptedKey.encrypted),
71
+ algorithm: askarEncryptionAlgorithm,
72
+ nonce: keyAgreement.encryptedKey.iv ? new Uint8Array(keyAgreement.encryptedKey.iv) : void 0,
73
+ tag: keyAgreement.encryptedKey.tag ? new Uint8Array(keyAgreement.encryptedKey.tag) : void 0
74
+ });
75
+ return { contentEncryptionKey: contentEncryptionKey ?? derivedKey };
76
+ } catch (error) {
77
+ if (contentEncryptionKey) contentEncryptionKey.handle.free();
78
+ else derivedKey.handle.free();
79
+ throw error;
80
+ } finally {
81
+ if (contentEncryptionKey) derivedKey.handle.free();
82
+ }
83
+ }
84
+
85
+ //#endregion
86
+ export { askarSupportedKeyAgreementAlgorithms, deriveDecryptionKey, deriveEncryptionKey };
87
+ //# sourceMappingURL=deriveKey.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deriveKey.mjs","names":["contentEncryptionKey: Key | undefined","encryptedContentEncryptionKey: Kms.KmsEncryptedKey | undefined"],"sources":["../../../src/kms/crypto/deriveKey.ts"],"sourcesContent":["import { Kms, TypedArrayEncoder } from '@credo-ts/core'\nimport { askar, Key } from '@openwallet-foundation/askar-shared'\nimport { jwkEncToAskarAlg } from '../../utils'\n\nexport const askarSupportedKeyAgreementAlgorithms = [\n 'ECDH-ES',\n 'ECDH-ES+A128KW',\n 'ECDH-ES+A256KW',\n 'ECDH-HSALSA20',\n] satisfies Kms.KnownJwaKeyAgreementAlgorithm[]\n\ntype AskarSupportedKeyAgreementEncryptOptions = Kms.KmsKeyAgreementEncryptOptions & {\n algorithm: (typeof askarSupportedKeyAgreementAlgorithms)[number]\n}\n\ntype AskarSupportedKeyAgreementDecryptOptions = Kms.KmsKeyAgreementDecryptOptions & {\n algorithm: (typeof askarSupportedKeyAgreementAlgorithms)[number]\n}\n\nexport function deriveEncryptionKey(options: {\n keyAgreement: AskarSupportedKeyAgreementEncryptOptions\n senderKey: Key\n recipientKey: Key\n encryption: Kms.KmsEncryptDataEncryption\n}) {\n const { keyAgreement, encryption, senderKey, recipientKey } = options\n\n const askarEncryptionAlgorithm = jwkEncToAskarAlg[encryption.algorithm as keyof typeof jwkEncToAskarAlg]\n if (!askarEncryptionAlgorithm) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `encryption with algorithm '${encryption.algorithm}'`,\n 'askar'\n )\n }\n\n // This should be handled on a higher level as we only support combined key agreemnt + encryption\n if (keyAgreement.algorithm === 'ECDH-HSALSA20') {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `derive key for algorithm '${keyAgreement.algorithm}' with encryption algorithm '${encryption.algorithm}'`,\n 'askar'\n )\n }\n\n const askarKeyWrappingAlgorithm =\n keyAgreement.algorithm !== 'ECDH-ES'\n ? jwkEncToAskarAlg[keyAgreement.algorithm.replace('ECDH-ES+', '') as keyof typeof jwkEncToAskarAlg]\n : undefined\n\n const derivedKey = new Key(\n askar.keyDeriveEcdhEs({\n algId: TypedArrayEncoder.fromString(\n keyAgreement.algorithm === 'ECDH-ES' ? encryption.algorithm : keyAgreement.algorithm\n ),\n receive: false,\n apv: keyAgreement.apv ? new Uint8Array(keyAgreement.apv) : new Uint8Array([]),\n apu: keyAgreement.apu ? new Uint8Array(keyAgreement.apu) : new Uint8Array([]),\n algorithm: askarKeyWrappingAlgorithm ?? askarEncryptionAlgorithm,\n ephemeralKey: senderKey,\n recipientKey: recipientKey,\n })\n )\n let contentEncryptionKey: Key | undefined\n let encryptedContentEncryptionKey: Kms.KmsEncryptedKey | undefined\n try {\n // Key wrapping\n if (keyAgreement.algorithm !== 'ECDH-ES') {\n contentEncryptionKey = Key.generate(askarEncryptionAlgorithm)\n\n const wrappedKey = derivedKey.wrapKey({\n other: contentEncryptionKey,\n })\n encryptedContentEncryptionKey = {\n encrypted: new Uint8Array(wrappedKey.ciphertext),\n iv: new Uint8Array(wrappedKey.nonce),\n tag: new Uint8Array(wrappedKey.tag),\n }\n }\n\n return {\n contentEncryptionKey: contentEncryptionKey ?? derivedKey,\n encryptedContentEncryptionKey,\n }\n } catch (error) {\n if (contentEncryptionKey) {\n contentEncryptionKey.handle.free()\n }\n // We only free the derived key if there is no content encryption key\n // as in this case the derived key is already freed in the finally clause\n else {\n derivedKey.handle.free()\n }\n\n throw error\n } finally {\n // If there is a content encryption key, it means we can free the\n // derived key\n if (contentEncryptionKey) {\n derivedKey.handle.free()\n }\n }\n}\n\nexport function deriveDecryptionKey(options: {\n keyAgreement: AskarSupportedKeyAgreementDecryptOptions\n senderKey: Key\n recipientKey: Key\n decryption: Kms.KmsDecryptDataDecryption\n}) {\n const { keyAgreement, decryption, senderKey, recipientKey } = options\n\n const askarEncryptionAlgorithm = jwkEncToAskarAlg[decryption.algorithm as keyof typeof jwkEncToAskarAlg]\n if (!askarEncryptionAlgorithm) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `decryption with algorithm '${decryption.algorithm}'`,\n 'askar'\n )\n }\n\n if (keyAgreement.algorithm === 'ECDH-HSALSA20') {\n // This should be handled on a higher level as we only support combined key agreemnt + encryption\n throw new Kms.KeyManagementAlgorithmNotSupportedError(\n `derive key for algorithm '${keyAgreement.algorithm}' with encryption algorithm '${decryption.algorithm}'`,\n 'askar'\n )\n }\n\n const askarKeyWrappingAlgorithm =\n keyAgreement.algorithm !== 'ECDH-ES'\n ? jwkEncToAskarAlg[keyAgreement.algorithm.replace('ECDH-ES+', '') as keyof typeof jwkEncToAskarAlg]\n : undefined\n\n const derivedKey = new Key(\n askar.keyDeriveEcdhEs({\n algId: TypedArrayEncoder.fromString(\n keyAgreement.algorithm === 'ECDH-ES' ? decryption.algorithm : keyAgreement.algorithm\n ),\n receive: true,\n apv: keyAgreement.apv ? new Uint8Array(keyAgreement.apv) : new Uint8Array(),\n apu: keyAgreement.apu ? new Uint8Array(keyAgreement.apu) : new Uint8Array(),\n algorithm: askarKeyWrappingAlgorithm ?? askarEncryptionAlgorithm,\n ephemeralKey: senderKey,\n recipientKey: recipientKey,\n })\n )\n\n let contentEncryptionKey: Key | undefined\n try {\n // Key unwrapping\n if (keyAgreement.algorithm !== 'ECDH-ES') {\n contentEncryptionKey = derivedKey.unwrapKey({\n ciphertext: new Uint8Array(keyAgreement.encryptedKey.encrypted),\n algorithm: askarEncryptionAlgorithm,\n nonce: keyAgreement.encryptedKey.iv ? new Uint8Array(keyAgreement.encryptedKey.iv) : undefined,\n tag: keyAgreement.encryptedKey.tag ? new Uint8Array(keyAgreement.encryptedKey.tag) : undefined,\n })\n }\n\n return {\n contentEncryptionKey: contentEncryptionKey ?? derivedKey,\n }\n } catch (error) {\n if (contentEncryptionKey) {\n contentEncryptionKey.handle.free()\n } else {\n derivedKey.handle.free()\n }\n throw error\n } finally {\n if (contentEncryptionKey) {\n derivedKey.handle.free()\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { jwkEncToAskarAlg } from "../../utils/askarKeyTypes.mjs";
2
+ import "../../utils/index.mjs";
3
+ import { Kms } from "@credo-ts/core";
4
+ import { Key } from "@openwallet-foundation/askar-shared";
5
+
6
+ //#region src/kms/crypto/encrypt.ts
7
+ function aeadEncrypt(options) {
8
+ const { key, encryption, data } = options;
9
+ if (!jwkEncToAskarAlg[encryption.algorithm]) throw new Kms.KeyManagementAlgorithmNotSupportedError(`JWA encryption algorithm '${encryption.algorithm}'`, "askar");
10
+ const encrypted = key.aeadEncrypt({
11
+ message: new Uint8Array(data),
12
+ aad: encryption.aad ? new Uint8Array(encryption.aad) : void 0,
13
+ nonce: encryption.iv ? new Uint8Array(encryption.iv) : void 0
14
+ });
15
+ return {
16
+ encrypted: new Uint8Array(encrypted.ciphertext),
17
+ iv: new Uint8Array(encrypted.nonce),
18
+ tag: new Uint8Array(encrypted.tag)
19
+ };
20
+ }
21
+
22
+ //#endregion
23
+ export { aeadEncrypt };
24
+ //# sourceMappingURL=encrypt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt.mjs","names":[],"sources":["../../../src/kms/crypto/encrypt.ts"],"sourcesContent":["import { type AnyUint8Array, Kms } from '@credo-ts/core'\nimport { Key } from '@openwallet-foundation/askar-shared'\nimport { jwkEncToAskarAlg } from '../../utils'\n\nexport type AskarSupportedEncryptionOptions = Kms.KmsEncryptDataEncryption & {\n algorithm: keyof typeof jwkEncToAskarAlg\n}\n\nexport function aeadEncrypt(options: { key: Key; encryption: AskarSupportedEncryptionOptions; data: AnyUint8Array }) {\n const { key, encryption, data } = options\n\n const askarEncryptionAlgorithm = jwkEncToAskarAlg[encryption.algorithm]\n if (!askarEncryptionAlgorithm) {\n throw new Kms.KeyManagementAlgorithmNotSupportedError(`JWA encryption algorithm '${encryption.algorithm}'`, 'askar')\n }\n\n const encrypted = key.aeadEncrypt({\n message: new Uint8Array(data),\n aad: encryption.aad ? new Uint8Array(encryption.aad) : undefined,\n nonce: encryption.iv ? new Uint8Array(encryption.iv) : undefined,\n })\n\n return {\n encrypted: new Uint8Array(encrypted.ciphertext),\n iv: new Uint8Array(encrypted.nonce),\n tag: new Uint8Array(encrypted.tag),\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,YAAY,SAAyF;CACnH,MAAM,EAAE,KAAK,YAAY,SAAS;AAGlC,KAAI,CAD6B,iBAAiB,WAAW,WAE3D,OAAM,IAAI,IAAI,wCAAwC,6BAA6B,WAAW,UAAU,IAAI,QAAQ;CAGtH,MAAM,YAAY,IAAI,YAAY;EAChC,SAAS,IAAI,WAAW,KAAK;EAC7B,KAAK,WAAW,MAAM,IAAI,WAAW,WAAW,IAAI,GAAG;EACvD,OAAO,WAAW,KAAK,IAAI,WAAW,WAAW,GAAG,GAAG;EACxD,CAAC;AAEF,QAAO;EACL,WAAW,IAAI,WAAW,UAAU,WAAW;EAC/C,IAAI,IAAI,WAAW,UAAU,MAAM;EACnC,KAAK,IAAI,WAAW,UAAU,IAAI;EACnC"}
@@ -0,0 +1,19 @@
1
+ import { CryptoBox } from "@openwallet-foundation/askar-shared";
2
+
3
+ //#region src/kms/crypto/randomBytes.ts
4
+ function randomBytes(length) {
5
+ const buffer = new Uint8Array(length);
6
+ const CBOX_NONCE_LENGTH = 24;
7
+ const genCount = Math.ceil(length / CBOX_NONCE_LENGTH);
8
+ const buf = new Uint8Array(genCount * CBOX_NONCE_LENGTH);
9
+ for (let i = 0; i < genCount; i++) {
10
+ const randomBytes$1 = CryptoBox.randomNonce();
11
+ buf.set(randomBytes$1, CBOX_NONCE_LENGTH * i);
12
+ }
13
+ buffer.set(buf.subarray(0, length));
14
+ return buffer;
15
+ }
16
+
17
+ //#endregion
18
+ export { randomBytes };
19
+ //# sourceMappingURL=randomBytes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"randomBytes.mjs","names":["randomBytes"],"sources":["../../../src/kms/crypto/randomBytes.ts"],"sourcesContent":["import type { Uint8ArrayBuffer } from '@credo-ts/core'\nimport { CryptoBox } from '@openwallet-foundation/askar-shared'\n\nexport function randomBytes(length: number): Uint8ArrayBuffer {\n const buffer = new Uint8Array(length)\n const CBOX_NONCE_LENGTH = 24\n\n const genCount = Math.ceil(length / CBOX_NONCE_LENGTH)\n const buf = new Uint8Array(genCount * CBOX_NONCE_LENGTH)\n for (let i = 0; i < genCount; i++) {\n const randomBytes = CryptoBox.randomNonce()\n buf.set(randomBytes, CBOX_NONCE_LENGTH * i)\n }\n buffer.set(buf.subarray(0, length))\n\n return buffer\n}\n"],"mappings":";;;AAGA,SAAgB,YAAY,QAAkC;CAC5D,MAAM,SAAS,IAAI,WAAW,OAAO;CACrC,MAAM,oBAAoB;CAE1B,MAAM,WAAW,KAAK,KAAK,SAAS,kBAAkB;CACtD,MAAM,MAAM,IAAI,WAAW,WAAW,kBAAkB;AACxD,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAAK;EACjC,MAAMA,gBAAc,UAAU,aAAa;AAC3C,MAAI,IAAIA,eAAa,oBAAoB,EAAE;;AAE7C,QAAO,IAAI,IAAI,SAAS,GAAG,OAAO,CAAC;AAEnC,QAAO"}
@@ -0,0 +1,34 @@
1
+ import { AskarStoreManager } from "../AskarStoreManager.mjs";
2
+ import { AgentContext, BaseRecord, BaseRecordConstructor, Query, QueryOptions, StorageService } from "@credo-ts/core";
3
+
4
+ //#region src/storage/AskarStorageService.d.ts
5
+ declare class AskarStorageService<T extends BaseRecord> implements StorageService<T> {
6
+ private askarStoreManager;
7
+ constructor(askarStoreManager: AskarStoreManager);
8
+ private withSession;
9
+ private withTransaction;
10
+ /** @inheritDoc */
11
+ save(agentContext: AgentContext, record: T): Promise<void>;
12
+ /** @inheritDoc */
13
+ update(agentContext: AgentContext, record: T): Promise<void>;
14
+ /**
15
+ * Update the record by id with a lock based on the value returned in `updateCallback`.
16
+ *
17
+ * NOTE that this has no effect when SQLite is used, as SQLite does not support row level
18
+ * locking
19
+ */
20
+ updateByIdWithLock(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>, id: string, updateCallback: (record: T) => Promise<T>): Promise<T>;
21
+ /** @inheritDoc */
22
+ delete(agentContext: AgentContext, record: T): Promise<void>;
23
+ /** @inheritDoc */
24
+ deleteById(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>, id: string): Promise<void>;
25
+ /** @inheritDoc */
26
+ getById(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>, id: string): Promise<T>;
27
+ /** @inheritDoc */
28
+ getAll(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>): Promise<T[]>;
29
+ /** @inheritDoc */
30
+ findByQuery(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>, query: Query<T>, queryOptions?: QueryOptions): Promise<T[]>;
31
+ }
32
+ //#endregion
33
+ export { AskarStorageService };
34
+ //# sourceMappingURL=AskarStorageService.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AskarStorageService.d.mts","names":[],"sources":["../../src/storage/AskarStorageService.ts"],"sourcesContent":[],"mappings":";;;;cAiBa,8BAA8B,uBAAuB,eAAe;;EAApE,WAAA,CAAA,iBAAmB,EACgB,iBADhB;EAAW,QAAA,WAAA;EAAsC,QAAA,eAAA;EACjC;EAWd,IAAA,CAAA,YAAA,EAAA,YAAA,EAAA,MAAA,EAAsB,CAAtB,CAAA,EAAuB,OAAvB,CAAA,IAAA,CAAA;EAAsB;EAAC,MAAA,CAAA,YAAA,EAoBrB,YApBqB,EAAA,MAAA,EAoBC,CApBD,CAAA,EAoBK,OApBL,CAAA,IAAA,CAAA;EAoBrB;;;;;;EAgCP,kBAAA,CAAA,YAAA,EAHX,YAGW,EAAA,WAAA,EAFZ,qBAEY,CAFU,CAEV,CAAA,EAAA,EAAA,EAAA,MAAA,EAAA,cAAA,EAAA,CAAA,MAAA,EAAA,CAAA,EAAA,GAAM,OAAN,CAAc,CAAd,CAAA,CAAA,EACxB,OADwB,CAChB,CADgB,CAAA;EAAc;EAAR,MAAA,CAAA,YAAA,EA+BC,YA/BD,EAAA,MAAA,EA+BuB,CA/BvB,CAAA,EA+BwB,OA/BxB,CAAA,IAAA,CAAA;EACtB;EAAR,UAAA,CAAA,YAAA,EA8Ca,YA9Cb,EAAA,WAAA,EA+CY,qBA/CZ,CA+CkC,CA/ClC,CAAA,EAAA,EAAA,EAAA,MAAA,CAAA,EAiDA,OAjDA,CAAA,IAAA,CAAA;EA8B+B;EAAsB,OAAA,CAAA,YAAA,EAkCrB,YAlCqB,EAAA,WAAA,EAkCM,qBAlCN,CAkC4B,CAlC5B,CAAA,EAAA,EAAA,EAAA,MAAA,CAAA,EAkC6C,OAlC7C,CAkCqD,CAlCrD,CAAA;EAAC;EAgBzC,MAAA,CAAA,YAAA,EAoCkB,YApClB,EAAA,WAAA,EAoC6C,qBApC7C,CAoCmE,CApCnE,CAAA,CAAA,EAoCwE,OApCxE,CAoCgF,CApChF,EAAA,CAAA;EACqB;EAAtB,WAAA,CAAA,YAAA,EA+CC,YA/CD,EAAA,WAAA,EAgDA,qBAhDA,CAgDsB,CAhDtB,CAAA,EAAA,KAAA,EAiDN,KAjDM,CAiDA,CAjDA,CAAA,EAAA,YAAA,CAAA,EAkDE,YAlDF,CAAA,EAmDZ,OAnDY,CAmDJ,CAnDI,EAAA,CAAA"}
@@ -0,0 +1,169 @@
1
+ import { AskarError as AskarError$1 } from "../error/AskarError.mjs";
2
+ import "../error/index.mjs";
3
+ import { askarQueryFromSearchQuery, recordToInstance, transformFromRecordTagValues } from "./utils.mjs";
4
+ import { AskarErrorCode, isAskarError } from "../utils/askarError.mjs";
5
+ import { __decorateMetadata } from "../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
+ import { AskarStoreManager } from "../AskarStoreManager.mjs";
8
+ import { CredoError, JsonTransformer, RecordDuplicateError, RecordNotFoundError, injectable } from "@credo-ts/core";
9
+ import { Scan, Session } from "@openwallet-foundation/askar-shared";
10
+
11
+ //#region src/storage/AskarStorageService.ts
12
+ var _ref;
13
+ let AskarStorageService = class AskarStorageService$1 {
14
+ constructor(askarStoreManager) {
15
+ this.askarStoreManager = askarStoreManager;
16
+ }
17
+ withSession(agentContext, callback) {
18
+ return this.askarStoreManager.withSession(agentContext, callback);
19
+ }
20
+ withTransaction(agentContext, callback) {
21
+ return this.askarStoreManager.withTransaction(agentContext, callback);
22
+ }
23
+ /** @inheritDoc */
24
+ async save(agentContext, record) {
25
+ record.updatedAt = /* @__PURE__ */ new Date();
26
+ const value = JsonTransformer.serialize(record);
27
+ const tags = transformFromRecordTagValues(record.getTags());
28
+ try {
29
+ await this.withSession(agentContext, (session) => session.insert({
30
+ category: record.type,
31
+ name: record.id,
32
+ value,
33
+ tags
34
+ }));
35
+ } catch (error) {
36
+ if (isAskarError(error, AskarErrorCode.Duplicate)) throw new RecordDuplicateError(`Record with id ${record.id} already exists`, { recordType: record.type });
37
+ throw new AskarError$1("Error saving record", { cause: error });
38
+ }
39
+ }
40
+ /** @inheritDoc */
41
+ async update(agentContext, record) {
42
+ record.updatedAt = /* @__PURE__ */ new Date();
43
+ const value = JsonTransformer.serialize(record);
44
+ const tags = transformFromRecordTagValues(record.getTags());
45
+ try {
46
+ await this.withSession(agentContext, (session) => session.replace({
47
+ category: record.type,
48
+ name: record.id,
49
+ value,
50
+ tags
51
+ }));
52
+ } catch (error) {
53
+ if (isAskarError(error, AskarErrorCode.NotFound)) throw new RecordNotFoundError(`record with id ${record.id} not found.`, {
54
+ recordType: record.type,
55
+ cause: error
56
+ });
57
+ throw new AskarError$1("Error updating record", { cause: error });
58
+ }
59
+ }
60
+ /**
61
+ * Update the record by id with a lock based on the value returned in `updateCallback`.
62
+ *
63
+ * NOTE that this has no effect when SQLite is used, as SQLite does not support row level
64
+ * locking
65
+ */
66
+ async updateByIdWithLock(agentContext, recordClass, id, updateCallback) {
67
+ try {
68
+ return await this.withTransaction(agentContext, async (session) => {
69
+ const record = await session.fetch({
70
+ category: recordClass.type,
71
+ name: id,
72
+ forUpdate: true
73
+ });
74
+ if (!record) throw new RecordNotFoundError(`record with id ${id} not found.`, { recordType: recordClass.type });
75
+ const updatedRecord = await updateCallback(recordToInstance(record, recordClass));
76
+ updatedRecord.updatedAt = /* @__PURE__ */ new Date();
77
+ const value = JsonTransformer.serialize(updatedRecord);
78
+ const tags = transformFromRecordTagValues(updatedRecord.getTags());
79
+ await session.replace({
80
+ category: updatedRecord.type,
81
+ name: updatedRecord.id,
82
+ value,
83
+ tags
84
+ });
85
+ return updatedRecord;
86
+ });
87
+ } catch (error) {
88
+ if (error instanceof CredoError) throw error;
89
+ throw new AskarError$1("Error updating record", { cause: error });
90
+ }
91
+ }
92
+ /** @inheritDoc */
93
+ async delete(agentContext, record) {
94
+ try {
95
+ await this.withSession(agentContext, (session) => session.remove({
96
+ category: record.type,
97
+ name: record.id
98
+ }));
99
+ } catch (error) {
100
+ if (isAskarError(error, AskarErrorCode.NotFound)) throw new RecordNotFoundError(`record with id ${record.id} not found.`, {
101
+ recordType: record.type,
102
+ cause: error
103
+ });
104
+ throw new AskarError$1("Error deleting record", { cause: error });
105
+ }
106
+ }
107
+ /** @inheritDoc */
108
+ async deleteById(agentContext, recordClass, id) {
109
+ try {
110
+ await this.withSession(agentContext, (session) => session.remove({
111
+ category: recordClass.type,
112
+ name: id
113
+ }));
114
+ } catch (error) {
115
+ if (isAskarError(error, AskarErrorCode.NotFound)) throw new RecordNotFoundError(`record with id ${id} not found.`, {
116
+ recordType: recordClass.type,
117
+ cause: error
118
+ });
119
+ throw new AskarError$1("Error deleting record", { cause: error });
120
+ }
121
+ }
122
+ /** @inheritDoc */
123
+ async getById(agentContext, recordClass, id) {
124
+ try {
125
+ const record = await this.withSession(agentContext, (session) => session.fetch({
126
+ category: recordClass.type,
127
+ name: id
128
+ }));
129
+ if (!record) throw new RecordNotFoundError(`record with id ${id} not found.`, { recordType: recordClass.type });
130
+ return recordToInstance(record, recordClass);
131
+ } catch (error) {
132
+ if (error instanceof RecordNotFoundError) throw error;
133
+ throw new AskarError$1(`Error getting record ${recordClass.name}`, { cause: error });
134
+ }
135
+ }
136
+ /** @inheritDoc */
137
+ async getAll(agentContext, recordClass) {
138
+ const records = await this.withSession(agentContext, (session) => session.fetchAll({ category: recordClass.type }));
139
+ const instances = [];
140
+ for (const record of records) instances.push(recordToInstance(record, recordClass));
141
+ return instances;
142
+ }
143
+ /** @inheritDoc */
144
+ async findByQuery(agentContext, recordClass, query, queryOptions) {
145
+ const askarQuery = askarQueryFromSearchQuery(query);
146
+ const { store, profile } = await this.askarStoreManager.getInitializedStoreWithProfile(agentContext);
147
+ const scan = new Scan({
148
+ category: recordClass.type,
149
+ store,
150
+ tagFilter: askarQuery,
151
+ profile,
152
+ offset: queryOptions?.offset,
153
+ limit: queryOptions?.limit
154
+ });
155
+ const instances = [];
156
+ try {
157
+ const records = await scan.fetchAll();
158
+ for (const record of records) instances.push(recordToInstance(record, recordClass));
159
+ return instances;
160
+ } catch (error) {
161
+ throw new AskarError$1(`Error executing query. ${error.message}`, { cause: error });
162
+ }
163
+ }
164
+ };
165
+ AskarStorageService = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof AskarStoreManager !== "undefined" && AskarStoreManager) === "function" ? _ref : Object])], AskarStorageService);
166
+
167
+ //#endregion
168
+ export { AskarStorageService };
169
+ //# sourceMappingURL=AskarStorageService.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AskarStorageService.mjs","names":["AskarStorageService","askarStoreManager: AskarStoreManager","AskarError"],"sources":["../../src/storage/AskarStorageService.ts"],"sourcesContent":["import type {\n AgentContext,\n BaseRecord,\n BaseRecordConstructor,\n Query,\n QueryOptions,\n StorageService,\n} from '@credo-ts/core'\nimport { CredoError, injectable, JsonTransformer, RecordDuplicateError, RecordNotFoundError } from '@credo-ts/core'\nimport { Scan, Session } from '@openwallet-foundation/askar-shared'\n\nimport { AskarStoreManager } from '../AskarStoreManager'\nimport { AskarError } from '../error'\nimport { AskarErrorCode, isAskarError } from '../utils/askarError'\nimport { askarQueryFromSearchQuery, recordToInstance, transformFromRecordTagValues } from './utils'\n\n@injectable()\nexport class AskarStorageService<T extends BaseRecord> implements StorageService<T> {\n public constructor(private askarStoreManager: AskarStoreManager) {}\n\n private withSession<Return>(agentContext: AgentContext, callback: (session: Session) => Return) {\n return this.askarStoreManager.withSession(agentContext, callback)\n }\n\n private withTransaction<Return>(agentContext: AgentContext, callback: (session: Session) => Return) {\n return this.askarStoreManager.withTransaction(agentContext, callback)\n }\n\n /** @inheritDoc */\n public async save(agentContext: AgentContext, record: T) {\n record.updatedAt = new Date()\n\n const value = JsonTransformer.serialize(record)\n const tags = transformFromRecordTagValues(record.getTags()) as Record<string, string>\n\n try {\n await this.withSession(agentContext, (session) =>\n session.insert({ category: record.type, name: record.id, value, tags })\n )\n } catch (error) {\n if (isAskarError(error, AskarErrorCode.Duplicate)) {\n throw new RecordDuplicateError(`Record with id ${record.id} already exists`, { recordType: record.type })\n }\n\n throw new AskarError('Error saving record', { cause: error })\n }\n }\n\n /** @inheritDoc */\n public async update(agentContext: AgentContext, record: T): Promise<void> {\n record.updatedAt = new Date()\n\n const value = JsonTransformer.serialize(record)\n const tags = transformFromRecordTagValues(record.getTags()) as Record<string, string>\n\n try {\n await this.withSession(agentContext, (session) =>\n session.replace({ category: record.type, name: record.id, value, tags })\n )\n } catch (error) {\n if (isAskarError(error, AskarErrorCode.NotFound)) {\n throw new RecordNotFoundError(`record with id ${record.id} not found.`, {\n recordType: record.type,\n cause: error,\n })\n }\n\n throw new AskarError('Error updating record', { cause: error })\n }\n }\n\n /**\n * Update the record by id with a lock based on the value returned in `updateCallback`.\n *\n * NOTE that this has no effect when SQLite is used, as SQLite does not support row level\n * locking\n */\n public async updateByIdWithLock(\n agentContext: AgentContext,\n recordClass: BaseRecordConstructor<T>,\n id: string,\n updateCallback: (record: T) => Promise<T>\n ): Promise<T> {\n try {\n const updatedRecord = await this.withTransaction(agentContext, async (session) => {\n const record = await session.fetch({ category: recordClass.type, name: id, forUpdate: true })\n\n if (!record) {\n throw new RecordNotFoundError(`record with id ${id} not found.`, {\n recordType: recordClass.type,\n })\n }\n\n const recordInstance = recordToInstance(record, recordClass)\n const updatedRecord = await updateCallback(recordInstance)\n\n updatedRecord.updatedAt = new Date()\n const value = JsonTransformer.serialize(updatedRecord)\n const tags = transformFromRecordTagValues(updatedRecord.getTags()) as Record<string, string>\n\n await session.replace({ category: updatedRecord.type, name: updatedRecord.id, value, tags })\n\n return updatedRecord\n })\n return updatedRecord\n } catch (error) {\n if (error instanceof CredoError) throw error\n throw new AskarError('Error updating record', { cause: error })\n }\n }\n\n /** @inheritDoc */\n public async delete(agentContext: AgentContext, record: T) {\n try {\n await this.withSession(agentContext, (session) => session.remove({ category: record.type, name: record.id }))\n } catch (error) {\n if (isAskarError(error, AskarErrorCode.NotFound)) {\n throw new RecordNotFoundError(`record with id ${record.id} not found.`, {\n recordType: record.type,\n cause: error,\n })\n }\n throw new AskarError('Error deleting record', { cause: error })\n }\n }\n\n /** @inheritDoc */\n public async deleteById(\n agentContext: AgentContext,\n recordClass: BaseRecordConstructor<T>,\n id: string\n ): Promise<void> {\n try {\n await this.withSession(agentContext, (session) => session.remove({ category: recordClass.type, name: id }))\n } catch (error) {\n if (isAskarError(error, AskarErrorCode.NotFound)) {\n throw new RecordNotFoundError(`record with id ${id} not found.`, {\n recordType: recordClass.type,\n cause: error,\n })\n }\n throw new AskarError('Error deleting record', { cause: error })\n }\n }\n\n /** @inheritDoc */\n public async getById(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>, id: string): Promise<T> {\n try {\n const record = await this.withSession(agentContext, (session) =>\n session.fetch({ category: recordClass.type, name: id })\n )\n if (!record) {\n throw new RecordNotFoundError(`record with id ${id} not found.`, {\n recordType: recordClass.type,\n })\n }\n return recordToInstance(record, recordClass)\n } catch (error) {\n if (error instanceof RecordNotFoundError) throw error\n throw new AskarError(`Error getting record ${recordClass.name}`, { cause: error })\n }\n }\n\n /** @inheritDoc */\n public async getAll(agentContext: AgentContext, recordClass: BaseRecordConstructor<T>): Promise<T[]> {\n const records = await this.withSession(agentContext, (session) => session.fetchAll({ category: recordClass.type }))\n\n const instances = []\n for (const record of records) {\n instances.push(recordToInstance(record, recordClass))\n }\n return instances\n }\n\n /** @inheritDoc */\n public async findByQuery(\n agentContext: AgentContext,\n recordClass: BaseRecordConstructor<T>,\n query: Query<T>,\n queryOptions?: QueryOptions\n ): Promise<T[]> {\n const askarQuery = askarQueryFromSearchQuery(query)\n\n const { store, profile } = await this.askarStoreManager.getInitializedStoreWithProfile(agentContext)\n const scan = new Scan({\n category: recordClass.type,\n store,\n tagFilter: askarQuery,\n profile,\n offset: queryOptions?.offset,\n limit: queryOptions?.limit,\n })\n\n const instances = []\n try {\n const records = await scan.fetchAll()\n for (const record of records) {\n instances.push(recordToInstance(record, recordClass))\n }\n return instances\n } catch (error) {\n throw new AskarError(`Error executing query. ${error.message}`, { cause: error })\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAiBO,gCAAMA,sBAAuE;CAClF,AAAO,YAAY,AAAQC,mBAAsC;EAAtC;;CAE3B,AAAQ,YAAoB,cAA4B,UAAwC;AAC9F,SAAO,KAAK,kBAAkB,YAAY,cAAc,SAAS;;CAGnE,AAAQ,gBAAwB,cAA4B,UAAwC;AAClG,SAAO,KAAK,kBAAkB,gBAAgB,cAAc,SAAS;;;CAIvE,MAAa,KAAK,cAA4B,QAAW;AACvD,SAAO,4BAAY,IAAI,MAAM;EAE7B,MAAM,QAAQ,gBAAgB,UAAU,OAAO;EAC/C,MAAM,OAAO,6BAA6B,OAAO,SAAS,CAAC;AAE3D,MAAI;AACF,SAAM,KAAK,YAAY,eAAe,YACpC,QAAQ,OAAO;IAAE,UAAU,OAAO;IAAM,MAAM,OAAO;IAAI;IAAO;IAAM,CAAC,CACxE;WACM,OAAO;AACd,OAAI,aAAa,OAAO,eAAe,UAAU,CAC/C,OAAM,IAAI,qBAAqB,kBAAkB,OAAO,GAAG,kBAAkB,EAAE,YAAY,OAAO,MAAM,CAAC;AAG3G,SAAM,IAAIC,aAAW,uBAAuB,EAAE,OAAO,OAAO,CAAC;;;;CAKjE,MAAa,OAAO,cAA4B,QAA0B;AACxE,SAAO,4BAAY,IAAI,MAAM;EAE7B,MAAM,QAAQ,gBAAgB,UAAU,OAAO;EAC/C,MAAM,OAAO,6BAA6B,OAAO,SAAS,CAAC;AAE3D,MAAI;AACF,SAAM,KAAK,YAAY,eAAe,YACpC,QAAQ,QAAQ;IAAE,UAAU,OAAO;IAAM,MAAM,OAAO;IAAI;IAAO;IAAM,CAAC,CACzE;WACM,OAAO;AACd,OAAI,aAAa,OAAO,eAAe,SAAS,CAC9C,OAAM,IAAI,oBAAoB,kBAAkB,OAAO,GAAG,cAAc;IACtE,YAAY,OAAO;IACnB,OAAO;IACR,CAAC;AAGJ,SAAM,IAAIA,aAAW,yBAAyB,EAAE,OAAO,OAAO,CAAC;;;;;;;;;CAUnE,MAAa,mBACX,cACA,aACA,IACA,gBACY;AACZ,MAAI;AAqBF,UApBsB,MAAM,KAAK,gBAAgB,cAAc,OAAO,YAAY;IAChF,MAAM,SAAS,MAAM,QAAQ,MAAM;KAAE,UAAU,YAAY;KAAM,MAAM;KAAI,WAAW;KAAM,CAAC;AAE7F,QAAI,CAAC,OACH,OAAM,IAAI,oBAAoB,kBAAkB,GAAG,cAAc,EAC/D,YAAY,YAAY,MACzB,CAAC;IAIJ,MAAM,gBAAgB,MAAM,eADL,iBAAiB,QAAQ,YAAY,CACF;AAE1D,kBAAc,4BAAY,IAAI,MAAM;IACpC,MAAM,QAAQ,gBAAgB,UAAU,cAAc;IACtD,MAAM,OAAO,6BAA6B,cAAc,SAAS,CAAC;AAElE,UAAM,QAAQ,QAAQ;KAAE,UAAU,cAAc;KAAM,MAAM,cAAc;KAAI;KAAO;KAAM,CAAC;AAE5F,WAAO;KACP;WAEK,OAAO;AACd,OAAI,iBAAiB,WAAY,OAAM;AACvC,SAAM,IAAIA,aAAW,yBAAyB,EAAE,OAAO,OAAO,CAAC;;;;CAKnE,MAAa,OAAO,cAA4B,QAAW;AACzD,MAAI;AACF,SAAM,KAAK,YAAY,eAAe,YAAY,QAAQ,OAAO;IAAE,UAAU,OAAO;IAAM,MAAM,OAAO;IAAI,CAAC,CAAC;WACtG,OAAO;AACd,OAAI,aAAa,OAAO,eAAe,SAAS,CAC9C,OAAM,IAAI,oBAAoB,kBAAkB,OAAO,GAAG,cAAc;IACtE,YAAY,OAAO;IACnB,OAAO;IACR,CAAC;AAEJ,SAAM,IAAIA,aAAW,yBAAyB,EAAE,OAAO,OAAO,CAAC;;;;CAKnE,MAAa,WACX,cACA,aACA,IACe;AACf,MAAI;AACF,SAAM,KAAK,YAAY,eAAe,YAAY,QAAQ,OAAO;IAAE,UAAU,YAAY;IAAM,MAAM;IAAI,CAAC,CAAC;WACpG,OAAO;AACd,OAAI,aAAa,OAAO,eAAe,SAAS,CAC9C,OAAM,IAAI,oBAAoB,kBAAkB,GAAG,cAAc;IAC/D,YAAY,YAAY;IACxB,OAAO;IACR,CAAC;AAEJ,SAAM,IAAIA,aAAW,yBAAyB,EAAE,OAAO,OAAO,CAAC;;;;CAKnE,MAAa,QAAQ,cAA4B,aAAuC,IAAwB;AAC9G,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,YAAY,eAAe,YACnD,QAAQ,MAAM;IAAE,UAAU,YAAY;IAAM,MAAM;IAAI,CAAC,CACxD;AACD,OAAI,CAAC,OACH,OAAM,IAAI,oBAAoB,kBAAkB,GAAG,cAAc,EAC/D,YAAY,YAAY,MACzB,CAAC;AAEJ,UAAO,iBAAiB,QAAQ,YAAY;WACrC,OAAO;AACd,OAAI,iBAAiB,oBAAqB,OAAM;AAChD,SAAM,IAAIA,aAAW,wBAAwB,YAAY,QAAQ,EAAE,OAAO,OAAO,CAAC;;;;CAKtF,MAAa,OAAO,cAA4B,aAAqD;EACnG,MAAM,UAAU,MAAM,KAAK,YAAY,eAAe,YAAY,QAAQ,SAAS,EAAE,UAAU,YAAY,MAAM,CAAC,CAAC;EAEnH,MAAM,YAAY,EAAE;AACpB,OAAK,MAAM,UAAU,QACnB,WAAU,KAAK,iBAAiB,QAAQ,YAAY,CAAC;AAEvD,SAAO;;;CAIT,MAAa,YACX,cACA,aACA,OACA,cACc;EACd,MAAM,aAAa,0BAA0B,MAAM;EAEnD,MAAM,EAAE,OAAO,YAAY,MAAM,KAAK,kBAAkB,+BAA+B,aAAa;EACpG,MAAM,OAAO,IAAI,KAAK;GACpB,UAAU,YAAY;GACtB;GACA,WAAW;GACX;GACA,QAAQ,cAAc;GACtB,OAAO,cAAc;GACtB,CAAC;EAEF,MAAM,YAAY,EAAE;AACpB,MAAI;GACF,MAAM,UAAU,MAAM,KAAK,UAAU;AACrC,QAAK,MAAM,UAAU,QACnB,WAAU,KAAK,iBAAiB,QAAQ,YAAY,CAAC;AAEvD,UAAO;WACA,OAAO;AACd,SAAM,IAAIA,aAAW,0BAA0B,MAAM,WAAW,EAAE,OAAO,OAAO,CAAC;;;;kCAzLtF,YAAY"}
@@ -0,0 +1 @@
1
+ import { AskarStorageService } from "./AskarStorageService.mjs";
@@ -0,0 +1 @@
1
+ import { AskarStorageService } from "./AskarStorageService.mjs";
@@ -0,0 +1,8 @@
1
+ import { BaseRecord, BaseRecordConstructor, Query } from "@credo-ts/core";
2
+ import { EntryObject } from "@openwallet-foundation/askar-shared";
3
+
4
+ //#region src/storage/utils.d.ts
5
+ declare function recordToInstance<T extends BaseRecord>(record: EntryObject, recordClass: BaseRecordConstructor<T>): T;
6
+ //#endregion
7
+ export { recordToInstance };
8
+ //# sourceMappingURL=utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/storage/utils.ts"],"sourcesContent":[],"mappings":";;;;iBAIgB,2BAA2B,oBAAoB,0BAA0B,sBAAsB,KAAK"}
@@ -0,0 +1,58 @@
1
+ import { JsonTransformer } from "@credo-ts/core";
2
+
3
+ //#region src/storage/utils.ts
4
+ function recordToInstance(record, recordClass) {
5
+ const instance = JsonTransformer.deserialize(record.value, recordClass);
6
+ instance.id = record.name;
7
+ const tags = record.tags ? transformToRecordTagValues(record.tags) : {};
8
+ instance.replaceTags(tags);
9
+ return instance;
10
+ }
11
+ function transformToRecordTagValues(tags) {
12
+ const transformedTags = {};
13
+ for (const [key, value] of Object.entries(tags)) if (value === "1" && key?.includes(":")) {
14
+ const [tagName, ...tagValues] = key.split(":");
15
+ const tagValue = tagValues.join(":");
16
+ const transformedValue = transformedTags[tagName];
17
+ if (Array.isArray(transformedValue)) transformedTags[tagName] = [...transformedValue, tagValue];
18
+ else transformedTags[tagName] = [tagValue];
19
+ } else if (value === "1" || value === "0") transformedTags[key] = value === "1";
20
+ else if (value === "n__1" || value === "n__0") transformedTags[key] = value === "n__1" ? "1" : "0";
21
+ else transformedTags[key] = value;
22
+ return transformedTags;
23
+ }
24
+ function transformFromRecordTagValues(tags) {
25
+ const transformedTags = {};
26
+ for (const [key, value] of Object.entries(tags)) if (value === null) transformedTags[key] = void 0;
27
+ else if (typeof value === "boolean") transformedTags[key] = value ? "1" : "0";
28
+ else if (value === "1" || value === "0") transformedTags[key] = `n__${value}`;
29
+ else if (Array.isArray(value)) for (const item of value) {
30
+ const tagName = `${key}:${item}`;
31
+ transformedTags[tagName] = "1";
32
+ }
33
+ else transformedTags[key] = value;
34
+ return transformedTags;
35
+ }
36
+ /**
37
+ * Transforms the search query into a wallet query compatible with Askar WQL.
38
+ *
39
+ * The format used by Credo is almost the same as the WQL query, with the exception of
40
+ * the encoding of values, however this is handled by the {@link AskarStorageServiceUtil.transformToRecordTagValues}
41
+ * method.
42
+ */
43
+ function askarQueryFromSearchQuery(query) {
44
+ let { $and, $or, $not, ...tags } = query;
45
+ $and = $and?.map((q) => askarQueryFromSearchQuery(q));
46
+ $or = $or?.map((q) => askarQueryFromSearchQuery(q));
47
+ $not = $not ? askarQueryFromSearchQuery($not) : void 0;
48
+ return {
49
+ ...transformFromRecordTagValues(tags),
50
+ $and,
51
+ $or,
52
+ $not
53
+ };
54
+ }
55
+
56
+ //#endregion
57
+ export { askarQueryFromSearchQuery, recordToInstance, transformFromRecordTagValues };
58
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":["transformedTags: TagsBase","transformedTags: { [key: string]: string | undefined }"],"sources":["../../src/storage/utils.ts"],"sourcesContent":["import type { BaseRecord, BaseRecordConstructor, Query, TagsBase } from '@credo-ts/core'\nimport { JsonTransformer } from '@credo-ts/core'\nimport type { EntryObject } from '@openwallet-foundation/askar-shared'\n\nexport function recordToInstance<T extends BaseRecord>(record: EntryObject, recordClass: BaseRecordConstructor<T>): T {\n const instance = JsonTransformer.deserialize<T>(record.value as string, recordClass)\n instance.id = record.name\n\n const tags = record.tags ? transformToRecordTagValues(record.tags) : {}\n instance.replaceTags(tags)\n\n return instance\n}\n\nexport function transformToRecordTagValues(tags: Record<string, unknown>): TagsBase {\n const transformedTags: TagsBase = {}\n\n for (const [key, value] of Object.entries(tags)) {\n // If the value is a boolean string ('1' or '0')\n // use the boolean val\n if (value === '1' && key?.includes(':')) {\n const [tagName, ...tagValues] = key.split(':')\n const tagValue = tagValues.join(':')\n\n const transformedValue = transformedTags[tagName]\n\n if (Array.isArray(transformedValue)) {\n transformedTags[tagName] = [...transformedValue, tagValue]\n } else {\n transformedTags[tagName] = [tagValue]\n }\n }\n // Transform '1' and '0' to boolean\n else if (value === '1' || value === '0') {\n transformedTags[key] = value === '1'\n }\n // If 1 or 0 is prefixed with 'n__' we need to remove it. This is to prevent\n // casting the value to a boolean\n else if (value === 'n__1' || value === 'n__0') {\n transformedTags[key] = value === 'n__1' ? '1' : '0'\n }\n // Otherwise just use the value\n else {\n transformedTags[key] = value as string\n }\n }\n\n return transformedTags\n}\n\nexport function transformFromRecordTagValues(tags: TagsBase): { [key: string]: string | undefined } {\n const transformedTags: { [key: string]: string | undefined } = {}\n\n for (const [key, value] of Object.entries(tags)) {\n // If the value is of type null we use the value undefined\n // Askar doesn't support null as a value\n if (value === null) {\n transformedTags[key] = undefined\n }\n // If the value is a boolean use the Askar\n // '1' or '0' syntax\n else if (typeof value === 'boolean') {\n transformedTags[key] = value ? '1' : '0'\n }\n // If the value is 1 or 0, we need to add something to the value, otherwise\n // the next time we deserialize the tag values it will be converted to boolean\n else if (value === '1' || value === '0') {\n transformedTags[key] = `n__${value}`\n }\n // If the value is an array we create a tag for each array\n // item (\"tagName:arrayItem\" = \"1\")\n else if (Array.isArray(value)) {\n for (const item of value) {\n const tagName = `${key}:${item}`\n transformedTags[tagName] = '1'\n }\n }\n // Otherwise just use the value\n else {\n transformedTags[key] = value\n }\n }\n\n return transformedTags\n}\n\n/**\n * Transforms the search query into a wallet query compatible with Askar WQL.\n *\n * The format used by Credo is almost the same as the WQL query, with the exception of\n * the encoding of values, however this is handled by the {@link AskarStorageServiceUtil.transformToRecordTagValues}\n * method.\n */\nexport function askarQueryFromSearchQuery<T extends BaseRecord>(query: Query<T>): Record<string, unknown> {\n let { $and, $or, $not, ...tags } = query\n\n $and = ($and as Query<T>[] | undefined)?.map((q) => askarQueryFromSearchQuery(q))\n $or = ($or as Query<T>[] | undefined)?.map((q) => askarQueryFromSearchQuery(q))\n $not = $not ? askarQueryFromSearchQuery($not as Query<T>) : undefined\n\n const askarQuery = {\n ...transformFromRecordTagValues(tags as unknown as TagsBase),\n $and,\n $or,\n $not,\n }\n\n return askarQuery\n}\n"],"mappings":";;;AAIA,SAAgB,iBAAuC,QAAqB,aAA0C;CACpH,MAAM,WAAW,gBAAgB,YAAe,OAAO,OAAiB,YAAY;AACpF,UAAS,KAAK,OAAO;CAErB,MAAM,OAAO,OAAO,OAAO,2BAA2B,OAAO,KAAK,GAAG,EAAE;AACvE,UAAS,YAAY,KAAK;AAE1B,QAAO;;AAGT,SAAgB,2BAA2B,MAAyC;CAClF,MAAMA,kBAA4B,EAAE;AAEpC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,CAG7C,KAAI,UAAU,OAAO,KAAK,SAAS,IAAI,EAAE;EACvC,MAAM,CAAC,SAAS,GAAG,aAAa,IAAI,MAAM,IAAI;EAC9C,MAAM,WAAW,UAAU,KAAK,IAAI;EAEpC,MAAM,mBAAmB,gBAAgB;AAEzC,MAAI,MAAM,QAAQ,iBAAiB,CACjC,iBAAgB,WAAW,CAAC,GAAG,kBAAkB,SAAS;MAE1D,iBAAgB,WAAW,CAAC,SAAS;YAIhC,UAAU,OAAO,UAAU,IAClC,iBAAgB,OAAO,UAAU;UAI1B,UAAU,UAAU,UAAU,OACrC,iBAAgB,OAAO,UAAU,SAAS,MAAM;KAIhD,iBAAgB,OAAO;AAI3B,QAAO;;AAGT,SAAgB,6BAA6B,MAAuD;CAClG,MAAMC,kBAAyD,EAAE;AAEjE,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,CAG7C,KAAI,UAAU,KACZ,iBAAgB,OAAO;UAIhB,OAAO,UAAU,UACxB,iBAAgB,OAAO,QAAQ,MAAM;UAI9B,UAAU,OAAO,UAAU,IAClC,iBAAgB,OAAO,MAAM;UAItB,MAAM,QAAQ,MAAM,CAC3B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,GAAG,IAAI,GAAG;AAC1B,kBAAgB,WAAW;;KAK7B,iBAAgB,OAAO;AAI3B,QAAO;;;;;;;;;AAUT,SAAgB,0BAAgD,OAA0C;CACxG,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS;AAEnC,QAAQ,MAAiC,KAAK,MAAM,0BAA0B,EAAE,CAAC;AACjF,OAAO,KAAgC,KAAK,MAAM,0BAA0B,EAAE,CAAC;AAC/E,QAAO,OAAO,0BAA0B,KAAiB,GAAG;AAS5D,QAPmB;EACjB,GAAG,6BAA6B,KAA4B;EAC5D;EACA;EACA;EACD"}