From e23287c239886ab3e88be7cc9d2efeba0357586b Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Thu, 7 Mar 2024 16:46:25 +0100 Subject: [PATCH] Fix/cred status publisher (#193) * Fix nullifier session typo, add types to ZeroKnowledgeProofRequest params * Add mocked publisher --- package-lock.json | 4 +- package.json | 2 +- src/iden3comm/types/protocol/auth.ts | 6 +- src/identity/identity-wallet.ts | 19 +++- src/proof/provers/inputs-generator.ts | 4 +- .../on-chain-revocation.test.ts | 6 +- .../credential-statuses}/rhs.test.ts | 26 ++--- .../sparse-merkle-tree-proof.test.ts | 94 +++++++++++++++++++ 8 files changed, 135 insertions(+), 26 deletions(-) rename tests/{onchain => credentials/credential-statuses}/on-chain-revocation.test.ts (99%) rename tests/{rhs => credentials/credential-statuses}/rhs.test.ts (94%) create mode 100644 tests/credentials/credential-statuses/sparse-merkle-tree-proof.test.ts diff --git a/package-lock.json b/package-lock.json index 12f55eb5..0339fc70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@0xpolygonid/js-sdk", - "version": "1.8.1", + "version": "1.8.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@0xpolygonid/js-sdk", - "version": "1.8.1", + "version": "1.8.2", "license": "AGPL-3.0", "dependencies": { "ajv": "8.12.0", diff --git a/package.json b/package.json index 2dd503b7..4d436368 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@0xpolygonid/js-sdk", - "version": "1.8.1", + "version": "1.8.2", "description": "SDK to work with Polygon ID", "main": "dist/node/cjs/index.js", "module": "dist/node/esm/index.js", diff --git a/src/iden3comm/types/protocol/auth.ts b/src/iden3comm/types/protocol/auth.ts index a1e321d5..8f6fdaf5 100644 --- a/src/iden3comm/types/protocol/auth.ts +++ b/src/iden3comm/types/protocol/auth.ts @@ -1,6 +1,7 @@ import { ZKProof } from '@iden3/js-jwz'; import { MediaType } from '../../constants'; import { JSONObject, ProtocolMessage } from '../packer'; +import { DID } from '@iden3/js-iden3-core'; /** AuthorizationResponseMessage is struct the represents iden3message authorization response */ export type AuthorizationResponseMessage = { @@ -46,7 +47,10 @@ export type ZeroKnowledgeProofRequest = { circuitId: string; optional?: boolean; query: JSONObject; - params?: JSONObject; + params?: { + nullifierSessionId?: string | number; + verifierDid?: DID; + }; }; /** ZeroKnowledgeProofResponse represents structure of zkp response */ diff --git a/src/identity/identity-wallet.ts b/src/identity/identity-wallet.ts index 034f56c3..6d0a6056 100644 --- a/src/identity/identity-wallet.ts +++ b/src/identity/identity-wallet.ts @@ -390,15 +390,26 @@ export class IdentityWallet implements IIdentityWallet { credentialStatusPublisherRegistry?: CredentialStatusPublisherRegistry; } ) { + this._credentialStatusPublisherRegistry = this.getCredentialStatusPublisherRegistry(_opts); + } + + private getCredentialStatusPublisherRegistry( + _opts: + | { credentialStatusPublisherRegistry?: CredentialStatusPublisherRegistry | undefined } + | undefined + ): CredentialStatusPublisherRegistry { if (!_opts?.credentialStatusPublisherRegistry) { - this._credentialStatusPublisherRegistry = new CredentialStatusPublisherRegistry(); - this._credentialStatusPublisherRegistry.register( + const registry = new CredentialStatusPublisherRegistry(); + const emptyPublisher = { publish: () => Promise.resolve() }; + registry.register( CredentialStatusType.Iden3ReverseSparseMerkleTreeProof, new Iden3SmtRhsCredentialStatusPublisher() ); + registry.register(CredentialStatusType.SparseMerkleTreeProof, emptyPublisher); + registry.register(CredentialStatusType.Iden3commRevocationStatusV1, emptyPublisher); + return registry; } else { - this._credentialStatusPublisherRegistry = this._opts - ?.credentialStatusPublisherRegistry as CredentialStatusPublisherRegistry; + return this._opts?.credentialStatusPublisherRegistry as CredentialStatusPublisherRegistry; } } diff --git a/src/proof/provers/inputs-generator.ts b/src/proof/provers/inputs-generator.ts index 223bbf6d..738cd71a 100644 --- a/src/proof/provers/inputs-generator.ts +++ b/src/proof/provers/inputs-generator.ts @@ -523,8 +523,8 @@ export class InputGenerator { circuitInputs.proofType = proofType; circuitInputs.linkNonce = params.linkNonce ?? BigInt(0); circuitInputs.verifierID = params.verifierDid ? DID.idFromDID(params.verifierDid) : undefined; - circuitInputs.nullifierSessionID = proofReq.params?.nullifierSessionID - ? BigInt(proofReq.params?.nullifierSessionID?.toString()) + circuitInputs.nullifierSessionID = proofReq.params?.nullifierSessionId + ? BigInt(proofReq.params?.nullifierSessionId?.toString()) : BigInt(0); let isEthIdentity = true; diff --git a/tests/onchain/on-chain-revocation.test.ts b/tests/credentials/credential-statuses/on-chain-revocation.test.ts similarity index 99% rename from tests/onchain/on-chain-revocation.test.ts rename to tests/credentials/credential-statuses/on-chain-revocation.test.ts index c697e576..d90fbafb 100644 --- a/tests/onchain/on-chain-revocation.test.ts +++ b/tests/credentials/credential-statuses/on-chain-revocation.test.ts @@ -25,7 +25,7 @@ import { Iden3OnchainSmtCredentialStatusPublisher, SDK_EVENTS, MessageBus -} from '../../src'; +} from '../../../src'; import { createIdentity, @@ -34,7 +34,7 @@ import { RPC_URL, WALLET_KEY, RHS_CONTRACT_ADDRESS -} from '../helpers'; +} from '../../helpers'; import chai from 'chai'; import path from 'path'; @@ -190,7 +190,7 @@ describe('onchain revocation checks', () => { beforeEach(async () => { circuitStorage = new FSCircuitStorage({ - dirname: path.join(__dirname, '../proofs/testdata') + dirname: path.join(__dirname, '../../proofs/testdata') }); const ethStorage = new EthStateStorage({ diff --git a/tests/rhs/rhs.test.ts b/tests/credentials/credential-statuses/rhs.test.ts similarity index 94% rename from tests/rhs/rhs.test.ts rename to tests/credentials/credential-statuses/rhs.test.ts index 7a1f0f14..5166751b 100644 --- a/tests/rhs/rhs.test.ts +++ b/tests/credentials/credential-statuses/rhs.test.ts @@ -1,25 +1,25 @@ -import { InMemoryDataSource } from './../../src/storage/memory/data-source'; -import { CredentialStorage } from './../../src/storage/shared/credential-storage'; -import { Identity, IdentityStorage, IdentityWallet, Profile, byteEncoder } from '../../src'; -import { BjjProvider, KMS, KmsKeyType } from '../../src/kms'; -import { InMemoryPrivateKeyStore } from '../../src/kms/store'; -import { IDataStorage, IStateStorage } from '../../src/storage/interfaces'; -import { InMemoryMerkleTreeStorage } from '../../src/storage/memory'; -import { CredentialRequest, CredentialWallet } from '../../src/credentials'; -import { defaultEthConnectionConfig, EthStateStorage } from '../../src/storage/blockchain/state'; +import { InMemoryDataSource } from '../../../src/storage/memory/data-source'; +import { CredentialStorage } from '../../../src/storage/shared/credential-storage'; +import { Identity, IdentityStorage, IdentityWallet, Profile, byteEncoder } from '../../../src'; +import { BjjProvider, KMS, KmsKeyType } from '../../../src/kms'; +import { InMemoryPrivateKeyStore } from '../../../src/kms/store'; +import { IDataStorage, IStateStorage } from '../../../src/storage/interfaces'; +import { InMemoryMerkleTreeStorage } from '../../../src/storage/memory'; +import { CredentialRequest, CredentialWallet } from '../../../src/credentials'; +import { defaultEthConnectionConfig, EthStateStorage } from '../../../src/storage/blockchain/state'; import { CredentialStatus, CredentialStatusType, RevocationStatus, VerifiableConstants, W3CCredential -} from '../../src/verifiable'; +} from '../../../src/verifiable'; import { Proof } from '@iden3/js-merkletree'; -import { RootInfo, StateProof } from '../../src/storage/entities/state'; +import { RootInfo, StateProof } from '../../../src/storage/entities/state'; import { Blockchain, DidMethod, NetworkId } from '@iden3/js-iden3-core'; import { expect } from 'chai'; -import { RHSResolver } from '../../src/credentials'; -import { CredentialStatusResolverRegistry } from '../../src/credentials'; +import { RHSResolver } from '../../../src/credentials'; +import { CredentialStatusResolverRegistry } from '../../../src/credentials'; describe('rhs', () => { let idWallet: IdentityWallet; diff --git a/tests/credentials/credential-statuses/sparse-merkle-tree-proof.test.ts b/tests/credentials/credential-statuses/sparse-merkle-tree-proof.test.ts new file mode 100644 index 00000000..56fdc9d4 --- /dev/null +++ b/tests/credentials/credential-statuses/sparse-merkle-tree-proof.test.ts @@ -0,0 +1,94 @@ +import { IdentityWallet } from '../../../src'; +import { IDataStorage } from '../../../src/storage/interfaces'; +import { CredentialRequest, CredentialWallet } from '../../../src/credentials'; +import { CredentialStatusType } from '../../../src/verifiable'; +import { expect } from 'chai'; +import { + MOCK_STATE_STORAGE, + SEED_USER, + createIdentity, + getInMemoryDataStorage, + registerBJJIntoInMemoryKMS +} from '../../helpers'; +import { DID } from '@iden3/js-iden3-core'; +import fetchMock from '@gr2m/fetch-mock'; +import { Proof, ZERO_HASH } from '@iden3/js-merkletree'; + +describe('SparseMerkleTreeProof', () => { + let idWallet: IdentityWallet; + let credWallet: CredentialWallet; + + let dataStorage: IDataStorage; + + let userDID: DID; + let issuerDID: DID; + const walletUrl = 'https://user-wallet.com'; + const issuerWalletUrl = 'https://issuer.com'; + + beforeEach(async () => { + const kms = registerBJJIntoInMemoryKMS(); + dataStorage = getInMemoryDataStorage(MOCK_STATE_STORAGE); + + credWallet = new CredentialWallet(dataStorage); + idWallet = new IdentityWallet(kms, dataStorage, credWallet); + + const { did: didUser, credential: userAuthCredential } = await createIdentity(idWallet, { + seed: SEED_USER, + revocationOpts: { + type: CredentialStatusType.SparseMerkleTreeProof, + id: walletUrl + } + }); + userDID = didUser; + + expect(userAuthCredential).not.to.be.undefined; + + const { did: didIssuer, credential: issuerAuthCredential } = await createIdentity(idWallet, { + revocationOpts: { + type: CredentialStatusType.SparseMerkleTreeProof, + id: issuerWalletUrl + } + }); + expect(issuerAuthCredential).not.to.be.undefined; + issuerDID = didIssuer; + const mockRevStatus = JSON.stringify({ + mtp: new Proof(), + issuer: { + state: ZERO_HASH.hex(), + claimsTreeRoot: ZERO_HASH.hex(), + revocationTreeRoot: ZERO_HASH.hex(), + rootOfRoots: ZERO_HASH.hex() + } + }); + fetchMock.spy(); + fetchMock.mock(`begin:${walletUrl}`, mockRevStatus); + fetchMock.mock(`begin:${issuerWalletUrl}`, mockRevStatus); + }); + + afterEach(() => { + fetchMock.restore(); + }); + + it('issue credential', async () => { + const credRequest: CredentialRequest = { + credentialSchema: + 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/kyc-nonmerklized.json', + type: 'KYCAgeCredential', + credentialSubject: { + id: userDID.string(), + birthday: 19960424, + documentType: 99 + }, + expiration: 2793526400, + revocationOpts: { + type: CredentialStatusType.SparseMerkleTreeProof, + id: walletUrl + } + }; + const issuedCredential = await idWallet.issueCredential(issuerDID, credRequest); + + await credWallet.save(issuedCredential); + + expect(issuedCredential).not.to.be.undefined; + }); +});