From 62bd89c4b08215cb6968955fdfaa01f19460ce76 Mon Sep 17 00:00:00 2001 From: Andraz <69682837+andyv09@users.noreply.github.com> Date: Wed, 28 Jun 2023 14:50:19 +0200 Subject: [PATCH] feat: refactor tests (#286) --------- Co-authored-by: Martin Domajnko Co-authored-by: Martin Domajnko <35891136+martines3000@users.noreply.github.com> --- packages/snap/package.json | 3 +- packages/snap/snap.manifest.json | 2 +- packages/snap/src/utils/keyPair.ts | 7 +- packages/snap/src/utils/params.ts | 6 + packages/snap/src/veramo/setup.ts | 9 + packages/snap/tests/data/constants.ts | 55 + .../data/credentials/examplePayload.json | 18 + packages/snap/tests/data/defaultSnapState.ts | 30 + .../documentResolution/cheqdResolution.json | 60 + .../documentResolution/ebsiResolution.json | 40 + .../documentResolution/ensResolution.json | 48 + .../documentResolution/ethrResolution.json | 26 + .../documentResolution/ionResolution.json | 58 + .../documentResolution/keyResolution.json | 34 + .../documentResolution/webResolution.json | 51 + .../tests/data/identifiers/didEthrMainnet.ts | 35 + .../snap/tests/data/identifiers/didKey.ts | 58 + .../verifiable-credentials/exampleEIP712.json | 131 ++ .../verifiable-credentials/exampleJSONLD.json | 26 + .../verifiable-credentials/exampleJWT.json | 30 + .../verifiable-credentials/exampleJWT_2.json | 26 + .../verifiable-credentials/exampleJWT_3.json | 26 + .../e2e/createVerifiableCredential.spec.ts | 222 ++ .../e2e/createVerifiablePresentation.spec.ts | 242 +++ .../e2e/deleteVerifiableCredentials.spec.ts | 283 +++ .../snap/tests/e2e/getAccountSettings.spec.ts | 44 + .../tests/e2e/getAvailableMethods.spec.ts | 43 + .../tests/e2e/getAvailableVCStores.spec.ts | 43 + packages/snap/tests/e2e/getDID.spec.ts | 100 + .../snap/tests/e2e/getSelectedMethod.spec.ts | 75 + .../snap/tests/e2e/getSnapSettings.spec.ts | 44 + packages/snap/tests/e2e/getVCStore.spec.ts | 42 + .../e2e/queryVerifiableCredentials.spec.ts | 346 +++ packages/snap/tests/e2e/resolveDID.spec.ts | 96 + .../e2e/saveVerifiableCredential.spec.ts | 419 ++++ .../snap/tests/e2e/setCeramicSession.spec.ts | 49 + .../snap/tests/e2e/setCurrentAccount.spec.ts | 98 + packages/snap/tests/e2e/setVCStore.spec.ts | 96 + .../snap/tests/e2e/switchDIDMethod.spec.ts | 75 + .../e2e/validateStoredCeramicSession.spec.ts | 75 + packages/snap/tests/e2e/verifyData.spec.ts | 143 ++ .../{testUtils => helpers}/generateTestVCs.ts | 0 .../snap.mock.ts => helpers/snapMock.ts} | 32 +- packages/snap/tests/rpc/onRpcRequest.spec.ts | 1860 ----------------- packages/snap/tests/testUtils/constants.ts | 539 ----- .../tests/testUtils/didDocumentConstants.ts | 262 --- .../ceramic.spec.ts} | 17 +- .../didUtils.spec.ts => unit/did.spec.ts} | 150 +- packages/snap/tests/unit/keyPair.spec.ts | 3 + .../requestParams.spec.ts} | 178 +- .../stateUtils.spec.ts => unit/state.spec.ts} | 54 +- .../veramo.spec.ts} | 708 +++---- packages/snap/tests/utils/init.spec.ts | 26 - packages/snap/tests/utils/keyPair.spec.ts | 81 - packages/snap/tests/utils/snapUtils.spec.ts | 344 --- .../tests/utils/universalResolver.spec.ts | 67 - packages/snap/tsconfig.json | 5 +- pnpm-lock.yaml | 342 ++- 58 files changed, 3994 insertions(+), 3988 deletions(-) create mode 100644 packages/snap/tests/data/constants.ts create mode 100644 packages/snap/tests/data/credentials/examplePayload.json create mode 100644 packages/snap/tests/data/defaultSnapState.ts create mode 100644 packages/snap/tests/data/documentResolution/cheqdResolution.json create mode 100644 packages/snap/tests/data/documentResolution/ebsiResolution.json create mode 100644 packages/snap/tests/data/documentResolution/ensResolution.json create mode 100644 packages/snap/tests/data/documentResolution/ethrResolution.json create mode 100644 packages/snap/tests/data/documentResolution/ionResolution.json create mode 100644 packages/snap/tests/data/documentResolution/keyResolution.json create mode 100644 packages/snap/tests/data/documentResolution/webResolution.json create mode 100644 packages/snap/tests/data/identifiers/didEthrMainnet.ts create mode 100644 packages/snap/tests/data/identifiers/didKey.ts create mode 100644 packages/snap/tests/data/verifiable-credentials/exampleEIP712.json create mode 100644 packages/snap/tests/data/verifiable-credentials/exampleJSONLD.json create mode 100644 packages/snap/tests/data/verifiable-credentials/exampleJWT.json create mode 100644 packages/snap/tests/data/verifiable-credentials/exampleJWT_2.json create mode 100644 packages/snap/tests/data/verifiable-credentials/exampleJWT_3.json create mode 100644 packages/snap/tests/e2e/createVerifiableCredential.spec.ts create mode 100644 packages/snap/tests/e2e/createVerifiablePresentation.spec.ts create mode 100644 packages/snap/tests/e2e/deleteVerifiableCredentials.spec.ts create mode 100644 packages/snap/tests/e2e/getAccountSettings.spec.ts create mode 100644 packages/snap/tests/e2e/getAvailableMethods.spec.ts create mode 100644 packages/snap/tests/e2e/getAvailableVCStores.spec.ts create mode 100644 packages/snap/tests/e2e/getDID.spec.ts create mode 100644 packages/snap/tests/e2e/getSelectedMethod.spec.ts create mode 100644 packages/snap/tests/e2e/getSnapSettings.spec.ts create mode 100644 packages/snap/tests/e2e/getVCStore.spec.ts create mode 100644 packages/snap/tests/e2e/queryVerifiableCredentials.spec.ts create mode 100644 packages/snap/tests/e2e/resolveDID.spec.ts create mode 100644 packages/snap/tests/e2e/saveVerifiableCredential.spec.ts create mode 100644 packages/snap/tests/e2e/setCeramicSession.spec.ts create mode 100644 packages/snap/tests/e2e/setCurrentAccount.spec.ts create mode 100644 packages/snap/tests/e2e/setVCStore.spec.ts create mode 100644 packages/snap/tests/e2e/switchDIDMethod.spec.ts create mode 100644 packages/snap/tests/e2e/validateStoredCeramicSession.spec.ts create mode 100644 packages/snap/tests/e2e/verifyData.spec.ts rename packages/snap/tests/{testUtils => helpers}/generateTestVCs.ts (100%) rename packages/snap/tests/{testUtils/snap.mock.ts => helpers/snapMock.ts} (80%) delete mode 100644 packages/snap/tests/rpc/onRpcRequest.spec.ts delete mode 100644 packages/snap/tests/testUtils/constants.ts delete mode 100644 packages/snap/tests/testUtils/didDocumentConstants.ts rename packages/snap/tests/{utils/ceramicUtils.spec.ts => unit/ceramic.spec.ts} (91%) rename packages/snap/tests/{utils/didUtils.spec.ts => unit/did.spec.ts} (54%) create mode 100644 packages/snap/tests/unit/keyPair.spec.ts rename packages/snap/tests/{utils/params.spec.ts => unit/requestParams.spec.ts} (80%) rename packages/snap/tests/{utils/stateUtils.spec.ts => unit/state.spec.ts} (70%) rename packages/snap/tests/{utils/veramoUtils.spec.ts => unit/veramo.spec.ts} (65%) delete mode 100644 packages/snap/tests/utils/init.spec.ts delete mode 100644 packages/snap/tests/utils/keyPair.spec.ts delete mode 100644 packages/snap/tests/utils/snapUtils.spec.ts delete mode 100644 packages/snap/tests/utils/universalResolver.spec.ts diff --git a/packages/snap/package.json b/packages/snap/package.json index f63093392..ee2a1abc2 100644 --- a/packages/snap/package.json +++ b/packages/snap/package.json @@ -48,7 +48,7 @@ "lint:prettier": "prettier . --check", "serve": "mm-snap serve", "start": "pnpm mm-snap --version && pnpm build && pnpm serve", - "test": "pnpm jest", + "test": "cross-env NODE_OPTIONS=--max-old-space-size=4096 jest", "test:ci": "pnpm run test --silent --coverage" }, "dependencies": { @@ -73,6 +73,7 @@ "@veramo/core": "5.2.0", "@veramo/credential-eip712": "5.2.0", "@veramo/credential-ld": "5.2.0", + "@veramo/credential-status": "5.1.2", "@veramo/credential-w3c": "5.2.0", "@veramo/did-manager": "5.1.2", "@veramo/did-provider-ethr": "5.1.2", diff --git a/packages/snap/snap.manifest.json b/packages/snap/snap.manifest.json index e6acd3260..11ad7a770 100644 --- a/packages/snap/snap.manifest.json +++ b/packages/snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/blockchain-lab-um/masca.git" }, "source": { - "shasum": "NICVoqT9n64Cp6xUV8A7EpHGuOHqJfNySqeK7Y9zQd4=", + "shasum": "kmCawCo4l4I05DMa8yFbnj3mUEBRE8n1eJK0TgBfm/U=", "location": { "npm": { "filePath": "dist/snap.js", diff --git a/packages/snap/src/utils/keyPair.ts b/packages/snap/src/utils/keyPair.ts index 12fc17c0f..0b9ab01a3 100644 --- a/packages/snap/src/utils/keyPair.ts +++ b/packages/snap/src/utils/keyPair.ts @@ -14,8 +14,8 @@ const methodIndexMapping: Record = { 'did:key': 0, 'did:key:ebsi': 0, 'did:jwk': 1, - 'did:ethr': 0, - 'did:pkh': 0, + 'did:ethr': 3, + 'did:pkh': 3, }; export async function getAccountIndexFromEntropy(params: { @@ -50,11 +50,10 @@ export async function getAddressKeyDeriver( ct = didCoinTypeMappping[method]; } - // FIXME: in future coinType 60 will be rejected when passed to this method const bip44CoinTypeNode = (await snap.request({ method: 'snap_getBip44Entropy', params: { - coinType: ct, + coinType: 1236, }, })) as BIP44CoinTypeNode; return bip44CoinTypeNode; diff --git a/packages/snap/src/utils/params.ts b/packages/snap/src/utils/params.ts index e678eb0dd..5734842e7 100644 --- a/packages/snap/src/utils/params.ts +++ b/packages/snap/src/utils/params.ts @@ -100,7 +100,9 @@ export function isValidCreateVPRequest( if ( 'proofOptions' in param && param.proofOptions !== null && + param.proofOptions !== undefined && param.proofOptions?.domain !== null && + param.proofOptions?.domain !== undefined && typeof param.proofOptions?.domain !== 'string' ) { throw new Error('Domain is not a string'); @@ -110,7 +112,9 @@ export function isValidCreateVPRequest( if ( 'proofOptions' in param && param.proofOptions !== null && + param.proofOptions !== undefined && param.proofOptions?.challenge !== null && + param.proofOptions?.challenge !== undefined && typeof param.proofOptions?.challenge !== 'string' ) { throw new Error('Challenge is not a string'); @@ -120,7 +124,9 @@ export function isValidCreateVPRequest( if ( 'proofOptions' in param && param.proofOptions !== null && + param.proofOptions !== undefined && param.proofOptions?.type !== null && + param.proofOptions?.type !== undefined && typeof param.proofOptions?.type !== 'string' ) { throw new Error('Type is not a string'); diff --git a/packages/snap/src/veramo/setup.ts b/packages/snap/src/veramo/setup.ts index d74262838..36d4728fc 100644 --- a/packages/snap/src/veramo/setup.ts +++ b/packages/snap/src/veramo/setup.ts @@ -16,6 +16,7 @@ import { MetaMaskInpageProvider } from '@metamask/providers'; import type { SnapsGlobalObject } from '@metamask/snaps-types'; import { createAgent, + CredentialStatus, type ICredentialVerifier, type IDataStore, type IDIDManager, @@ -24,6 +25,7 @@ import { type TAgent, } from '@veramo/core'; import { CredentialIssuerEIP712 } from '@veramo/credential-eip712'; +import { CredentialStatusPlugin } from '@veramo/credential-status'; import { CredentialPlugin, type ICredentialIssuer, @@ -121,6 +123,13 @@ export const getAgent = async ( plugins: [ new CredentialPlugin(), new CredentialIssuerEIP712(), + new CredentialStatusPlugin({ + // TODO implement this + StatusList2021Entry: ( + _credential: any, + _didDoc: any + ): Promise => Promise.resolve({ revoked: false }), + }), new KeyManager({ store: new MemoryKeyStore(), kms: { diff --git a/packages/snap/tests/data/constants.ts b/packages/snap/tests/data/constants.ts new file mode 100644 index 000000000..8be7050d5 --- /dev/null +++ b/packages/snap/tests/data/constants.ts @@ -0,0 +1,55 @@ +import { MinimalImportableKey } from '@veramo/core'; + +export const mnemonic = + 'prosper pair similar canoe work humble loud wild aunt reunion olive obscure'; +export const account = '0xb6665128eE91D84590f70c3268765384A9CAfBCd'; +export const account2 = '0x461e557A07AC110BC947F18b3828e26f013dac39'; +export const privateKey = + '0x63ce0077f0d617dbf54d5f335de2983313c6356f25b45e0f68f85bee1490a6ae'; +export const privateKey2 = + '0xb29764680b2a07fa4a762d255e3f689fb5c05cc885e6dfd3de5d5948b5a6b47f'; + +export const importablePrivateKey: MinimalImportableKey = { + kid: 'importedTestKey', + kms: 'snap', + type: 'Secp256k1', + privateKeyHex: privateKey.substring(2), +} as const; + +// Query params + +// For exampleJWT.json +export const jsonPath = + '$[?(@.data.credentialSubject.placeOfBirth == "Asgard")]'; + +// For exampleJWT_2.json & VCs returned by createTestVCs() +export const jsonPath2 = + '$[?(@.data.credentialSubject.accomplishmentType == "Developer Certificate")]'; + +// Errors + +export const resolutionNotFound = { + didDocument: null, + didResolutionMetadata: { + error: 'invalidDid', + message: 'Error: invalidDid: invalid key type', + }, + didDocumentMetadata: {}, +}; + +export const resolutionMethodNotSupported = { + didDocument: null, + didResolutionMetadata: { + error: 'unsupportedDidMethod', + }, + didDocumentMetadata: {}, +}; + +export const resolutionInvalidDID = { + didDocument: null, + didResolutionMetadata: { + error: 'invalidDid', + message: 'Not a valid did:ethr: 0x5:0x123', + }, + didDocumentMetadata: {}, +}; diff --git a/packages/snap/tests/data/credentials/examplePayload.json b/packages/snap/tests/data/credentials/examplePayload.json new file mode 100644 index 000000000..9539400db --- /dev/null +++ b/packages/snap/tests/data/credentials/examplePayload.json @@ -0,0 +1,18 @@ +{ + "type": ["VerifiableCredential", "ProgramCompletionCertificate"], + "credentialSubject": { + "accomplishmentType": "Developer Certificate", + "learnerName": "John Doe", + "achievement": "Certified Solidity Developer 2", + "courseProvider": "https://blockchain-lab.um.si/", + "id": "did:web:example.johndoe.com" + }, + "credentialSchema": { + "id": "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json", + "type": "JsonSchemaValidator2018" + }, + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json" + ] +} diff --git a/packages/snap/tests/data/defaultSnapState.ts b/packages/snap/tests/data/defaultSnapState.ts new file mode 100644 index 000000000..ba2a364cf --- /dev/null +++ b/packages/snap/tests/data/defaultSnapState.ts @@ -0,0 +1,30 @@ +import { MascaAccountState, MascaState } from '@blockchain-lab-um/masca-types'; + +import { getEmptyAccountState } from '../../src/utils/config'; + +const defaultSnapState = (address: string): MascaState => { + const accountState: Record = {}; + accountState[address] = getEmptyAccountState(); + + return { + accountState, + currentAccount: address, + snapConfig: { + dApp: { + disablePopups: false, + friendlyDapps: [], + }, + snap: { + acceptedTerms: true, + }, + }, + }; +}; + +export const getDefaultSnapState = (address: string): MascaState => { + const state = structuredClone(defaultSnapState(address)); + // Session is valid for two years from 15/06/2023 for address 1 only + state.accountState[address].ceramicSession = + 'eyJzZXNzaW9uS2V5U2VlZCI6IlJCcGVUK3poMmFpQ2xOTVBZYXllYUFSSVBhVkZUZ1pZVHU4M3I0dHBpR1U9IiwiY2FjYW8iOnsiaCI6eyJ0IjoiZWlwNDM2MSJ9LCJwIjp7ImRvbWFpbiI6Ik15Tm9kZUFwcCIsImlhdCI6IjIwMjMtMDYtMTVUMTI6Mjc6NTguNzgyWiIsImlzcyI6ImRpZDpwa2g6ZWlwMTU1OjE6MHhiNjY2NTEyOGVlOTFkODQ1OTBmNzBjMzI2ODc2NTM4NGE5Y2FmYmNkIiwiYXVkIjoiZGlkOmtleTp6Nk1rd1V6aW5FU2lGdWo2dlR1bk1kbVYyTWtvbm1ud3lkdlE4Rjlwc0xzQ0xyUW8iLCJ2ZXJzaW9uIjoiMSIsIm5vbmNlIjoiSnFKTTNZcFc5ayIsImV4cCI6IjIwMjUtMDYtMTRUMTI6Mjc6NTguNzgyWiIsInN0YXRlbWVudCI6IkdpdmUgdGhpcyBhcHBsaWNhdGlvbiBhY2Nlc3MgdG8gc29tZSBvZiB5b3VyIGRhdGEgb24gQ2VyYW1pYyIsInJlc291cmNlcyI6WyJjZXJhbWljOi8vKj9tb2RlbD1ranpsNmh2ZnJidzZjNmlkYWFjdzVkNGdjNDgxZW5wYmV1djRmYXQ2NmdqcTFrazlpdnRhbmFkc2UwNzQ2ZGwiXX0sInMiOnsidCI6ImVpcDE5MSIsInMiOiIweGNmZjk0YjgyZmVlODZmZmM0Zjg0ZjYxODFmMDRkNGY2NGY5ZmVmZTAyODgyNzg4Mzc1M2ZhNWFiYThiM2VkYWQ3NzdhZThjMGY3ZTQ0MTIzMzM2ZmQzNjIwNjA5MWE0NmM0MDYxZTQzZGY4OGVhYzdmZWI2ZTE2M2Y5Yzc2OWI3MWMifX19'; + return structuredClone(state); +}; diff --git a/packages/snap/tests/data/documentResolution/cheqdResolution.json b/packages/snap/tests/data/documentResolution/cheqdResolution.json new file mode 100644 index 000000000..7377aa9c9 --- /dev/null +++ b/packages/snap/tests/data/documentResolution/cheqdResolution.json @@ -0,0 +1,60 @@ +{ + "did": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN", + "didDocumentMetadata": { + "created": "2022-04-05T11:49:19Z", + "versionId": "4fa8e367-c70e-533e-babf-3732d9761061" + }, + "didResolutionMetadata": { + "contentType": "application/did+ld+json", + "retrieved": "2023-06-01T09:34:29Z", + "did": { + "didString": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN", + "methodSpecificId": "mainnet:Ps1ysXP2Ae6GBfxNhNQNKN", + "method": "cheqd" + }, + "pattern": "^(did:cheqd:.+)$", + "driverUrl": "http://cheqd-did-driver:8080/1.0/identifiers/$1", + "duration": 1034 + }, + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN", + "verificationMethod": [ + { + "id": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#key1", + "type": "Ed25519VerificationKey2020", + "controller": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN", + "publicKeyMultibase": "z6Mkta7joRuvDh7UnoESdgpr9dDUMh5LvdoECDi3WGrJoscA" + } + ], + "authentication": ["did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#key1"], + "service": [ + { + "id": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#website", + "type": "LinkedDomains", + "serviceEndpoint": ["https://www.cheqd.io"] + }, + { + "id": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#non-fungible-image", + "type": "LinkedDomains", + "serviceEndpoint": [ + "https://gateway.ipfs.io/ipfs/bafybeihetj2ng3d74k7t754atv2s5dk76pcqtvxls6dntef3xa6rax25xe" + ] + }, + { + "id": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#twitter", + "type": "LinkedDomains", + "serviceEndpoint": ["https://twitter.com/cheqd_io"] + }, + { + "id": "did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#linkedin", + "type": "LinkedDomains", + "serviceEndpoint": ["https://www.linkedin.com/company/cheqd-identity/"] + } + ] + }, + "@context": "https://w3id.org/did-resolution/v1" +} diff --git a/packages/snap/tests/data/documentResolution/ebsiResolution.json b/packages/snap/tests/data/documentResolution/ebsiResolution.json new file mode 100644 index 000000000..0ea1f5184 --- /dev/null +++ b/packages/snap/tests/data/documentResolution/ebsiResolution.json @@ -0,0 +1,40 @@ +{ + "did": "did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd", + "didDocumentMetadata": {}, + "didResolutionMetadata": { + "contentType": "application/did+ld+json", + "pattern": "^(did:ebsi:.+)$", + "driverUrl": "https://api-pilot.ebsi.eu/did-registry/v3/identifiers/$1", + "duration": 953, + "did": { + "didString": "did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd", + "methodSpecificId": "ziE2n8Ckhi6ut5Z8Cexrihd", + "method": "ebsi" + } + }, + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "authentication": ["did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#key-1"], + "service": [], + "id": "did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd", + "assertionMethod": ["did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#key-1"], + "verificationMethod": [ + { + "id": "did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#key-1", + "controller": "did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd", + "type": "JsonWebKey2020", + "publicKeyJwk": { + "kty": "EC", + "crv": "secp256k1", + "x": "masUHNuJ0oH0C_e5rLUu5VKwmU2l-a7rrNTqA__afN8", + "y": "UmGGX_WgRFXbw6qTli9xcQ0owtkZVuUGVyM23e8rZe8", + "kid": "did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#keys-1" + } + } + ] + }, + "@context": "https://w3id.org/did-resolution/v1" +} diff --git a/packages/snap/tests/data/documentResolution/ensResolution.json b/packages/snap/tests/data/documentResolution/ensResolution.json new file mode 100644 index 000000000..d79838b8e --- /dev/null +++ b/packages/snap/tests/data/documentResolution/ensResolution.json @@ -0,0 +1,48 @@ +{ + "did": "did:ens:vitalik.eth", + "didDocumentMetadata": {}, + "didResolutionMetadata": { + "pattern": "^(did:ens:.+)$", + "driverUrl": "http://uni-resolver-driver-did-uport:8081/1.0/identifiers/", + "duration": 461, + "did": { + "didString": "did:ens:vitalik.eth", + "methodSpecificId": "vitalik.eth", + "method": "ens" + }, + "contentType": "application/did+ld+json", + "convertedFrom": "application/did+json", + "convertedTo": "application/did+ld+json" + }, + "didDocument": { + "assertionMethod": [ + "did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" + ], + "service": [ + { + "id": "did:ens:vitalik.eth#Web3PublicProfile-0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + "type": "Web3PublicProfile", + "serviceEndpoint": "vitalik.eth" + } + ], + "capabilityDelegation": [ + "did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" + ], + "id": "did:ens:vitalik.eth", + "verificationMethod": [ + { + "id": "did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + "type": "EcdsaSecp256k1RecoveryMethod2020", + "controller": "did:ens:vitalik.eth", + "blockchainAccountId": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155:1" + } + ], + "capabilityInvocation": [ + "did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" + ], + "authentication": [ + "did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" + ] + }, + "@context": "https://w3id.org/did-resolution/v1" +} diff --git a/packages/snap/tests/data/documentResolution/ethrResolution.json b/packages/snap/tests/data/documentResolution/ethrResolution.json new file mode 100644 index 000000000..fe0067931 --- /dev/null +++ b/packages/snap/tests/data/documentResolution/ethrResolution.json @@ -0,0 +1,26 @@ +{ + "didDocumentMetadata": {}, + "didResolutionMetadata": { "contentType": "application/did+ld+json" }, + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/suites/secp256k1recovery-2020/v2" + ], + "id": "did:ethr:0x1:0xb6665128eE91D84590f70c3268765384A9CAfBCd", + "verificationMethod": [ + { + "id": "did:ethr:0x1:0xb6665128eE91D84590f70c3268765384A9CAfBCd#controller", + "type": "EcdsaSecp256k1RecoveryMethod2020", + "controller": "did:ethr:0x1:0xb6665128eE91D84590f70c3268765384A9CAfBCd", + "blockchainAccountId": "eip155:1:0xb6665128eE91D84590f70c3268765384A9CAfBCd" + } + ], + "authentication": [ + "did:ethr:0x1:0xb6665128eE91D84590f70c3268765384A9CAfBCd#controller" + ], + "assertionMethod": [ + "did:ethr:0x1:0xb6665128eE91D84590f70c3268765384A9CAfBCd#controller" + ] + }, + "did": "did:ethr:0x1:0xb6665128eE91D84590f70c3268765384A9CAfBCd#controller" +} diff --git a/packages/snap/tests/data/documentResolution/ionResolution.json b/packages/snap/tests/data/documentResolution/ionResolution.json new file mode 100644 index 000000000..9932b41d2 --- /dev/null +++ b/packages/snap/tests/data/documentResolution/ionResolution.json @@ -0,0 +1,58 @@ +{ + "did": "did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w", + "didDocumentMetadata": { + "method": { + "published": true, + "recoveryCommitment": "EiDKYXZ2MkHRCYDVtXI7ONiTkTdVfs9Tnb-tDDHGXLzmOw", + "updateCommitment": "EiDNk40DUvxCef8_BinU5DDIAhNWE4e7Ea9Q6P7GAbJ6VA" + }, + "canonicalId": "did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w" + }, + "didResolutionMetadata": { + "contentType": "application/did+ld+json", + "pattern": "^(did:ion:(?!test).+)$", + "driverUrl": "http://driver-did-ion:8080/1.0/identifiers/", + "duration": 21, + "did": { + "didString": "did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w", + "methodSpecificId": "EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w", + "method": "ion" + } + }, + "didDocument": { + "id": "did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w", + "@context": [ + "https://www.w3.org/ns/did/v1", + { + "@base": "did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w" + } + ], + "service": [ + { + "id": "#linkedin", + "type": "linkedin", + "serviceEndpoint": "linkedin.com/in/henry-tsai-6b884014" + }, + { + "id": "#github", + "type": "github", + "serviceEndpoint": "github.com/thehenrytsai" + } + ], + "verificationMethod": [ + { + "id": "#someKeyId", + "controller": "did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w", + "type": "EcdsaSecp256k1VerificationKey2019", + "publicKeyJwk": { + "kty": "EC", + "crv": "secp256k1", + "x": "WfY7Px6AgH6x-_dgAoRbg8weYRJA36ON-gQiFnETrqw", + "y": "IzFx3BUGztK0cyDStiunXbrZYYTtKbOUzx16SUK0sAY" + } + } + ], + "authentication": ["#someKeyId"] + }, + "@context": "https://w3id.org/did-resolution/v1" +} diff --git a/packages/snap/tests/data/documentResolution/keyResolution.json b/packages/snap/tests/data/documentResolution/keyResolution.json new file mode 100644 index 000000000..13a4ae7c9 --- /dev/null +++ b/packages/snap/tests/data/documentResolution/keyResolution.json @@ -0,0 +1,34 @@ +{ + "didDocumentMetadata": {}, + "didResolutionMetadata": {}, + "didDocument": { + "id": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG", + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security#EcdsaSecp256k1VerificationKey2019", + "https://w3id.org/security#publicKeyJwk" + ], + "assertionMethod": [ + "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG" + ], + "authentication": [ + "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG" + ], + "verificationMethod": [ + { + "id": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG", + "type": "EcdsaSecp256k1VerificationKey2019", + "controller": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG", + "publicKeyJwk": { + "alg": "ES256K", + "crv": "secp256k1", + "kty": "EC", + "use": "sig", + "x": "mYwjizdBUXEAX_SWUFaBm37kIYv9tFuFzjOnsSVhtps", + "y": "O0F2sHia0CfabHJrh03MaAkzto9ECoXTjmenM-H2vsw" + } + } + ] + }, + "did": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG" +} diff --git a/packages/snap/tests/data/documentResolution/webResolution.json b/packages/snap/tests/data/documentResolution/webResolution.json new file mode 100644 index 000000000..b6c2bdb5b --- /dev/null +++ b/packages/snap/tests/data/documentResolution/webResolution.json @@ -0,0 +1,51 @@ +{ + "did": "did:web:did.actor:alice", + "didDocumentMetadata": {}, + "didResolutionMetadata": { + "contentType": "application/did+ld+json", + "pattern": "^(did:web:.+)$", + "driverUrl": "http://uni-resolver-driver-did-uport:8081/1.0/identifiers/", + "duration": 139, + "did": { + "didString": "did:web:did.actor:alice", + "methodSpecificId": "did.actor:alice", + "method": "web" + } + }, + "didDocument": { + "@context": [ + "https://w3.org/ns/did/v1", + "https://w3id.org/security/suites/ed25519-2018/v1" + ], + "id": "did:web:did.actor:alice", + "publicKey": [ + { + "id": "did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN", + "controller": "did:web:did.actor:alice", + "type": "Ed25519VerificationKey2018", + "publicKeyBase58": "DK7uJiq9PnPnj7AmNZqVBFoLuwTjT1hFPrk6LSjZ2JRz" + } + ], + "authentication": [ + "did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN" + ], + "assertionMethod": [ + "did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN" + ], + "capabilityDelegation": [ + "did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN" + ], + "capabilityInvocation": [ + "did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN" + ], + "keyAgreement": [ + { + "id": "did:web:did.actor:alice#zC8GybikEfyNaausDA4mkT4egP7SNLx2T1d1kujLQbcP6h", + "type": "X25519KeyAgreementKey2019", + "controller": "did:web:did.actor:alice", + "publicKeyBase58": "CaSHXEvLKS6SfN9aBfkVGBpp15jSnaHazqHgLHp8KZ3Y" + } + ] + }, + "@context": "https://w3id.org/did-resolution/v1" +} diff --git a/packages/snap/tests/data/identifiers/didEthrMainnet.ts b/packages/snap/tests/data/identifiers/didEthrMainnet.ts new file mode 100644 index 000000000..e289792ef --- /dev/null +++ b/packages/snap/tests/data/identifiers/didEthrMainnet.ts @@ -0,0 +1,35 @@ +export const exampleDIDEthrMainnet = + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85'; +export const exampleDIDEthrMainnetDocument = { + '@context': [ + 'https://www.w3.org/ns/did/v1', + 'https://w3id.org/security/suites/secp256k1recovery-2020/v2', + ], + id: 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', + verificationMethod: [ + { + id: 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controller', + type: 'EcdsaSecp256k1RecoveryMethod2020', + controller: + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', + blockchainAccountId: + 'eip155:1:0xb6665128eE91D84590f70c3268765384A9CAfBCd', + }, + { + id: 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controllerKey', + type: 'EcdsaSecp256k1VerificationKey2019', + controller: + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', + publicKeyHex: + '0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', + }, + ], + authentication: [ + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controller', + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controllerKey', + ], + assertionMethod: [ + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controller', + 'did:ethr:0x1:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controllerKey', + ], +}; diff --git a/packages/snap/tests/data/identifiers/didKey.ts b/packages/snap/tests/data/identifiers/didKey.ts new file mode 100644 index 000000000..4d1bcecb0 --- /dev/null +++ b/packages/snap/tests/data/identifiers/didKey.ts @@ -0,0 +1,58 @@ +export const exampleDIDKeyIdentifier = + 'zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG'; +export const exampleDIDKey = `did:key:${exampleDIDKeyIdentifier}`; +export const exampleDIDKeyDocument = { + '@context': [ + 'https://www.w3.org/ns/did/v1', + 'https://w3id.org/security#EcdsaSecp256k1VerificationKey2019', + 'https://w3id.org/security#publicKeyJwk', + ], + id: 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + verificationMethod: [ + { + id: 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + type: 'EcdsaSecp256k1VerificationKey2019', + controller: 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + publicKeyJwk: { + alg: 'ES256K', + kty: 'EC', + use: 'sig', + crv: 'secp256k1', + x: 'mYwjizdBUXEAX_SWUFaBm37kIYv9tFuFzjOnsSVhtps', + y: 'O0F2sHia0CfabHJrh03MaAkzto9ECoXTjmenM-H2vsw', + }, + }, + ], + authentication: [ + 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + ], + assertionMethod: [ + 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + ], +}; + +export const exampleDIDKeyImportedAccount = { + controllerKeyId: 'metamask-0xb6665128eE91D84590f70c3268765384A9CAfBCd', + did: 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + keys: [ + { + kid: 'metamask-0xb6665128eE91D84590f70c3268765384A9CAfBCd', + kms: 'snap', + meta: { + algorithms: [ + 'ES256K', + 'ES256K-R', + 'eth_signTransaction', + 'eth_signTypedData', + 'eth_signMessage', + 'eth_rawSign', + ], + }, + publicKeyHex: + '04998c238b37415171005ff4965056819b7ee4218bfdb45b85ce33a7b12561b69b3b4176b0789ad027da6c726b874dcc680933b68f440a85d38e67a733e1f6becc', + type: 'Secp256k1', + }, + ], + provider: 'did:key', + services: [], +}; diff --git a/packages/snap/tests/data/verifiable-credentials/exampleEIP712.json b/packages/snap/tests/data/verifiable-credentials/exampleEIP712.json new file mode 100644 index 000000000..00ac7cdf3 --- /dev/null +++ b/packages/snap/tests/data/verifiable-credentials/exampleEIP712.json @@ -0,0 +1,131 @@ +{ + "type": ["VerifiableCredential", "ProgramCompletionCertificate"], + "credentialSubject": { + "accomplishmentType": "Developer Certificate", + "learnerName": "John Doe", + "achievement": "Certified Solidity Developer 2", + "courseProvider": "https://blockchain-lab.um.si/", + "id": "did:web:example.johndoe.com" + }, + "credentialSchema": { + "id": "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json", + "type": "JsonSchemaValidator2018" + }, + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json" + ], + "issuer": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG", + "issuanceDate": "2023-06-26T07:22:41.573Z", + "proof": { + "verificationMethod": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG#zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG", + "created": "2023-06-26T07:22:41.573Z", + "proofPurpose": "assertionMethod", + "type": "EthereumEip712Signature2021", + "proofValue": "0xc978fd3dbd394a882e4a8c7ae7db59d38425e0b74168ac16b53d02a22f342acf007d524e6d83ce70abbb5c00ac9967926e7efa5fe76407d3e9debcf097b2cd611b", + "eip712": { + "domain": { + "chainId": 1, + "name": "VerifiableCredential", + "version": "1" + }, + "types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + } + ], + "CredentialSchema": [ + { + "name": "id", + "type": "string" + }, + { + "name": "type", + "type": "string" + } + ], + "CredentialSubject": [ + { + "name": "accomplishmentType", + "type": "string" + }, + { + "name": "achievement", + "type": "string" + }, + { + "name": "courseProvider", + "type": "string" + }, + { + "name": "id", + "type": "string" + }, + { + "name": "learnerName", + "type": "string" + } + ], + "Proof": [ + { + "name": "created", + "type": "string" + }, + { + "name": "proofPurpose", + "type": "string" + }, + { + "name": "type", + "type": "string" + }, + { + "name": "verificationMethod", + "type": "string" + } + ], + "VerifiableCredential": [ + { + "name": "@context", + "type": "string[]" + }, + { + "name": "credentialSchema", + "type": "CredentialSchema" + }, + { + "name": "credentialSubject", + "type": "CredentialSubject" + }, + { + "name": "issuanceDate", + "type": "string" + }, + { + "name": "issuer", + "type": "string" + }, + { + "name": "proof", + "type": "Proof" + }, + { + "name": "type", + "type": "string[]" + } + ] + }, + "primaryType": "VerifiableCredential" + } + } +} diff --git a/packages/snap/tests/data/verifiable-credentials/exampleJSONLD.json b/packages/snap/tests/data/verifiable-credentials/exampleJSONLD.json new file mode 100644 index 000000000..02219b8a5 --- /dev/null +++ b/packages/snap/tests/data/verifiable-credentials/exampleJSONLD.json @@ -0,0 +1,26 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json" + ], + "type": ["VerifiableCredential", "CourseCredential"], + "issuer": { + "id": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj", + "name": "tenant" + }, + "issuanceDate": "2021-07-26T01:05:05.152Z", + "credentialSubject": { + "accomplishmentType": "Developer Certificate", + "learnerName": "Bob", + "achievement": "Certified Solidity Developer 2", + "courseProvider": "https://blockchain-lab.um.si/", + "id": "did:ethr:goerli:0xb6665128ee91d84590f70c3268765384a9cafbcd" + }, + "proof": { + "type": "Ed25519Signature2018", + "created": "2021-07-26T01:05:06Z", + "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..o6hnrrWpArG8LQz2Ex_u66_BtuPdp3Hkz18nhNdNhJ7J1k_2lmCCwsNdmo-kNFirZdSIMzqO-V3wEjMDphVEAA", + "proofPurpose": "assertionMethod", + "verificationMethod": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj#z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj" + } +} diff --git a/packages/snap/tests/data/verifiable-credentials/exampleJWT.json b/packages/snap/tests/data/verifiable-credentials/exampleJWT.json new file mode 100644 index 000000000..617589406 --- /dev/null +++ b/packages/snap/tests/data/verifiable-credentials/exampleJWT.json @@ -0,0 +1,30 @@ +{ + "credentialSubject": { + "currentAddress": "2570 24th Street", + "dateOfBirth": "1985-05-25", + "familyName": "Doe", + "gender": "F", + "givenName": "Susan", + "issued": "2020-08-01", + "personalIdentifier": "I1234561", + "placeOfBirth": "Asgard", + "userId": "auth0|6371065f0d58f1830efa260d", + "id": "did:ethr:0x02e85a63c1efa1ce3a4d0c0ad2b784f19f1595008fd50d5d9f61134c372fab68a9" + }, + "issuer": { "id": "did:web:asgard-state.auth0lab.com" }, + "id": "574a0a69-eef6-4da7-846b-19cf77f25558", + "type": ["VerifiableCredential", "IDCard"], + "credentialStatus": { + "id": "https://asgard-state.auth0lab.com/vcs/credential/status/3#105", + "type": "StatusList2021Entry", + "statusPurpose": "revocation", + "statusListIndex": 105, + "statusListCredential": "https://asgard-state.auth0lab.com/vcs/credential/status/3" + }, + "@context": ["https://www.w3.org/2018/credentials/v1"], + "issuanceDate": "2022-11-13T14:59:54.000Z", + "proof": { + "type": "JwtProof2020", + "jwt": "eyJraWQiOiJkaWQ6d2ViOmFzZ2FyZC1zdGF0ZS5hdXRoMGxhYi5jb20jMDRiYTAxMmNhMzhhYTZjYTgyMjAyMzVhYTNkYTdkODVmNzg2ODg0ZTUwMjFmNzM3ODg2MDZhODYyYmMwMTNhNTAyODYyY2U5NmM5Y2U3ZWQ4OTJmZmY2ZDBmZjliZDg5MTg5OWE0MzI3Y2Q0ZDQ0NDY3MTdkMjg5NzhhMDYwYjU1NCIsImFsZyI6IkVTMjU2SyIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiSURDYXJkIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImN1cnJlbnRBZGRyZXNzIjoiMjU3MCAyNHRoIFN0cmVldCIsImRhdGVPZkJpcnRoIjoiMTk4NS0wNS0yNSIsImZhbWlseU5hbWUiOiJEb2UiLCJnZW5kZXIiOiJGIiwiZ2l2ZW5OYW1lIjoiU3VzYW4iLCJpc3N1ZWQiOiIyMDIwLTA4LTAxIiwicGVyc29uYWxJZGVudGlmaWVyIjoiSTEyMzQ1NjEiLCJwbGFjZU9mQmlydGgiOiJBc2dhcmQiLCJ1c2VySWQiOiJhdXRoMHw2MzcxMDY1ZjBkNThmMTgzMGVmYTI2MGQifSwiY3JlZGVudGlhbFN0YXR1cyI6eyJpZCI6Imh0dHBzOi8vYXNnYXJkLXN0YXRlLmF1dGgwbGFiLmNvbS92Y3MvY3JlZGVudGlhbC9zdGF0dXMvMyMxMDUiLCJ0eXBlIjoiU3RhdHVzTGlzdDIwMjFFbnRyeSIsInN0YXR1c1B1cnBvc2UiOiJyZXZvY2F0aW9uIiwic3RhdHVzTGlzdEluZGV4IjoxMDUsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiaHR0cHM6Ly9hc2dhcmQtc3RhdGUuYXV0aDBsYWIuY29tL3Zjcy9jcmVkZW50aWFsL3N0YXR1cy8zIn19LCJzdWIiOiJkaWQ6ZXRocjoweDAyZTg1YTYzYzFlZmExY2UzYTRkMGMwYWQyYjc4NGYxOWYxNTk1MDA4ZmQ1MGQ1ZDlmNjExMzRjMzcyZmFiNjhhOSIsImp0aSI6IjU3NGEwYTY5LWVlZjYtNGRhNy04NDZiLTE5Y2Y3N2YyNTU1OCIsIm5iZiI6MTY2ODM1MTU5NCwiaXNzIjoiZGlkOndlYjphc2dhcmQtc3RhdGUuYXV0aDBsYWIuY29tIn0.dQB8vT_aNtUJfjtjMECNSSSUvEDKOXXueV9mNNdu3gzeTFgsLCsxjkTx2qTGOr-9AC3PZq1aczc9vXRnZ7zKaw" + } +} diff --git a/packages/snap/tests/data/verifiable-credentials/exampleJWT_2.json b/packages/snap/tests/data/verifiable-credentials/exampleJWT_2.json new file mode 100644 index 000000000..cbf9b0ea2 --- /dev/null +++ b/packages/snap/tests/data/verifiable-credentials/exampleJWT_2.json @@ -0,0 +1,26 @@ +{ + "credentialSubject": { + "accomplishmentType": "Developer Certificate", + "learnerName": "John Doe", + "achievement": "Certified Solidity Developer 2", + "courseProvider": "https://blockchain-lab.um.si/", + "id": "did:web:example.johndoe.com" + }, + "issuer": { + "id": "did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG" + }, + "type": ["VerifiableCredential", "ProgramCompletionCertificate"], + "credentialSchema": { + "id": "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json", + "type": "JsonSchemaValidator2018" + }, + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json" + ], + "issuanceDate": "2023-06-25T19:25:47.000Z", + "proof": { + "type": "JwtProof2020", + "jwt": "eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9sZC1jb250ZXh0Lmpzb24iXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlByb2dyYW1Db21wbGV0aW9uQ2VydGlmaWNhdGUiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiYWNjb21wbGlzaG1lbnRUeXBlIjoiRGV2ZWxvcGVyIENlcnRpZmljYXRlIiwibGVhcm5lck5hbWUiOiJKb2huIERvZSIsImFjaGlldmVtZW50IjoiQ2VydGlmaWVkIFNvbGlkaXR5IERldmVsb3BlciAyIiwiY291cnNlUHJvdmlkZXIiOiJodHRwczovL2Jsb2NrY2hhaW4tbGFiLnVtLnNpLyJ9LCJjcmVkZW50aWFsU2NoZW1hIjp7ImlkIjoiaHR0cHM6Ly9iZXRhLmFwaS5zY2hlbWFzLnNlcnRvLmlkL3YxL3B1YmxpYy9wcm9ncmFtLWNvbXBsZXRpb24tY2VydGlmaWNhdGUvMS4wL2pzb24tc2NoZW1hLmpzb24iLCJ0eXBlIjoiSnNvblNjaGVtYVZhbGlkYXRvcjIwMTgifX0sInN1YiI6ImRpZDp3ZWI6ZXhhbXBsZS5qb2huZG9lLmNvbSIsIm5iZiI6MTY4NzcyMTE0NywiaXNzIjoiZGlkOmtleTp6UTNzaFhrQjVFekxaOXJQYTRQcjZuZjR6dVVNY21ONEt5SFpnOUVqYU5uUXp4M1BHIn0.kYYHASC6HSAEaDzQcnGIK4kkjKnYkHClY3IpNsc5QpEcJZXFcb7aWBtYwAHu9unb4Y3OejbJ6xWtu49JsG-9AA" + } +} diff --git a/packages/snap/tests/data/verifiable-credentials/exampleJWT_3.json b/packages/snap/tests/data/verifiable-credentials/exampleJWT_3.json new file mode 100644 index 000000000..eb9f25f8b --- /dev/null +++ b/packages/snap/tests/data/verifiable-credentials/exampleJWT_3.json @@ -0,0 +1,26 @@ +{ + "credentialSubject": { + "accomplishmentType": "Developer Certificate", + "learnerName": "John Doe", + "achievement": "Certified Solidity Developer 2", + "courseProvider": "https://blockchain-lab.um.si/", + "id": "did:web:example.johndoe.com" + }, + "issuer": { + "id": "did:jwk:eyJhbGciOiJFUzI1NksiLCJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsInVzZSI6InNpZyIsIngiOiJlU01sN3BRMWRfX0JzOEpYM1lKb1V3ZVpyTFZ2Zm1TSEUzdG9IenMwbnpjIiwieSI6IlNoajV1M0ZiQkNEZnpEX1lFSW5tVmRWUmdNVU9PdGV3X0lsZEpwT2duaWMifQ" + }, + "type": ["VerifiableCredential", "ProgramCompletionCertificate"], + "credentialSchema": { + "id": "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json", + "type": "JsonSchemaValidator2018" + }, + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json" + ], + "issuanceDate": "2023-06-26T07:05:39.000Z", + "proof": { + "type": "JwtProof2020", + "jwt": "eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9sZC1jb250ZXh0Lmpzb24iXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlByb2dyYW1Db21wbGV0aW9uQ2VydGlmaWNhdGUiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiYWNjb21wbGlzaG1lbnRUeXBlIjoiRGV2ZWxvcGVyIENlcnRpZmljYXRlIiwibGVhcm5lck5hbWUiOiJKb2huIERvZSIsImFjaGlldmVtZW50IjoiQ2VydGlmaWVkIFNvbGlkaXR5IERldmVsb3BlciAyIiwiY291cnNlUHJvdmlkZXIiOiJodHRwczovL2Jsb2NrY2hhaW4tbGFiLnVtLnNpLyJ9LCJjcmVkZW50aWFsU2NoZW1hIjp7ImlkIjoiaHR0cHM6Ly9iZXRhLmFwaS5zY2hlbWFzLnNlcnRvLmlkL3YxL3B1YmxpYy9wcm9ncmFtLWNvbXBsZXRpb24tY2VydGlmaWNhdGUvMS4wL2pzb24tc2NoZW1hLmpzb24iLCJ0eXBlIjoiSnNvblNjaGVtYVZhbGlkYXRvcjIwMTgifX0sInN1YiI6ImRpZDp3ZWI6ZXhhbXBsZS5qb2huZG9lLmNvbSIsIm5iZiI6MTY4Nzc2MzEzOSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZVekkxTmtzaUxDSmpjbllpT2lKelpXTndNalUyYXpFaUxDSnJkSGtpT2lKRlF5SXNJblZ6WlNJNkluTnBaeUlzSW5naU9pSmxVMDFzTjNCUk1XUmZYMEp6T0VwWU0xbEtiMVYzWlZweVRGWjJabTFUU0VVemRHOUllbk13Ym5waklpd2llU0k2SWxOb2FqVjFNMFppUWtORVpucEVYMWxGU1c1dFZtUldVbWROVlU5UGRHVjNYMGxzWkVwd1QyZHVhV01pZlEifQ.E-bso-dJCdyQA_-f94E1ZtUA_iyyLt2t27jz_jN53qU9rvhr0q0YBJFXlNIotvkSqUqG1RuVTgxMZaUcG6iYmw" + } +} diff --git a/packages/snap/tests/e2e/createVerifiableCredential.spec.ts b/packages/snap/tests/e2e/createVerifiableCredential.spec.ts new file mode 100644 index 000000000..3bb9c9162 --- /dev/null +++ b/packages/snap/tests/e2e/createVerifiableCredential.spec.ts @@ -0,0 +1,222 @@ +import { + AvailableMethods, + AvailableVCStores, + QueryVCsRequestResult, +} from '@blockchain-lab-um/masca-types'; +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import type { VerifiableCredential } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account } from '../data/constants'; +import examplePayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +const methods: AvailableMethods[] = ['did:key', 'did:jwk']; +// TODO: Resolve bugs for lds and EthereumEip712Signature2021 +const proofFormats = ['jwt' /* 'lds', */ /* 'EthereumEip712Signature2021' */]; +const proofTypes: Record = { + jwt: 'JwtProof2020', + lds: 'Ed25519Signature2018', + EthereumEip712Signature2021: 'EthereumEip712Signature2021', +}; + +// TODO: Enable ceramic +const stores: AvailableVCStores[][] = [ + ['snap'], + // ['ceramic'], + // ['snap', 'ceramic'], +]; + +describe('createVerifiableCredential', () => { + describe.each(methods)('Using method %s', (method) => { + let snapMock: SnapsGlobalObject & SnapMock; + let issuer: string; + let agent: Agent; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + const switchMethod = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'switchDIDMethod', + params: { + didMethod: method, + }, + }, + })) as Result; + + if (isError(switchMethod)) { + throw new Error(switchMethod.error); + } + + issuer = switchMethod.data; + }); + + beforeEach(async () => { + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + describe.each(proofFormats)('Using Proof Format: %s', (proofFormat) => { + it('Should create a VerifiableCredential', async () => { + const vc = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVC', + params: { + minimalUnsignedCredential: examplePayload, + proofFormat, + }, + }, + })) as Result; + + if (isError(vc)) { + throw new Error(vc.error); + } + + const validity = await agent.verifyCredential({ + credential: vc.data, + }); + expect(validity.verified).toBe(true); + + if (typeof vc.data.issuer === 'string') { + expect(vc.data.issuer).toBe(issuer); + } else { + expect(vc.data.issuer.id).toBe(issuer); + } + expect(vc.data.proof.type).toBe(proofTypes[proofFormat]); + expect.assertions(3); + }); + + it.each(stores)( + 'Should create and save a VerifiableCredential in %s ', + async (store) => { + const vc = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVC', + params: { + minimalUnsignedCredential: examplePayload, + proofFormat, + options: { + save: true, + store, + }, + }, + }, + })) as Result; + + if (isError(vc)) { + throw new Error(vc.error); + } + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data[0].data).toEqual(vc.data); + expect(res.data[0].metadata.store).toEqual([store]); + + expect.assertions(2); + } + ); + }); + + it('Should create a VC without proofFormat option set', async () => { + const vc = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVC', + params: { + minimalUnsignedCredential: examplePayload, + }, + }, + })) as Result; + + if (isError(vc)) { + throw new Error(vc.error); + } + + const validity = await agent.verifyCredential({ credential: vc.data }); + expect(validity.verified).toBe(true); + if (typeof vc.data.issuer === 'string') { + expect(vc.data.issuer).toBe(issuer); + } else { + expect(vc.data.issuer.id).toBe(issuer); + } + expect(vc.data.proof.type).toBe(proofTypes.jwt); + expect.assertions(3); + }); + + it('Should fail creating a VC without minimalUnsignedCredential', async () => { + const vc = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVC', + params: {}, + }, + })) as Result; + + if (!isError(vc)) { + throw new Error('Should have failed'); + } + expect(vc.error).toBe('Error: Invalid CreateVC request'); + expect.assertions(1); + }); + + it('Should fail creating a VC with invalid minimalUnsignedCredential', async () => { + const vc = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVC', + params: { + minimalUnsignedCredential: {}, + }, + }, + })) as Result; + + if (!isError(vc)) { + throw new Error('Should have failed'); + } + expect(vc.error).toBe( + 'TypeError: schema_error: credentialSubject must not be empty' + ); + expect.assertions(1); + }); + }); +}); diff --git a/packages/snap/tests/e2e/createVerifiablePresentation.spec.ts b/packages/snap/tests/e2e/createVerifiablePresentation.spec.ts new file mode 100644 index 000000000..fe93c265f --- /dev/null +++ b/packages/snap/tests/e2e/createVerifiablePresentation.spec.ts @@ -0,0 +1,242 @@ +import { AvailableMethods, ProofOptions } from '@blockchain-lab-um/masca-types'; +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import { VerifiablePresentation } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import exampleVCEIP712 from '../data/verifiable-credentials/exampleEIP712.json'; +import exampleVCJSONLD from '../data/verifiable-credentials/exampleJSONLD.json'; +import exampleVC_2 from '../data/verifiable-credentials/exampleJWT_2.json'; +import exampleVC_3 from '../data/verifiable-credentials/exampleJWT_3.json'; +import exampleVC from '../data/verifiable-credentials/exampleJWT.json'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +const methods: AvailableMethods[] = ['did:key', 'did:jwk']; +// TODO: Resolve bugs for lds and EthereumEip712Signature2021 +const proofFormats = ['jwt' /* 'lds', */ /* 'EthereumEip712Signature2021' */]; +const proofTypes: Record = { + jwt: 'JwtProof2020', + lds: 'Ed25519Signature2018', + EthereumEip712Signature2021: 'EthereumEip712Signature2021', +}; +const options: ProofOptions[] = [ + { domain: undefined, challenge: undefined }, + { domain: 'localhost', challenge: undefined }, + { domain: undefined, challenge: 'test-challenge' }, + { domain: 'localhost-domain', challenge: 'challenge & domain' }, +]; + +const vcs = [ + { title: 'JWT', vcs: [exampleVC] }, + { title: 'JSON-LD', vcs: [exampleVCJSONLD] }, + { title: 'EIP712', vcs: [exampleVCEIP712] }, + { title: '2 JWTs', vcs: [exampleVC, exampleVC_2] }, + { title: '3 JWTs', vcs: [exampleVC, exampleVC_2, exampleVC_3] }, + { title: 'JWT & EIP712', vcs: [exampleVC, exampleVCEIP712] }, + { title: 'JWT & JSON-LD', vcs: [exampleVC, exampleVCJSONLD] }, + { title: 'JSON-LD & EIP712', vcs: [exampleVCJSONLD, exampleVCEIP712] }, +]; + +describe('createVerifiablePresentation', () => { + describe.each(methods)('Using method %s', (method) => { + let snapMock: SnapsGlobalObject & SnapMock; + let issuer: string; + let agent: Agent; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + const switchMethod = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'switchDIDMethod', + params: { + didMethod: method, + }, + }, + })) as Result; + + if (isError(switchMethod)) { + throw new Error(switchMethod.error); + } + + issuer = switchMethod.data; + }); + + beforeEach(async () => { + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + describe.each(proofFormats)('Using Proof Format: %s', (proofFormat) => { + describe.each(vcs)('VC formats in VP: $title', (vc) => { + if (proofFormat === 'jwt') { + it.each(options)( + 'Should create a Verifiable Presentation with domain: `$domain` and challenge: `$challenge`', + async (option) => { + const vp = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVP', + params: { + vcs: vc.vcs, + proofFormat, + proofOptions: option, + }, + }, + })) as Result; + + if (isError(vp)) { + throw new Error(vp.error); + } + + const createdVP = vp.data; + + expect(createdVP).not.toBeNull(); + + const validity = await agent.verifyPresentation({ + presentation: createdVP, + challenge: option?.challenge, + domain: option?.domain, + }); + + expect(validity.verified).toBe(true); + expect(createdVP).not.toBeNull(); + + expect(createdVP.holder).toBe(issuer); + expect(createdVP.proof.type).toBe(proofTypes[proofFormat]); + expect.assertions(5); + } + ); + } else { + it('Should create a Verifiable Presentation without domain or challenge', async () => { + const vp = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVP', + params: { + vcs: vc.vcs, + proofFormat, + }, + }, + })) as Result; + + if (isError(vp)) { + throw new Error(vp.error); + } + + const createdVP = vp.data; + + expect(createdVP).not.toBeNull(); + + const validity = await agent.verifyPresentation({ + presentation: createdVP, + }); + + expect(validity.verified).toBe(true); + expect(createdVP).not.toBeNull(); + + expect(createdVP.holder).toBe(issuer); + expect(createdVP.proof.type).toBe(proofTypes[proofFormat]); + expect.assertions(5); + }); + } + }); + }); + + it('Should create a VP without proofFormat option set', async () => { + const vp = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVP', + params: { + vcs: [exampleVC], + }, + }, + })) as Result; + + if (isError(vp)) { + throw new Error(vp.error); + } + + const createdVP = vp.data; + + expect(createdVP).not.toBeNull(); + + const validity = await agent.verifyPresentation({ + presentation: createdVP, + }); + + expect(validity.verified).toBe(true); + expect(createdVP).not.toBeNull(); + + expect(createdVP.holder).toBe(issuer); + expect(createdVP.proof.type).toBe('JwtProof2020'); + expect.assertions(5); + }); + + it('Should fail creating a VP without any VC', async () => { + const vp = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVP', + params: { + vcs: [], + }, + }, + })) as Result; + + if (!isError(vp)) { + throw new Error('Should have failed'); + } + + expect(vp.error).toBe('Error: Invalid CreateVP request'); + expect.assertions(1); + }); + + it('Should fail creating a VP with invalid VC', async () => { + const vp = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVP', + params: { + vcs: [{ great: 'day' }], + }, + }, + })) as Result; + + if (!isError(vp)) { + throw new Error('Should have failed'); + } + + expect(vp.error).toBe( + `TypeError: Cannot read properties of undefined (reading 'jwt')` + ); + expect.assertions(1); + }); + }); +}); diff --git a/packages/snap/tests/e2e/deleteVerifiableCredentials.spec.ts b/packages/snap/tests/e2e/deleteVerifiableCredentials.spec.ts new file mode 100644 index 000000000..bf2fde130 --- /dev/null +++ b/packages/snap/tests/e2e/deleteVerifiableCredentials.spec.ts @@ -0,0 +1,283 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { IDataManagerSaveResult } from '@blockchain-lab-um/veramo-datamanager'; +import { DIDDataStore } from '@glazed/did-datastore'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import type { VerifiableCredential } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import type { StoredCredentials } from '../../src/veramo/plugins/ceramicDataStore/ceramicDataStore'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account, importablePrivateKey } from '../data/constants'; +import examplePayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createTestVCs } from '../helpers/generateTestVCs'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('deleteVC', () => { + let ceramicData: StoredCredentials; + let snapMock: SnapsGlobalObject & SnapMock; + let agent: Agent; + let generatedVC: VerifiableCredential; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + + // Create test identifier for issuing the VC + const identifier = await agent.didManagerCreate({ + provider: 'did:ethr', + kms: 'snap', + }); + await agent.keyManagerImport(importablePrivateKey); + + // Create test VC + const res = await createTestVCs( + { + agent, + proofFormat: 'jwt', + payload: { + issuer: identifier.did, + ...examplePayload, + }, + }, + { + keyRef: 'importedTestKey', + } + ); + generatedVC = res.exampleVeramoVCJWT; + + // Created VC should be valid + const verifyResult = await agent.verifyCredential({ + credential: generatedVC, + }); + + if (verifyResult.verified === false) { + throw new Error('Generated VC is not valid'); + } + + // Ceramic mock + DIDDataStore.prototype.get = jest + .fn() + .mockImplementation(async (_key, _did) => Promise.resolve(ceramicData)); + + DIDDataStore.prototype.merge = jest.fn().mockImplementation( + async (_key, content, _options?) => + new Promise((resolve) => { + ceramicData = content as StoredCredentials; + resolve(ceramicData); + }) + ); + }); + + beforeEach(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + // Clear stores before each test + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + it('should succeed saving and deleting 1 VC', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + expect(saveRes.data).toEqual([ + { + id: expect.any(String), + store: ['snap'], + }, + ]); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'deleteVC', + params: { + id: saveRes.data[0].id, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual([true, false]); + const result = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + query: {}, + }, + }, + })) as Result; + + if (isError(result)) { + throw new Error(result.error); + } + + expect(result.data).toHaveLength(0); + + expect.assertions(3); + }); + + it('should succeed saving and deleting 1 VC with store', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + expect(saveRes.data).toEqual([ + { + id: expect.any(String), + store: ['snap'], + }, + ]); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'deleteVC', + params: { + id: saveRes.data[0].id, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual([true]); + + const result = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + query: {}, + }, + }, + })) as Result; + + if (isError(result)) { + throw new Error(result.error); + } + + expect(result.data).toHaveLength(0); + + expect.assertions(3); + }); + it('should fail deleting 1 VC with wrong id', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + expect(saveRes.data).toEqual([ + { + id: expect.any(String), + store: ['snap'], + }, + ]); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'deleteVC', + params: { + id: 'wrong_id', + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toHaveLength(0); + + const result = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + query: {}, + }, + }, + })) as Result; + + if (isError(result)) { + throw new Error(result.error); + } + + expect(result.data).toHaveLength(1); + + expect.assertions(3); + }); +}); diff --git a/packages/snap/tests/e2e/getAccountSettings.spec.ts b/packages/snap/tests/e2e/getAccountSettings.spec.ts new file mode 100644 index 000000000..343ef71e3 --- /dev/null +++ b/packages/snap/tests/e2e/getAccountSettings.spec.ts @@ -0,0 +1,44 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('getAccountSettings', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should succeed and return account settings', async () => { + const state = getDefaultSnapState(account); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getAccountSettings', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(state.accountState[account].accountConfig); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/getAvailableMethods.spec.ts b/packages/snap/tests/e2e/getAvailableMethods.spec.ts new file mode 100644 index 000000000..1465f137e --- /dev/null +++ b/packages/snap/tests/e2e/getAvailableMethods.spec.ts @@ -0,0 +1,43 @@ +import { availableMethods } from '@blockchain-lab-um/masca-types'; +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('getAvailableMethods', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should succeed and return available methods', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getAvailableMethods', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(availableMethods); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/getAvailableVCStores.spec.ts b/packages/snap/tests/e2e/getAvailableVCStores.spec.ts new file mode 100644 index 000000000..00df7ce91 --- /dev/null +++ b/packages/snap/tests/e2e/getAvailableVCStores.spec.ts @@ -0,0 +1,43 @@ +import { availableVCStores } from '@blockchain-lab-um/masca-types'; +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('getAvailableVCStores', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should succeed and return available VC stores', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getAvailableVCStores', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(availableVCStores); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/getDID.spec.ts b/packages/snap/tests/e2e/getDID.spec.ts new file mode 100644 index 000000000..6605e43fc --- /dev/null +++ b/packages/snap/tests/e2e/getDID.spec.ts @@ -0,0 +1,100 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +// TODO verify that these are the correct dids (after keypair implementation is complete and final mappings are set) +const methods = [ + { + method: 'did:key', + did: 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + }, + { + method: 'did:jwk', + did: 'did:jwk:eyJhbGciOiJFUzI1NksiLCJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsInVzZSI6InNpZyIsIngiOiJlU01sN3BRMWRfX0JzOEpYM1lKb1V3ZVpyTFZ2Zm1TSEUzdG9IenMwbnpjIiwieSI6IlNoajV1M0ZiQkNEZnpEX1lFSW5tVmRWUmdNVU9PdGV3X0lsZEpwT2duaWMifQ', + }, + { + method: 'did:key:ebsi', + underlyingMethod: 'did:key', + did: 'did:key:zBhBLmYmyihtomRdJJNEKzbPj51o4a3GYFeZoRHSABKUwqdjiQPY2fa6K44b7RtyESctmKyS3RTWEcXJUa749Zst4jc5mtxcVUSFEE7bYmZ6Srqj9Mv9vjCdi369c9W9XDekwR7C6o1YwejLq61PoNaY55CVMA87xD3JWct6rpZPuzdjoNg7fcx', + }, +]; + +describe('getDID', () => { + let snapMock: SnapsGlobalObject & SnapMock; + let agent: Agent; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + beforeEach(async () => { + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + it.todo('Should return correct did:ethr'); + + it.todo('Should return correct did:pkh'); + + it.each(methods)( + 'should return correct identifier for $method', + async (methodObj) => { + const switchMethod = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'switchDIDMethod', + params: { + didMethod: methodObj.method, + }, + }, + })) as Result; + + if (isError(switchMethod)) { + throw new Error(switchMethod.error); + } + + if (methodObj.underlyingMethod) { + expect( + switchMethod.data.substring(0, methodObj.underlyingMethod.length) + ).toBe(methodObj.underlyingMethod); + } else { + expect(switchMethod.data.substring(0, methodObj.method.length)).toBe( + methodObj.method + ); + } + + const did = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getDID', + params: {}, + }, + })) as Result; + + if (isError(did)) { + throw new Error(did.error); + } + + expect(did.data).toBe(methodObj.did); + expect.assertions(2); + } + ); +}); diff --git a/packages/snap/tests/e2e/getSelectedMethod.spec.ts b/packages/snap/tests/e2e/getSelectedMethod.spec.ts new file mode 100644 index 000000000..6cb57c13a --- /dev/null +++ b/packages/snap/tests/e2e/getSelectedMethod.spec.ts @@ -0,0 +1,75 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('getSelectedMethod', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should succeed and return did:ethr', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getSelectedMethod', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toBe('did:ethr'); + + expect.assertions(1); + }); + + it('should succeed and return did:key', async () => { + await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'switchDIDMethod', + params: { + didMethod: 'did:key', + }, + }, + }); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getSelectedMethod', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toBe('did:key'); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/getSnapSettings.spec.ts b/packages/snap/tests/e2e/getSnapSettings.spec.ts new file mode 100644 index 000000000..4d7217e79 --- /dev/null +++ b/packages/snap/tests/e2e/getSnapSettings.spec.ts @@ -0,0 +1,44 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('getSnapSettings', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + const state = getDefaultSnapState(account); + it('should succeed and return snap settings', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getSnapSettings', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(state.snapConfig); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/getVCStore.spec.ts b/packages/snap/tests/e2e/getVCStore.spec.ts new file mode 100644 index 000000000..9cc18b53a --- /dev/null +++ b/packages/snap/tests/e2e/getVCStore.spec.ts @@ -0,0 +1,42 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('getVCStore', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should succeed and return snap', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getVCStore', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual({ ceramic: true, snap: true }); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/queryVerifiableCredentials.spec.ts b/packages/snap/tests/e2e/queryVerifiableCredentials.spec.ts new file mode 100644 index 000000000..e79a1abc1 --- /dev/null +++ b/packages/snap/tests/e2e/queryVerifiableCredentials.spec.ts @@ -0,0 +1,346 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { IDataManagerSaveResult } from '@blockchain-lab-um/veramo-datamanager'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import { VerifiableCredential } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account, importablePrivateKey, jsonPath2 } from '../data/constants'; +import examplePayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createTestVCs } from '../helpers/generateTestVCs'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('queryVerifiableCredentials', () => { + let snapMock: SnapsGlobalObject & SnapMock; + let agent: Agent; + let generatedVC: VerifiableCredential; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + // Create test identifier for issuing the VC + const identifier = await agent.didManagerCreate({ + provider: 'did:ethr', + kms: 'snap', + }); + await agent.keyManagerImport(importablePrivateKey); + + // Create test VC + const res = await createTestVCs( + { + agent, + proofFormat: 'jwt', + payload: { + issuer: identifier.did, + ...examplePayload, + }, + }, + { + keyRef: 'importedTestKey', + } + ); + generatedVC = res.exampleVeramoVCJWT; + + // Created VC should be valid + const verifyResult = await agent.verifyCredential({ + credential: generatedVC, + }); + + if (verifyResult.verified === false) { + throw new Error('Generated VC is not valid'); + } + }); + + beforeEach(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + // Clear stores before each test + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + it('should succeed with empty array', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual([]); + + expect.assertions(1); + }); + + it('should succeed with 1 VC matching query - filter by ID', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + store: ['snap'], + }, + }, + ]; + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + filter: { + type: 'id', + filter: saveRes.data[0].id, + }, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(expectedResult); + + expect.assertions(1); + }); + + it('should succeed with 1 VC matching query - no filter or store', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + store: ['snap'], + }, + }, + ]; + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(expectedResult); + + expect.assertions(1); + }); + + it('should succeed with 1 VC matching query - store defined', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + store: ['snap'], + }, + }, + ]; + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(expectedResult); + + expect.assertions(1); + }); + + it('should succeed with 1 VC matching query - without store', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + }, + }, + ]; + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + options: { returnStore: false }, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(expectedResult); + + expect.assertions(1); + }); + + it('should succeed with 1 VC matching query - filter by JSONPath', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + store: ['snap'], + }, + }, + ]; + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + options: { store: 'snap' }, + filter: { + type: 'JSONPath', + filter: jsonPath2, + }, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(expectedResult); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/resolveDID.spec.ts b/packages/snap/tests/e2e/resolveDID.spec.ts new file mode 100644 index 000000000..7fb425c65 --- /dev/null +++ b/packages/snap/tests/e2e/resolveDID.spec.ts @@ -0,0 +1,96 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import { SnapsGlobalObject } from '@metamask/snaps-types'; +import { DIDResolutionResult } from 'did-resolver'; + +import { onRpcRequest } from '../../src'; +import { Agent, getAgent } from '../../src/veramo/setup'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import cheqdResolution from '../data/documentResolution/cheqdResolution.json'; +import ebsiResolution from '../data/documentResolution/ebsiResolution.json'; +import ensResolution from '../data/documentResolution/ensResolution.json'; +import ethrResolution from '../data/documentResolution/ethrResolution.json'; +import ionResolution from '../data/documentResolution/ionResolution.json'; +import keyResolution from '../data/documentResolution/keyResolution.json'; +import webResolution from '../data/documentResolution/webResolution.json'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('resolveDID', () => { + let snapMock: SnapsGlobalObject & SnapMock; + let ethereumMock: MetaMaskInpageProvider; + let agent: Agent; + + const methods = [ + ebsiResolution, + ensResolution, + ionResolution, + cheqdResolution, + webResolution, + ethrResolution, + keyResolution, + ]; + + beforeAll(async () => { + snapMock = createMockSnap(); + global.snap = snapMock; + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + }); + + it.each(methods)( + 'should resolve a $didResolutionMetadata.did.method method', + async (method) => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'resolveDID', + params: { + did: method.did, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data.didDocument).toEqual(method.didDocument); + expect(res.data.didDocumentMetadata).toEqual(method.didDocumentMetadata); + expect(res.data.didResolutionMetadata.did).toEqual( + method.didResolutionMetadata.did + ); + expect.assertions(3); + } + ); + + it('should return an error if the did is not found', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'resolveDID', + params: { + did: 'did:web:example.com', + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data.didDocument).toBeNull(); + expect(res.data.didDocumentMetadata).toEqual({}); + expect(res.data.didResolutionMetadata.error).toEqual('notFound'); + expect.assertions(3); + }); +}); diff --git a/packages/snap/tests/e2e/saveVerifiableCredential.spec.ts b/packages/snap/tests/e2e/saveVerifiableCredential.spec.ts new file mode 100644 index 000000000..5c2a8a73e --- /dev/null +++ b/packages/snap/tests/e2e/saveVerifiableCredential.spec.ts @@ -0,0 +1,419 @@ +import { + AvailableVCStores, + SaveVCOptions, +} from '@blockchain-lab-um/masca-types'; +import { isError, isSuccess, Result } from '@blockchain-lab-um/utils'; +import { IDataManagerSaveResult } from '@blockchain-lab-um/veramo-datamanager'; +import { DIDDataStore } from '@glazed/did-datastore'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import type { IIdentifier, VerifiableCredential } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import type { StoredCredentials } from '../../src/veramo/plugins/ceramicDataStore/ceramicDataStore'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account, importablePrivateKey } from '../data/constants'; +import examplePayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createTestVCs } from '../helpers/generateTestVCs'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('saveVerifiableCredential', () => { + let ceramicData: StoredCredentials; + let snapMock: SnapsGlobalObject & SnapMock; + let identifier: IIdentifier; + let agent: Agent; + let generatedVC: VerifiableCredential; + + type StoreTests = { + title: string; + options?: SaveVCOptions; + results: string[]; + }; + + const options: StoreTests[] = [ + { title: 'snap', options: { store: 'snap' }, results: ['snap'] }, + { title: 'ceramic', options: { store: 'ceramic' }, results: ['ceramic'] }, + { title: '[snap]', options: { store: ['snap'] }, results: ['snap'] }, + { + title: '[ceramic]', + options: { store: ['ceramic'] }, + results: ['ceramic'], + }, + { + title: 'snap & ceramic', + options: { store: ['snap', 'ceramic'] }, + results: ['snap', 'ceramic'], + }, + { title: 'empty options object', options: {}, results: ['snap'] }, + { + title: 'undefined options object', + options: undefined, + results: ['snap'], + }, + ]; + const stores: AvailableVCStores[][] = [ + ['snap'], + ['ceramic'], + ['snap', 'ceramic'], + ]; + + beforeEach(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + // Clear stores before each test + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + identifier = await agent.didManagerCreate({ + provider: 'did:ethr', + kms: 'snap', + }); + await agent.keyManagerImport(importablePrivateKey); + + // Create test VC + const res = await createTestVCs( + { + agent, + proofFormat: 'jwt', + payload: { + issuer: identifier.did, + ...examplePayload, + }, + }, + { + keyRef: 'importedTestKey', + } + ); + generatedVC = res.exampleVeramoVCJWT; + + // Created VC should be valid + const verifyResult = await agent.verifyCredential({ + credential: generatedVC, + }); + + if (verifyResult.verified === false) { + throw new Error('Generated VC is not valid'); + } + + // Ceramic mock + DIDDataStore.prototype.get = jest + .fn() + .mockImplementation(async (_key, _did) => Promise.resolve(ceramicData)); + + DIDDataStore.prototype.merge = jest.fn().mockImplementation( + async (_key, content, _options?) => + new Promise((resolve) => { + ceramicData = content as StoredCredentials; + resolve(ceramicData); + }) + ); + }); + + it.each(options)( + 'Should save VC in correct store - $title', + async (store) => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: store.options as SaveVCOptions, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + + expect(saveRes.data).toEqual([ + { + id: expect.any(String), + store: store.results, + }, + ]); + expect.assertions(1); + } + ); + + it.each(options)( + 'Should save & query VC in correct store - $title', + async (store) => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: store.options as SaveVCOptions, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + expect(saveRes.data).toEqual([ + { + id: expect.any(String), + store: store.results, + }, + ]); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + store: store.results, + }, + }, + ]; + expect(res.data).toEqual(expectedResult); + + expect.assertions(2); + } + ); + + it.each(stores)( + 'Should succeed saving a JWT string and retrieving whole VC - %s', + async (store) => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC.proof.jwt, + options: { store }, + }, + }, + })) as Result; + + if (isError(saveRes)) { + throw new Error(saveRes.error); + } + expect(saveRes.data).toEqual([ + { + id: expect.any(String), + store: [store], + }, + ]); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + // console.log("String JWT", res.data[0].data) + const expectedResult = [ + { + data: generatedVC, + metadata: { + id: saveRes.data[0].id, + store: [store], + }, + }, + ]; + expect(res.data).toEqual(expectedResult); + + expect.assertions(2); + } + ); + + it('Should fail because store does not exist', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'non-existent-store' }, + }, + }, + })) as Result; + + if (!isError(saveRes)) { + throw new Error('Should have failed'); + } + expect(saveRes.error).toEqual( + 'Error: Store non-existent-store is not supported!' + ); + expect.assertions(1); + }); + + it('should fail saving VC and return false - user denied', async () => { + snapMock.rpcMocks.snap_dialog.mockReturnValue(false); + + let res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isSuccess(res)) { + throw new Error('Should return error'); + } + + expect(res.error).toBe('Error: User rejected the request.'); + + res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'queryVCs', + params: { + query: {}, + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual([]); + + expect.assertions(2); + }); + + it('should throw error because request is not valid', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + options: { store: 'snap' }, + }, + }, + })) as Result; + + if (isSuccess(saveRes)) { + throw new Error('Should return error'); + } + + expect(saveRes.error).toBe('Error: Invalid SaveVC request'); + + expect.assertions(1); + }); + + it('should throw error because request is not valid: store format', async () => { + const saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: 123 }, + }, + }, + })) as Result; + + if (isSuccess(saveRes)) { + throw new Error('Should return error'); + } + + expect(saveRes.error).toBe('Error: Store is invalid format'); + + expect.assertions(1); + }); + it('should throw error because request is not valid: store not supported in array', async () => { + let saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: ['snap', 'snapp'] }, + }, + }, + })) as Result; + + if (isSuccess(saveRes)) { + throw new Error('Should return error'); + } + + expect(saveRes.error).toBe('Error: Store snapp is not supported!'); + + saveRes = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'saveVC', + params: { + verifiableCredential: generatedVC, + options: { store: [] }, + }, + }, + })) as Result; + + if (isSuccess(saveRes)) { + throw new Error('Should return error'); + } + + expect(saveRes.error).toBe('Error: Store is invalid format'); + + expect.assertions(2); + }); +}); diff --git a/packages/snap/tests/e2e/setCeramicSession.spec.ts b/packages/snap/tests/e2e/setCeramicSession.spec.ts new file mode 100644 index 000000000..41ffa0f6d --- /dev/null +++ b/packages/snap/tests/e2e/setCeramicSession.spec.ts @@ -0,0 +1,49 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('setCeramicSession', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should fail to set invalid session', async () => { + const defaultState = getDefaultSnapState(account); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: defaultState, + }); + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'setCeramicSession', + params: { + serializedSession: 'abc', + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(true); + + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/setCurrentAccount.spec.ts b/packages/snap/tests/e2e/setCurrentAccount.spec.ts new file mode 100644 index 000000000..3cb8f9ba4 --- /dev/null +++ b/packages/snap/tests/e2e/setCurrentAccount.spec.ts @@ -0,0 +1,98 @@ +import { isError, isSuccess, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import { VerifiableCredential } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import exampleTestVCPayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('setCurrentAccount', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should succeed setting the current account', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'setCurrentAccount', + params: { + currentAccount: '0x41B821bB31902f05eD241b40A8fa3fE56aA76e68', + }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(true); + expect.assertions(1); + }); + + it('should fail setting the current account - missing current account parameter', async () => { + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'setCurrentAccount', + params: {}, + }, + })) as Result; + + if (isSuccess(res)) { + throw new Error('Should return error'); + } + + expect(res.error).toBe('Error: Invalid SetCurrentAccount request'); + expect.assertions(1); + }); + + it('should fail onRpcRequest - current account not set', async () => { + const defaultState = getDefaultSnapState(account); + defaultState.currentAccount = ''; + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: defaultState, + }); + + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVC', + params: { + minimalUnsignedCredential: exampleTestVCPayload, + proofFormat: 'jwt', + options: { + save: true, + }, + }, + }, + })) as Result; + + if (isSuccess(res)) { + throw new Error('Should return error'); + } + + expect(res.error).toBe( + 'Error: No account set. Use setCurrentAccount to set an account.' + ); + expect.assertions(1); + }); +}); diff --git a/packages/snap/tests/e2e/setVCStore.spec.ts b/packages/snap/tests/e2e/setVCStore.spec.ts new file mode 100644 index 000000000..8105cb8fd --- /dev/null +++ b/packages/snap/tests/e2e/setVCStore.spec.ts @@ -0,0 +1,96 @@ +import { isError, isSuccess, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('setVCStore', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should throw and error when using wrong vcStore', async () => { + let res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'setVCStore', + params: { store: 'ceramicc', value: true }, + }, + })) as Result; + + if (isSuccess(res)) { + throw new Error('Should return error'); + } + + expect(res.error).toBe('Error: Store ceramicc is not supported!'); + + res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'setVCStore', + params: { store: 'ceramic', value: 'tlo' }, + }, + })) as Result; + + if (isSuccess(res)) { + throw new Error('Should return error'); + } + + expect(res.error).toBe('Error: Invalid setVCStore request.'); + + expect.assertions(2); + }); + + it('should succeed toggling ceramic store to true', async () => { + let res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'setVCStore', + params: { store: 'ceramic', value: true }, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toBe(true); + + res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'getVCStore', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual({ ceramic: true, snap: true }); + + expect.assertions(2); + }); +}); diff --git a/packages/snap/tests/e2e/switchDIDMethod.spec.ts b/packages/snap/tests/e2e/switchDIDMethod.spec.ts new file mode 100644 index 000000000..1f21666fd --- /dev/null +++ b/packages/snap/tests/e2e/switchDIDMethod.spec.ts @@ -0,0 +1,75 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +// TODO verify that these are the correct dids (after keypair implementation is complete and final mappings are set) +const methods = [ + { + method: 'did:key', + did: 'did:key:zQ3shXkB5EzLZ9rPa4Pr6nf4zuUMcmN4KyHZg9EjaNnQzx3PG', + }, + { + method: 'did:jwk', + did: 'did:jwk:eyJhbGciOiJFUzI1NksiLCJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsInVzZSI6InNpZyIsIngiOiJlU01sN3BRMWRfX0JzOEpYM1lKb1V3ZVpyTFZ2Zm1TSEUzdG9IenMwbnpjIiwieSI6IlNoajV1M0ZiQkNEZnpEX1lFSW5tVmRWUmdNVU9PdGV3X0lsZEpwT2duaWMifQ', + }, + { + method: 'did:key:ebsi', + underlyingMethod: 'did:key', + did: 'did:key:zBhBLmYmyihtomRdJJNEKzbPj51o4a3GYFeZoRHSABKUwqdjiQPY2fa6K44b7RtyESctmKyS3RTWEcXJUa749Zst4jc5mtxcVUSFEE7bYmZ6Srqj9Mv9vjCdi369c9W9XDekwR7C6o1YwejLq61PoNaY55CVMA87xD3JWct6rpZPuzdjoNg7fcx', + }, +]; + +describe('getDID', () => { + let snapMock: SnapsGlobalObject & SnapMock; + let agent: Agent; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + beforeEach(async () => { + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + it.todo('Should return correct did:ethr'); + + it.todo('Should return correct did:pkh'); + + it.each(methods)( + 'should return correct identifier for $method', + async (methodObj) => { + const switchMethod = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'switchDIDMethod', + params: { + didMethod: methodObj.method, + }, + }, + })) as Result; + + if (isError(switchMethod)) { + throw new Error(switchMethod.error); + } + + expect(switchMethod.data).toEqual(methodObj.did); + } + ); +}); diff --git a/packages/snap/tests/e2e/validateStoredCeramicSession.spec.ts b/packages/snap/tests/e2e/validateStoredCeramicSession.spec.ts new file mode 100644 index 000000000..f286ddd00 --- /dev/null +++ b/packages/snap/tests/e2e/validateStoredCeramicSession.spec.ts @@ -0,0 +1,75 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; + +import { onRpcRequest } from '../../src'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('validateStoredCeramicSession', () => { + let snapMock: SnapsGlobalObject & SnapMock; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + }); + + it('should return true for valid session', async () => { + const defaultState = getDefaultSnapState(account); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: defaultState, + }); + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'validateStoredCeramicSession', + params: {}, + }, + })) as Result; + + if (isError(res)) { + throw new Error(res.error); + } + + expect(res.data).toEqual(true); + + expect.assertions(1); + }); + + it('should fail setting and invalid session string', async () => { + const defaultState = getDefaultSnapState(account); + defaultState.accountState[account].ceramicSession = 'invalid-session'; + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: defaultState, + }); + const res = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'validateStoredCeramicSession', + params: {}, + }, + })) as Result; + + if (!isError(res)) { + throw new Error('Should return error'); + } + + expect(res.error).toEqual('SyntaxError: Unexpected end of data'); + + expect.assertions(1); + }); + + it.todo('Set expired session and return false'); +}); diff --git a/packages/snap/tests/e2e/verifyData.spec.ts b/packages/snap/tests/e2e/verifyData.spec.ts new file mode 100644 index 000000000..a30855de5 --- /dev/null +++ b/packages/snap/tests/e2e/verifyData.spec.ts @@ -0,0 +1,143 @@ +import { isError, Result } from '@blockchain-lab-um/utils'; +import { MetaMaskInpageProvider } from '@metamask/providers'; +import type { SnapsGlobalObject } from '@metamask/snaps-types'; +import { VerifiableCredential, VerifiablePresentation } from '@veramo/core'; + +import { onRpcRequest } from '../../src'; +import { getAgent, type Agent } from '../../src/veramo/setup'; +import { account, importablePrivateKey } from '../data/constants'; +import examplePayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createTestVCs } from '../helpers/generateTestVCs'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +describe('verifyData', () => { + let snapMock: SnapsGlobalObject & SnapMock; + let agent: Agent; + let generatedVC: VerifiableCredential; + + beforeAll(async () => { + snapMock = createMockSnap(); + snapMock.rpcMocks.snap_manageState({ + operation: 'update', + newState: getDefaultSnapState(account), + }); + snapMock.rpcMocks.snap_dialog.mockReturnValue(true); + const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + agent = await getAgent(snapMock, ethereumMock); + global.snap = snapMock; + global.ethereum = snapMock as unknown as MetaMaskInpageProvider; + + // Create test identifier for issuing the VC + const identifier = await agent.didManagerCreate({ + provider: 'did:ethr', + kms: 'snap', + }); + await agent.keyManagerImport(importablePrivateKey); + + // Create test VC + const res = await createTestVCs( + { + agent, + proofFormat: 'jwt', + payload: { + issuer: identifier.did, + ...examplePayload, + }, + }, + { + keyRef: 'importedTestKey', + } + ); + generatedVC = res.exampleVeramoVCJWT; + + // Created VC should be valid + const verifyResult = await agent.verifyCredential({ + credential: generatedVC, + }); + + if (verifyResult.verified === false) { + throw new Error('Generated VC is not valid'); + } + }); + + beforeEach(async () => { + await agent.clear({ options: { store: ['snap', 'ceramic'] } }); + }); + + it('should succeed verifiying a VC', async () => { + const verifyDataResult = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'verifyData', + params: { + credential: generatedVC, + }, + }, + })) as Result; + + if (isError(verifyDataResult)) { + throw new Error(verifyDataResult.error); + } + + expect(verifyDataResult.data).toBe(true); + expect.assertions(1); + }); + + it('should succeed verifying a VP', async () => { + const switchMethodResult = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'switchDIDMethod', + params: { + didMethod: 'did:key', + }, + }, + })) as Result; + + if (isError(switchMethodResult)) { + throw new Error(switchMethodResult.error); + } + + const createVPResult = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'createVP', + params: { + vcs: [generatedVC], + }, + }, + })) as Result; + + if (isError(createVPResult)) { + throw new Error(createVPResult.error); + } + + const verified = (await onRpcRequest({ + origin: 'localhost', + request: { + id: 'test-id', + jsonrpc: '2.0', + method: 'verifyData', + params: { + presentation: createVPResult.data, + }, + }, + })) as Result; + + if (isError(verified)) { + throw new Error(verified.error); + } + + expect(verified.data).toBe(true); + expect.assertions(1); + }); + + it.todo('should succeed verifying a VP with domain and challenge'); +}); diff --git a/packages/snap/tests/testUtils/generateTestVCs.ts b/packages/snap/tests/helpers/generateTestVCs.ts similarity index 100% rename from packages/snap/tests/testUtils/generateTestVCs.ts rename to packages/snap/tests/helpers/generateTestVCs.ts diff --git a/packages/snap/tests/testUtils/snap.mock.ts b/packages/snap/tests/helpers/snapMock.ts similarity index 80% rename from packages/snap/tests/testUtils/snap.mock.ts rename to packages/snap/tests/helpers/snapMock.ts index f11b77d04..3856cfb4a 100644 --- a/packages/snap/tests/testUtils/snap.mock.ts +++ b/packages/snap/tests/helpers/snapMock.ts @@ -3,14 +3,9 @@ import { BIP44CoinTypeNode } from '@metamask/key-tree'; import type { RequestArguments } from '@metamask/providers/dist/BaseProvider'; import type { Maybe } from '@metamask/providers/dist/utils'; import type { SnapsGlobalObject } from '@metamask/snaps-types'; -import { - AlchemyProvider, - Wallet, - type Filter, - type TransactionRequest, -} from 'ethers'; +import { AlchemyProvider, type Filter, type TransactionRequest } from 'ethers'; -import { account, mnemonic, privateKey } from './constants'; +import { account, mnemonic } from '../data/constants'; interface ISnapMock { request(args: RequestArguments): Promise>; @@ -20,11 +15,10 @@ interface SnapManageState { operation: 'get' | 'update' | 'clear'; newState: unknown; } + export class SnapMock implements ISnapMock { private snapState: MascaState | null = null; - private snap: Wallet = new Wallet(privateKey); - private snapManageState(params: SnapManageState): MascaState | null { if (!params) { return null; @@ -52,11 +46,6 @@ export class SnapMock implements ISnapMock { } } - private async snapPersonalSign(data: string[]): Promise { - const signature = await this.snap.signMessage(data[0]); - return signature; - } - private async snapEthCall(data: any[]): Promise { const apiKey = 'NRFBwig_CLVL0WnQLY3dUo8YkPmW-7iN'; const provider = new AlchemyProvider('goerli', apiKey); @@ -98,11 +87,6 @@ export class SnapMock implements ISnapMock { .mockImplementation((params: unknown) => this.snapManageState(params as SnapManageState) ), - personal_sign: jest - .fn() - .mockImplementation(async (data: unknown) => - this.snapPersonalSign(data as string[]) - ), eth_call: jest .fn() .mockImplementation(async (data: unknown) => @@ -113,20 +97,10 @@ export class SnapMock implements ISnapMock { .mockImplementation(async (data: unknown) => this.snapEthLogs(data as any[]) ), - eth_signTypedData_v4: jest - .fn() - .mockImplementation((...params: unknown[]) => { - const { domain, types, message } = JSON.parse(params[1] as string); - - delete types.EIP712Domain; - - return this.snap.signTypedData(domain, types, message); - }), }; request(args: RequestArguments): Promise> { const { method, params } = args; - // @ts-expect-error Args params won't cause an issue // eslint-disable-next-line return this.rpcMocks[method](params); } diff --git a/packages/snap/tests/rpc/onRpcRequest.spec.ts b/packages/snap/tests/rpc/onRpcRequest.spec.ts deleted file mode 100644 index 629c29009..000000000 --- a/packages/snap/tests/rpc/onRpcRequest.spec.ts +++ /dev/null @@ -1,1860 +0,0 @@ -import { - availableMethods, - availableVCStores, - type QueryVCsRequestResult, -} from '@blockchain-lab-um/masca-types'; -import { isError, isSuccess, type Result } from '@blockchain-lab-um/utils'; -import type { IDataManagerSaveResult } from '@blockchain-lab-um/veramo-datamanager'; -import { DIDDataStore } from '@glazed/did-datastore'; -import { MetaMaskInpageProvider } from '@metamask/providers'; -import type { SnapsGlobalObject } from '@metamask/snaps-types'; -import type { - DIDResolutionResult, - IIdentifier, - VerifiableCredential, - VerifiablePresentation, -} from '@veramo/core'; - -import { onRpcRequest } from '../../src'; -import { veramoClearVCs } from '../../src/utils/veramoUtils'; -import type { StoredCredentials } from '../../src/veramo/plugins/ceramicDataStore/ceramicDataStore'; -import { getAgent, type Agent } from '../../src/veramo/setup'; -import { - account, - exampleDID, - exampleDIDDocument, - exampleDIDKey, - exampleTestKey, - exampleTestVCPayload, - exampleVC, - getDefaultSnapState, - jsonPath, -} from '../testUtils/constants'; -import { createTestVCs } from '../testUtils/generateTestVCs'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; - -jest.mock('uuid'); - -describe('onRpcRequest', () => { - let ceramicData: StoredCredentials; - let snapMock: SnapsGlobalObject & SnapMock; - let identifier: IIdentifier; - let agent: Agent; - let exampleVeramoVCJWT: VerifiableCredential; - - beforeEach(() => { - snapMock = createMockSnap(); - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: getDefaultSnapState(), - }); - global.snap = snapMock; - global.ethereum = snapMock as unknown as MetaMaskInpageProvider; - }); - - beforeAll(async () => { - snapMock = createMockSnap(); - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: getDefaultSnapState(), - }); - const ethereumMock = snapMock as unknown as MetaMaskInpageProvider; - agent = await getAgent(snapMock, ethereumMock); - identifier = await agent.didManagerCreate({ - provider: 'did:ethr', - kms: 'snap', - }); - await agent.keyManagerImport(exampleTestKey); - ({ exampleVeramoVCJWT } = await createTestVCs( - { - agent, - proofFormat: 'jwt', - payload: { - issuer: identifier.did, - ...exampleTestVCPayload, - }, - }, - { - keyRef: 'importedTestKey', - } - )); - - // Ceramic mock - DIDDataStore.prototype.get = jest - .fn() - .mockImplementation(async (_key, _did) => Promise.resolve(ceramicData)); - - DIDDataStore.prototype.merge = jest.fn().mockImplementation( - async (_key, content, _options?) => - new Promise((resolve) => { - ceramicData = content as StoredCredentials; - resolve(ceramicData); - }) - ); - }); - - describe('saveVC', () => { - it('should succeed saving 1 VC and return id', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - expect(saveRes.data).toEqual([ - { - id: expect.any(String), - store: ['snap'], - }, - ]); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: ['snap'], - }, - }, - ]; - - expect(res.data).toEqual(expectedResult); - - expect.assertions(2); - }); - - it('should succeed saving 1 VC without store param and return id', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - expect(saveRes.data).toEqual([ - { - id: expect.any(String), - store: ['snap'], - }, - ]); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - query: {}, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: ['snap'], - }, - }, - ]; - - expect(res.data).toEqual(expectedResult); - - expect.assertions(2); - }); - - it('should succeed saving 1 VC in Snap & Ceramic', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - await veramoClearVCs({ - snap: snapMock, - ethereum, - store: 'ceramic', - }); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: ['snap', 'ceramic'] }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - expect(saveRes.data).toEqual([ - { - id: expect.any(String), - store: expect.arrayContaining(['snap', 'ceramic']), - }, - ]); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - query: {}, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: expect.arrayContaining(['snap', 'ceramic']), - }, - }, - ]; - - expect(res.data).toEqual(expectedResult); - - await veramoClearVCs({ - snap: snapMock, - ethereum, - store: 'ceramic', - }); - - expect.assertions(2); - }); - - it('should fail saving VC and return false - user denied', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(false); - - let res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: User rejected the request.'); - - res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - query: {}, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual([]); - - expect.assertions(2); - }); - - it('should return error because store is not supported', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snapp' }, - }, - }, - })) as Result; - - if (isSuccess(saveRes)) { - throw new Error('Should return error'); - } - - expect(saveRes.error).toBe('Error: Store snapp is not supported!'); - - expect.assertions(1); - }); - - it('should throw error because request is not valid', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isSuccess(saveRes)) { - throw new Error('Should return error'); - } - - expect(saveRes.error).toBe('Error: Invalid SaveVC request'); - - expect.assertions(1); - }); - - it('should throw error because request is not valid: store format', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 123 }, - }, - }, - })) as Result; - - if (isSuccess(saveRes)) { - throw new Error('Should return error'); - } - - expect(saveRes.error).toBe('Error: Store is invalid format'); - - expect.assertions(1); - }); - it('should throw error because request is not valid: store not supported in array', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - let saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: ['snap', 'snapp'] }, - }, - }, - })) as Result; - - if (isSuccess(saveRes)) { - throw new Error('Should return error'); - } - - expect(saveRes.error).toBe('Error: Store snapp is not supported!'); - - saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: [] }, - }, - }, - })) as Result; - - if (isSuccess(saveRes)) { - throw new Error('Should return error'); - } - - expect(saveRes.error).toBe('Error: Store is invalid format'); - - expect.assertions(2); - }); - }); - - describe('queryVCs', () => { - it('should succeed with empty array', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual([]); - - expect.assertions(1); - }); - - it('should succeed with 1 VC matching query - filter by ID', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: ['snap'], - }, - }, - ]; - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - filter: { - type: 'id', - filter: saveRes.data[0].id, - }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(expectedResult); - - expect.assertions(1); - }); - - it('should succeed with 1 VC matching query - no filter or store', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: ['snap'], - }, - }, - ]; - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(expectedResult); - - expect.assertions(1); - }); - - it('should succeed with 1 VC matching query - store defined', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: ['snap'], - }, - }, - ]; - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(expectedResult); - - expect.assertions(1); - }); - - it('should succeed with 1 VC matching query - without store', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - }, - }, - ]; - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - options: { returnStore: false }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(expectedResult); - - expect.assertions(1); - }); - - it('should succeed with 1 VC matching query - filter by JSONPath', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const expectedResult = [ - { - data: exampleVeramoVCJWT, - metadata: { - id: saveRes.data[0].id, - store: ['snap'], - }, - }, - ]; - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - options: { store: 'snap' }, - filter: { - type: 'JSONPath', - filter: jsonPath, - }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(expectedResult); - - expect.assertions(1); - }); - }); - - describe('deleteVC', () => { - it('should succeed saving and deleting 1 VC', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - expect(saveRes.data).toEqual([ - { - id: expect.any(String), - store: ['snap'], - }, - ]); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'deleteVC', - params: { - id: saveRes.data[0].id, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual([true]); - const result = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - query: {}, - }, - }, - })) as Result; - - if (isError(result)) { - throw new Error(result.error); - } - - expect(result.data).toHaveLength(0); - - expect.assertions(3); - }); - - it('should succeed saving and deleting 1 VC with store', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - expect(saveRes.data).toEqual([ - { - id: expect.any(String), - store: ['snap'], - }, - ]); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'deleteVC', - params: { - id: saveRes.data[0].id, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual([true]); - - const result = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - query: {}, - }, - }, - })) as Result; - - if (isError(result)) { - throw new Error(result.error); - } - - expect(result.data).toHaveLength(0); - - expect.assertions(3); - }); - it('should fail deleting 1 VC with wrong id', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - expect(saveRes.data).toEqual([ - { - id: expect.any(String), - store: ['snap'], - }, - ]); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'deleteVC', - params: { - id: 'wrong_id', - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toHaveLength(0); - - const result = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: { - query: {}, - }, - }, - })) as Result; - - if (isError(result)) { - throw new Error(result.error); - } - - expect(result.data).toHaveLength(1); - - expect.assertions(3); - }); - }); - - describe('createVP', () => { - it('should succeed creating VP', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - // const agent = await getAgent(snapMock); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const VPRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVP', - params: { - vcs: [exampleVC], - }, - }, - })) as Result; - - if (isError(VPRes)) { - throw new Error(VPRes.error); - } - - const createdVP = VPRes.data; - - expect(createdVP).not.toBeNull(); - - // const verifyResult = (await agent.verifyPresentation({ - // presentation: createdVP, - // })) as IVerifyResult; - - // expect(verifyResult.verified).toBe(true); - - expect.assertions(1); - }); - it('should succeed creating VP with did:key', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - // const agent = await getAgent(snapMock); - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { didMethod: 'did:key' }, - }, - }); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVP', - params: { - vcs: [exampleVC], - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - const createdVP = res.data; - - expect(createdVP).not.toBeNull(); - - // const verifyResult = (await agent.verifyPresentation({ - // presentation: createdVP, - // })) as IVerifyResult; - - // expect(verifyResult.verified).toBe(true); - - expect.assertions(1); - }); - }); - - describe('togglePopups', () => { - it('should succeed toggling popups and return true', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'togglePopups', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBe(true); - - expect.assertions(1); - }); - - it('should fail toggling popups', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(false); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'togglePopups', - params: {}, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: User rejected disabling popups'); - - expect.assertions(1); - }); - }); - - describe('getDID', () => { - it('should succeed returning current did (did:ethr)', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getDID', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(exampleDID); - - expect.assertions(1); - }); - - it('should succeed returning current did (did:key)', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:key', - }, - }, - }); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getDID', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(exampleDIDKey); - - expect.assertions(1); - }); - it('should succeed returning current did (did:pkh)', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:pkh', - }, - }, - }); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getDID', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toInclude('did:pkh:'); - - expect.assertions(1); - }); - it('should succeed returning current did (did:jwk)', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:jwk', - }, - }, - }); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getDID', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toInclude('did:jwk:'); - - expect.assertions(1); - }); - }); - - describe('switchDIDMethod', () => { - it('should succeed switching method to did:key and return did', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:key', - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBe( - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik' - ); - - expect.assertions(1); - }); - - it('should succeed switching method to did:key:ebsi and return did', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:key:ebsi', - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBe( - 'did:key:zBhBLmYmyihtomRdJJNEKzbPj51o4a3GYFeZoRHSABKUwqdjiQPY2f6geyy4qmWsbqyd1juUr3tNwKrGCgftPAwFbp1CFFZoyfVwRScvCDcfhuUYaT3YLVrTNmNdmWkKUMEKJjyRXWCTcaTeNdMAvNEKHAUJHrjKBRL29wsznXWnGnqAyhqKvyA' - ); - - expect.assertions(1); - }); - - it('should fail switching method to did:key', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(false); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:key', - }, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: User rejected method switch'); - - expect.assertions(1); - }); - - it('should fail switching method because method is not supported', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(false); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:keyy', - }, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: Did method is not supported!'); - - expect.assertions(1); - }); - - it('should fail switching method because request is bad', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(false); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: {}, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: Invalid switchDIDMethod request.'); - - expect.assertions(1); - }); - }); - - describe('getSelectedMethod', () => { - it('should succeed and return did:ethr', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getSelectedMethod', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBe('did:ethr'); - - expect.assertions(1); - }); - - it('should succeed and return did:key', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'switchDIDMethod', - params: { - didMethod: 'did:key', - }, - }, - }); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getSelectedMethod', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBe('did:key'); - - expect.assertions(1); - }); - }); - - describe('getAvailableMethods', () => { - it('should succeed and return available methods', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getAvailableMethods', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(availableMethods); - - expect.assertions(1); - }); - }); - - describe('setVCStore', () => { - it('should throw and error when using wrong vcStore', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - let res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'setVCStore', - params: { store: 'ceramicc', value: true }, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: Store ceramicc is not supported!'); - - res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'setVCStore', - params: { store: 'ceramic', value: 'tlo' }, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: Invalid setVCStore request.'); - - expect.assertions(2); - }); - - it('should succeed toggling ceramic store to true', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - let res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'setVCStore', - params: { store: 'ceramic', value: true }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBe(true); - - res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getVCStore', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual({ ceramic: true, snap: true }); - - expect.assertions(2); - }); - }); - - describe('getVCStore', () => { - it('should succeed and return snap', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getVCStore', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual({ ceramic: true, snap: true }); - - expect.assertions(1); - }); - }); - - describe('getAvailableVCStores', () => { - it('should succeed and return available VC stores', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getAvailableVCStores', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(availableVCStores); - - expect.assertions(1); - }); - }); - - describe('getAccountSettings', () => { - const state = getDefaultSnapState(); - it('should succeed and return account settings', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getAccountSettings', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(state.accountState[account].accountConfig); - - expect.assertions(1); - }); - }); - - describe('getSnapSettings', () => { - const state = getDefaultSnapState(); - it('should succeed and return snap settings', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'getSnapSettings', - params: {}, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toEqual(state.snapConfig); - - expect.assertions(1); - }); - }); - - describe('resolveDID', () => { - it('should succeed resolving did:ethr', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'resolveDID', - params: { did: exampleDID }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data.didDocument).toEqual(exampleDIDDocument); - expect.assertions(1); - }); - }); - - describe('verifyCredential', () => { - it('should succeed verifiying a VC', async () => { - const verified = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'verifyData', - params: { - credential: exampleVeramoVCJWT, - }, - }, - })) as Result; - - if (isError(verified)) { - throw new Error(verified.error); - } - - expect(verified.data).toBe(true); - expect.assertions(1); - }); - - it('should succeed verifying a VP', async () => { - snapMock.rpcMocks.snap_dialog.mockReturnValue(true); - - const saveRes = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'saveVC', - params: { - verifiableCredential: exampleVeramoVCJWT, - options: { store: 'snap' }, - }, - }, - })) as Result; - - if (isError(saveRes)) { - throw new Error(saveRes.error); - } - - const createdVP = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVP', - params: { - vcs: [exampleVC], - }, - }, - })) as Result; - - if (isError(createdVP)) { - throw new Error(createdVP.error); - } - - const verified = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'verifyData', - params: { - presentation: createdVP.data, - }, - }, - })) as Result; - - if (isError(verified)) { - throw new Error(verified.error); - } - - expect(verified.data).toBe(true); - expect.assertions(1); - }); - }); - - describe('createVC', () => { - it('should succeed creating a VC', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVC', - params: { - minimalUnsignedCredential: exampleTestVCPayload, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toContainKey('proof'); - expect.assertions(1); - }); - it('should succeed creating a JWT VC', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVC', - params: { - minimalUnsignedCredential: exampleTestVCPayload, - proofFormat: 'jwt', - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toContainKey('proof'); - expect(res.data.proof.type).toBe('JwtProof2020'); - expect.assertions(2); - }); - - it('should succeed creating a EIP VC', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVC', - params: { - minimalUnsignedCredential: exampleTestVCPayload, - proofFormat: 'EthereumEip712Signature2021', - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toContainKey('proof'); - expect(res.data.proof.type).toBe('EthereumEip712Signature2021'); - expect.assertions(2); - }); - - it.todo('should succeed creating a JSON-LD VC'); - - it.todo('should fail creating an EIP VC - invalid VC'); - - it('should succeed creating and saving a JWT VC', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVC', - params: { - minimalUnsignedCredential: exampleTestVCPayload, - proofFormat: 'jwt', - options: { - save: true, - }, - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toContainKey('proof'); - expect(res.data.proof.type).toBe('JwtProof2020'); - - const resQuery = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'queryVCs', - params: {}, - }, - })) as Result; - - if (isError(resQuery)) { - throw new Error(resQuery.error); - } - expect(resQuery.data).toHaveLength(1); - expect(resQuery.data[0].data).toEqual(res.data); - - expect.assertions(4); - }); - }); - - describe('setCurrentAccount', () => { - it('should succeed setting the current account', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'setCurrentAccount', - params: { - currentAccount: '0x41B821bB31902f05eD241b40A8fa3fE56aA76e68', - }, - }, - })) as Result; - - if (isError(res)) { - throw new Error(res.error); - } - - expect(res.data).toBeTrue(); - expect.assertions(1); - }); - - it('should fail setting the current account - missing current account parameter', async () => { - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'setCurrentAccount', - params: {}, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe('Error: Invalid SetCurrentAccount request'); - expect.assertions(1); - }); - - it('should fail onRpcRequest - current account not set', async () => { - const defaultState = getDefaultSnapState(); - defaultState.currentAccount = ''; - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: defaultState, - }); - - const res = (await onRpcRequest({ - origin: 'localhost', - request: { - id: 'test-id', - jsonrpc: '2.0', - method: 'createVC', - params: { - minimalUnsignedCredential: exampleTestVCPayload, - proofFormat: 'jwt', - options: { - save: true, - }, - }, - }, - })) as Result; - - if (isSuccess(res)) { - throw new Error('Should return error'); - } - - expect(res.error).toBe( - 'Error: No account set. Use setCurrentAccount to set an account.' - ); - expect.assertions(1); - }); - }); -}); diff --git a/packages/snap/tests/testUtils/constants.ts b/packages/snap/tests/testUtils/constants.ts deleted file mode 100644 index 85dd34f21..000000000 --- a/packages/snap/tests/testUtils/constants.ts +++ /dev/null @@ -1,539 +0,0 @@ -import { MascaState } from '@blockchain-lab-um/masca-types'; -import type { JsonBIP44CoinTypeNode } from '@metamask/key-tree'; -import { heading, panel, text } from '@metamask/snaps-ui'; -import type { - DIDDocument, - DIDResolutionResult, - IIdentifier, - MinimalImportableKey, - W3CVerifiableCredential, -} from '@veramo/core'; - -import type { SnapConfirmParams } from '../../src/interfaces'; -import { getEmptyAccountState } from '../../src/utils/config'; - -export const mnemonic = - 'prosper pair similar canoe work humble loud wild aunt reunion olive obscure'; -export const privateKey = - '0x63ce0077f0d617dbf54d5f335de2983313c6356f25b45e0f68f85bee1490a6ae'; -export const privateKey2 = - '0xb29764680b2a07fa4a762d255e3f689fb5c05cc885e6dfd3de5d5948b5a6b47f'; -export const account = '0xb6665128eE91D84590f70c3268765384A9CAfBCd'; -export const account2 = '0x461e557A07AC110BC947F18b3828e26f013dac39'; -export const publicKey = - '0x0480a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae850a9f561d414001a8bdefdb713c619d2caf08a0c9655b0cf42de065bc51e0169a'; -export const publicKey2 = - '0x048b551f480b75379ab40abf9fb89dbf1ecc850dfc5855eb7016d5f6c5a76abdc96bfc53007fa105b863c618c4e7767e585e1aa5c0c0dacc75884ee80a48a05508'; -export const compressedPublicKey = - '0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85'; -export const signedMsg = - '0x30eb4dbf93e7bfdb109ed03f7803f2378fa27d18ddc233cb3d121b5ba13253fe2515076d1ba66f3dc282c182479b843c925c62eb1f5a0676bcaf995e8e7552941c'; -export const infuraToken = '0ec03090465d400c988a14831aacfe37'; -export const publicKeyHex = - '0480a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae850a9f561d414001a8bdefdb713c619d2caf08a0c9655b0cf42de065bc51e0169a'; -export const exampleDIDKeyIdentifier = - 'zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik'; -export const exampleDIDKey = `did:key:${exampleDIDKeyIdentifier}`; -export const exampleDID = - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85'; -export const exampleImportedDID: IIdentifier = { - did: 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - provider: 'did:ethr', - controllerKeyId: 'metamask-0xb6665128eE91D84590f70c3268765384A9CAfBCd', - keys: [ - { - kid: 'metamask-0xb6665128eE91D84590f70c3268765384A9CAfBCd', - type: 'Secp256k1', - kms: 'web3', - privateKeyHex: - '63ce0077f0d617dbf54d5f335de2983313c6356f25b45e0f68f85bee1490a6ae', - publicKeyHex: - '0480a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae850a9f561d414001a8bdefdb713c619d2caf08a0c9655b0cf42de065bc51e0169a', - }, - ], - services: [], -}; - -export const exampleTestKey: MinimalImportableKey = { - kid: 'importedTestKey', - kms: 'snap', - type: 'Secp256k1', - privateKeyHex: - 'e63886b5ba367dc2aff9acea6d955ee7c39115f12eaf2aa6b1a2eaa852036668', -} as const; - -export const exampleTestVCPayload = { - type: ['VerifiableCredential', 'ProgramCompletionCertificate'], - credentialSubject: { - accomplishmentType: 'Developer Certificate', - learnerName: 'Bob', - achievement: 'Certified Solidity Developer 2', - courseProvider: 'https://blockchain-lab.um.si/', - id: 'did:ethr:goerli:0xb6665128ee91d84590f70c3268765384a9cafbcd', - }, - credentialSchema: { - id: 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json', - type: 'JsonSchemaValidator2018', - }, - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json', - ], -}; - -export const exampleDIDDocument: DIDDocument = { - '@context': [ - 'https://www.w3.org/ns/did/v1', - 'https://w3id.org/security/suites/secp256k1recovery-2020/v2', - ], - id: 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - verificationMethod: [ - { - id: 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controller', - type: 'EcdsaSecp256k1RecoveryMethod2020', - controller: - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - blockchainAccountId: - 'eip155:5:0xb6665128eE91D84590f70c3268765384A9CAfBCd', - }, - { - id: 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controllerKey', - type: 'EcdsaSecp256k1VerificationKey2019', - controller: - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - publicKeyHex: - '0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - }, - ], - authentication: [ - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controller', - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controllerKey', - ], - assertionMethod: [ - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controller', - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85#controllerKey', - ], -}; - -export const resolutionNotFound = { - didDocument: null, - didResolutionMetadata: { - error: 'invalidDid', - message: 'Error: invalidDid: invalid key type', - }, - didDocumentMetadata: {}, -}; - -export const resolutionMethodNotSupported = { - didDocument: null, - didResolutionMetadata: { - error: 'unsupportedDidMethod', - }, - didDocumentMetadata: {}, -}; - -export const resolutionInvalidDID = { - didDocument: null, - didResolutionMetadata: { - error: 'invalidDid', - message: 'Not a valid did:ethr: 0x5:0x123', - }, - didDocumentMetadata: {}, -}; - -export const exampleDIDKeyDocumentUniResovler = { - '@context': [ - 'https://www.w3.org/ns/did/v1', - 'https://w3id.org/security#EcdsaSecp256k1VerificationKey2019', - 'https://w3id.org/security#publicKeyJwk', - ], - id: 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - verificationMethod: [ - { - id: 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - type: 'EcdsaSecp256k1VerificationKey2019', - controller: 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - publicKeyJwk: { - kty: 'EC', - alg: 'ES256K', - use: 'sig', - crv: 'secp256k1', - x: 'gKnNSP1Db4wfgbFW62FWGM1XPD6x5tk3oXuCIgJ8roU', - y: 'Cp9WHUFAAai979txPGGdLK8IoMllWwz0LeBlvFHgFpo', - }, - }, - ], - authentication: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], - assertionMethod: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], -}; - -export const exampleDIDKeyDocument: DIDDocument = { - id: 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - '@context': [ - 'https://www.w3.org/ns/did/v1', - 'https://w3id.org/security/suites/secp256k1-2019/v1', - ], - assertionMethod: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], - authentication: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], - capabilityInvocation: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], - capabilityDelegation: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], - keyAgreement: [ - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - ], - verificationMethod: [ - { - id: 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - type: 'EcdsaSecp256k1RecoveryMethod2020', - controller: - 'did:key:zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik#zQ3shW537fJMvkiw69S1FLvBaE8pyzAx4agHu6iaYzTCejuik', - publicKeyHex, - }, - ], -}; - -export const exampleDIDKeyResolution: DIDResolutionResult = { - didDocumentMetadata: {}, - didResolutionMetadata: {}, - didDocument: exampleDIDKeyDocument, -}; - -export const exampleImportedDIDWIthoutPrivateKey: IIdentifier = { - did: 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - provider: 'did:ethr', - controllerKeyId: 'metamask-0xb6665128eE91D84590f70c3268765384A9CAfBCd', - keys: [ - { - kid: 'metamask-0xb6665128eE91D84590f70c3268765384A9CAfBCd', - type: 'Secp256k1', - kms: 'snap', - publicKeyHex: - '0480a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae850a9f561d414001a8bdefdb713c619d2caf08a0c9655b0cf42de065bc51e0169a', - meta: { - algorithms: [ - 'ES256K', - 'ES256K-R', - 'eth_signTransaction', - 'eth_signTypedData', - 'eth_signMessage', - 'eth_rawSign', - ], - }, - }, - ], - services: [], -}; - -export const exampleVC = { - credentialSubject: { - accomplishmentType: 'Developer Certificate', - learnerName: 'Bob', - achievement: 'Certified Solidity Developer 2', - courseProvider: 'https://blockchain-lab.um.si/', - id: 'did:ethr:goerli:0xb6665128ee91d84590f70c3268765384a9cafbcd', - }, - issuer: { - id: 'did:ethr:goerli:0x0241abd662da06d0af2f0152a80bc037f65a7f901160cfe1eb35ef3f0c532a2a4d', - }, - id: 'b2f479c5-2058-4286-a70d-f636966266de', - type: ['VerifiableCredential', 'ProgramCompletionCertificate'], - credentialSchema: { - id: 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json', - type: 'JsonSchemaValidator2018', - }, - '@context': ['https://www.w3.org/2018/credentials/v1'], - issuanceDate: '2022-09-16T11:37:05.000Z', - proof: { - type: 'JwtProof2020', - jwt: 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9sZC1jb250ZXh0Lmpzb24iXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlByb2dyYW1Db21wbGV0aW9uQ2VydGlmaWNhdGUiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiYWNjb21wbGlzaG1lbnRUeXBlIjoiRGV2ZWxvcGVyIENlcnRpZmljYXRlIiwibGVhcm5lck5hbWUiOiJCb2IiLCJhY2hpZXZlbWVudCI6IkNlcnRpZmllZCBTb2xpZGl0eSBEZXZlbG9wZXIgMiIsImNvdXJzZVByb3ZpZGVyIjoiaHR0cHM6Ly9ibG9ja2NoYWluLWxhYi51bS5zaS8ifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9qc29uLXNjaGVtYS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWFWYWxpZGF0b3IyMDE4In19LCJzdWIiOiJkaWQ6ZXRocjpyaW5rZWJ5OjB4YjY2NjUxMjhlZTkxZDg0NTkwZjcwYzMyNjg3NjUzODRhOWNhZmJjZCIsImp0aSI6ImIyZjQ3OWM1LTIwNTgtNDI4Ni1hNzBkLWY2MzY5NjYyNjZkZSIsIm5iZiI6MTY2MzMyODIyNSwiaXNzIjoiZGlkOmV0aHI6cmlua2VieToweDAyNDFhYmQ2NjJkYTA2ZDBhZjJmMDE1MmE4MGJjMDM3ZjY1YTdmOTAxMTYwY2ZlMWViMzVlZjNmMGM1MzJhMmE0ZCJ9.lbUqHPCkgBtX_uulh_3JRYK2GKirUCRgJDUK5IdVI55vG6aOTk6UtEezH3j4H3VB85eCmJm_mFM7Ks6OOZCVfA', - }, -}; - -export const exampleVCJSONLD: W3CVerifiableCredential = { - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json', - ], - type: ['VerifiableCredential', 'CourseCredential'], - issuer: { - id: 'did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj', - name: 'tenant', - }, - issuanceDate: '2021-07-26T01:05:05.152Z', - credentialSubject: { - accomplishmentType: 'Developer Certificate', - learnerName: 'Bob', - achievement: 'Certified Solidity Developer 2', - courseProvider: 'https://blockchain-lab.um.si/', - id: 'did:ethr:goerli:0xb6665128ee91d84590f70c3268765384a9cafbcd', - }, - proof: { - type: 'Ed25519Signature2018', - created: '2021-07-26T01:05:06Z', - jws: 'eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..o6hnrrWpArG8LQz2Ex_u66_BtuPdp3Hkz18nhNdNhJ7J1k_2lmCCwsNdmo-kNFirZdSIMzqO-V3wEjMDphVEAA', - proofPurpose: 'assertionMethod', - verificationMethod: - 'did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj#z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj', - }, -}; - -export const exampleVCEIP712: W3CVerifiableCredential = { - issuer: 'did:key:zQ3shYMgaxxFxwm3ipuCPD3n6WT58Up6qUaJUAnYZUeb7EBXW', - type: ['VerifiableCredential', 'Custom'], - credentialSubject: { - accomplishmentType: 'Developer Certificate', - learnerName: 'Bob', - achievement: 'Certified Solidity Developer 2', - courseProvider: 'https://blockchain-lab.um.si/', - id: 'did:ethr:goerli:0xb6665128ee91d84590f70c3268765384a9cafbcd', - }, - '@context': ['https://www.w3.org/2018/credentials/v1'], - issuanceDate: '2022-08-12T08:56:59.619Z', - proof: { - verificationMethod: - 'did:key:zQ3shYMgaxxFxwm3ipuCPD3n6WT58Up6qUaJUAnYZUeb7EBXW#zQ3shYMgaxxFxwm3ipuCPD3n6WT58Up6qUaJUAnYZUeb7EBXW', - created: '2022-08-12T08:56:59.619Z', - proofPurpose: 'assertionMethod', - type: 'EthereumEip712Signature2021', - proofValue: - '0xdf3910af95b8207e6fd1cbbc9beb21941fcbff0eb4032aee356ee52eb340ca2d26bfd8156c811460b4651d140f5b7130532c5e8228e488696435564236f4a0f71c', - eip712: { - domain: { - chainId: 4, - name: 'VerifiableCredential', - version: '1', - }, - messageSchema: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - ], - Proof: [ - { - name: 'created', - type: 'string', - }, - { - name: 'proofPurpose', - type: 'string', - }, - { - name: 'type', - type: 'string', - }, - { - name: 'verificationMethod', - type: 'string', - }, - ], - VerifiablePresentation: [ - { - name: '@context', - type: 'string[]', - }, - { - name: 'holder', - type: 'string', - }, - { - name: 'issuanceDate', - type: 'string', - }, - { - name: 'proof', - type: 'Proof', - }, - { - name: 'type', - type: 'string[]', - }, - { - name: 'verifiableCredential', - type: 'string[]', - }, - ], - }, - primaryType: 'VerifiableCredential', - }, - }, -}; - -export const exampleVCinVP = { - credentialSubject: { - accomplishmentType: 'Developer Certificate', - learnerName: 'Bob', - achievement: 'Certified Solidity Developer 2', - courseProvider: 'https://blockchain-lab.um.si/', - id: 'did:ethr:rinkeby:0xb6665128ee91d84590f70c3268765384a9cafbcd', - }, - issuer: { - id: 'did:ethr:rinkeby:0x0241abd662da06d0af2f0152a80bc037f65a7f901160cfe1eb35ef3f0c532a2a4d', - }, - id: 'b2f479c5-2058-4286-a70d-f636966266de', - type: ['VerifiableCredential', 'ProgramCompletionCertificate'], - credentialSchema: { - id: 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json', - type: 'JsonSchemaValidator2018', - }, - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json', - ], - issuanceDate: '2022-09-16T11:37:05.000Z', - proof: { - type: 'JwtProof2020', - jwt: 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9sZC1jb250ZXh0Lmpzb24iXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlByb2dyYW1Db21wbGV0aW9uQ2VydGlmaWNhdGUiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiYWNjb21wbGlzaG1lbnRUeXBlIjoiRGV2ZWxvcGVyIENlcnRpZmljYXRlIiwibGVhcm5lck5hbWUiOiJCb2IiLCJhY2hpZXZlbWVudCI6IkNlcnRpZmllZCBTb2xpZGl0eSBEZXZlbG9wZXIgMiIsImNvdXJzZVByb3ZpZGVyIjoiaHR0cHM6Ly9ibG9ja2NoYWluLWxhYi51bS5zaS8ifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9qc29uLXNjaGVtYS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWFWYWxpZGF0b3IyMDE4In19LCJzdWIiOiJkaWQ6ZXRocjpyaW5rZWJ5OjB4YjY2NjUxMjhlZTkxZDg0NTkwZjcwYzMyNjg3NjUzODRhOWNhZmJjZCIsImp0aSI6ImIyZjQ3OWM1LTIwNTgtNDI4Ni1hNzBkLWY2MzY5NjYyNjZkZSIsIm5iZiI6MTY2MzMyODIyNSwiaXNzIjoiZGlkOmV0aHI6cmlua2VieToweDAyNDFhYmQ2NjJkYTA2ZDBhZjJmMDE1MmE4MGJjMDM3ZjY1YTdmOTAxMTYwY2ZlMWViMzVlZjNmMGM1MzJhMmE0ZCJ9.lbUqHPCkgBtX_uulh_3JRYK2GKirUCRgJDUK5IdVI55vG6aOTk6UtEezH3j4H3VB85eCmJm_mFM7Ks6OOZCVfA', - }, -}; - -export const jsonPath = - '$[?(@.data.credentialSubject.achievement == "Certified Solidity Developer 2")]'; - -export const exampleVCJWT = { - verifiableCredential: [ - { - credentialSubject: { - accomplishmentType: 'Developer Certificate', - learnerName: 'Bob', - achievement: 'Certified Solidity Developer 2', - courseProvider: 'https://blockchain-lab.um.si/', - id: 'did:ethr:goerli:0xb6665128ee91d84590f70c3268765384a9cafbcd', - }, - issuer: { - id: 'did:ethr:goerli:0x0241abd662da06d0af2f0152a80bc037f65a7f901160cfe1eb35ef3f0c532a2a4d', - }, - id: 'b2f479c5-2058-4286-a70d-f636966266de', - type: ['VerifiableCredential', 'ProgramCompletionCertificate'], - credentialSchema: { - id: 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/json-schema.json', - type: 'JsonSchemaValidator2018', - }, - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://beta.api.schemas.serto.id/v1/public/program-completion-certificate/1.0/ld-context.json', - ], - issuanceDate: '2022-09-16T11:37:05.000Z', - proof: { - type: 'JwtProof2020', - jwt: 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9sZC1jb250ZXh0Lmpzb24iXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlByb2dyYW1Db21wbGV0aW9uQ2VydGlmaWNhdGUiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiYWNjb21wbGlzaG1lbnRUeXBlIjoiRGV2ZWxvcGVyIENlcnRpZmljYXRlIiwibGVhcm5lck5hbWUiOiJCb2IiLCJhY2hpZXZlbWVudCI6IkNlcnRpZmllZCBTb2xpZGl0eSBEZXZlbG9wZXIgMiIsImNvdXJzZVByb3ZpZGVyIjoiaHR0cHM6Ly9ibG9ja2NoYWluLWxhYi51bS5zaS8ifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vYmV0YS5hcGkuc2NoZW1hcy5zZXJ0by5pZC92MS9wdWJsaWMvcHJvZ3JhbS1jb21wbGV0aW9uLWNlcnRpZmljYXRlLzEuMC9qc29uLXNjaGVtYS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWFWYWxpZGF0b3IyMDE4In19LCJzdWIiOiJkaWQ6ZXRocjpyaW5rZWJ5OjB4YjY2NjUxMjhlZTkxZDg0NTkwZjcwYzMyNjg3NjUzODRhOWNhZmJjZCIsImp0aSI6ImIyZjQ3OWM1LTIwNTgtNDI4Ni1hNzBkLWY2MzY5NjYyNjZkZSIsIm5iZiI6MTY2MzMyODIyNSwiaXNzIjoiZGlkOmV0aHI6cmlua2VieToweDAyNDFhYmQ2NjJkYTA2ZDBhZjJmMDE1MmE4MGJjMDM3ZjY1YTdmOTAxMTYwY2ZlMWViMzVlZjNmMGM1MzJhMmE0ZCJ9.lbUqHPCkgBtX_uulh_3JRYK2GKirUCRgJDUK5IdVI55vG6aOTk6UtEezH3j4H3VB85eCmJm_mFM7Ks6OOZCVfA', - }, - }, - ], - holder: - 'did:ethr:0x5:0x0280a9cd48fd436f8c1f81b156eb615618cd573c3eb1e6d937a17b8222027cae85', - type: ['VerifiablePresentation', 'Custom'], - '@context': ['https://www.w3.org/2018/credentials/v1'], - issuanceDate: '2022-11-08T12:43:09.000Z', - proof: { - type: 'JwtProof2020', - jwt: 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2cCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iLCJDdXN0b20iXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKaGJHY2lPaUpGVXpJMU5rc2lMQ0owZVhBaU9pSktWMVFpZlEuZXlKMll5STZleUpBWTI5dWRHVjRkQ0k2V3lKb2RIUndjem92TDNkM2R5NTNNeTV2Y21jdk1qQXhPQzlqY21Wa1pXNTBhV0ZzY3k5Mk1TSXNJbWgwZEhCek9pOHZZbVYwWVM1aGNHa3VjMk5vWlcxaGN5NXpaWEowYnk1cFpDOTJNUzl3ZFdKc2FXTXZjSEp2WjNKaGJTMWpiMjF3YkdWMGFXOXVMV05sY25ScFptbGpZWFJsTHpFdU1DOXNaQzFqYjI1MFpYaDBMbXB6YjI0aVhTd2lkSGx3WlNJNld5SldaWEpwWm1saFlteGxRM0psWkdWdWRHbGhiQ0lzSWxCeWIyZHlZVzFEYjIxd2JHVjBhVzl1UTJWeWRHbG1hV05oZEdVaVhTd2lZM0psWkdWdWRHbGhiRk4xWW1wbFkzUWlPbnNpWVdOamIyMXdiR2x6YUcxbGJuUlVlWEJsSWpvaVJHVjJaV3h2Y0dWeUlFTmxjblJwWm1sallYUmxJaXdpYkdWaGNtNWxjazVoYldVaU9pSkNiMklpTENKaFkyaHBaWFpsYldWdWRDSTZJa05sY25ScFptbGxaQ0JUYjJ4cFpHbDBlU0JFWlhabGJHOXdaWElnTWlJc0ltTnZkWEp6WlZCeWIzWnBaR1Z5SWpvaWFIUjBjSE02THk5aWJHOWphMk5vWVdsdUxXeGhZaTUxYlM1emFTOGlmU3dpWTNKbFpHVnVkR2xoYkZOamFHVnRZU0k2ZXlKcFpDSTZJbWgwZEhCek9pOHZZbVYwWVM1aGNHa3VjMk5vWlcxaGN5NXpaWEowYnk1cFpDOTJNUzl3ZFdKc2FXTXZjSEp2WjNKaGJTMWpiMjF3YkdWMGFXOXVMV05sY25ScFptbGpZWFJsTHpFdU1DOXFjMjl1TFhOamFHVnRZUzVxYzI5dUlpd2lkSGx3WlNJNklrcHpiMjVUWTJobGJXRldZV3hwWkdGMGIzSXlNREU0SW4xOUxDSnpkV0lpT2lKa2FXUTZaWFJvY2pweWFXNXJaV0o1T2pCNFlqWTJOalV4TWpobFpUa3haRGcwTlRrd1pqY3dZek15TmpnM05qVXpPRFJoT1dOaFptSmpaQ0lzSW1wMGFTSTZJbUl5WmpRM09XTTFMVEl3TlRndE5ESTROaTFoTnpCa0xXWTJNelk1TmpZeU5qWmtaU0lzSW01aVppSTZNVFkyTXpNeU9ESXlOU3dpYVhOeklqb2laR2xrT21WMGFISTZjbWx1YTJWaWVUb3dlREF5TkRGaFltUTJOakprWVRBMlpEQmhaakptTURFMU1tRTRNR0pqTURNM1pqWTFZVGRtT1RBeE1UWXdZMlpsTVdWaU16Vmxaak5tTUdNMU16SmhNbUUwWkNKOS5sYlVxSFBDa2dCdFhfdXVsaF8zSlJZSzJHS2lyVUNSZ0pEVUs1SWRWSTU1dkc2YU9UazZVdEVlekgzajRIM1ZCODVlQ21KbV9tRk03S3M2T09aQ1ZmQSJdfSwibmJmIjoxNjY3OTExMzg5LCJpc3MiOiJkaWQ6ZXRocjoweDU6MHhiNjY2NTEyOGVlOTFkODQ1OTBmNzBjMzI2ODc2NTM4NGE5Y2FmYmNkIn0.oVLAXFtdL_DrT7Qr9YjSfWwXYv9E2IlMAHVVVLswzQlS-bCpH3-RrlUEpJRljg-ajnk72FuDs-Mzkxa7CmvW5g', - }, -}; - -const defaultSnapState: MascaState = { - accountState: { - '0xb6665128eE91D84590f70c3268765384A9CAfBCd': getEmptyAccountState(), - }, - currentAccount: '0xb6665128eE91D84590f70c3268765384A9CAfBCd', - snapConfig: { - dApp: { - disablePopups: false, - friendlyDapps: [], - }, - snap: { - acceptedTerms: true, - }, - }, -}; - -export const getDefaultSnapState = (): MascaState => { - defaultSnapState.accountState[address].publicKey = publicKey; - // Session is valid for two years from 15/06/2023 - defaultSnapState.accountState[address].ceramicSession = - 'eyJzZXNzaW9uS2V5U2VlZCI6IlJCcGVUK3poMmFpQ2xOTVBZYXllYUFSSVBhVkZUZ1pZVHU4M3I0dHBpR1U9IiwiY2FjYW8iOnsiaCI6eyJ0IjoiZWlwNDM2MSJ9LCJwIjp7ImRvbWFpbiI6Ik15Tm9kZUFwcCIsImlhdCI6IjIwMjMtMDYtMTVUMTI6Mjc6NTguNzgyWiIsImlzcyI6ImRpZDpwa2g6ZWlwMTU1OjE6MHhiNjY2NTEyOGVlOTFkODQ1OTBmNzBjMzI2ODc2NTM4NGE5Y2FmYmNkIiwiYXVkIjoiZGlkOmtleTp6Nk1rd1V6aW5FU2lGdWo2dlR1bk1kbVYyTWtvbm1ud3lkdlE4Rjlwc0xzQ0xyUW8iLCJ2ZXJzaW9uIjoiMSIsIm5vbmNlIjoiSnFKTTNZcFc5ayIsImV4cCI6IjIwMjUtMDYtMTRUMTI6Mjc6NTguNzgyWiIsInN0YXRlbWVudCI6IkdpdmUgdGhpcyBhcHBsaWNhdGlvbiBhY2Nlc3MgdG8gc29tZSBvZiB5b3VyIGRhdGEgb24gQ2VyYW1pYyIsInJlc291cmNlcyI6WyJjZXJhbWljOi8vKj9tb2RlbD1ranpsNmh2ZnJidzZjNmlkYWFjdzVkNGdjNDgxZW5wYmV1djRmYXQ2NmdqcTFrazlpdnRhbmFkc2UwNzQ2ZGwiXX0sInMiOnsidCI6ImVpcDE5MSIsInMiOiIweGNmZjk0YjgyZmVlODZmZmM0Zjg0ZjYxODFmMDRkNGY2NGY5ZmVmZTAyODgyNzg4Mzc1M2ZhNWFiYThiM2VkYWQ3NzdhZThjMGY3ZTQ0MTIzMzM2ZmQzNjIwNjA5MWE0NmM0MDYxZTQzZGY4OGVhYzdmZWI2ZTE2M2Y5Yzc2OWI3MWMifX19'; - return structuredClone(defaultSnapState); -}; - -export const snapConfirmParams: SnapConfirmParams = { - prompt: 'Test prompt', - description: 'Test description', - textAreaContent: 'Test text area content', -}; - -export const bip44Entropy: JsonBIP44CoinTypeNode = { - depth: 2, - parentFingerprint: 2220627503, - index: 2147483708, - privateKey: - 'dd5b8deefcf550f3ecb0a49b2018ef9fb5b5c2ad146478d3633bf7ce5a5a2f17', - publicKey: - '043efeddf040859e8d00620b6eb1bf255d82e7fc34cb0eaffc305fe69685454163910ea2cc84a617f3f4e30b74bdbcf14b884f092e8d0dc8d966e904bd988b3a94', - chainCode: '006c9539cb5984e48b8ca8e8f1648c92ed2dccc3e6a7043cdcabc681e054b627', - coin_type: 60, - path: "m / bip32:44' / bip32:60'", -}; - -export const derivedKeyChainCode = - '0xbbfe64aaa2157420865e979f19bdd0da7af456d075d7e4d4bb1ee92e548ac440'; -export const derivedKeyDerivationPath = - "m / bip32:44' / bip32:60' / bip32:0' / bip32:0"; - -export const content = panel([ - heading('Title of the panel'), - text('Text of the panel'), -]); - -export const didWebVC = { - credentialSubject: { - currentAddress: '2570 24th Street', - dateOfBirth: '1985-05-25', - familyName: 'Doe', - gender: 'F', - givenName: 'Susan', - issued: '2020-08-01', - personalIdentifier: 'I1234561', - placeOfBirth: 'Asgard', - userId: 'auth0|6371065f0d58f1830efa260d', - id: 'did:ethr:0x02e85a63c1efa1ce3a4d0c0ad2b784f19f1595008fd50d5d9f61134c372fab68a9', - }, - issuer: { - id: 'did:web:asgard-state.auth0lab.com', - }, - id: '574a0a69-eef6-4da7-846b-19cf77f25558', - type: ['VerifiableCredential', 'IDCard'], - credentialStatus: { - id: 'https://asgard-state.auth0lab.com/vcs/credential/status/3#105', - type: 'StatusList2021Entry', - statusPurpose: 'revocation', - statusListIndex: 105, - statusListCredential: - 'https://asgard-state.auth0lab.com/vcs/credential/status/3', - }, - '@context': ['https://www.w3.org/2018/credentials/v1'], - issuanceDate: '2022-11-13T14:59:54.000Z', - proof: { - type: 'JwtProof2020', - jwt: 'eyJraWQiOiJkaWQ6d2ViOmFzZ2FyZC1zdGF0ZS5hdXRoMGxhYi5jb20jMDRiYTAxMmNhMzhhYTZjYTgyMjAyMzVhYTNkYTdkODVmNzg2ODg0ZTUwMjFmNzM3ODg2MDZhODYyYmMwMTNhNTAyODYyY2U5NmM5Y2U3ZWQ4OTJmZmY2ZDBmZjliZDg5MTg5OWE0MzI3Y2Q0ZDQ0NDY3MTdkMjg5NzhhMDYwYjU1NCIsImFsZyI6IkVTMjU2SyIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiSURDYXJkIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImN1cnJlbnRBZGRyZXNzIjoiMjU3MCAyNHRoIFN0cmVldCIsImRhdGVPZkJpcnRoIjoiMTk4NS0wNS0yNSIsImZhbWlseU5hbWUiOiJEb2UiLCJnZW5kZXIiOiJGIiwiZ2l2ZW5OYW1lIjoiU3VzYW4iLCJpc3N1ZWQiOiIyMDIwLTA4LTAxIiwicGVyc29uYWxJZGVudGlmaWVyIjoiSTEyMzQ1NjEiLCJwbGFjZU9mQmlydGgiOiJBc2dhcmQiLCJ1c2VySWQiOiJhdXRoMHw2MzcxMDY1ZjBkNThmMTgzMGVmYTI2MGQifSwiY3JlZGVudGlhbFN0YXR1cyI6eyJpZCI6Imh0dHBzOi8vYXNnYXJkLXN0YXRlLmF1dGgwbGFiLmNvbS92Y3MvY3JlZGVudGlhbC9zdGF0dXMvMyMxMDUiLCJ0eXBlIjoiU3RhdHVzTGlzdDIwMjFFbnRyeSIsInN0YXR1c1B1cnBvc2UiOiJyZXZvY2F0aW9uIiwic3RhdHVzTGlzdEluZGV4IjoxMDUsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiaHR0cHM6Ly9hc2dhcmQtc3RhdGUuYXV0aDBsYWIuY29tL3Zjcy9jcmVkZW50aWFsL3N0YXR1cy8zIn19LCJzdWIiOiJkaWQ6ZXRocjoweDAyZTg1YTYzYzFlZmExY2UzYTRkMGMwYWQyYjc4NGYxOWYxNTk1MDA4ZmQ1MGQ1ZDlmNjExMzRjMzcyZmFiNjhhOSIsImp0aSI6IjU3NGEwYTY5LWVlZjYtNGRhNy04NDZiLTE5Y2Y3N2YyNTU1OCIsIm5iZiI6MTY2ODM1MTU5NCwiaXNzIjoiZGlkOndlYjphc2dhcmQtc3RhdGUuYXV0aDBsYWIuY29tIn0.dQB8vT_aNtUJfjtjMECNSSSUvEDKOXXueV9mNNdu3gzeTFgsLCsxjkTx2qTGOr-9AC3PZq1aczc9vXRnZ7zKaw', - }, -}; diff --git a/packages/snap/tests/testUtils/didDocumentConstants.ts b/packages/snap/tests/testUtils/didDocumentConstants.ts deleted file mode 100644 index 32fc38bd2..000000000 --- a/packages/snap/tests/testUtils/didDocumentConstants.ts +++ /dev/null @@ -1,262 +0,0 @@ -export const didIonResult = { - did: 'did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - didDocumentMetadata: { - method: { - published: true, - recoveryCommitment: 'EiDKYXZ2MkHRCYDVtXI7ONiTkTdVfs9Tnb-tDDHGXLzmOw', - updateCommitment: 'EiDNk40DUvxCef8_BinU5DDIAhNWE4e7Ea9Q6P7GAbJ6VA', - }, - canonicalId: 'did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - }, - didResolutionMetadata: { - contentType: 'application/did+ld+json', - pattern: '^(did:ion:(?!test).+)$', - driverUrl: 'http://driver-did-ion:8080/1.0/identifiers/', - duration: 21, - did: { - didString: 'did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - methodSpecificId: 'EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - method: 'ion', - }, - }, - didDocument: { - id: 'did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - '@context': [ - 'https://www.w3.org/ns/did/v1', - { - '@base': 'did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - }, - ], - service: [ - { - id: '#linkedin', - type: 'linkedin', - serviceEndpoint: 'linkedin.com/in/henry-tsai-6b884014', - }, - { - id: '#github', - type: 'github', - serviceEndpoint: 'github.com/thehenrytsai', - }, - ], - verificationMethod: [ - { - id: '#someKeyId', - controller: 'did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w', - type: 'EcdsaSecp256k1VerificationKey2019', - publicKeyJwk: { - kty: 'EC', - crv: 'secp256k1', - x: 'WfY7Px6AgH6x-_dgAoRbg8weYRJA36ON-gQiFnETrqw', - y: 'IzFx3BUGztK0cyDStiunXbrZYYTtKbOUzx16SUK0sAY', - }, - }, - ], - authentication: ['#someKeyId'], - }, - '@context': 'https://w3id.org/did-resolution/v1', -}; - -export const didEnsResult = { - did: 'did:ens:vitalik.eth', - didDocumentMetadata: {}, - didResolutionMetadata: { - pattern: '^(did:ens:.+)$', - driverUrl: 'http://uni-resolver-driver-did-uport:8081/1.0/identifiers/', - duration: 461, - did: { - didString: 'did:ens:vitalik.eth', - methodSpecificId: 'vitalik.eth', - method: 'ens', - }, - contentType: 'application/did+ld+json', - convertedFrom: 'application/did+json', - convertedTo: 'application/did+ld+json', - }, - didDocument: { - assertionMethod: [ - 'did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - ], - service: [ - { - id: 'did:ens:vitalik.eth#Web3PublicProfile-0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - type: 'Web3PublicProfile', - serviceEndpoint: 'vitalik.eth', - }, - ], - capabilityDelegation: [ - 'did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - ], - id: 'did:ens:vitalik.eth', - verificationMethod: [ - { - id: 'did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - type: 'EcdsaSecp256k1RecoveryMethod2020', - controller: 'did:ens:vitalik.eth', - blockchainAccountId: - '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155:1', - }, - ], - capabilityInvocation: [ - 'did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - ], - authentication: [ - 'did:ens:vitalik.eth#0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - ], - }, - '@context': 'https://w3id.org/did-resolution/v1', -}; - -export const didEbsiResult = { - did: 'did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd', - didDocumentMetadata: {}, - didResolutionMetadata: { - contentType: 'application/did+ld+json', - pattern: '^(did:ebsi:.+)$', - driverUrl: 'https://api-pilot.ebsi.eu/did-registry/v3/identifiers/$1', - duration: 953, - did: { - didString: 'did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd', - methodSpecificId: 'ziE2n8Ckhi6ut5Z8Cexrihd', - method: 'ebsi', - }, - }, - didDocument: { - '@context': [ - 'https://www.w3.org/ns/did/v1', - 'https://w3id.org/security/suites/jws-2020/v1', - ], - authentication: ['did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#key-1'], - service: [], - id: 'did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd', - assertionMethod: ['did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#key-1'], - verificationMethod: [ - { - id: 'did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#key-1', - controller: 'did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd', - type: 'JsonWebKey2020', - publicKeyJwk: { - kty: 'EC', - crv: 'secp256k1', - x: 'masUHNuJ0oH0C_e5rLUu5VKwmU2l-a7rrNTqA__afN8', - y: 'UmGGX_WgRFXbw6qTli9xcQ0owtkZVuUGVyM23e8rZe8', - kid: 'did:ebsi:ziE2n8Ckhi6ut5Z8Cexrihd#keys-1', - }, - }, - ], - }, - '@context': 'https://w3id.org/did-resolution/v1', -}; - -export const didCheqdResult = { - did: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN', - didDocumentMetadata: { - created: '2022-04-05T11:49:19Z', - versionId: '4fa8e367-c70e-533e-babf-3732d9761061', - }, - didResolutionMetadata: { - contentType: 'application/did+ld+json', - retrieved: '2023-06-01T09:34:29Z', - did: { - didString: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN', - methodSpecificId: 'mainnet:Ps1ysXP2Ae6GBfxNhNQNKN', - method: 'cheqd', - }, - pattern: '^(did:cheqd:.+)$', - driverUrl: 'http://cheqd-did-driver:8080/1.0/identifiers/$1', - duration: 1034, - }, - didDocument: { - '@context': [ - 'https://www.w3.org/ns/did/v1', - 'https://w3id.org/security/suites/ed25519-2020/v1', - ], - id: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN', - verificationMethod: [ - { - id: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#key1', - type: 'Ed25519VerificationKey2020', - controller: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN', - publicKeyMultibase: 'z6Mkta7joRuvDh7UnoESdgpr9dDUMh5LvdoECDi3WGrJoscA', - }, - ], - authentication: ['did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#key1'], - service: [ - { - id: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#website', - type: 'LinkedDomains', - serviceEndpoint: ['https://www.cheqd.io'], - }, - { - id: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#non-fungible-image', - type: 'LinkedDomains', - serviceEndpoint: [ - 'https://gateway.ipfs.io/ipfs/bafybeihetj2ng3d74k7t754atv2s5dk76pcqtvxls6dntef3xa6rax25xe', - ], - }, - { - id: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#twitter', - type: 'LinkedDomains', - serviceEndpoint: ['https://twitter.com/cheqd_io'], - }, - { - id: 'did:cheqd:mainnet:Ps1ysXP2Ae6GBfxNhNQNKN#linkedin', - type: 'LinkedDomains', - serviceEndpoint: ['https://www.linkedin.com/company/cheqd-identity/'], - }, - ], - }, - '@context': 'https://w3id.org/did-resolution/v1', -}; - -export const didWebResult = { - did: 'did:web:did.actor:alice', - didDocumentMetadata: {}, - didResolutionMetadata: { - contentType: 'application/did+ld+json', - pattern: '^(did:web:.+)$', - driverUrl: 'http://uni-resolver-driver-did-uport:8081/1.0/identifiers/', - duration: 139, - did: { - didString: 'did:web:did.actor:alice', - methodSpecificId: 'did.actor:alice', - method: 'web', - }, - }, - didDocument: { - '@context': [ - 'https://w3.org/ns/did/v1', - 'https://w3id.org/security/suites/ed25519-2018/v1', - ], - id: 'did:web:did.actor:alice', - publicKey: [ - { - id: 'did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN', - controller: 'did:web:did.actor:alice', - type: 'Ed25519VerificationKey2018', - publicKeyBase58: 'DK7uJiq9PnPnj7AmNZqVBFoLuwTjT1hFPrk6LSjZ2JRz', - }, - ], - authentication: [ - 'did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN', - ], - assertionMethod: [ - 'did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN', - ], - capabilityDelegation: [ - 'did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN', - ], - capabilityInvocation: [ - 'did:web:did.actor:alice#z6MkrmNwty5ajKtFqc1U48oL2MMLjWjartwc5sf2AihZwXDN', - ], - keyAgreement: [ - { - id: 'did:web:did.actor:alice#zC8GybikEfyNaausDA4mkT4egP7SNLx2T1d1kujLQbcP6h', - type: 'X25519KeyAgreementKey2019', - controller: 'did:web:did.actor:alice', - publicKeyBase58: 'CaSHXEvLKS6SfN9aBfkVGBpp15jSnaHazqHgLHp8KZ3Y', - }, - ], - }, - '@context': 'https://w3id.org/did-resolution/v1', -}; diff --git a/packages/snap/tests/utils/ceramicUtils.spec.ts b/packages/snap/tests/unit/ceramic.spec.ts similarity index 91% rename from packages/snap/tests/utils/ceramicUtils.spec.ts rename to packages/snap/tests/unit/ceramic.spec.ts index c552c4ab3..5b9d36168 100644 --- a/packages/snap/tests/utils/ceramicUtils.spec.ts +++ b/packages/snap/tests/unit/ceramic.spec.ts @@ -1,3 +1,4 @@ +// TODO Revisit after composeDB is implemented import { MetaMaskInpageProvider } from '@metamask/providers'; import type { SnapsGlobalObject } from '@metamask/snaps-types'; import type { W3CVerifiableCredential } from '@veramo/core'; @@ -8,12 +9,10 @@ import { veramoQueryVCs, veramoSaveVC, } from '../../src/utils/veramoUtils'; -import { - exampleVC, - exampleVCinVP, - getDefaultSnapState, -} from '../testUtils/constants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import exampleVC from '../data/verifiable-credentials/exampleJWT.json'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; describe('Utils [ceramic]', () => { let snapMock: SnapsGlobalObject & SnapMock; @@ -23,7 +22,7 @@ describe('Utils [ceramic]', () => { snapMock = createMockSnap(); snapMock.rpcMocks.snap_manageState({ operation: 'update', - newState: getDefaultSnapState(), + newState: getDefaultSnapState(account), }); ethereumMock = snapMock as unknown as MetaMaskInpageProvider; @@ -38,7 +37,7 @@ describe('Utils [ceramic]', () => { snapMock = createMockSnap(); snapMock.rpcMocks.snap_manageState({ operation: 'update', - newState: getDefaultSnapState(), + newState: getDefaultSnapState(account), }); global.snap = snapMock; global.ethereum = ethereumMock; @@ -164,7 +163,7 @@ describe('Utils [ceramic]', () => { options: { store: ['ceramic'], returnStore: true }, }); expect(vcs).toHaveLength(1); - expect(vcs[0].data).toStrictEqual(exampleVCinVP); + expect(vcs[0].data).toStrictEqual(exampleVC); expect.assertions(2); }); diff --git a/packages/snap/tests/utils/didUtils.spec.ts b/packages/snap/tests/unit/did.spec.ts similarity index 54% rename from packages/snap/tests/utils/didUtils.spec.ts rename to packages/snap/tests/unit/did.spec.ts index 0320e161b..d48e41da3 100644 --- a/packages/snap/tests/utils/didUtils.spec.ts +++ b/packages/snap/tests/unit/did.spec.ts @@ -1,7 +1,6 @@ import { BIP44CoinTypeNode } from '@metamask/key-tree'; import { MetaMaskInpageProvider } from '@metamask/providers'; import type { SnapsGlobalObject } from '@metamask/snaps-types'; -import elliptic from 'elliptic'; import { changeCurrentMethod, @@ -11,19 +10,20 @@ import { } from '../../src/utils/didUtils'; import { account, - bip44Entropy, - exampleDID, - exampleDIDDocument, - exampleDIDKey, - exampleDIDKeyDocumentUniResovler, - getDefaultSnapState, resolutionInvalidDID, resolutionMethodNotSupported, resolutionNotFound, -} from '../testUtils/constants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; - -const { ec: EC } = elliptic; +} from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { + exampleDIDEthrMainnet, + exampleDIDEthrMainnetDocument, +} from '../data/identifiers/didEthrMainnet'; +import { + exampleDIDKey, + exampleDIDKeyDocument, +} from '../data/identifiers/didKey'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; describe('Utils [did]', () => { let snapMock: SnapsGlobalObject & SnapMock; @@ -33,14 +33,14 @@ describe('Utils [did]', () => { snapMock = createMockSnap(); snapMock.rpcMocks.snap_manageState({ operation: 'update', - newState: getDefaultSnapState(), + newState: getDefaultSnapState(account), }); ethereumMock = snapMock as unknown as MetaMaskInpageProvider; }); describe('changeCurrentVCStore', () => { it("should succeed setting VC store to 'snap'", async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); await expect( changeCurrentVCStore({ @@ -52,7 +52,7 @@ describe('Utils [did]', () => { }) ).resolves.not.toThrow(); - const expectedState = getDefaultSnapState(); + const expectedState = getDefaultSnapState(account); expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ operation: 'update', @@ -63,7 +63,7 @@ describe('Utils [did]', () => { }); it("should succeed setting VC store to 'ceramic'", async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); await expect( changeCurrentVCStore({ @@ -75,7 +75,7 @@ describe('Utils [did]', () => { }) ).resolves.not.toThrow(); - const expectedState = getDefaultSnapState(); + const expectedState = getDefaultSnapState(account); expectedState.accountState[account].accountConfig.ssi.vcStore.ceramic = true; @@ -89,17 +89,14 @@ describe('Utils [did]', () => { }); describe('getCurrentDid', () => { - it('should return did:ethr', async () => { - const initialState = getDefaultSnapState(); + it.skip('should return did:ethr', async () => { + const initialState = getDefaultSnapState(account); - const ctx = new EC('secp256k1'); - const ecPublicKey = ctx.keyFromPublic( - initialState.accountState[account].publicKey.slice(2), - 'hex' - ); - const compactPublicKey = `0x${ecPublicKey.getPublic(true, 'hex')}`; + const bip44Entropy = await snapMock.rpcMocks.snap_getBip44Entropy({ + coinType: 1236, + }); - const expectedDid = `did:ethr:0x5:${compactPublicKey}`; + const expectedDid = `did:ethr:0x5`; await expect( getCurrentDid({ @@ -115,10 +112,14 @@ describe('Utils [did]', () => { }); it('should return did:key', async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); initialState.accountState[account].accountConfig.ssi.didMethod = 'did:key'; + const bip44Entropy = await snapMock.rpcMocks.snap_getBip44Entropy({ + coinType: 1236, + }); + await expect( getCurrentDid({ ethereum: ethereumMock, @@ -134,8 +135,12 @@ describe('Utils [did]', () => { }); describe('changeCurrentMethod', () => { - it("should succeed setting DID method to 'did:ethr'", async () => { - const initialState = getDefaultSnapState(); + it.skip("should succeed setting DID method to 'did:ethr'", async () => { + const initialState = getDefaultSnapState(account); + + const bip44Entropy = await snapMock.rpcMocks.snap_getBip44Entropy({ + coinType: 1236, + }); await expect( changeCurrentMethod({ @@ -144,7 +149,6 @@ describe('Utils [did]', () => { account, ethereum: ethereumMock, bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - didMethod: 'did:ethr', }) ).resolves.toMatch(/(did:ethr)/i); @@ -153,7 +157,11 @@ describe('Utils [did]', () => { }); it("should succeed setting DID method to 'did:key'", async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); + + const bip44Entropy = await snapMock.rpcMocks.snap_getBip44Entropy({ + coinType: 1236, + }); await expect( changeCurrentMethod({ @@ -168,53 +176,53 @@ describe('Utils [did]', () => { expect.assertions(1); }); + }); - describe('resolveDID', () => { - it('should succeed resolving did:ethr identifier', async () => { - const didDoc = await resolveDid({ - did: exampleDID, - snap: snapMock, - ethereum: ethereumMock, - }); - expect(didDoc.didDocument).toEqual(exampleDIDDocument); - expect.assertions(1); + describe('resolveDID', () => { + it('should succeed resolving did:ethr identifier', async () => { + const didDoc = await resolveDid({ + did: exampleDIDEthrMainnet, + snap: snapMock, + ethereum: ethereumMock, }); - it('should succeed resolving did:key identifier', async () => { - const didDoc = await resolveDid({ - did: exampleDIDKey, - snap: snapMock, - ethereum: ethereumMock, - }); - expect(didDoc.didDocument).toEqual(exampleDIDKeyDocumentUniResovler); - expect.assertions(1); + expect(didDoc.didDocument).toEqual(exampleDIDEthrMainnetDocument); + expect.assertions(1); + }); + it('should succeed resolving did:key identifier', async () => { + const didDoc = await resolveDid({ + did: exampleDIDKey, + snap: snapMock, + ethereum: ethereumMock, }); - it('should resolve invalid did', async () => { - const didDoc = await resolveDid({ - did: 'did:ethr:0x5:0x123', - snap: snapMock, - ethereum: ethereumMock, - }); - expect(didDoc).toEqual(resolutionInvalidDID); - expect.assertions(1); + expect(didDoc.didDocument).toEqual(exampleDIDKeyDocument); + expect.assertions(1); + }); + it('should resolve invalid did', async () => { + const didDoc = await resolveDid({ + did: 'did:ethr:0x5:0x123', + snap: snapMock, + ethereum: ethereumMock, }); - it('should resolve nonExisting did', async () => { - const didDoc = await resolveDid({ - did: 'did:key:zQ3shW537', - snap: snapMock, - ethereum: ethereumMock, - }); - expect(didDoc).toEqual(resolutionNotFound); - expect.assertions(1); + expect(didDoc).toEqual(resolutionInvalidDID); + expect.assertions(1); + }); + it('should resolve nonExisting did', async () => { + const didDoc = await resolveDid({ + did: 'did:key:zQ3shW537', + snap: snapMock, + ethereum: ethereumMock, }); - it('should resolve methodNotSupported', async () => { - const didDoc = await resolveDid({ - did: 'did:keyclopse:zQ3shW537', - snap: snapMock, - ethereum: ethereumMock, - }); - expect(didDoc).toEqual(resolutionMethodNotSupported); - expect.assertions(1); + expect(didDoc).toEqual(resolutionNotFound); + expect.assertions(1); + }); + it('should resolve methodNotSupported', async () => { + const didDoc = await resolveDid({ + did: 'did:keyclopse:zQ3shW537', + snap: snapMock, + ethereum: ethereumMock, }); + expect(didDoc).toEqual(resolutionMethodNotSupported); + expect.assertions(1); }); }); }); diff --git a/packages/snap/tests/unit/keyPair.spec.ts b/packages/snap/tests/unit/keyPair.spec.ts new file mode 100644 index 000000000..7ae07dfc4 --- /dev/null +++ b/packages/snap/tests/unit/keyPair.spec.ts @@ -0,0 +1,3 @@ +describe('Utils [keyPair]', () => { + it.todo('Implement tests'); +}); diff --git a/packages/snap/tests/utils/params.spec.ts b/packages/snap/tests/unit/requestParams.spec.ts similarity index 80% rename from packages/snap/tests/utils/params.spec.ts rename to packages/snap/tests/unit/requestParams.spec.ts index 09d8ce06f..deaec55c9 100644 --- a/packages/snap/tests/utils/params.spec.ts +++ b/packages/snap/tests/unit/requestParams.spec.ts @@ -7,29 +7,29 @@ import { isValidSaveVCRequest, isValidSwitchMethodRequest, } from '../../src/utils/params'; -import { - account, - exampleTestVCPayload, - exampleVC, - getDefaultSnapState, -} from '../testUtils/constants'; +import { account } from '../data/constants'; +import * as exampleVCPayload from '../data/credentials/examplePayload.json'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import * as exampleVC from '../data/verifiable-credentials/exampleJWT.json'; describe('Utils [params]', () => { - /* - isValidQueryVCsRequest - */ - describe('isValidQueryVCsRequest', () => { - it.todo('Add test'); - }); describe('isValidResolveDIDRequest', () => { + it('should not fail for proper request', () => { + expect(() => + isValidResolveDIDRequest({ did: 'did:ethr:0x1234321' }) + ).not.toThrow(Error); + }); it('should fail for null', () => { expect(() => isValidResolveDIDRequest(null)).toThrow(Error); }); + it('should fail for wrong type', () => { + expect(() => isValidResolveDIDRequest({ did: 123 })).toThrow(Error); + }); }); describe('isValidQueryRequest', () => { it('should fail for not enabled store', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidQueryRequest({ options: { store: 'ceramic' } }, account, state) @@ -37,17 +37,17 @@ describe('Utils [params]', () => { }); it('should not fail for null', () => { expect(() => - isValidQueryRequest(null, account, getDefaultSnapState()) + isValidQueryRequest(null, account, getDefaultSnapState(account)) ).not.toThrow(Error); }); it('should not fail for undefined', () => { expect(() => - isValidQueryRequest(undefined, account, getDefaultSnapState()) + isValidQueryRequest(undefined, account, getDefaultSnapState(account)) ).not.toThrow(Error); }); it('should not fail for empty object', () => { expect(() => - isValidQueryRequest({}, account, getDefaultSnapState()) + isValidQueryRequest({}, account, getDefaultSnapState(account)) ).not.toThrow(Error); }); it('should not fail for object with filter', () => { @@ -55,7 +55,7 @@ describe('Utils [params]', () => { isValidQueryRequest( { filter: { type: 'abc', filter: {} } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow(Error); }); @@ -64,7 +64,7 @@ describe('Utils [params]', () => { isValidQueryRequest( { filter: { filter: {} } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Filter type is missing or not a string!'); }); @@ -73,13 +73,17 @@ describe('Utils [params]', () => { isValidQueryRequest( { filter: { type: 123, filter: {} } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Filter type is missing or not a string!'); }); it('should not fail for empty options object', () => { expect(() => - isValidQueryRequest({ options: {} }, account, getDefaultSnapState()) + isValidQueryRequest( + { options: {} }, + account, + getDefaultSnapState(account) + ) ).not.toThrow('Filter type is missing or not a string!'); }); it('should not fail for options object with one store', () => { @@ -87,7 +91,7 @@ describe('Utils [params]', () => { isValidQueryRequest( { options: { store: 'snap' } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('Filter type is missing or not a string!'); }); @@ -96,7 +100,7 @@ describe('Utils [params]', () => { isValidQueryRequest( { options: { store: ['snap', 'ceramic'] } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('Filter type is missing or not a string!'); }); @@ -105,7 +109,7 @@ describe('Utils [params]', () => { isValidQueryRequest( { options: { store: ['snapp', 'ceramic'] } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Store snapp is not supported!'); }); @@ -114,7 +118,7 @@ describe('Utils [params]', () => { isValidQueryRequest( { options: { store: true } }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Store is invalid format'); }); @@ -125,7 +129,7 @@ describe('Utils [params]', () => { options: { store: ['snap', 'ceramic'], returnStore: false }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('Filter type is missing or not a string!'); }); @@ -136,41 +140,45 @@ describe('Utils [params]', () => { options: { store: ['snap', 'ceramic'], returnStore: 123 }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('ReturnStore is invalid format'); }); }); /* - isValidSaveVCRequest - */ + isValidSaveVCRequest + */ describe('isValidSaveVCRequest', () => { it('should fail for null', () => { expect(() => - isValidSaveVCRequest(null, account, getDefaultSnapState()) + isValidSaveVCRequest(null, account, getDefaultSnapState(account)) ).toThrow(Error); }); it('should fail for empty object', () => { expect(() => - isValidSaveVCRequest({}, account, getDefaultSnapState()) + isValidSaveVCRequest({}, account, getDefaultSnapState(account)) ).toThrow(Error); }); it('should fail for string', () => { expect(() => - isValidSaveVCRequest('infuraToken', account, getDefaultSnapState()) + isValidSaveVCRequest( + 'infuraToken', + account, + getDefaultSnapState(account) + ) ).toThrow(Error); }); it('should fail for number', () => { expect(() => - isValidSaveVCRequest(42, account, getDefaultSnapState()) + isValidSaveVCRequest(42, account, getDefaultSnapState(account)) ).toThrow(Error); }); it('should fail for not enabled store', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidSaveVCRequest( @@ -183,8 +191,8 @@ describe('Utils [params]', () => { }); /* - isValidCreateVPRequest - */ + isValidCreateVPRequest + */ describe('isValidCreateVPRequest', () => { it('should succeed if vcId is a string', () => { expect(() => @@ -193,7 +201,7 @@ describe('Utils [params]', () => { vcs: [{ id: 'test-id' }, { id: 'test-id-2' }], }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow(); }); @@ -205,32 +213,36 @@ describe('Utils [params]', () => { vcs: [{ id: 'test-id' }, { id: 'test-id-2' }], }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow(); }); it('should fail for null', () => { expect(() => - isValidCreateVPRequest(null, account, getDefaultSnapState()) + isValidCreateVPRequest(null, account, getDefaultSnapState(account)) ).toThrow(Error); }); it('should fail for empty object', () => { expect(() => - isValidCreateVPRequest({}, account, getDefaultSnapState()) + isValidCreateVPRequest({}, account, getDefaultSnapState(account)) ).toThrow(Error); }); it('should fail for string', () => { expect(() => - isValidCreateVPRequest('infuraToken', account, getDefaultSnapState()) + isValidCreateVPRequest( + 'infuraToken', + account, + getDefaultSnapState(account) + ) ).toThrow(Error); }); it('should fail for number', () => { expect(() => - isValidCreateVPRequest(42, account, getDefaultSnapState()) + isValidCreateVPRequest(42, account, getDefaultSnapState(account)) ).toThrow(Error); }); @@ -241,7 +253,7 @@ describe('Utils [params]', () => { vcs: [], }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow(Error); }); @@ -253,7 +265,7 @@ describe('Utils [params]', () => { vcs: null, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Invalid CreateVP request'); }); @@ -265,7 +277,7 @@ describe('Utils [params]', () => { proofFormat: 'wrong', }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Proof format not supported'); }); @@ -277,7 +289,7 @@ describe('Utils [params]', () => { proofFormat: 'jwt', }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('err'); }); @@ -289,7 +301,7 @@ describe('Utils [params]', () => { proofFormat: 'jwt', }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('err'); }); @@ -303,7 +315,7 @@ describe('Utils [params]', () => { proofOptions: {}, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('Store is not supported!'); }); @@ -316,7 +328,7 @@ describe('Utils [params]', () => { proofOptions: { domain: 'test', challenge: 'test' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('Store is not supported!'); }); @@ -329,7 +341,7 @@ describe('Utils [params]', () => { proofOptions: { domain: 123, challenge: 'test' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Domain is not a string'); }); @@ -342,7 +354,7 @@ describe('Utils [params]', () => { proofOptions: { challenge: 123, domain: 'test' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Challenge is not a string'); }); @@ -355,7 +367,7 @@ describe('Utils [params]', () => { proofOptions: { type: 123, challenge: 'test', domain: 'test' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Type is not a string'); }); @@ -373,15 +385,15 @@ describe('Utils [params]', () => { proofOptions: { type: 'Eth', domain: 'test', challenge: 'test' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow('Store is not supported!'); }); }); /* - isValidSwitchMethodRequest - */ + isValidSwitchMethodRequest + */ describe('isValidSwitchMethodRequest', () => { it('should succeed if didMethod is a valid string', () => { expect(() => @@ -424,7 +436,7 @@ describe('Utils [params]', () => { }); describe('isValidDeleteVCsRequest', () => { it('should fail for not enabled store', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidDeleteVCRequest( @@ -439,13 +451,17 @@ describe('Utils [params]', () => { isValidDeleteVCRequest( { didMethod: 42 }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow(Error); }); it('should not throw for string id', () => { expect(() => - isValidDeleteVCRequest({ id: '123' }, account, getDefaultSnapState()) + isValidDeleteVCRequest( + { id: '123' }, + account, + getDefaultSnapState(account) + ) ).not.toThrow(Error); }); it('should not throw for list of string ids', () => { @@ -453,7 +469,7 @@ describe('Utils [params]', () => { isValidDeleteVCRequest( { id: ['123', '456'] }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow(Error); }); @@ -465,7 +481,7 @@ describe('Utils [params]', () => { options: { store: 'snap' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow(Error); }); @@ -477,7 +493,7 @@ describe('Utils [params]', () => { options: { store: ['snap', 'ceramic'] }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).not.toThrow(Error); }); @@ -489,7 +505,7 @@ describe('Utils [params]', () => { options: { store: 'snapp' }, }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('Store snapp is not supported!'); }); @@ -498,24 +514,28 @@ describe('Utils [params]', () => { isValidDeleteVCRequest( { id: ['123', 456] }, account, - getDefaultSnapState() + getDefaultSnapState(account) ) ).toThrow('ID is not a string or array of strings'); }); it('should throw for empty list of ids', () => { expect(() => - isValidDeleteVCRequest({ id: [] }, account, getDefaultSnapState()) + isValidDeleteVCRequest( + { id: [] }, + account, + getDefaultSnapState(account) + ) ).toThrow('ID is not a string or array of strings'); }); }); describe('isValidCreateVCsRequest', () => { it('should pass with only unsignedVC', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, }, account, state @@ -523,12 +543,12 @@ describe('Utils [params]', () => { ).not.toThrow(); }); it('should pass with unsignedVC & PF', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jwt', }, account, @@ -537,12 +557,12 @@ describe('Utils [params]', () => { ).not.toThrow(); }); it('should pass with empty options', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jwt', options: {}, }, @@ -552,12 +572,12 @@ describe('Utils [params]', () => { ).not.toThrow(); }); it('should pass with save option', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jwt', options: { save: true }, }, @@ -567,12 +587,12 @@ describe('Utils [params]', () => { ).not.toThrow(); }); it('should pass with full option', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jwt', options: { save: true, store: ['snap'] }, }, @@ -582,12 +602,12 @@ describe('Utils [params]', () => { ).not.toThrow(); }); it('should fail for not enabled store', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jwt', options: { save: true, store: 'ceramic' }, }, @@ -597,12 +617,12 @@ describe('Utils [params]', () => { ).toThrow('Store ceramic is not enabled!'); }); it('should fail for invalid store', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jwt', options: { save: true, store: 'ceramicc' }, }, @@ -612,12 +632,12 @@ describe('Utils [params]', () => { ).toThrow('Store ceramicc is not supported!'); }); it('should fail for invalid PF', () => { - const state = getDefaultSnapState(); + const state = getDefaultSnapState(account); state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; expect(() => isValidCreateVCRequest( { - minimalUnsignedCredential: exampleTestVCPayload, + minimalUnsignedCredential: exampleVCPayload, proofFormat: 'jws', options: { save: true, store: 'snap' }, }, diff --git a/packages/snap/tests/utils/stateUtils.spec.ts b/packages/snap/tests/unit/state.spec.ts similarity index 70% rename from packages/snap/tests/utils/stateUtils.spec.ts rename to packages/snap/tests/unit/state.spec.ts index f2c52750d..1c5f4bd29 100644 --- a/packages/snap/tests/utils/stateUtils.spec.ts +++ b/packages/snap/tests/unit/state.spec.ts @@ -1,12 +1,7 @@ -import { BIP44CoinTypeNode } from '@metamask/key-tree'; import { MetaMaskInpageProvider } from '@metamask/providers'; import type { SnapsGlobalObject } from '@metamask/snaps-types'; -import { - getEmptyAccountState, - getInitialSnapState, -} from '../../src/utils/config'; -import { setAccountPublicKey } from '../../src/utils/snapUtils'; +import { getInitialSnapState } from '../../src/utils/config'; import { getSnapState, getSnapStateUnchecked, @@ -14,13 +9,9 @@ import { initSnapState, updateSnapState, } from '../../src/utils/stateUtils'; -import { - account, - bip44Entropy, - getDefaultSnapState, - publicKey, -} from '../testUtils/constants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; +import { account } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; describe('Utils [state]', () => { let snapMock: SnapsGlobalObject & SnapMock; @@ -30,14 +21,14 @@ describe('Utils [state]', () => { snapMock = createMockSnap(); snapMock.rpcMocks.snap_manageState({ operation: 'update', - newState: getDefaultSnapState(), + newState: getDefaultSnapState(account), }); ethereumMock = snapMock as unknown as MetaMaskInpageProvider; }); describe('updateSnapState', () => { it('should succeed updating snap state with default state', async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); await expect( updateSnapState(snapMock, initialState) @@ -81,7 +72,7 @@ describe('Utils [state]', () => { }); it('should succeed getting initial snap state', async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); await expect(getSnapState(snapMock)).resolves.toEqual(initialState); @@ -101,7 +92,7 @@ describe('Utils [state]', () => { }); it('should succeed getting initial snap state', async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); await expect(getSnapStateUnchecked(snapMock)).resolves.toEqual( initialState @@ -129,7 +120,7 @@ describe('Utils [state]', () => { describe('initAccountState', () => { it('should succeed initializing empty account state', async () => { const initialState = getInitialSnapState(); - const defaultState = getDefaultSnapState(); + const defaultState = getDefaultSnapState(account); defaultState.accountState[account].publicKey = ''; await expect( @@ -138,33 +129,6 @@ describe('Utils [state]', () => { ethereum: ethereumMock, state: initialState, account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - origin: 'localhost', - }) - ).resolves.not.toThrow(); - - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: initialState, - }); - - expect.assertions(2); - }); - }); - - describe('setPublicKey', () => { - it('should succeed setting public key', async () => { - const initialState = getInitialSnapState(); - initialState.accountState[account] = getEmptyAccountState(); - const defaultState = getDefaultSnapState(); - defaultState.accountState[account].publicKey = publicKey; - await expect( - setAccountPublicKey({ - snap: snapMock, - ethereum: ethereumMock, - state: initialState, - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, origin: 'localhost', }) ).resolves.not.toThrow(); diff --git a/packages/snap/tests/utils/veramoUtils.spec.ts b/packages/snap/tests/unit/veramo.spec.ts similarity index 65% rename from packages/snap/tests/utils/veramoUtils.spec.ts rename to packages/snap/tests/unit/veramo.spec.ts index 8312da08e..e50977739 100644 --- a/packages/snap/tests/utils/veramoUtils.spec.ts +++ b/packages/snap/tests/unit/veramo.spec.ts @@ -3,12 +3,11 @@ import { DIDDataStore } from '@glazed/did-datastore'; import { BIP44CoinTypeNode } from '@metamask/key-tree/dist/BIP44CoinTypeNode'; import { MetaMaskInpageProvider } from '@metamask/providers'; import type { SnapsGlobalObject } from '@metamask/snaps-types'; -import type { IIdentifier } from '@veramo/core'; +import { IIdentifier } from '@veramo/core'; -import * as snapUtils from '../../src/utils/snapUtils'; +import { getEnabledVCStores } from '../../src/utils/snapUtils'; import { veramoClearVCs, - veramoCreateVP, veramoDeleteVC, veramoImportMetaMaskAccount, veramoQueryVCs, @@ -17,34 +16,38 @@ import { } from '../../src/utils/veramoUtils'; import type { StoredCredentials } from '../../src/veramo/plugins/ceramicDataStore/ceramicDataStore'; import { getAgent } from '../../src/veramo/setup'; +import { account, jsonPath } from '../data/constants'; +import { getDefaultSnapState } from '../data/defaultSnapState'; import { - account, - bip44Entropy, - exampleDID, - exampleImportedDIDWIthoutPrivateKey, - exampleVC, - exampleVCEIP712, - exampleVCinVP, - exampleVCJSONLD, - getDefaultSnapState, - jsonPath, -} from '../testUtils/constants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; + exampleDIDKey, + exampleDIDKeyImportedAccount, +} from '../data/identifiers/didKey'; +import exampleVCEIP712 from '../data/verifiable-credentials/exampleEIP712.json'; +import exampleVCJSONLD from '../data/verifiable-credentials/exampleJSONLD.json'; +import exampleVC_2 from '../data/verifiable-credentials/exampleJWT_2.json'; +import exampleVC_3 from '../data/verifiable-credentials/exampleJWT_3.json'; +import exampleVC from '../data/verifiable-credentials/exampleJWT.json'; +import { createMockSnap, SnapMock } from '../helpers/snapMock'; + +const credentials = [exampleVC, exampleVC_2, exampleVC_3, exampleVCEIP712]; describe('Utils [veramo]', () => { let snapMock: SnapsGlobalObject & SnapMock; let ethereumMock: MetaMaskInpageProvider; let ceramicData: StoredCredentials; - - beforeEach(() => { + let bip44Entropy: BIP44CoinTypeNode; + beforeEach(async () => { snapMock = createMockSnap(); snapMock.rpcMocks.snap_manageState({ operation: 'update', - newState: getDefaultSnapState(), + newState: getDefaultSnapState(account), }); ceramicData = {} as StoredCredentials; global.snap = snapMock; ethereumMock = snapMock as unknown as MetaMaskInpageProvider; + bip44Entropy = await snapMock.rpcMocks.snap_getBip44Entropy({ + coinType: 1236, + }); }); beforeAll(() => { @@ -193,7 +196,7 @@ describe('Utils [veramo]', () => { }, ]; - const expectedState = getDefaultSnapState(); + const expectedState = getDefaultSnapState(account); expectedState.accountState[account].vcs[res[0].id] = exampleVC; expect(res).toEqual(expectedResult); expect(snapMock.rpcMocks.snap_manageState).toHaveBeenLastCalledWith({ @@ -297,7 +300,7 @@ describe('Utils [veramo]', () => { expect(res).toIncludeSameMembers(expectedResult); - const expectedState = getDefaultSnapState(); + const expectedState = getDefaultSnapState(account); expectedState.accountState[account].vcs[res[0].id] = exampleVC; await veramoDeleteVC({ snap: snapMock, @@ -331,7 +334,7 @@ describe('Utils [veramo]', () => { store: ['snap'], }); - const expectedState = getDefaultSnapState(); + const expectedState = getDefaultSnapState(account); expectedState.accountState[account].vcs[res[0].id] = exampleVC; expect(snapMock.rpcMocks.snap_manageState).toHaveBeenLastCalledWith({ @@ -363,7 +366,7 @@ describe('Utils [veramo]', () => { store: ['snap'], }); - const expectedState = getDefaultSnapState(); + const expectedState = getDefaultSnapState(account); expectedState.accountState[account].vcs[res[0].id] = exampleVC; expect(snapMock.rpcMocks.snap_manageState).toHaveBeenLastCalledWith({ @@ -401,7 +404,7 @@ describe('Utils [veramo]', () => { }); it('should return all VCs from snap store - toggle ceramicVCStore', async () => { - let state = getDefaultSnapState(); + let state = getDefaultSnapState(account); await veramoSaveVC({ snap: snapMock, @@ -431,7 +434,7 @@ describe('Utils [veramo]', () => { newState: state, }); - const resRet = snapUtils.getEnabledVCStores(account, state); + const resRet = getEnabledVCStores(account, state); expect(resRet).toEqual(['snap']); let queryRes = await veramoQueryVCs({ @@ -459,7 +462,7 @@ describe('Utils [veramo]', () => { newState: state, }); - const resRet2 = snapUtils.getEnabledVCStores(account, state); + const resRet2 = getEnabledVCStores(account, state); expect(resRet2).toEqual(['snap', 'ceramic']); queryRes = await veramoQueryVCs({ @@ -526,8 +529,16 @@ describe('Utils [veramo]', () => { }); expect(vcs).toHaveLength(1); - expect(vcs[0].data).toEqual(exampleVCinVP); - + expect(vcs[0].data).toContainAllKeys([ + 'credentialSubject', + 'issuer', + 'id', + 'type', + 'credentialStatus', + '@context', + 'issuanceDate', + 'proof', + ]); expect.assertions(3); }); @@ -683,7 +694,9 @@ describe('Utils [veramo]', () => { describe('veramoImportMetaMaskAccount', () => { it('should succeed importing metamask account', async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); + initialState.accountState[account].accountConfig.ssi.didMethod = + 'did:key'; snapMock.rpcMocks.snap_manageState.mockResolvedValue(initialState); const agent = await getAgent(snapMock, ethereumMock); expect( @@ -694,22 +707,24 @@ describe('Utils [veramo]', () => { ethereum: ethereumMock, state: initialState, account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, + bip44CoinTypeNode: bip44Entropy, }, agent ) ).did - ).toEqual(exampleDID); + ).toEqual(exampleDIDKey); - await expect(agent.didManagerGet({ did: exampleDID })).resolves.toEqual( - exampleImportedDIDWIthoutPrivateKey - ); + await expect( + agent.didManagerGet({ did: exampleDIDKey }) + ).resolves.toEqual(exampleDIDKeyImportedAccount); expect.assertions(2); }); it('should succeed importing metamask account when DID already exists', async () => { - const initialState = getDefaultSnapState(); + const initialState = getDefaultSnapState(account); + initialState.accountState[account].accountConfig.ssi.didMethod = + 'did:key'; snapMock.rpcMocks.snap_manageState.mockResolvedValue(initialState); const agent = await getAgent(snapMock, ethereumMock); @@ -721,16 +736,16 @@ describe('Utils [veramo]', () => { ethereum: ethereumMock, state: initialState, account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, + bip44CoinTypeNode: bip44Entropy, }, agent ) ).did - ).toEqual(exampleDID); + ).toEqual(exampleDIDKey); - await expect(agent.didManagerGet({ did: exampleDID })).resolves.toEqual( - exampleImportedDIDWIthoutPrivateKey - ); + await expect( + agent.didManagerGet({ did: exampleDIDKey }) + ).resolves.toEqual(exampleDIDKeyImportedAccount); expect( ( await veramoImportMetaMaskAccount( @@ -739,12 +754,12 @@ describe('Utils [veramo]', () => { ethereum: ethereumMock, state: initialState, account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, + bip44CoinTypeNode: bip44Entropy, }, agent ) ).did - ).toEqual(exampleDID); + ).toEqual(exampleDIDKey); expect(await agent.didManagerFind()).toHaveLength(1); @@ -752,84 +767,19 @@ describe('Utils [veramo]', () => { }); }); describe('veramoVerifyData', () => { - it('should succeed validating a VC - JWT', async () => { - const agent = await getAgent(snapMock, ethereumMock); - const identity: IIdentifier = await agent.didManagerCreate({ - provider: 'did:ethr', - kms: 'snap', - }); - - const credential = await agent.createVerifiableCredential({ - proofFormat: 'jwt', - credential: { - issuer: identity.did, - credentialSubject: { - hello: 'world', - }, - }, - }); - - const verifyResult = await veramoVerifyData({ - snap: snapMock, - ethereum: ethereumMock, - data: { credential }, - }); - - expect(verifyResult.verified).toBe(true); - expect.assertions(1); - }); - - it('should succeed validating a VC - Eip712', async () => { - const agent = await getAgent(snapMock, ethereumMock); - const identity: IIdentifier = await agent.didManagerCreate({ - provider: 'did:ethr', - kms: 'snap', - }); - - const credential = await agent.createVerifiableCredential({ - proofFormat: 'EthereumEip712Signature2021', - credential: { - issuer: identity.did, - credentialSubject: { - hello: 'world', - }, - }, - }); - - const verifyResult = await veramoVerifyData({ - snap: snapMock, - ethereum: ethereumMock, - data: { credential }, - }); - - expect(verifyResult.verified).toBe(true); - expect.assertions(1); - }); - - it.skip('should succeed validating a VC - lds', async () => { - const agent = await getAgent(snapMock, ethereumMock); - const identity: IIdentifier = await agent.didManagerCreate({ - provider: 'did:ethr', - kms: 'snap', - }); - - const credential = await agent.createVerifiableCredential({ - proofFormat: 'lds', - credential: { - issuer: identity.did, - credentialSubject: {}, - }, - }); - - const verifyResult = await veramoVerifyData({ - snap: snapMock, - ethereum: ethereumMock, - data: { credential }, - }); + it.each(credentials)( + 'should succeed validating a VC $issuer.id $proof.type', + async (credential) => { + const verifyResult = await veramoVerifyData({ + snap: snapMock, + ethereum: ethereumMock, + data: { credential }, + }); - expect(verifyResult.verified).toBe(true); - expect.assertions(1); - }); + expect(verifyResult.verified).toBe(true); + expect.assertions(1); + } + ); it('should succeed validating a VP - JWT', async () => { const agent = await getAgent(snapMock, ethereumMock); @@ -937,265 +887,265 @@ describe('Utils [veramo]', () => { }); }); - describe('veramoCreateVP', () => { - it('should succeed creating a valid VP', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - const agent = await getAgent(snapMock, ethereumMock); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC, - store: ['snap'], - }); - - const createdVP = await veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { proofFormat: 'jwt', vcs: [exampleVC] } - ); - expect(createdVP).not.toBeNull(); - - const verifyResult = await agent.verifyPresentation({ - presentation: createdVP, - }); - - expect(verifyResult.verified).toBe(true); - - expect.assertions(2); - }); - - it.skip('should succeed creating a valid VP - lds', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - const agent = await getAgent(snapMock, ethereumMock); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - // verifiableCredential: exampleVCJSONLD, - verifiableCredential: exampleVC, - store: ['snap'], - }); - - const createdVP = await veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { - proofFormat: 'lds', - vcs: [{ id: res[0].id }], - proofOptions: { challenge: 'test-challenge' }, - } - ); - - expect(createdVP).not.toBeNull(); - - // Waiting for Veramo to fix this - // await expect( - // await agent.verifyPresentation({ - // presentation: createdVP as VerifiablePresentation, - // challenge: 'test-challenge', - // }) - // ).toThrow(); - // expect(verifyResult.verified).toBe(true); - expect.assertions(1); - }); - - it('should succeed creating a valid VP - eip712', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - const agent = await getAgent(snapMock, ethereumMock); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC, - store: ['snap'], - }); - - const createdVP = await veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { proofFormat: 'EthereumEip712Signature2021', vcs: [exampleVC] } - ); - expect(createdVP).not.toBeNull(); - - const verifyResult = await agent.verifyPresentation({ - presentation: createdVP, - }); - - expect(verifyResult.verified).toBe(true); - - expect.assertions(2); - }); - - it('should succeed creating a valid VP with one false id', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - const agent = await getAgent(snapMock, ethereumMock); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC, - store: ['snap'], - }); - - const createdVP = await veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { proofFormat: 'jwt', vcs: [exampleVC] } - ); - expect(createdVP).not.toBeNull(); - - const verifyResult = await agent.verifyPresentation({ - presentation: createdVP, - }); - - expect(verifyResult.verified).toBe(true); - - expect.assertions(2); - }); - - it('should succeed creating a valid VP with 2 VCs', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - const agent = await getAgent(snapMock, ethereumMock); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC, - store: ['snap'], - }); - - const createdVP = await veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { proofFormat: 'jwt', vcs: [exampleVC, exampleVC] } - ); - expect(createdVP).not.toBeNull(); - - const verifyResult = await agent.verifyPresentation({ - presentation: createdVP, - }); - - expect(createdVP?.verifiableCredential).toStrictEqual([ - exampleVCinVP, - exampleVCinVP, - ]); - - expect(verifyResult.verified).toBe(true); - - expect.assertions(3); - }); - - it('should succeed creating a valid VP with 4 different types of VCs', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - const agent = await getAgent(snapMock, ethereumMock); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC, - store: ['snap'], - }); - const resjwt = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC.proof.jwt, - store: ['snap'], - }); - const res2 = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVCJSONLD, - store: ['snap'], - }); - - const res3 = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVCEIP712, - store: ['snap'], - }); - - const createdVP = await veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { - proofFormat: 'jwt', - vcs: [exampleVC, exampleVC, exampleVCJSONLD, exampleVCEIP712], - } - ); - expect(createdVP).not.toBeNull(); - - const verifyResult = await agent.verifyPresentation({ - presentation: createdVP, - }); - - expect(createdVP?.verifiableCredential).toStrictEqual([ - exampleVCinVP, - exampleVCinVP, - exampleVCJSONLD, - exampleVCEIP712, - ]); - - expect(verifyResult.verified).toBe(true); - - expect.assertions(3); - }); - - it('should fail creating a VP and throw user rejected error', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(false); - - const res = await veramoSaveVC({ - snap: snapMock, - ethereum: ethereumMock, - verifiableCredential: exampleVC, - store: ['snap'], - }); - - await expect( - veramoCreateVP( - { - snap: snapMock, - ethereum: ethereumMock, - state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }, - { proofFormat: 'jwt', vcs: [{ id: res[0].id }] } - ) - ).rejects.toThrow('User rejected create VP request'); - - expect.assertions(1); - }); - }); + // describe('veramoCreateVP', () => { + // it('should succeed creating a valid VP', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); + // const agent = await getAgent(snapMock, ethereumMock); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + + // const createdVP = await veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { proofFormat: 'jwt', vcs: [exampleVC] } + // ); + // expect(createdVP).not.toBeNull(); + + // const verifyResult = await agent.verifyPresentation({ + // presentation: createdVP, + // }); + + // expect(verifyResult.verified).toBe(true); + + // expect.assertions(2); + // }); + + // it.skip('should succeed creating a valid VP - lds', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); + // const agent = await getAgent(snapMock, ethereumMock); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // // verifiableCredential: exampleVCJSONLD, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + + // const createdVP = await veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { + // proofFormat: 'lds', + // vcs: [{ id: res[0].id }], + // proofOptions: { challenge: 'test-challenge' }, + // } + // ); + + // expect(createdVP).not.toBeNull(); + + // // Waiting for Veramo to fix this + // // await expect( + // // await agent.verifyPresentation({ + // // presentation: createdVP as VerifiablePresentation, + // // challenge: 'test-challenge', + // // }) + // // ).toThrow(); + // // expect(verifyResult.verified).toBe(true); + // expect.assertions(1); + // }); + + // it('should succeed creating a valid VP - eip712', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); + // const agent = await getAgent(snapMock, ethereumMock); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + + // const createdVP = await veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { proofFormat: 'EthereumEip712Signature2021', vcs: [exampleVC] } + // ); + // expect(createdVP).not.toBeNull(); + + // const verifyResult = await agent.verifyPresentation({ + // presentation: createdVP, + // }); + + // expect(verifyResult.verified).toBe(true); + + // expect.assertions(2); + // }); + + // it('should succeed creating a valid VP with one false id', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); + // const agent = await getAgent(snapMock, ethereumMock); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + + // const createdVP = await veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { proofFormat: 'jwt', vcs: [exampleVC] } + // ); + // expect(createdVP).not.toBeNull(); + + // const verifyResult = await agent.verifyPresentation({ + // presentation: createdVP, + // }); + + // expect(verifyResult.verified).toBe(true); + + // expect.assertions(2); + // }); + + // it('should succeed creating a valid VP with 2 VCs', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); + // const agent = await getAgent(snapMock, ethereumMock); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + + // const createdVP = await veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { proofFormat: 'jwt', vcs: [exampleVC, exampleVC] } + // ); + // expect(createdVP).not.toBeNull(); + + // const verifyResult = await agent.verifyPresentation({ + // presentation: createdVP, + // }); + + // expect(createdVP?.verifiableCredential).toStrictEqual([ + // exampleVCinVP, + // exampleVCinVP, + // ]); + + // expect(verifyResult.verified).toBe(true); + + // expect.assertions(3); + // }); + + // it('should succeed creating a valid VP with 4 different types of VCs', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); + // const agent = await getAgent(snapMock, ethereumMock); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + // const resjwt = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC.proof.jwt, + // store: ['snap'], + // }); + // const res2 = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVCJSONLD, + // store: ['snap'], + // }); + + // const res3 = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVCEIP712, + // store: ['snap'], + // }); + + // const createdVP = await veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { + // proofFormat: 'jwt', + // vcs: [exampleVC, exampleVC, exampleVCJSONLD, exampleVCEIP712], + // } + // ); + // expect(createdVP).not.toBeNull(); + + // const verifyResult = await agent.verifyPresentation({ + // presentation: createdVP, + // }); + + // expect(createdVP?.verifiableCredential).toStrictEqual([ + // exampleVCinVP, + // exampleVCinVP, + // exampleVCJSONLD, + // exampleVCEIP712, + // ]); + + // expect(verifyResult.verified).toBe(true); + + // expect.assertions(3); + // }); + + // it('should fail creating a VP and throw user rejected error', async () => { + // snapMock.rpcMocks.snap_dialog.mockResolvedValue(false); + + // const res = await veramoSaveVC({ + // snap: snapMock, + // ethereum: ethereumMock, + // verifiableCredential: exampleVC, + // store: ['snap'], + // }); + + // await expect( + // veramoCreateVP( + // { + // snap: snapMock, + // ethereum: ethereumMock, + // state: snapMock.rpcMocks.snap_manageState({ operation: 'get' }), + // account, + // bip44CoinTypeNode: bip44Entropy , + // }, + // { proofFormat: 'jwt', vcs: [{ id: res[0].id }] } + // ) + // ).rejects.toThrow('User rejected create VP request'); + + // expect.assertions(1); + // }); + // }); }); diff --git a/packages/snap/tests/utils/init.spec.ts b/packages/snap/tests/utils/init.spec.ts deleted file mode 100644 index 9f257e774..000000000 --- a/packages/snap/tests/utils/init.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { SnapsGlobalObject } from '@metamask/snaps-types'; - -import { getInitialSnapState } from '../../src/utils/config'; -import { init } from '../../src/utils/init'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; - -describe('RPC handler [init]', () => { - let snapMock: SnapsGlobalObject & SnapMock; - - beforeEach(() => { - snapMock = createMockSnap(); - }); - - it('should succeed for accepted terms and conditions', async () => { - const initialState = getInitialSnapState(); - snapMock.rpcMocks.snap_dialog.mockReturnValueOnce(true); - - await expect(init(snapMock)).resolves.toEqual(initialState); - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: initialState, - }); - - expect.assertions(2); - }); -}); diff --git a/packages/snap/tests/utils/keyPair.spec.ts b/packages/snap/tests/utils/keyPair.spec.ts deleted file mode 100644 index 7fd80fda0..000000000 --- a/packages/snap/tests/utils/keyPair.spec.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { BIP44CoinTypeNode } from '@metamask/key-tree'; -import type { SnapsGlobalObject } from '@metamask/snaps-types'; - -import { getEmptyAccountState } from '../../src/utils/config'; -import { snapGetKeysFromAddress } from '../../src/utils/keyPair'; -import { - account, - account2, - bip44Entropy, - getDefaultSnapState, - privateKey, - privateKey2, - publicKey, - publicKey2, -} from '../testUtils/constants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; - -describe('keyPair', () => { - let snapMock: SnapsGlobalObject & SnapMock; - - beforeEach(() => { - snapMock = createMockSnap(); - }); - - describe('snapGetKeysFromAddress', () => { - it('should get the ground address key of a specific address index from the BIP-44 entropy correctly', async () => { - // Initial state - const initialState = getDefaultSnapState(); - - // Add another account - initialState.accountState[account2] = getEmptyAccountState(); - - // Derive keys for the first account - let res = await snapGetKeysFromAddress({ - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - account, - snap: snapMock, - }); - - expect(res).toStrictEqual({ - account, - addressIndex: 0, - derivationPath: "m / bip32:44' / bip32:60' / bip32:0' / bip32:0", - privateKey, - publicKey, - }); - - // Derive keys for the second account - res = await snapGetKeysFromAddress({ - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - account: account2, - snap: snapMock, - }); - - expect(res).toStrictEqual({ - address: account2, - addressIndex: 1, - derivationPath: "m / bip32:44' / bip32:60' / bip32:0' / bip32:0", - privateKey: privateKey2, - publicKey: publicKey2, - }); - - expect.assertions(2); - }); - - it('should fail to get a ground key', async () => { - const initialState = getDefaultSnapState(); - initialState.accountState['0x'] = getEmptyAccountState(); - - await expect( - snapGetKeysFromAddress({ - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - account: '0x', - snap: snapMock, - }) - ).rejects.toThrow('Failed to get keys'); - - expect.assertions(1); - }); - }); -}); diff --git a/packages/snap/tests/utils/snapUtils.spec.ts b/packages/snap/tests/utils/snapUtils.spec.ts deleted file mode 100644 index 122b0a4f3..000000000 --- a/packages/snap/tests/utils/snapUtils.spec.ts +++ /dev/null @@ -1,344 +0,0 @@ -import { getCompressedPublicKey } from '@blockchain-lab-um/utils'; -import { BIP44CoinTypeNode } from '@metamask/key-tree'; -import { MetaMaskInpageProvider } from '@metamask/providers'; -import type { SnapsGlobalObject } from '@metamask/snaps-types'; - -import { - addFriendlyDapp, - getCurrentAccount, - getCurrentNetwork, - getPublicKey, - removeFriendlyDapp, - snapConfirm, - togglePopups, -} from '../../src/utils/snapUtils'; -import * as snapUtils from '../../src/utils/snapUtils'; -import { - account, - bip44Entropy, - compressedPublicKey, - content, - getDefaultSnapState, - publicKey, -} from '../testUtils/constants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; - -describe('Utils [snap]', () => { - let snapMock: SnapsGlobalObject & SnapMock; - let ethereumMock: MetaMaskInpageProvider; - - beforeEach(() => { - snapMock = createMockSnap(); - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: getDefaultSnapState(), - }); - ethereumMock = snapMock as unknown as MetaMaskInpageProvider; - }); - - describe('getCurrentAccount', () => { - it('should succeed and return test account', () => { - const state = getDefaultSnapState(); - expect(getCurrentAccount(state)).toBe(account); - - expect.assertions(1); - }); - }); - - describe('getCurrentNetwork', () => { - it('should succeed for mainnet (0x1)', async () => { - snapMock.rpcMocks.eth_chainId.mockResolvedValue('0x5'); - - await expect(getCurrentNetwork(ethereumMock)).resolves.toBe('0x5'); - - expect.assertions(1); - }); - - it('should succeed for goerli (0x5)', async () => { - snapMock.rpcMocks.eth_chainId.mockResolvedValue('0x5'); - - await expect(getCurrentNetwork(ethereumMock)).resolves.toBe('0x5'); - - expect.assertions(1); - }); - }); - - describe('togglePopups', () => { - it('should succeed and toggle popups (off -> on)', async () => { - const initialState = getDefaultSnapState(); - - await expect(togglePopups(snapMock, initialState)).resolves.not.toThrow(); - - // Call should be `update` with the correct arguments - const expectedState = getDefaultSnapState(); - expectedState.snapConfig.dApp.disablePopups = true; - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: expectedState, - }); - - expect.assertions(2); - }); - - it('should succeed and toggle popups (on -> off)', async () => { - const initialState = getDefaultSnapState(); - initialState.snapConfig.dApp.disablePopups = true; - - await expect(togglePopups(snapMock, initialState)).resolves.not.toThrow(); - - // Call should be `update` with the correct arguments - const expectedState = getDefaultSnapState(); - expectedState.snapConfig.dApp.disablePopups = false; - - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: expectedState, - }); - - expect.assertions(2); - }); - }); - - describe('addFriendlyDapp', () => { - it('should succeed adding dApp when friendlyDapps empty', async () => { - const dApp = 'test_dApp_42'; - const initialState = getDefaultSnapState(); - - await expect( - addFriendlyDapp(snapMock, initialState, dApp) - ).resolves.not.toThrow(); - - const expectedState = getDefaultSnapState(); - expectedState.snapConfig.dApp.friendlyDapps = [dApp]; - - // Call should be `update` with the correct arguments - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: expectedState, - }); - - expect.assertions(2); - }); - - it('should succeed adding dApp when friendlyDapps not empty', async () => { - const dApp = 'test_dApp_42'; - const initialState = getDefaultSnapState(); - initialState.snapConfig.dApp.friendlyDapps = [ - 'test_dApp_1', - 'test_dApp_2', - 'test_dApp_3', - ]; - - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: initialState, - }); - - await expect( - addFriendlyDapp(snapMock, initialState, dApp) - ).resolves.not.toThrow(); - - const expectedState = getDefaultSnapState(); - expectedState.snapConfig.dApp.friendlyDapps = [ - 'test_dApp_1', - 'test_dApp_2', - 'test_dApp_3', - dApp, - ]; - - // Call should be `update` with the correct arguments - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: expectedState, - }); - - expect.assertions(2); - }); - }); - - describe('removeFriendlyDapp', () => { - it('should succeed removing dApp when there is only one', async () => { - const dApp = 'test_dApp_42'; - const initialState = getDefaultSnapState(); - initialState.snapConfig.dApp.friendlyDapps = [dApp]; - - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: initialState, - }); - - await expect( - removeFriendlyDapp(snapMock, initialState, dApp) - ).resolves.not.toThrow(); - - const expectedState = getDefaultSnapState(); - - // Call should be `update` with the correct arguments - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: expectedState, - }); - - expect.assertions(2); - }); - - it('should succeed removing dApp when there are many', async () => { - const dApp = 'test_dApp_42'; - const initialState = getDefaultSnapState(); - initialState.snapConfig.dApp.friendlyDapps = [ - 'test_dApp_1', - dApp, - 'test_dApp_2', - 'test_dApp_3', - ]; - - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: initialState, - }); - - await expect( - removeFriendlyDapp(snapMock, initialState, dApp) - ).resolves.not.toThrow(); - - const expectedState = getDefaultSnapState(); - expectedState.snapConfig.dApp.friendlyDapps = [ - 'test_dApp_1', - 'test_dApp_2', - 'test_dApp_3', - ]; - - // Call should be `update` with the correct arguments - expect(snapMock.rpcMocks.snap_manageState).toHaveBeenCalledWith({ - operation: 'update', - newState: expectedState, - }); - - expect.assertions(2); - }); - }); - - describe('getPublicKey', () => { - it('should succeed getting public key', async () => { - const initialState = getDefaultSnapState(); - initialState.accountState[account].publicKey = ''; - - await expect( - getPublicKey({ - snap: snapMock, - state: initialState, - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }) - ).resolves.toEqual(publicKey); - - expect.assertions(1); - }); - - it('should succeed getting public key (saved in snap state)', async () => { - const initialState = getDefaultSnapState(); - - await expect( - getPublicKey({ - snap: snapMock, - state: initialState, - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }) - ).resolves.toEqual(publicKey); - - expect.assertions(1); - }); - }); - - describe('getCompressedPublicKey', () => { - it('should generate correct compressed public key', async () => { - const initialState = getDefaultSnapState(); - initialState.accountState[account].publicKey = ''; - const pk = await getPublicKey({ - snap: snapMock, - state: initialState, - account, - bip44CoinTypeNode: bip44Entropy as BIP44CoinTypeNode, - }); - const compressedPK = getCompressedPublicKey(pk); - - expect(compressedPK).toEqual(compressedPublicKey); - }); - }); - - describe('snapConfirm', () => { - it('should return true', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(true); - - await expect(snapConfirm(snapMock, content)).resolves.toBe(true); - expect(snapMock.rpcMocks.snap_dialog).toHaveBeenCalledWith({ - content: { - children: [ - { type: 'heading', value: 'Title of the panel' }, - { type: 'text', value: 'Text of the panel' }, - ], - type: 'panel', - }, - type: 'confirmation', - }); - }); - it('should return false', async () => { - snapMock.rpcMocks.snap_dialog.mockResolvedValue(false); - - await expect(snapConfirm(snapMock, content)).resolves.toBe(false); - expect(snapMock.rpcMocks.snap_dialog).toHaveBeenCalledWith({ - content: { - children: [ - { type: 'heading', value: 'Title of the panel' }, - { type: 'text', value: 'Text of the panel' }, - ], - type: 'panel', - }, - type: 'confirmation', - }); - expect.assertions(2); - }); - }); - - describe('getEnabledVCStores', () => { - it('should return ceramic & snap', () => { - const state = getDefaultSnapState(); - - expect(snapUtils.getEnabledVCStores(account, state)).toEqual([ - 'snap', - 'ceramic', - ]); - - expect.assertions(1); - }); - - it('should return ceramic & snap (when both are passed)', () => { - const state = getDefaultSnapState(); - - expect( - snapUtils.getEnabledVCStores(account, state, ['snap', 'ceramic']) - ).toEqual(['snap', 'ceramic']); - - expect.assertions(1); - }); - - it('should return snap', () => { - const state = getDefaultSnapState(); - state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; - expect(snapUtils.getEnabledVCStores(account, state)).toEqual(['snap']); - - expect.assertions(1); - }); - it('should return snap (when ceramic is passed aswell)', () => { - const state = getDefaultSnapState(); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - state.accountState[account].accountConfig.ssi.vcStore.ceramic = false; - expect( - snapUtils.getEnabledVCStores(account, state, ['snap', 'ceramic']) - ).toEqual(['snap']); - - expect.assertions(1); - }); - }); -}); diff --git a/packages/snap/tests/utils/universalResolver.spec.ts b/packages/snap/tests/utils/universalResolver.spec.ts deleted file mode 100644 index 5ebfdf51d..000000000 --- a/packages/snap/tests/utils/universalResolver.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { MetaMaskInpageProvider } from '@metamask/providers'; -import { SnapsGlobalObject } from '@metamask/snaps-types'; - -import { Agent, getAgent } from '../../src/veramo/setup'; -import { getDefaultSnapState } from '../testUtils/constants'; -import { - didCheqdResult, - didEbsiResult, - didEnsResult, - didIonResult, - // didPolygonidResult, - didWebResult, -} from '../testUtils/didDocumentConstants'; -import { createMockSnap, SnapMock } from '../testUtils/snap.mock'; - -describe('Universal Resolver', () => { - let snapMock: SnapsGlobalObject & SnapMock; - let ethereumMock: MetaMaskInpageProvider; - let agent: Agent; - - const methods = [ - didIonResult, - didEnsResult, - didEbsiResult, - didCheqdResult, - // didPolygonidResult, - didWebResult, - ]; - - beforeAll(async () => { - snapMock = createMockSnap(); - global.snap = snapMock; - snapMock.rpcMocks.snap_manageState({ - operation: 'update', - newState: getDefaultSnapState(), - }); - ethereumMock = snapMock as unknown as MetaMaskInpageProvider; - agent = await getAgent(snapMock, ethereumMock); - }); - - it.each(methods)( - 'should resolve a $didResolutionMetadata.did.method method', - async (method) => { - const res = await agent.resolveDid({ - didUrl: method.did, - }); - - expect(res.didDocument).toEqual(method.didDocument); - expect(res.didDocumentMetadata).toEqual(method.didDocumentMetadata); - expect(res.didResolutionMetadata.did).toEqual( - method.didResolutionMetadata.did - ); - expect.assertions(3); - } - ); - - it('should return an error if the did is not found', async () => { - const res = await agent.resolveDid({ - didUrl: 'did:web:example.com', - }); - - expect(res.didDocument).toBeNull(); - expect(res.didDocumentMetadata).toEqual({}); - expect(res.didResolutionMetadata.error).toEqual('notFound'); - expect.assertions(3); - }); -}); diff --git a/packages/snap/tsconfig.json b/packages/snap/tsconfig.json index bba52371c..1e012ed97 100644 --- a/packages/snap/tsconfig.json +++ b/packages/snap/tsconfig.json @@ -7,8 +7,9 @@ "declaration": true, "inlineSourceMap": true, "incremental": false, - "removeComments": true + "removeComments": true, + "resolveJsonModule": true }, "files": ["jest.d.ts"], - "include": ["src/**/*", "tests/**/*"] + "include": ["src/**/*"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a6a747ac..17c453f55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,10 +159,10 @@ importers: version: 5.2.0 '@veramo/credential-ld': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/credential-w3c': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/data-store': specifier: 5.2.0 version: 5.2.0(better-sqlite3@8.4.0)(ts-node@10.9.1) @@ -376,10 +376,10 @@ importers: version: 5.2.0 '@veramo/credential-ld': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/credential-w3c': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/data-store': specifier: 5.2.0 version: 5.2.0(better-sqlite3@8.4.0)(ts-node@10.9.1) @@ -676,7 +676,7 @@ importers: version: 5.1.2 '@veramo/credential-w3c': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/data-store': specifier: 5.2.0 version: 5.2.0(better-sqlite3@8.4.0)(ts-node@10.9.1) @@ -854,7 +854,7 @@ importers: version: 5.2.0 '@veramo/credential-ld': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/did-manager': specifier: 5.1.2 version: 5.1.2 @@ -927,7 +927,7 @@ importers: version: 5.59.8(eslint@8.41.0)(typescript@5.1.3) '@veramo/cli': specifier: 5.2.0 - version: 5.2.0(@types/node@18.16.15)(expo@48.0.19)(react-native@0.71.11)(ts-node@10.9.1) + version: 5.2.0(@types/node@18.16.15)(expo@48.0.19)(react-native@0.71.10)(ts-node@10.9.1) eslint: specifier: ^8.33.0 version: 8.41.0 @@ -1584,10 +1584,13 @@ importers: version: 5.2.0 '@veramo/credential-ld': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) + '@veramo/credential-status': + specifier: 5.1.2 + version: 5.1.2 '@veramo/credential-w3c': specifier: 5.2.0 - version: 5.2.0(expo@48.0.19)(react-native@0.71.11) + version: 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/did-manager': specifier: 5.1.2 version: 5.1.2 @@ -6010,13 +6013,13 @@ packages: resolution: {integrity: sha512-1xKdJnfITMvrF/sCgwBx2C4p7qcNAARyIvrAOZGqIHmBaT/hAenpC8bf44qVY+UIMuCYP23kqpIfJQebQDThDQ==} engines: {node: '>=12'} - /@digitalcredentials/ed25519-signature-2020@3.0.2(expo@48.0.19)(react-native@0.71.11): + /@digitalcredentials/ed25519-signature-2020@3.0.2(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-R8IrR21Dh+75CYriQov3nVHKaOVusbxfk9gyi6eCAwLHKn6fllUt+2LQfuUrL7Ts/sGIJqQcev7YvkX9GvyYRA==} engines: {node: '>=14'} dependencies: '@digitalcredentials/base58-universal': 1.0.1 '@digitalcredentials/ed25519-verification-key-2020': 3.2.2 - '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.10) ed25519-signature-2018-context: 1.1.0 ed25519-signature-2020-context: 1.1.0 transitivePeerDependencies: @@ -6052,14 +6055,14 @@ packages: - domexception - web-streams-polyfill - /@digitalcredentials/jsonld-signatures@9.3.1(expo@48.0.19)(react-native@0.71.11): + /@digitalcredentials/jsonld-signatures@9.3.1(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-YMh1e1GpTeHDqq2a2Kd+pLcHsMiPeKyE2Zs17NSwqckij7UMRVDQ54S5VQhHvoXZ1mlkpVaI2xtj5M5N6rzylw==} engines: {node: '>=12'} dependencies: '@digitalbazaar/security-context': 1.0.0 - '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.10) fast-text-encoding: 1.0.6 - isomorphic-webcrypto: 2.3.8(expo@48.0.19)(react-native@0.71.11) + isomorphic-webcrypto: 2.3.8(expo@48.0.19)(react-native@0.71.10) serialize-error: 8.1.0 transitivePeerDependencies: - domexception @@ -6067,12 +6070,12 @@ packages: - react-native - web-streams-polyfill - /@digitalcredentials/jsonld@5.2.1(expo@48.0.19)(react-native@0.71.11): + /@digitalcredentials/jsonld@5.2.1(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-pDiO1liw8xs+J/43qnMZsxyz0VOWOb7Q2yUlBt/tyjq6SlT9xPo+3716tJPbjGPnou2lQRw3H5/I++z+6oQ07w==} engines: {node: '>=12'} dependencies: '@digitalcredentials/http-client': 1.2.2 - '@digitalcredentials/rdf-canonize': 1.0.0(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/rdf-canonize': 1.0.0(expo@48.0.19)(react-native@0.71.10) canonicalize: 1.0.8 lru-cache: 6.0.0 transitivePeerDependencies: @@ -6085,22 +6088,22 @@ packages: resolution: {integrity: sha512-g0QvhJMTSFCoUkEvSeggwVTJa2jFkQXjf/mpTn9sePkz+5OouMEDfXUWL61juTaxK5JWPEFc0PKlolXzHaHHHQ==} engines: {node: '>=16.0'} - /@digitalcredentials/rdf-canonize@1.0.0(expo@48.0.19)(react-native@0.71.11): + /@digitalcredentials/rdf-canonize@1.0.0(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-z8St0Ex2doecsExCFK1uI4gJC+a5EqYYu1xpRH1pKmqSS9l/nxfuVxexNFyaeEum4dUdg1EetIC2rTwLIFhPRA==} engines: {node: '>=12'} dependencies: fast-text-encoding: 1.0.6 - isomorphic-webcrypto: 2.3.8(expo@48.0.19)(react-native@0.71.11) + isomorphic-webcrypto: 2.3.8(expo@48.0.19)(react-native@0.71.10) transitivePeerDependencies: - expo - react-native - /@digitalcredentials/vc@5.0.0(expo@48.0.19)(react-native@0.71.11): + /@digitalcredentials/vc@5.0.0(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-87ARRxlAdIuUPArbMYJ8vUY7QqkIvJGFrBwfTH1PcB8Wz1E/M4q3oc/WLrDyJNg4o/irVVB5gkA9iIntTYSpoA==} engines: {node: '>=12'} dependencies: - '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.11) - '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.10) + '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.10) credentials-context: 2.0.0 transitivePeerDependencies: - domexception @@ -8695,7 +8698,7 @@ packages: resolution: {integrity: sha512-o7thG9p8+pijmEcJCWLMNLKEqQzac9ihTZ0BbSFuuyGEfCxK6oiVf2GDmZoldmmwC8u7u3VHjqMwgbblIM9eSg==} engines: {node: '>=14.0.0'} dependencies: - '@metamask/utils': 6.0.0 + '@metamask/utils': 6.0.1 '@noble/secp256k1': 1.7.1 superstruct: 1.0.3 transitivePeerDependencies: @@ -8797,8 +8800,8 @@ packages: - c-kzg - supports-color - /@metamask/utils@6.0.0: - resolution: {integrity: sha512-/0GkcKBFok7ZMwScYef/4YbsJYqFBzTPoQHp+oUF9HFikx1OJe7joG0J8Rnpcbr5NB2dhvAY/aOjZqyJN8yDBQ==} + /@metamask/utils@6.0.1: + resolution: {integrity: sha512-4jk/T5SibXkUommI2b2vZw7XnIAY7KVGa0/oZfL3JgYfwYDqjT306Mq3yLgdRvEnnA5RSbG1ttK0KIr/4O81kw==} engines: {node: '>=16.0.0'} dependencies: '@ethereumjs/tx': 4.1.2 @@ -10189,8 +10192,8 @@ packages: - encoding optional: true - /@react-native-community/cli-platform-ios@10.2.4: - resolution: {integrity: sha512-/6K+jeRhcGojFIJMWMXV2eY5n/In+YUzBr/DKWQOeHBOHkESRNheG310xSAIjgB46YniSSUKhSyeuhalTbm9OQ==} + /@react-native-community/cli-platform-ios@10.2.1: + resolution: {integrity: sha512-hz4zu4Y6eyj7D0lnZx8Mf2c2si8y+zh/zUTgCTaPPLzQD8jSZNNBtUUiA1cARm2razpe8marCZ1QbTMAGbf3mg==} dependencies: '@react-native-community/cli-tools': 10.1.1 chalk: 4.1.2 @@ -10215,19 +10218,19 @@ packages: - encoding optional: true - /@react-native-community/cli-plugin-metro@10.2.3(@babel/core@7.22.5): - resolution: {integrity: sha512-jHi2oDuTePmW4NEyVT8JEGNlIYcnFXCSV2ZMp4rnDrUk4TzzyvS3IMvDlESEmG8Kry8rvP0KSUx/hTpy37Sbkw==} + /@react-native-community/cli-plugin-metro@10.2.2(@babel/core@7.22.5): + resolution: {integrity: sha512-sTGjZlD3OGqbF9v1ajwUIXhGmjw9NyJ/14Lo0sg7xH8Pv4qUd5ZvQ6+DWYrQn3IKFUMfGFWYyL81ovLuPylrpw==} dependencies: '@react-native-community/cli-server-api': 10.1.1 '@react-native-community/cli-tools': 10.1.1 chalk: 4.1.2 execa: 1.0.0 - metro: 0.73.10 - metro-config: 0.73.10 - metro-core: 0.73.10 - metro-react-native-babel-transformer: 0.73.10(@babel/core@7.22.5) - metro-resolver: 0.73.10 - metro-runtime: 0.73.10 + metro: 0.73.9 + metro-config: 0.73.9 + metro-core: 0.73.9 + metro-react-native-babel-transformer: 0.73.9(@babel/core@7.22.5) + metro-resolver: 0.73.9 + metro-runtime: 0.73.9 readline: 1.3.0 transitivePeerDependencies: - '@babel/core' @@ -10278,8 +10281,8 @@ packages: joi: 17.9.2 optional: true - /@react-native-community/cli@10.2.4(@babel/core@7.22.5): - resolution: {integrity: sha512-E9BUDHfLEsnjkjeJqECuCjl4E/1Ox9Nl6hkQBhEqjZm4AaQxgU7M6AyFfOgaXn5v3am16/R4ZOUTrJnGJWS3GA==} + /@react-native-community/cli@10.2.2(@babel/core@7.22.5): + resolution: {integrity: sha512-aZVcVIqj+OG6CrliR/Yn8wHxrvyzbFBY9cj7n0MvRw/P54QUru2nNqUTSSbqv0Qaa297yHJbe6kFDojDMSTM8Q==} engines: {node: '>=14'} hasBin: true dependencies: @@ -10288,7 +10291,7 @@ packages: '@react-native-community/cli-debugger-ui': 10.0.0 '@react-native-community/cli-doctor': 10.2.5 '@react-native-community/cli-hermes': 10.2.0 - '@react-native-community/cli-plugin-metro': 10.2.3(@babel/core@7.22.5) + '@react-native-community/cli-plugin-metro': 10.2.2(@babel/core@7.22.5) '@react-native-community/cli-server-api': 10.1.1 '@react-native-community/cli-tools': 10.1.1 '@react-native-community/cli-types': 10.0.0 @@ -12053,7 +12056,7 @@ packages: wonka: 4.0.15 optional: true - /@veramo/cli@5.2.0(@types/node@18.16.15)(expo@48.0.19)(react-native@0.71.11)(ts-node@10.9.1): + /@veramo/cli@5.2.0(@types/node@18.16.15)(expo@48.0.19)(react-native@0.71.10)(ts-node@10.9.1): resolution: {integrity: sha512-RjWtK91YdGjkJplpdimWvJTe776pGMYrMmfIfH0aKHLRwz8hqeKEGIDiepcQ5HK3eaD1I4t/mLbpedzaoyzZdw==} hasBin: true dependencies: @@ -12065,8 +12068,8 @@ packages: '@veramo/core': 5.2.0 '@veramo/core-types': 5.1.2 '@veramo/credential-eip712': 5.2.0 - '@veramo/credential-ld': 5.2.0(expo@48.0.19)(react-native@0.71.11) - '@veramo/credential-w3c': 5.2.0(expo@48.0.19)(react-native@0.71.11) + '@veramo/credential-ld': 5.2.0(expo@48.0.19)(react-native@0.71.10) + '@veramo/credential-w3c': 5.2.0(expo@48.0.19)(react-native@0.71.10) '@veramo/data-store': 5.2.0(pg@8.11.0)(sqlite3@5.1.6)(ts-node@10.9.1) '@veramo/did-comm': 5.2.0 '@veramo/did-discovery': 5.1.2 @@ -12179,18 +12182,18 @@ packages: - encoding - supports-color - /@veramo/credential-ld@5.2.0(expo@48.0.19)(react-native@0.71.11): + /@veramo/credential-ld@5.2.0(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-tQJpZWq143cxt9DtGTyUp4idqNZdacVpbI2IqsbDiPch1+VOpf7huE5h35CJvLaH0cld0g/+TFiJgVbon642Sw==} dependencies: - '@digitalcredentials/ed25519-signature-2020': 3.0.2(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/ed25519-signature-2020': 3.0.2(expo@48.0.19)(react-native@0.71.10) '@digitalcredentials/ed25519-verification-key-2020': 4.0.0 - '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.11) - '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.11) - '@digitalcredentials/vc': 5.0.0(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.10) + '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.10) + '@digitalcredentials/vc': 5.0.0(expo@48.0.19)(react-native@0.71.10) '@transmute/credentials-context': 0.7.0-unstable.81 '@transmute/ed25519-signature-2018': 0.7.0-unstable.81 '@transmute/json-web-signature': 0.7.0-unstable.81 - '@veramo-community/lds-ecdsa-secp256k1-recovery2020': github.com/uport-project/EcdsaSecp256k1RecoverySignature2020/ab0db52de6f4e6663ef271a48009ba26e688ef9b(expo@48.0.19)(react-native@0.71.11) + '@veramo-community/lds-ecdsa-secp256k1-recovery2020': github.com/uport-project/EcdsaSecp256k1RecoverySignature2020/ab0db52de6f4e6663ef271a48009ba26e688ef9b(expo@48.0.19)(react-native@0.71.10) '@veramo/core-types': 5.1.2 '@veramo/utils': 5.2.0 cross-fetch: 3.1.6(patch_hash=b7u473fsyomrwof2p2enxrunba) @@ -12205,7 +12208,20 @@ packages: - supports-color - web-streams-polyfill - /@veramo/credential-w3c@5.2.0(expo@48.0.19)(react-native@0.71.11): + /@veramo/credential-status@5.1.2: + resolution: {integrity: sha512-ToRLVgQqR3bsL4/jsTtqKcXvI7ktmp2a17JQ+5RHX0McygTLv1mqNcOPfebMC4UMhQkdy4QUbQeaSjPG5S9ZFg==} + dependencies: + '@veramo/core-types': 5.1.2 + '@veramo/utils': 5.2.0 + credential-status: 2.0.5 + did-jwt: 6.11.6 + did-resolver: 4.1.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@veramo/credential-w3c@5.2.0(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-wQ6dzFChBC1DJivzghSDqe4vzZtg/IP1bjhIHh91q4Su4BmPYasvyFcwq0JjgPr4SyrPQGowZUBmGOmLZdM05g==} dependencies: '@veramo/core-types': 5.1.2 @@ -12219,7 +12235,7 @@ packages: uint8arrays: 3.1.1 uuid: 9.0.0 optionalDependencies: - '@veramo/credential-ld': 5.2.0(expo@48.0.19)(react-native@0.71.11) + '@veramo/credential-ld': 5.2.0(expo@48.0.19)(react-native@0.71.10) transitivePeerDependencies: - domexception - encoding @@ -19577,7 +19593,7 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} - /isomorphic-webcrypto@2.3.8(expo@48.0.19)(react-native@0.71.11): + /isomorphic-webcrypto@2.3.8(expo@48.0.19)(react-native@0.71.10): resolution: {integrity: sha512-XddQSI0WYlSCjxtm1AI8kWQOulf7hAN3k3DclF1sxDJZqOe0pcsOt675zvWW91cZH9hYs3nlA3Ev8QK5i80SxQ==} dependencies: '@peculiar/webcrypto': 1.4.3 @@ -19591,7 +19607,7 @@ packages: '@unimodules/core': 7.1.2 '@unimodules/react-native-adapter': 6.3.9 expo-random: 13.1.1(expo@48.0.19) - react-native-securerandom: 0.1.1(react-native@0.71.11) + react-native-securerandom: 0.1.1(react-native@0.71.10) transitivePeerDependencies: - expo - react-native @@ -20181,10 +20197,6 @@ packages: resolution: {integrity: sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==} optional: true - /jsc-safe-url@0.2.4: - resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} - optional: true - /jscodeshift@0.13.1(@babel/preset-env@7.22.5): resolution: {integrity: sha512-lGyiEbGOvmMRKgWk4vf+lUrCWO/8YR8sUR3FKF1Cq5fovjZDlIcw3Hu5ppLHAnEXshVffvaM0eyuY/AbOeYpnQ==} hasBin: true @@ -21062,37 +21074,37 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - /metro-babel-transformer@0.73.10: - resolution: {integrity: sha512-Yv2myTSnpzt/lTyurLvqYbBkytvUJcLHN8XD3t7W6rGiLTQPzmf1zypHQLphvcAXtCWBOXFtH7KLOSi2/qMg+A==} + /metro-babel-transformer@0.73.9: + resolution: {integrity: sha512-DlYwg9wwYIZTHtic7dyD4BP0SDftoltZ3clma76nHu43blMWsCnrImHeHsAVne3XsQ+RJaSRxhN5nkG2VyVHwA==} dependencies: '@babel/core': 7.22.5 hermes-parser: 0.8.0 - metro-source-map: 0.73.10 + metro-source-map: 0.73.9 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color optional: true - /metro-cache-key@0.73.10: - resolution: {integrity: sha512-JMVDl/EREDiUW//cIcUzRjKSwE2AFxVWk47cFBer+KA4ohXIG2CQPEquT56hOw1Y1s6gKNxxs1OlAOEsubrFjw==} + /metro-cache-key@0.73.9: + resolution: {integrity: sha512-uJg+6Al7UoGIuGfoxqPBy6y1Ewq7Y8/YapGYIDh6sohInwt/kYKnPZgLDYHIPvY2deORnQ/2CYo4tOeBTnhCXQ==} optional: true - /metro-cache@0.73.10: - resolution: {integrity: sha512-wPGlQZpdVlM404m7MxJqJ+hTReDr5epvfPbt2LerUAHY9RN99w61FeeAe25BMZBwgUgDtAsfGlJ51MBHg8MAqw==} + /metro-cache@0.73.9: + resolution: {integrity: sha512-upiRxY8rrQkUWj7ieACD6tna7xXuXdu2ZqrheksT79ePI0aN/t0memf6WcyUtJUMHZetke3j+ppELNvlmp3tOw==} dependencies: - metro-core: 0.73.10 + metro-core: 0.73.9 rimraf: 3.0.2 optional: true - /metro-config@0.73.10: - resolution: {integrity: sha512-wIlybd1Z9I8K2KcStTiJxTB7OK529dxFgogNpKCTU/3DxkgAASqSkgXnZP6kVyqjh5EOWAKFe5U6IPic7kXDdQ==} + /metro-config@0.73.9: + resolution: {integrity: sha512-NiWl1nkYtjqecDmw77tbRbXnzIAwdO6DXGZTuKSkH+H/c1NKq1eizO8Fe+NQyFtwR9YLqn8Q0WN1nmkwM1j8CA==} dependencies: cosmiconfig: 5.2.1 jest-validate: 26.6.2 - metro: 0.73.10 - metro-cache: 0.73.10 - metro-core: 0.73.10 - metro-runtime: 0.73.10 + metro: 0.73.9 + metro-cache: 0.73.9 + metro-core: 0.73.9 + metro-runtime: 0.73.9 transitivePeerDependencies: - bufferutil - encoding @@ -21100,15 +21112,15 @@ packages: - utf-8-validate optional: true - /metro-core@0.73.10: - resolution: {integrity: sha512-5uYkajIxKyL6W45iz/ftNnYPe1l92CvF2QJeon1CHsMXkEiOJxEjo41l+iSnO/YodBGrmMCyupSO4wOQGUc0lw==} + /metro-core@0.73.9: + resolution: {integrity: sha512-1NTs0IErlKcFTfYyRT3ljdgrISWpl1nys+gaHkXapzTSpvtX9F1NQNn5cgAuE+XIuTJhbsCdfIJiM2JXbrJQaQ==} dependencies: lodash.throttle: 4.1.1 - metro-resolver: 0.73.10 + metro-resolver: 0.73.9 optional: true - /metro-file-map@0.73.10: - resolution: {integrity: sha512-XOMWAybeaXyD6zmVZPnoCCL2oO3rp4ta76oUlqWP0skBzhFxVtkE/UtDwApEMUY361JeBBago647gnKiARs+1g==} + /metro-file-map@0.73.9: + resolution: {integrity: sha512-R/Wg3HYeQhYY3ehWtfedw8V0ne4lpufG7a21L3GWer8tafnC9pmjoCKEbJz9XZkVj9i1FtxE7UTbrtZNeIILxQ==} dependencies: abort-controller: 3.0.0 anymatch: 3.1.3 @@ -21129,12 +21141,12 @@ packages: - supports-color optional: true - /metro-hermes-compiler@0.73.10: - resolution: {integrity: sha512-rTRWEzkVrwtQLiYkOXhSdsKkIObnL+Jqo+IXHI7VEK2aSLWRAbtGNqECBs44kbOUypDYTFFE+WLtoqvUWqYkWg==} + /metro-hermes-compiler@0.73.9: + resolution: {integrity: sha512-5B3vXIwQkZMSh3DQQY23XpTCpX9kPLqZbA3rDuAcbGW0tzC3f8dCenkyBb0GcCzyTDncJeot/A7oVCVK6zapwg==} optional: true - /metro-inspector-proxy@0.73.10: - resolution: {integrity: sha512-CEEvocYc5xCCZBtGSIggMCiRiXTrnBbh8pmjKQqm9TtJZALeOGyt5pXUaEkKGnhrXETrexsg6yIbsQHhEvVfvQ==} + /metro-inspector-proxy@0.73.9: + resolution: {integrity: sha512-B3WrWZnlYhtTrv0IaX3aUAhi2qVILPAZQzb5paO1e+xrz4YZHk9c7dXv7qe7B/IQ132e3w46y3AL7rFo90qVjA==} hasBin: true dependencies: connect: 3.7.0 @@ -21147,65 +21159,18 @@ packages: - utf-8-validate optional: true - /metro-minify-terser@0.73.10: - resolution: {integrity: sha512-uG7TSKQ/i0p9kM1qXrwbmY3v+6BrMItsOcEXcSP8Z+68bb+t9HeVK0T/hIfUu1v1PEnonhkhfzVsaP8QyTd5lQ==} + /metro-minify-terser@0.73.9: + resolution: {integrity: sha512-MTGPu2qV5qtzPJ2SqH6s58awHDtZ4jd7lmmLR+7TXDwtZDjIBA0YVfI0Zak2Haby2SqoNKrhhUns/b4dPAQAVg==} dependencies: terser: 5.18.1 optional: true - /metro-minify-uglify@0.73.10: - resolution: {integrity: sha512-eocnSeJKnLz/UoYntVFhCJffED7SLSgbCHgNvI6ju6hFb6EFHGJT9OLbkJWeXaWBWD3Zw5mYLS8GGqGn/CHZPA==} + /metro-minify-uglify@0.73.9: + resolution: {integrity: sha512-gzxD/7WjYcnCNGiFJaA26z34rjOp+c/Ft++194Wg91lYep3TeWQ0CnH8t2HRS7AYDHU81SGWgvD3U7WV0g4LGA==} dependencies: uglify-es: 3.3.9 optional: true - /metro-react-native-babel-preset@0.73.10(@babel/core@7.22.5): - resolution: {integrity: sha512-1/dnH4EHwFb2RKEKx34vVDpUS3urt2WEeR8FYim+ogqALg4sTpG7yeQPxWpbgKATezt4rNfqAANpIyH19MS4BQ==} - peerDependencies: - '@babel/core': '*' - dependencies: - '@babel/core': 7.22.5 - '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.22.5) - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.5) - '@babel/plugin-proposal-export-default-from': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.22.5) - '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.22.5) - '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.22.5) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.5) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.5) - '@babel/plugin-syntax-export-default-from': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.5) - '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-classes': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-flow-strip-types': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-react-display-name': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-runtime': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-typescript': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.5) - '@babel/template': 7.22.5 - react-refresh: 0.4.3 - transitivePeerDependencies: - - supports-color - optional: true - /metro-react-native-babel-preset@0.73.9(@babel/core@7.22.5): resolution: {integrity: sha512-AoD7v132iYDV4K78yN2OLgTPwtAKn0XlD2pOhzyBxiI8PeXzozhbKyPV7zUOJUPETj+pcEVfuYj5ZN/8+bhbCw==} peerDependencies: @@ -21253,57 +21218,57 @@ packages: - supports-color optional: true - /metro-react-native-babel-transformer@0.73.10(@babel/core@7.22.5): - resolution: {integrity: sha512-4G/upwqKdmKEjmsNa92/NEgsOxUWOygBVs+FXWfXWKgybrmcjh3NoqdRYrROo9ZRA/sB9Y/ZXKVkWOGKHtGzgg==} + /metro-react-native-babel-transformer@0.73.9(@babel/core@7.22.5): + resolution: {integrity: sha512-DSdrEHuQ22ixY7DyipyKkIcqhOJrt5s6h6X7BYJCP9AMUfXOwLe2biY3BcgJz5GOXv8/Akry4vTCvQscVS1otQ==} peerDependencies: '@babel/core': '*' dependencies: '@babel/core': 7.22.5 babel-preset-fbjs: 3.4.0(@babel/core@7.22.5) hermes-parser: 0.8.0 - metro-babel-transformer: 0.73.10 - metro-react-native-babel-preset: 0.73.10(@babel/core@7.22.5) - metro-source-map: 0.73.10 + metro-babel-transformer: 0.73.9 + metro-react-native-babel-preset: 0.73.9(@babel/core@7.22.5) + metro-source-map: 0.73.9 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color optional: true - /metro-resolver@0.73.10: - resolution: {integrity: sha512-HeXbs+0wjakaaVQ5BI7eT7uqxlZTc9rnyw6cdBWWMgUWB++KpoI0Ge7Hi6eQAOoVAzXC3m26mPFYLejpzTWjng==} + /metro-resolver@0.73.9: + resolution: {integrity: sha512-Ej3wAPOeNRPDnJmkK0zk7vJ33iU07n+oPhpcf5L0NFkWneMmSM2bflMPibI86UjzZGmRfn0AhGhs8yGeBwQ/Xg==} dependencies: absolute-path: 0.0.0 optional: true - /metro-runtime@0.73.10: - resolution: {integrity: sha512-EpVKm4eN0Fgx2PEWpJ5NiMArV8zVoOin866jIIvzFLpmkZz1UEqgjf2JAfUJnjgv3fjSV3JqeGG2vZCaGQBTow==} + /metro-runtime@0.73.9: + resolution: {integrity: sha512-d5Hs83FpKB9r8q8Vb95+fa6ESpwysmPr4lL1I2rM2qXAFiO7OAPT9Bc23WmXgidkBtD0uUFdB2lG+H1ATz8rZg==} dependencies: '@babel/runtime': 7.22.3 react-refresh: 0.4.3 optional: true - /metro-source-map@0.73.10: - resolution: {integrity: sha512-NAGv14701p/YaFZ76KzyPkacBw/QlEJF1f8elfs23N1tC33YyKLDKvPAzFJiYqjdcFvuuuDCA8JCXd2TgLxNPw==} + /metro-source-map@0.73.9: + resolution: {integrity: sha512-l4VZKzdqafipriETYR6lsrwtavCF1+CMhCOY9XbyWeTrpGSNgJQgdeJpttzEZTHQQTLR0csQo0nD1ef3zEP6IQ==} dependencies: '@babel/traverse': 7.22.5 '@babel/types': 7.22.5 invariant: 2.2.4 - metro-symbolicate: 0.73.10 + metro-symbolicate: 0.73.9 nullthrows: 1.1.1 - ob1: 0.73.10 + ob1: 0.73.9 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color optional: true - /metro-symbolicate@0.73.10: - resolution: {integrity: sha512-PmCe3TOe1c/NVwMlB+B17me951kfkB3Wve5RqJn+ErPAj93od1nxicp6OJe7JT4QBRnpUP8p9tw2sHKqceIzkA==} + /metro-symbolicate@0.73.9: + resolution: {integrity: sha512-4TUOwxRHHqbEHxRqRJ3wZY5TA8xq7AHMtXrXcjegMH9FscgYztsrIG9aNBUBS+VLB6g1qc6BYbfIgoAnLjCDyw==} engines: {node: '>=8.3'} hasBin: true dependencies: invariant: 2.2.4 - metro-source-map: 0.73.10 + metro-source-map: 0.73.9 nullthrows: 1.1.1 source-map: 0.5.7 through2: 2.0.5 @@ -21312,8 +21277,8 @@ packages: - supports-color optional: true - /metro-transform-plugins@0.73.10: - resolution: {integrity: sha512-D4AgD3Vsrac+4YksaPmxs/0ocT67bvwTkFSIgWWeDvWwIG0U1iHzTS9f8Bvb4PITnXryDoFtjI6OWF7uOpGxpA==} + /metro-transform-plugins@0.73.9: + resolution: {integrity: sha512-r9NeiqMngmooX2VOKLJVQrMuV7PAydbqst5bFhdVBPcFpZkxxqyzjzo+kzrszGy2UpSQBZr2P1L6OMjLHwQwfQ==} dependencies: '@babel/core': 7.22.5 '@babel/generator': 7.22.5 @@ -21324,21 +21289,21 @@ packages: - supports-color optional: true - /metro-transform-worker@0.73.10: - resolution: {integrity: sha512-IySvVubudFxahxOljWtP0QIMMpgUrCP0bW16cz2Enof0PdumwmR7uU3dTbNq6S+XTzuMHR+076aIe4VhPAWsIQ==} + /metro-transform-worker@0.73.9: + resolution: {integrity: sha512-Rq4b489sIaTUENA+WCvtu9yvlT/C6zFMWhU4sq+97W29Zj0mPBjdk+qGT5n1ZBgtBIJzZWt1KxeYuc17f4aYtQ==} dependencies: '@babel/core': 7.22.5 '@babel/generator': 7.22.5 '@babel/parser': 7.22.5 '@babel/types': 7.22.5 babel-preset-fbjs: 3.4.0(@babel/core@7.22.5) - metro: 0.73.10 - metro-babel-transformer: 0.73.10 - metro-cache: 0.73.10 - metro-cache-key: 0.73.10 - metro-hermes-compiler: 0.73.10 - metro-source-map: 0.73.10 - metro-transform-plugins: 0.73.10 + metro: 0.73.9 + metro-babel-transformer: 0.73.9 + metro-cache: 0.73.9 + metro-cache-key: 0.73.9 + metro-hermes-compiler: 0.73.9 + metro-source-map: 0.73.9 + metro-transform-plugins: 0.73.9 nullthrows: 1.1.1 transitivePeerDependencies: - bufferutil @@ -21347,8 +21312,8 @@ packages: - utf-8-validate optional: true - /metro@0.73.10: - resolution: {integrity: sha512-J2gBhNHFtc/Z48ysF0B/bfTwUwaRDLjNv7egfhQCc+934dpXcjJG2KZFeuybF+CvA9vo4QUi56G2U+RSAJ5tsA==} + /metro@0.73.9: + resolution: {integrity: sha512-BlYbPmTF60hpetyNdKhdvi57dSqutb+/oK0u3ni4emIh78PiI0axGo7RfdsZ/mn3saASXc94tDbpC5yn7+NpEg==} hasBin: true dependencies: '@babel/code-frame': 7.22.5 @@ -21372,25 +21337,24 @@ packages: image-size: 0.6.3 invariant: 2.2.4 jest-worker: 27.5.1 - jsc-safe-url: 0.2.4 lodash.throttle: 4.1.1 - metro-babel-transformer: 0.73.10 - metro-cache: 0.73.10 - metro-cache-key: 0.73.10 - metro-config: 0.73.10 - metro-core: 0.73.10 - metro-file-map: 0.73.10 - metro-hermes-compiler: 0.73.10 - metro-inspector-proxy: 0.73.10 - metro-minify-terser: 0.73.10 - metro-minify-uglify: 0.73.10 - metro-react-native-babel-preset: 0.73.10(@babel/core@7.22.5) - metro-resolver: 0.73.10 - metro-runtime: 0.73.10 - metro-source-map: 0.73.10 - metro-symbolicate: 0.73.10 - metro-transform-plugins: 0.73.10 - metro-transform-worker: 0.73.10 + metro-babel-transformer: 0.73.9 + metro-cache: 0.73.9 + metro-cache-key: 0.73.9 + metro-config: 0.73.9 + metro-core: 0.73.9 + metro-file-map: 0.73.9 + metro-hermes-compiler: 0.73.9 + metro-inspector-proxy: 0.73.9 + metro-minify-terser: 0.73.9 + metro-minify-uglify: 0.73.9 + metro-react-native-babel-preset: 0.73.9(@babel/core@7.22.5) + metro-resolver: 0.73.9 + metro-runtime: 0.73.9 + metro-source-map: 0.73.9 + metro-symbolicate: 0.73.9 + metro-transform-plugins: 0.73.9 + metro-transform-worker: 0.73.9 mime-types: 2.1.35 node-fetch: 2.6.11 nullthrows: 1.1.1 @@ -22323,8 +22287,8 @@ packages: yargs: 17.7.2 dev: true - /ob1@0.73.10: - resolution: {integrity: sha512-aO6EYC+QRRCkZxVJhCWhLKgVjhNuD6Gu1riGjxrIm89CqLsmKgxzYDDEsktmKsoDeRdWGQM5EdMzXDl5xcVfsw==} + /ob1@0.73.9: + resolution: {integrity: sha512-kHOzCOFXmAM26fy7V/YuXNKne2TyRiXbFAvPBIbuedJCZZWQZHLdPzMeXJI4Egt6IcfDttRzN3jQ90wOwq1iNw==} optional: true /object-assign@4.1.1: @@ -24188,27 +24152,27 @@ packages: resolution: {integrity: sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ==} optional: true - /react-native-securerandom@0.1.1(react-native@0.71.11): + /react-native-securerandom@0.1.1(react-native@0.71.10): resolution: {integrity: sha512-CozcCx0lpBLevxiXEb86kwLRalBCHNjiGPlw3P7Fi27U6ZLdfjOCNRHD1LtBKcvPvI3TvkBXB3GOtLvqaYJLGw==} requiresBuild: true peerDependencies: react-native: '*' dependencies: base64-js: 1.5.1 - react-native: 0.71.11(@babel/core@7.22.5)(@babel/preset-env@7.22.5)(react@18.2.0) + react-native: 0.71.10(@babel/core@7.22.5)(@babel/preset-env@7.22.5)(react@18.2.0) optional: true - /react-native@0.71.11(@babel/core@7.22.5)(@babel/preset-env@7.22.5)(react@18.2.0): - resolution: {integrity: sha512-++8IxgUe4Ev+bTiFlLfJCdSoE5cReVP1DTpVJ8f/QtzaxA3h1008Y3Xah1Q5vsR4rZcYMO7Pn3af+wOshdQFug==} + /react-native@0.71.10(@babel/core@7.22.5)(@babel/preset-env@7.22.5)(react@18.2.0): + resolution: {integrity: sha512-O+sWH9ln7euxhHdooVL8is2FiVc7CfAp2zsKgIRhbq/8lGbJr5ZyT6QkCQK0M8Sx1zNe9puebr+BE8uBFsartg==} engines: {node: '>=14'} hasBin: true peerDependencies: react: 18.2.0 dependencies: '@jest/create-cache-key-function': 29.5.0 - '@react-native-community/cli': 10.2.4(@babel/core@7.22.5) + '@react-native-community/cli': 10.2.2(@babel/core@7.22.5) '@react-native-community/cli-platform-android': 10.2.0 - '@react-native-community/cli-platform-ios': 10.2.4 + '@react-native-community/cli-platform-ios': 10.2.1 '@react-native/assets': 1.0.0 '@react-native/normalize-color': 2.1.0 '@react-native/polyfills': 2.0.0 @@ -24221,9 +24185,9 @@ packages: jest-environment-node: 29.5.0 jsc-android: 250231.0.0 memoize-one: 5.2.1 - metro-react-native-babel-transformer: 0.73.10(@babel/core@7.22.5) - metro-runtime: 0.73.10 - metro-source-map: 0.73.10 + metro-react-native-babel-transformer: 0.73.9(@babel/core@7.22.5) + metro-runtime: 0.73.9 + metro-source-map: 0.73.9 mkdirp: 0.5.6 nullthrows: 1.1.1 pretty-format: 26.6.2 @@ -28443,15 +28407,15 @@ packages: version: 1.9.0 dev: false - github.com/uport-project/EcdsaSecp256k1RecoverySignature2020/ab0db52de6f4e6663ef271a48009ba26e688ef9b(expo@48.0.19)(react-native@0.71.11): + github.com/uport-project/EcdsaSecp256k1RecoverySignature2020/ab0db52de6f4e6663ef271a48009ba26e688ef9b(expo@48.0.19)(react-native@0.71.10): resolution: {tarball: https://codeload.github.com/uport-project/EcdsaSecp256k1RecoverySignature2020/tar.gz/ab0db52de6f4e6663ef271a48009ba26e688ef9b} id: github.com/uport-project/EcdsaSecp256k1RecoverySignature2020/ab0db52de6f4e6663ef271a48009ba26e688ef9b name: '@veramo-community/lds-ecdsa-secp256k1-recovery2020' version: 0.0.8 dependencies: '@bitauth/libauth': 1.19.1 - '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.11) - '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.11) + '@digitalcredentials/jsonld': 5.2.1(expo@48.0.19)(react-native@0.71.10) + '@digitalcredentials/jsonld-signatures': 9.3.1(expo@48.0.19)(react-native@0.71.10) '@ethersproject/transactions': 5.7.0 '@trust/keyto': 1.0.1 base64url: 3.0.1