diff --git a/packages/credential-w3c/src/__tests__/message-handler.test.ts b/packages/credential-w3c/src/__tests__/message-handler.test.ts index 218221b72..3033afe44 100644 --- a/packages/credential-w3c/src/__tests__/message-handler.test.ts +++ b/packages/credential-w3c/src/__tests__/message-handler.test.ts @@ -2,8 +2,7 @@ import { DIDResolutionResult, IAgentContext, ICredentialPlugin, IResolver } from import { Message } from '../../../message-handler/src' import { IContext, MessageTypes, W3cMessageHandler } from '../message-handler.js' import { jest } from '@jest/globals' -import { blake2b } from '@noble/hashes/blake2b' -import { bytesToHex } from '../../../utils/src' +import { computeEntryHash } from '../../../utils/src' describe('@veramo/credential-w3c', () => { const handler = new W3cMessageHandler() @@ -120,7 +119,7 @@ describe('@veramo/credential-w3c', () => { message.addMetaData({ type: 'JWT', value: 'ES256K-R' }) const handled = await handler.handle(message, context) expect(handled.isValid()).toEqual(true) - expect(handled.id).toEqual(bytesToHex(blake2b(vcJwtSecp256k1))) + expect(handled.id).toEqual(computeEntryHash(vcJwtSecp256k1)) expect(handled.raw).toEqual(vcJwtSecp256k1) expect(handled.type).toEqual(MessageTypes.vc) expect(handled.from).toEqual(vcPayloadSecp256k1.iss) @@ -137,7 +136,7 @@ describe('@veramo/credential-w3c', () => { const handled = await handler.handle(message, context) expect(handled.isValid()).toEqual(true) - expect(handled.id).toEqual(bytesToHex(blake2b(vpJwtSecp256k1))) + expect(handled.id).toEqual(computeEntryHash(vpJwtSecp256k1)) expect(handled.raw).toEqual(vpJwtSecp256k1) expect(handled.type).toEqual(MessageTypes.vp) expect(handled.from).toEqual(vpPayloadSecp256k1.iss) @@ -187,7 +186,7 @@ describe('@veramo/credential-w3c', () => { message.addMetaData({ type: 'JWT', value: 'Ed25519' }) const handled = await handler.handle(message, context) expect(handled.isValid()).toEqual(true) - expect(handled.id).toEqual(bytesToHex(blake2b(vcJwtEd25519))) + expect(handled.id).toEqual(computeEntryHash(vcJwtEd25519)) expect(handled.raw).toEqual(vcJwtEd25519) expect(handled.type).toEqual(MessageTypes.vc) expect(handled.from).toEqual(vcPayloadEd25519.iss) @@ -203,7 +202,7 @@ describe('@veramo/credential-w3c', () => { const handled = await handler.handle(message, context) expect(handled.isValid()).toEqual(true) - expect(handled.id).toEqual(bytesToHex(blake2b(vpJwtEd25519))) + expect(handled.id).toEqual(computeEntryHash(vpJwtEd25519)) expect(handled.raw).toEqual(vpJwtEd25519) expect(handled.type).toEqual(MessageTypes.vp) expect(handled.from).toEqual(vpPayloadEd25519.iss) @@ -235,7 +234,7 @@ describe('@veramo/credential-w3c', () => { const handled = await handler.handle(message, context) expect(handled.isValid()).toEqual(true) - expect(handled.id).toEqual(bytesToHex(blake2b(vpMultiAudJwt))) + expect(handled.id).toEqual(computeEntryHash(vpMultiAudJwt)) expect(handled.raw).toEqual(vpMultiAudJwt) expect(handled.type).toEqual(MessageTypes.vp) expect(handled.from).toEqual(vpMultiAudPayload.iss) @@ -274,7 +273,7 @@ describe('@veramo/credential-w3c', () => { const handled = await handler.handle(message, context) expect(handled.isValid()).toEqual(true) - expect(handled.id).toEqual(bytesToHex(blake2b(token))) + expect(handled.id).toEqual(computeEntryHash(token)) expect(handled.raw).toEqual(token) expect(handled.type).toEqual(MessageTypes.vc) expect(handled.from).toEqual('did:ethr:0x54d59e3ffd76917f62db702ac354b17f3842955e') diff --git a/packages/data-store/src/__tests__/entities.test.ts b/packages/data-store/src/__tests__/entities.test.ts index 836bdd2b9..87982ded3 100644 --- a/packages/data-store/src/__tests__/entities.test.ts +++ b/packages/data-store/src/__tests__/entities.test.ts @@ -3,8 +3,7 @@ import { createPresentationEntity } from '../entities/presentation.js' import { Claim, Entities, Identifier, Message } from '../index.js' import { DataSource, In } from 'typeorm' import * as fs from 'fs' -import { bytesToHex } from '../../../utils/src' -import { blake2b } from '@noble/hashes/blake2b' +import { computeEntryHash } from '../../../utils/src' describe('DB entities test', () => { let connection: DataSource @@ -167,7 +166,7 @@ describe('DB entities test', () => { }) it('Message can have externally set id', async () => { - const customId = bytesToHex(blake2b('hash123')) + const customId = computeEntryHash('hash123') const message = new Message() message.type = 'custom' diff --git a/packages/utils/package.json b/packages/utils/package.json index 2a0a56b3f..28b3b05d7 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -12,8 +12,8 @@ "dependencies": { "@ethersproject/signing-key": "^5.7.0", "@ethersproject/transactions": "^5.7.0", + "@ipld/dag-pb": "^4.0.5", "@noble/curves": "^1.1.0", - "@noble/hashes": "^1.3.1", "@veramo/core-types": "workspace:^", "credential-status": "^2.0.5", "cross-fetch": "^4.0.0", @@ -21,6 +21,7 @@ "did-jwt": "^7.2.5", "did-jwt-vc": "^3.2.5", "did-resolver": "^4.1.0", + "ipfs-unixfs": "^11.1.0", "multiformats": "^12.0.1", "uint8arrays": "^4.0.6" }, diff --git a/packages/utils/src/__tests__/credential-utils.test.ts b/packages/utils/src/__tests__/credential-utils.test.ts index b7b34c503..e3c8982fc 100644 --- a/packages/utils/src/__tests__/credential-utils.test.ts +++ b/packages/utils/src/__tests__/credential-utils.test.ts @@ -181,7 +181,7 @@ describe('@veramo/utils credential utils', () => { expect(computeEntryHash(expandedCred)).toEqual(computeEntryHash(serializedCred)) expect(computeEntryHash(jwt)).toEqual(computeEntryHash(serializedCred)) expect(computeEntryHash(serializedCred)).toEqual( - '452f0fb4b876e22867585ee15a6aabb7a6f9ccccf6a2ee664e9f7618737792d64b219fef0792b9d73f3ff756a265083526ecb7313ae4972ef6290b600cacbe88', + 'QmYBWeZCoB1zbJwGou1svfgrq9muVQyy7uzokMfdeSEoHH', ) }) @@ -208,7 +208,7 @@ describe('@veramo/utils credential utils', () => { '{"issuer":{"id":"did:key:z6MkvGFkoFarw7pXRBkKqZKwDcc2L3U4AZC1RtBiceicUHqn"},"@context":["https://www.w3.org/2018/credentials/v1","https://veramo.io/contexts/profile/v1"],"type":["VerifiableCredential","Profile"],"issuanceDate":"2021-11-23T15:06:12.820Z","credentialSubject":{"id":"did:key:z6MkvGFkoFarw7pXRBkKqZKwDcc2L3U4AZC1RtBiceicUHqn","name":"Martin, the great"},"proof":{"type":"Ed25519Signature2018","created":"2021-11-23T15:06:12Z","verificationMethod":"did:key:z6MkvGFkoFarw7pXRBkKqZKwDcc2L3U4AZC1RtBiceicUHqn#z6MkvGFkoFarw7pXRBkKqZKwDcc2L3U4AZC1RtBiceicUHqn","proofPurpose":"assertionMethod","jws":"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..wKMmMZNdIgL_19HYJgpRL9SeKVzYT85S-ZyVdF3IMiaiL8nhX8i48D82TQtuQlTT960h_TOQ18fQFula6QxADA"}}' expect(computeEntryHash(expandedCred)).toEqual(computeEntryHash(serializedCred)) expect(computeEntryHash(serializedCred)).toEqual( - '357436ca94682f2872b26c35a64d52c8e12dfbf86561a8f219cb395482f5978758fb577c927874cdb01189853054433a07eca81a4b3a999be12290021eb9bcbb', + 'QmYeBhqpqiFUcsTS1qz7tkuVCJq8Z4VrrSJsjJc4Q7k9ig', ) }) diff --git a/packages/utils/src/credential-utils.ts b/packages/utils/src/credential-utils.ts index 73f9fa1fb..f1e70b3af 100644 --- a/packages/utils/src/credential-utils.ts +++ b/packages/utils/src/credential-utils.ts @@ -11,9 +11,10 @@ import { } from '@veramo/core-types' import { decodeJWT } from 'did-jwt' import { normalizeCredential, normalizePresentation } from 'did-jwt-vc' -import { blake2b } from '@noble/hashes/blake2b' -import { bytesToHex } from './encodings.js' - +import { sha256 } from 'multiformats/hashes/sha2' +import { code, encode, prepare } from '@ipld/dag-pb' +import { CID } from 'multiformats/cid' +import { UnixFS } from 'ipfs-unixfs' /** * Every Verifiable Credential `@context` property must contain this. * @@ -96,7 +97,18 @@ export function computeEntryHash( } else { hashable = JSON.stringify(input) } - return bytesToHex(blake2b(hashable)) + + const unixfs = new UnixFS({ + type: 'file', + data: new TextEncoder().encode(hashable) + }) + + const bytes = encode(prepare({ Data: unixfs.marshal() })) + const multihash = sha256.digest(bytes) + //@ts-ignore + const cid = CID.create(0, code, multihash).toString() + + return cid } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 323a3b96b..06b3d08a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1638,12 +1638,12 @@ importers: '@ethersproject/transactions': specifier: ^5.7.0 version: 5.7.0 + '@ipld/dag-pb': + specifier: ^4.0.5 + version: 4.0.5 '@noble/curves': specifier: ^1.1.0 version: 1.1.0 - '@noble/hashes': - specifier: ^1.3.1 - version: 1.3.1 '@veramo/core-types': specifier: workspace:^ version: link:../core-types @@ -1665,6 +1665,9 @@ importers: did-resolver: specifier: ^4.1.0 version: 4.1.0 + ipfs-unixfs: + specifier: ^11.1.0 + version: 11.1.0 multiformats: specifier: ^12.0.1 version: 12.0.1 @@ -6621,6 +6624,13 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@ipld/dag-pb@4.0.5: + resolution: {integrity: sha512-El2Jhmv6bWuakhvnw1dl6xOhqLeVhlY8DIAJ06NtZRAoDcOzeGzvOtPzMCszVgCT0EQz+LOctyfgQ5Oszba19A==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dependencies: + multiformats: 12.0.1 + dev: false + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -8060,6 +8070,49 @@ packages: config-chain: 1.1.13 dev: true + /@protobufjs/aspromise@1.1.2: + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + dev: false + + /@protobufjs/base64@1.1.2: + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + dev: false + + /@protobufjs/codegen@2.0.4: + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + dev: false + + /@protobufjs/eventemitter@1.1.0: + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + dev: false + + /@protobufjs/fetch@1.1.0: + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + dev: false + + /@protobufjs/float@1.0.2: + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + dev: false + + /@protobufjs/inquire@1.1.0: + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + dev: false + + /@protobufjs/path@1.1.2: + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + dev: false + + /@protobufjs/pool@1.1.0: + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + dev: false + + /@protobufjs/utf8@1.1.0: + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + dev: false + /@puppeteer/browsers@1.7.1: resolution: {integrity: sha512-nIb8SOBgDEMFY2iS2MdnUZOg2ikcYchRrBoF+wtdjieRFKR2uGRipHY/oFLo+2N6anDualyClPzGywTHRGrLfw==} engines: {node: '>=16.3.0'} @@ -13502,6 +13555,10 @@ packages: /err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + /err-code@3.0.1: + resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==} + dev: false + /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -16094,6 +16151,15 @@ packages: engines: {node: '>= 10'} dev: true + /ipfs-unixfs@11.1.0: + resolution: {integrity: sha512-Lq37nKLJOpRFjx3rcg3y+ZwUxBX7jluKfIt5UPp6wb1L3dP0sj1yaLR0Yg2CdGYvHWyUpZD1iTnT8upL0ToDOw==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dependencies: + err-code: 3.0.1 + protons-runtime: 5.0.2(uint8arraylist@2.4.3) + uint8arraylist: 2.4.3 + dev: false + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -18614,6 +18680,10 @@ packages: yargs: 15.4.1 dev: false + /long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + dev: false + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -21853,10 +21923,38 @@ packages: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: true + /protobufjs@7.2.5: + resolution: {integrity: sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==} + engines: {node: '>=12.0.0'} + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 20.6.2 + long: 5.2.3 + dev: false + /protocols@2.0.1: resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==} dev: true + /protons-runtime@5.0.2(uint8arraylist@2.4.3): + resolution: {integrity: sha512-eKppVrIS5dDh+Y61Yj4bDEOs2sQLQbQGIhr7EBiybPQhIMGBynzVXlYILPWl3Td1GDadobc8qevh5D+JwfG9bw==} + peerDependencies: + uint8arraylist: ^2.3.2 + dependencies: + protobufjs: 7.2.5 + uint8arraylist: 2.4.3 + dev: false + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -24632,6 +24730,13 @@ packages: requiresBuild: true optional: true + /uint8arraylist@2.4.3: + resolution: {integrity: sha512-oEVZr4/GrH87K0kjNce6z8pSCzLEPqHNLNR5sj8cJOySrTP8Vb/pMIbZKLJGhQKxm1TiZ31atNrpn820Pyqpow==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + dependencies: + uint8arrays: 4.0.6 + dev: false + /uint8arrays@3.1.1: resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} dependencies: