diff --git a/package-lock.json b/package-lock.json index f3e6ca77..9144dcd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@0xpolygonid/js-sdk", - "version": "1.14.1", + "version": "1.15.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@0xpolygonid/js-sdk", - "version": "1.14.1", + "version": "1.15.0", "license": "AGPL-3.0", "dependencies": { "@noble/curves": "^1.4.0", diff --git a/package.json b/package.json index 154ce722..78773fd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@0xpolygonid/js-sdk", - "version": "1.14.1", + "version": "1.15.0", "description": "SDK to work with Polygon ID", "main": "dist/node/cjs/index.js", "module": "dist/node/esm/index.js", diff --git a/src/iden3comm/constants.ts b/src/iden3comm/constants.ts index 95f09235..bfd33d2a 100644 --- a/src/iden3comm/constants.ts +++ b/src/iden3comm/constants.ts @@ -72,3 +72,6 @@ export const SUPPORTED_PUBLIC_KEY_TYPES = { 'JsonWebKey2020' ] }; + +export const DEFAULT_PROOF_VERIFY_DELAY = 1 * 60 * 60 * 1000; // 1 hour +export const DEFAULT_AUTH_VERIFY_DELAY = 5 * 60 * 1000; // 5 minutes diff --git a/src/iden3comm/handlers/auth.ts b/src/iden3comm/handlers/auth.ts index ed2c0afd..82690baa 100644 --- a/src/iden3comm/handlers/auth.ts +++ b/src/iden3comm/handlers/auth.ts @@ -3,6 +3,7 @@ import { IProofService } from '../../proof/proof-service'; import { PROTOCOL_MESSAGE_TYPE } from '../constants'; import { + StateVerificationOpts, AuthorizationRequestMessage, AuthorizationResponseMessage, BasicMessage, @@ -64,19 +65,17 @@ export function createAuthorizationRequestWithMessage( }; return request; } + /** * * Options to pass to auth response handler * * @public - * @interface AuthResponseHandlerOptions */ -export interface AuthResponseHandlerOptions { - // acceptedStateTransitionDelay is the period of time in milliseconds that a revoked state remains valid. - acceptedStateTransitionDelay?: number; +export type AuthResponseHandlerOptions = StateVerificationOpts & { // acceptedProofGenerationDelay is the period of time in milliseconds that a generated proof remains valid. acceptedProofGenerationDelay?: number; -} +}; /** * Interface that allows the processing of the authorization request in the raw format for given identifier diff --git a/src/iden3comm/handlers/credential-proposal.ts b/src/iden3comm/handlers/credential-proposal.ts index 5162381d..7e41dfdd 100644 --- a/src/iden3comm/handlers/credential-proposal.ts +++ b/src/iden3comm/handlers/credential-proposal.ts @@ -1,5 +1,4 @@ -import { PROTOCOL_MESSAGE_TYPE } from '../constants'; -import { MediaType } from '../constants'; +import { PROTOCOL_MESSAGE_TYPE, MediaType } from '../constants'; import { BasicMessage, CredentialOffer, @@ -214,17 +213,22 @@ export class CredentialProposalHandler throw new Error(`failed request. no 'credentials' in body`); } - const senderDID = DID.parse(proposalRequest.from); - let credOfferMessage: CredentialsOfferMessage | undefined = undefined; let proposalMessage: ProposalMessage | undefined = undefined; + for (let i = 0; i < proposalRequest.body.credentials.length; i++) { const cred = proposalRequest.body.credentials[i]; // check if there is credentials in the wallet let credsFromWallet: W3CCredential[] = []; + try { - credsFromWallet = await this._identityWallet.findOwnedCredentialsByDID(senderDID, { + credsFromWallet = await this._identityWallet.credentialWallet.findByQuery({ + credentialSubject: { + id: { + $eq: proposalRequest.from + } + }, type: cred.type, context: cred.context }); diff --git a/src/iden3comm/handlers/message-handler.ts b/src/iden3comm/handlers/message-handler.ts index 2d1dab20..0a608841 100644 --- a/src/iden3comm/handlers/message-handler.ts +++ b/src/iden3comm/handlers/message-handler.ts @@ -3,6 +3,9 @@ import { AuthMessageHandlerOptions } from './auth'; import { RevocationStatusMessageHandlerOptions } from './revocation-status'; import { ContractMessageHandlerOptions } from './contract-request'; import { PaymentHandlerOptions, PaymentRequestMessageHandlerOptions } from './payment'; +import { MediaType } from '../constants'; +import { proving } from '@iden3/js-jwz'; +import { DID } from '@iden3/js-iden3-core'; /** * iden3 Protocol message handler interface */ @@ -120,7 +123,7 @@ export class MessageHandler { | RevocationStatusMessageHandlerOptions | PaymentRequestMessageHandlerOptions | PaymentHandlerOptions - | { [key: string]: unknown } + | { senderDID?: DID; [key: string]: unknown } ): Promise { const { unpackedMediaType, unpackedMessage: message } = await this._params.packageManager.unpack(bytes); @@ -131,10 +134,20 @@ export class MessageHandler { const response = await this.messageHandler.handle(message, context); - if (response) { - return this._params.packageManager.packMessage(unpackedMediaType, response, {}); + if (!response) { + return null; } - return null; + let packerParams = {}; + const senderDID = (context as { senderDID?: DID })?.senderDID; + if (unpackedMediaType === MediaType.ZKPMessage && senderDID) { + packerParams = { + senderDID, + provingMethodAlg: proving.provingMethodGroth16AuthV2Instance.methodAlg + }; + return this._params.packageManager.packMessage(unpackedMediaType, response, packerParams); + } + + return this._params.packageManager.packMessage(MediaType.PlainMessage, response, packerParams); } } diff --git a/src/iden3comm/packers/zkp.ts b/src/iden3comm/packers/zkp.ts index adb1b862..93453cdb 100644 --- a/src/iden3comm/packers/zkp.ts +++ b/src/iden3comm/packers/zkp.ts @@ -1,4 +1,5 @@ import { + StateVerificationOpts, AuthDataPrepareFunc, BasicMessage, IPacker, @@ -9,7 +10,7 @@ import { } from '../types'; import { Token, Header, ProvingMethodAlg, proving } from '@iden3/js-jwz'; import { AuthV2PubSignals, CircuitId } from '../../circuits/index'; -import { DID, Id } from '@iden3/js-iden3-core'; +import { BytesHelper, DID } from '@iden3/js-iden3-core'; import { bytesToProtocolMessage } from '../utils/envelope'; import { ErrNoProvingMethodAlg, @@ -21,6 +22,7 @@ import { } from '../errors'; import { MediaType } from '../constants'; import { byteDecoder, byteEncoder } from '../../utils'; +import { DEFAULT_AUTH_VERIFY_DELAY } from '../constants'; const { getProvingMethod } = proving; @@ -70,8 +72,8 @@ export class VerificationHandlerFunc { * @param {Array} pubSignals - signals that must contain user id and state * @returns `Promise` */ - verify(id: string, pubSignals: Array): Promise { - return this.stateVerificationFunc(id, pubSignals); + verify(id: string, pubSignals: Array, opts?: StateVerificationOpts): Promise { + return this.stateVerificationFunc(id, pubSignals, opts); } } @@ -89,8 +91,11 @@ export class ZKPPacker implements IPacker { * @param {Map} verificationParamsMap - string is derived by JSON.parse(ProvingMethodAlg) */ constructor( - public provingParamsMap: Map, - public verificationParamsMap: Map + public readonly provingParamsMap: Map, + public readonly verificationParamsMap: Map, + private readonly _opts: StateVerificationOpts = { + acceptedStateTransitionDelay: DEFAULT_AUTH_VERIFY_DELAY + } ) {} /** @@ -150,8 +155,10 @@ export class ZKPPacker implements IPacker { const verificationResult = await verificationParams?.verificationFn?.verify( token.circuitId, - token.zkProof.pub_signals + token.zkProof.pub_signals, + this._opts ); + if (!verificationResult) { throw new Error(ErrStateVerificationFailed); } @@ -169,26 +176,31 @@ export class ZKPPacker implements IPacker { } } -const verifySender = (token: Token, msg: BasicMessage): void => { +const verifySender = async (token: Token, msg: BasicMessage): Promise => { switch (token.circuitId) { case CircuitId.AuthV2: - if (!msg.from || !verifyAuthV2Sender(msg.from, token.zkProof.pub_signals)) { - throw new Error(ErrSenderNotUsedTokenCreation); + { + if (!msg.from) { + throw new Error(ErrSenderNotUsedTokenCreation); + } + const authSignals = new AuthV2PubSignals().pubSignalsUnmarshal( + byteEncoder.encode(JSON.stringify(token.zkProof.pub_signals)) + ); + const did = DID.parseFromId(authSignals.userID); + + const msgHash = await token.getMessageHash(); + const challenge = BytesHelper.bytesToInt(msgHash.reverse()); + + if (challenge !== authSignals.challenge) { + throw new Error(ErrSenderNotUsedTokenCreation); + } + + if (msg.from !== did.string()) { + throw new Error(ErrSenderNotUsedTokenCreation); + } } break; default: throw new Error(ErrUnknownCircuitID); } }; - -const verifyAuthV2Sender = (from: string, pubSignals: Array): boolean => { - const authSignals = new AuthV2PubSignals(); - - const pubSig = authSignals.pubSignalsUnmarshal(byteEncoder.encode(JSON.stringify(pubSignals))); - return pubSig.userID ? checkSender(from, pubSig.userID) : false; -}; - -const checkSender = (from: string, id: Id): boolean => { - const did = DID.parseFromId(id); - return from === did.string(); -}; diff --git a/src/iden3comm/types/index.ts b/src/iden3comm/types/index.ts index 83ac6f84..9f08e4cb 100644 --- a/src/iden3comm/types/index.ts +++ b/src/iden3comm/types/index.ts @@ -8,4 +8,5 @@ export * from './protocol/proposal-request'; export * from './protocol/payment'; export * from './packer'; +export * from './models'; export * from './packageManager'; diff --git a/src/iden3comm/types/models.ts b/src/iden3comm/types/models.ts new file mode 100644 index 00000000..df1e6f6d --- /dev/null +++ b/src/iden3comm/types/models.ts @@ -0,0 +1,7 @@ +/** + * State verification options + */ +export type StateVerificationOpts = { + // acceptedStateTransitionDelay is the period of time in milliseconds that a revoked state remains valid. + acceptedStateTransitionDelay?: number; +}; diff --git a/src/iden3comm/types/packer.ts b/src/iden3comm/types/packer.ts index 05790936..4ff0c22a 100644 --- a/src/iden3comm/types/packer.ts +++ b/src/iden3comm/types/packer.ts @@ -4,6 +4,7 @@ import { ProvingMethodAlg } from '@iden3/js-jwz'; import { CircuitId } from '../../circuits'; import { MediaType } from '../constants'; import { DIDDocument, VerificationMethod } from 'did-resolver'; +import { StateVerificationOpts } from './models'; /** * Protocol message type */ @@ -79,7 +80,11 @@ export type AuthDataPrepareFunc = ( /** * signature of state function verifier */ -export type StateVerificationFunc = (id: string, pubSignals: Array) => Promise; +export type StateVerificationFunc = ( + id: string, + pubSignals: Array, + opts?: StateVerificationOpts +) => Promise; /** * Defines method that must be implemented by any packer diff --git a/src/identity/identity-wallet.ts b/src/identity/identity-wallet.ts index cb300875..119200d2 100644 --- a/src/identity/identity-wallet.ts +++ b/src/identity/identity-wallet.ts @@ -140,6 +140,14 @@ export interface IIdentityWallet { */ createIdentity(opts: IdentityCreationOptions): Promise<{ did: DID; credential: W3CCredential }>; + /** + * Credential wallet getter + * + * @returns {ICredentialWallet} + * @memberof IIdentityWallet + */ + get credentialWallet(): ICredentialWallet; + /** * Create Identity based in Ethereum address and it provides an identifier in DID form. * @@ -496,6 +504,10 @@ export class IdentityWallet implements IIdentityWallet { this._transactionService = new TransactionService(_storage.states.getRpcProvider()); } + get credentialWallet(): ICredentialWallet { + return this._credentialWallet; + } + private getCredentialStatusPublisherRegistry( _opts: | { credentialStatusPublisherRegistry?: CredentialStatusPublisherRegistry | undefined } diff --git a/src/proof/proof-service.ts b/src/proof/proof-service.ts index 71bcd4ff..020e6ad6 100644 --- a/src/proof/proof-service.ts +++ b/src/proof/proof-service.ts @@ -1,6 +1,18 @@ -import { BytesHelper, DID, MerklizedRootPosition } from '@iden3/js-iden3-core'; -import { Hash } from '@iden3/js-merkletree'; -import { AuthV2Inputs, CircuitId, Operators, Query, TreeState, ValueProof } from '../circuits'; +import { + BytesHelper, + DID, + MerklizedRootPosition, + getDateFromUnixTimestamp +} from '@iden3/js-iden3-core'; +import { + AuthV2Inputs, + AuthV2PubSignals, + CircuitId, + Operators, + Query, + TreeState, + ValueProof +} from '../circuits'; import { ICredentialWallet } from '../credentials'; import { IIdentityWallet } from '../identity'; import { @@ -22,7 +34,13 @@ import { IZKProver, NativeProver } from './provers/prover'; import { Merklizer, Options, getDocumentLoader } from '@iden3/js-jsonld-merklization'; import { ZKProof } from '@iden3/js-jwz'; import { Signer } from 'ethers'; -import { JSONObject, ZeroKnowledgeProofRequest, ZeroKnowledgeProofResponse } from '../iden3comm'; +import { + StateVerificationOpts, + JSONObject, + ZeroKnowledgeProofRequest, + ZeroKnowledgeProofResponse, + PROTOCOL_CONSTANTS +} from '../iden3comm'; import { cacheLoader } from '../schema-processor'; import { ICircuitStorage, IStateStorage } from '../storage'; import { byteDecoder, byteEncoder } from '../utils/encoding'; @@ -449,11 +467,6 @@ export class ProofService implements IProofService { const authPrepared = await this._inputsGenerator.prepareAuthBJJCredential(genesisDID); - const authClaimData = await this._inputsGenerator.newCircuitClaimData({ - credential: authPrepared.credential, - credentialCoreClaim: authPrepared.coreClaim - }); - const signature = await this._identityWallet.signChallenge(challenge, authPrepared.credential); const id = DID.idFromDID(genesisDID); const stateProof = await this._stateStorage.getGISTProof(id.bigInt()); @@ -464,22 +477,32 @@ export class ProofService implements IProofService { authInputs.genesisID = id; authInputs.profileNonce = BigInt(authProfileNonce); - authInputs.authClaim = authClaimData.claim; - authInputs.authClaimIncMtp = authClaimData.proof; + authInputs.authClaim = authPrepared.coreClaim; + authInputs.authClaimIncMtp = authPrepared.incProof.proof; authInputs.authClaimNonRevMtp = authPrepared.nonRevProof.proof; - authInputs.treeState = authClaimData.treeState; + authInputs.treeState = authPrepared.incProof.treeState; authInputs.signature = signature; authInputs.challenge = challenge; authInputs.gistProof = gistProof; return authInputs.inputsMarshal(); } - async verifyState(circuitId: string, pubSignals: string[]): Promise { + async verifyState( + circuitId: string, + pubSignals: string[], + opts: StateVerificationOpts = { + acceptedStateTransitionDelay: PROTOCOL_CONSTANTS.DEFAULT_AUTH_VERIFY_DELAY + } + ): Promise { if (circuitId !== CircuitId.AuthV2) { throw new Error(`CircuitId is not supported ${circuitId}`); } - const gistRoot = Hash.fromString(pubSignals[2]).bigInt(); - const userId = BigInt(pubSignals[0]); + + const authV2PubSignals = new AuthV2PubSignals().pubSignalsUnmarshal( + byteEncoder.encode(JSON.stringify(pubSignals)) + ); + const gistRoot = authV2PubSignals.GISTRoot.bigInt(); + const userId = authV2PubSignals.userID.bigInt(); const globalStateInfo = await this._stateStorage.getGISTRootInfo(gistRoot, userId); if (globalStateInfo.createdAtTimestamp === 0n) { @@ -494,7 +517,17 @@ export class ProofService implements IProofService { if (globalStateInfo.replacedAtTimestamp === 0n) { throw new Error(`state was replaced, but replaced time unknown`); } - return false; + + const timeDiff = + Date.now() - + getDateFromUnixTimestamp(Number(globalStateInfo.replacedAtTimestamp)).getTime(); + + if ( + timeDiff > + (opts?.acceptedStateTransitionDelay ?? PROTOCOL_CONSTANTS.DEFAULT_AUTH_VERIFY_DELAY) + ) { + throw new Error('global state is outdated'); + } } return true; diff --git a/src/proof/verifiers/pub-signals-verifier.ts b/src/proof/verifiers/pub-signals-verifier.ts index 59db896a..81a06622 100644 --- a/src/proof/verifiers/pub-signals-verifier.ts +++ b/src/proof/verifiers/pub-signals-verifier.ts @@ -1,7 +1,6 @@ import { DID, getDateFromUnixTimestamp, Id } from '@iden3/js-iden3-core'; import { DocumentLoader, getDocumentLoader, Path } from '@iden3/js-jsonld-merklization'; import { Hash } from '@iden3/js-merkletree'; -import { JSONObject } from '../../iden3comm'; import { IStateStorage, RootInfo, StateInfo } from '../../storage'; import { byteEncoder, isGenesisState } from '../../utils'; import { calculateCoreSchemaHash, ProofQuery, ProofType } from '../../verifiable'; @@ -33,6 +32,7 @@ import { parseQueriesMetadata, QueryMetadata } from '../common'; import { Operators } from '../../circuits'; import { calculateQueryHashV3 } from './query-hash'; import { JsonLd } from 'jsonld/jsonld-spec'; +import { PROTOCOL_CONSTANTS, JSONObject } from '../../iden3comm'; /** * Verify Context - params for pub signal verification @@ -50,8 +50,6 @@ export type VerifyContext = { export const userStateError = new Error(`user state is not valid`); const zeroInt = 0n; -const defaultProofVerifyOpts = 1 * 60 * 60 * 1000; // 1 hour -const defaultAuthVerifyOpts = 5 * 60 * 1000; // 5 minutes /** * PubSignalsVerifier provides verify method @@ -395,7 +393,7 @@ export class PubSignalsVerifier { // verify state const gist = await this.checkGlobalState(authV2PubSignals.GISTRoot, this.userId); - let acceptedStateTransitionDelay = defaultAuthVerifyOpts; + let acceptedStateTransitionDelay = PROTOCOL_CONSTANTS.DEFAULT_AUTH_VERIFY_DELAY; if (opts?.acceptedStateTransitionDelay) { acceptedStateTransitionDelay = opts.acceptedStateTransitionDelay; } @@ -604,7 +602,7 @@ export class PubSignalsVerifier { } catch (e) { const stateNotExistErr = ((e as unknown as { errorArgs: string[] })?.errorArgs ?? [])[0]; const errMsg = stateNotExistErr || (e as unknown as Error).message; - if (errMsg === 'State does not exist') { + if (errMsg.includes('State does not exist')) { if (isGenesis) { return { latest: true, @@ -714,7 +712,7 @@ export class PubSignalsVerifier { ); const acceptedStateTransitionDelay = - opts?.acceptedStateTransitionDelay ?? defaultProofVerifyOpts; + opts?.acceptedStateTransitionDelay ?? PROTOCOL_CONSTANTS.DEFAULT_PROOF_VERIFY_DELAY; if (!issuerNonRevStateResolved.latest) { const timeDiff = diff --git a/tests/handlers/auth.test.ts b/tests/handlers/auth.test.ts index 6fb7c0d1..c28b0ab2 100644 --- a/tests/handlers/auth.test.ts +++ b/tests/handlers/auth.test.ts @@ -43,13 +43,12 @@ import { NativeProver, VerifiableConstants } from '../../src'; -import { Token } from '@iden3/js-jwz'; +import { ProvingMethodAlg, Token } from '@iden3/js-jwz'; import { Blockchain, DID, DidMethod, NetworkId } from '@iden3/js-iden3-core'; import { expect } from 'chai'; import { ethers } from 'ethers'; import * as uuid from 'uuid'; import { - MOCK_STATE_STORAGE, getInMemoryDataStorage, registerKeyProvidersInMemoryKMS, IPFS_URL, @@ -61,8 +60,10 @@ import { STATE_CONTRACT, RPC_URL, SEED_ISSUER, - TEST_VERIFICATION_OPTS + TEST_VERIFICATION_OPTS, + MOCK_STATE_STORAGE } from '../helpers'; +import { getRandomBytes } from '@iden3/js-crypto'; describe('auth', () => { let idWallet: IdentityWallet; @@ -813,34 +814,6 @@ describe('auth', () => { expect(token).to.be.a('object'); }); - it('auth response: TestVerifyMessageWithoutProof', async () => { - const sender = '1125GJqgw6YEsKFwj63GY87MMxPL9kwDKxPUiwMLNZ'; - const userId = '119tqceWdRd2F6WnAyVuFQRFjK3WUXq2LorSPyG9LJ'; - const callback = 'https://test.com/callback'; - const msg = 'message to sign'; - const request: AuthorizationRequestMessage = createAuthorizationRequestWithMessage( - 'kyc verification', - msg, - sender, - callback - ); - - const response: AuthorizationResponseMessage = { - id: uuid.v4(), - thid: request.thid, - typ: request.typ, - type: PROTOCOL_CONSTANTS.PROTOCOL_MESSAGE_TYPE.AUTHORIZATION_RESPONSE_MESSAGE_TYPE, - from: userId, - to: sender, - body: { - message: request.body.message, - scope: [] - } - }; - - await authHandler.handleAuthorizationResponse(response, request); - }); - it('auth response: TestVerifyWithAtomicMTPProof', async () => { const sender = 'did:polygonid:polygon:mumbai:1125GJqgw6YEsKFwj63GY87MMxPL9kwDKxPUiwMLNZ'; const callback = 'https://test.com/callback'; @@ -1580,6 +1553,43 @@ describe('auth', () => { }); it('auth response: TestVerifyV3MessageWithMtpProof_Merklized_exists', async () => { + const stateEthConfig = defaultEthConnectionConfig; + stateEthConfig.url = RPC_URL; + stateEthConfig.contractAddress = STATE_CONTRACT; + const eth = new EthStateStorage(stateEthConfig); + + const kms = registerKeyProvidersInMemoryKMS(); + dataStorage = getInMemoryDataStorage(eth); + const circuitStorage = new FSCircuitStorage({ + dirname: path.join(__dirname, '../proofs/testdata') + }); + + const resolvers = new CredentialStatusResolverRegistry(); + resolvers.register( + CredentialStatusType.Iden3ReverseSparseMerkleTreeProof, + new RHSResolver(dataStorage.states) + ); + credWallet = new CredentialWallet(dataStorage, resolvers); + idWallet = new IdentityWallet(kms, dataStorage, credWallet); + + proofService = new ProofService(idWallet, credWallet, circuitStorage, eth, { + ipfsNodeURL: IPFS_URL + }); + const { did: issuerDID } = await createIdentity(idWallet, { + seed: getRandomBytes(32) + }); + const { did: userDID } = await createIdentity(idWallet, { + seed: getRandomBytes(32) + }); + + packageMgr = await getPackageMgr( + await circuitStorage.loadCircuitData(CircuitId.AuthV2), + proofService.generateAuthV2Inputs.bind(proofService), + proofService.verifyState.bind(proofService) + ); + + authHandler = new AuthHandler(packageMgr, proofService); + const claimReq: CredentialRequest = { credentialSchema: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v4.json', @@ -1639,11 +1649,64 @@ describe('auth', () => { const tokenStr = authRes.token; expect(tokenStr).to.be.a('string'); - await authHandler.handleAuthorizationResponse( + const { response } = await authHandler.handleAuthorizationResponse( + authRes.authResponse, + authReq, + TEST_VERIFICATION_OPTS + ); + + const token = await packageMgr.pack( + PROTOCOL_CONSTANTS.MediaType.ZKPMessage, + byteEncoder.encode(JSON.stringify(response)), + { + senderDID: issuerDID, + provingMethodAlg: new ProvingMethodAlg('groth16', 'authV2') + } + ); + + expect(token).to.be.a.string; + + const res = await idWallet.addCredentialsToMerkleTree([issuerCred], issuerDID); + + // publish to rhs + + await idWallet.publishStateToRHS(issuerDID, RHS_URL); + + // you must store stat info (e.g. state and it's roots) + + const ethSigner = new ethers.Wallet(WALLET_KEY, dataStorage.states.getRpcProvider()); + const txId = await proofService.transitState( + issuerDID, + res.oldTreeState, + true, + dataStorage.states, + ethSigner + ); + + const credsWithIden3MTPProof = await idWallet.generateIden3SparseMerkleTreeProof( + issuerDID, + res.credentials, + txId + ); + + await credWallet.saveAll(credsWithIden3MTPProof); + + const { response: resp2 } = await authHandler.handleAuthorizationResponse( authRes.authResponse, authReq, TEST_VERIFICATION_OPTS ); + + const token2 = await packageMgr.pack( + PROTOCOL_CONSTANTS.MediaType.ZKPMessage, + byteEncoder.encode(JSON.stringify(resp2)), + { + senderDID: issuerDID, + provingMethodAlg: new ProvingMethodAlg('groth16', 'authV2') + } + ); + + expect(token2).to.be.a.string; }); it('auth response: TestVerifyV3MessageWithMtpProof_Merklized_noop', async () => { @@ -1700,12 +1763,6 @@ describe('auth', () => { const tokenStr = authRes.token; expect(tokenStr).to.be.a('string'); - - await authHandler.handleAuthorizationResponse( - authRes.authResponse, - authReq, - TEST_VERIFICATION_OPTS - ); }); it('auth response: TestVerify v2 sig sd', async () => {