Skip to content

Commit

Permalink
add contract-request unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
volodymyr-basiuk committed Sep 28, 2023
1 parent 7444338 commit 553d631
Showing 1 changed file with 273 additions and 0 deletions.
273 changes: 273 additions & 0 deletions tests/handlers/contract-request.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
/* eslint-disable no-console */
import { Identity, Profile } from '../../src/storage/entities/identity';
import { IdentityStorage } from '../../src/storage/shared/identity-storage';
import { PlainPacker } from '../../src/iden3comm/packers/plain';
import {
CredentialStorage,
FSCircuitStorage,
IdentityWallet,
byteEncoder
} from '../../src';
import { BjjProvider, KMS, KmsKeyType } from '../../src/kms';
import { InMemoryPrivateKeyStore } from '../../src/kms/store';
import { IDataStorage, IStateStorage, IZKPVerifier } from '../../src/storage/interfaces';
import { InMemoryDataSource, InMemoryMerkleTreeStorage } from '../../src/storage/memory';
import { CredentialRequest, CredentialWallet } from '../../src/credentials';
import { ProofService } from '../../src/proof';
import { CircuitId } from '../../src/circuits';
import { CredentialStatusType, VerifiableConstants, W3CCredential } from '../../src/verifiable';
import { RootInfo, StateProof } from '../../src/storage/entities/state';
import path from 'path';
import { CircuitData } from '../../src/storage/entities/circuitData';
import {
AuthDataPrepareFunc,
ContractInvokeRequest,
ContractInvokeRequestBody,
ContractInvokeTransactionData,
ContractRequestHandler,
DataPrepareHandlerFunc,
IContractRequestHandler,
IPackageManager,
PackageManager,
ProvingParams,
StateVerificationFunc,
VerificationHandlerFunc,
VerificationParams,
ZeroKnowledgeProofRequest,
ZKPPacker
} from '../../src/iden3comm';
import { proving, ZKProof } from '@iden3/js-jwz';
import * as uuid from 'uuid';
import { MediaType, PROTOCOL_MESSAGE_TYPE } from '../../src/iden3comm/constants';
import { Blockchain, DidMethod, NetworkId } from '@iden3/js-iden3-core';
import { expect } from 'chai';
import { CredentialStatusResolverRegistry } from '../../src/credentials';
import { RHSResolver } from '../../src/credentials';

describe('contact-request', () => {
let idWallet: IdentityWallet;
let credWallet: CredentialWallet;

let dataStorage: IDataStorage;
let proofService: ProofService;
let contractRequest: IContractRequestHandler;
let packageMgr: IPackageManager;
const rhsUrl = process.env.RHS_URL as string;
const ipfsNodeURL = process.env.IPFS_URL as string;

const seedPhraseIssuer: Uint8Array = byteEncoder.encode('seedseedseedseedseedseedseedseed');
const seedPhrase: Uint8Array = byteEncoder.encode('seedseedseedseedseedseedseeduser');

const mockStateStorage: IStateStorage = {
getLatestStateById: async () => {
throw new Error(VerifiableConstants.ERRORS.IDENTITY_DOES_NOT_EXIST);
},
publishState: async () => {
return '0xc837f95c984892dbcc3ac41812ecb145fedc26d7003202c50e1b87e226a9b33c';
},
getGISTProof: (): Promise<StateProof> => {
return Promise.resolve({
root: 0n,
existence: false,
siblings: [],
index: 0n,
value: 0n,
auxExistence: false,
auxIndex: 0n,
auxValue: 0n
});
},
getGISTRootInfo: (): Promise<RootInfo> => {
return Promise.resolve({
root: 0n,
replacedByRoot: 0n,
createdAtTimestamp: 0n,
replacedAtTimestamp: 0n,
createdAtBlock: 0n,
replacedAtBlock: 0n
});
}

Check warning on line 89 in tests/handlers/contract-request.test.ts

View workflow job for this annotation

GitHub Actions / build (18.16.1)

'address' is defined but never used
};

Check warning on line 90 in tests/handlers/contract-request.test.ts

View workflow job for this annotation

GitHub Actions / build (18.16.1)

'chain_id' is defined but never used

Check warning on line 91 in tests/handlers/contract-request.test.ts

View workflow job for this annotation

GitHub Actions / build (18.16.1)

'requestIdProofs' is defined but never used
const mockZKPVerifier: IZKPVerifier = {
submitZKPResponse: async (
address: string,
chain_id: number,
requestIdProofs: Map<number, ZKProof>) => {
return ['txhash1'];
},
};

const getPackageMgr = async (
circuitData: CircuitData,
prepareFn: AuthDataPrepareFunc,
stateVerificationFn: StateVerificationFunc
): Promise<IPackageManager> => {
const authInputsHandler = new DataPrepareHandlerFunc(prepareFn);

const verificationFn = new VerificationHandlerFunc(stateVerificationFn);
const mapKey = proving.provingMethodGroth16AuthV2Instance.methodAlg.toString();

if (!circuitData.verificationKey) {
throw new Error(`verification key doesn't exist for ${circuitData.circuitId}`);
}
const verificationParamMap: Map<string, VerificationParams> = new Map([
[
mapKey,
{
key: circuitData.verificationKey,
verificationFn
}
]
]);

if (!circuitData.provingKey) {
throw new Error(`proving doesn't exist for ${circuitData.circuitId}`);
}
if (!circuitData.wasm) {
throw new Error(`wasm file doesn't exist for ${circuitData.circuitId}`);
}
const provingParamMap: Map<string, ProvingParams> = new Map();
provingParamMap.set(mapKey, {
dataPreparer: authInputsHandler,
provingKey: circuitData.provingKey,
wasm: circuitData.wasm
});

const mgr: IPackageManager = new PackageManager();
const packer = new ZKPPacker(provingParamMap, verificationParamMap);
const plainPacker = new PlainPacker();
mgr.registerPackers([packer, plainPacker]);

return mgr;
};

beforeEach(async () => {
const memoryKeyStore = new InMemoryPrivateKeyStore();
const bjjProvider = new BjjProvider(KmsKeyType.BabyJubJub, memoryKeyStore);
const kms = new KMS();
kms.registerKeyProvider(KmsKeyType.BabyJubJub, bjjProvider);
dataStorage = {
credential: new CredentialStorage(new InMemoryDataSource<W3CCredential>()),
identity: new IdentityStorage(
new InMemoryDataSource<Identity>(),
new InMemoryDataSource<Profile>()
),
mt: new InMemoryMerkleTreeStorage(40),
states: mockStateStorage
};
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, mockStateStorage, {
ipfsNodeURL
});
packageMgr = await getPackageMgr(
await circuitStorage.loadCircuitData(CircuitId.AuthV2),
proofService.generateAuthV2Inputs.bind(proofService),
proofService.verifyState.bind(proofService)
);
contractRequest = new ContractRequestHandler(packageMgr, proofService, mockZKPVerifier);
});

it('contract request flow', async () => {
const { did: userDID, credential: cred } = await idWallet.createIdentity({
method: DidMethod.Iden3,
blockchain: Blockchain.Polygon,
networkId: NetworkId.Mumbai,
seed: seedPhrase,
revocationOpts: {
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
id: rhsUrl
}
});

expect(cred).not.to.be.undefined;

const { did: issuerDID, credential: issuerAuthCredential } = await idWallet.createIdentity({
method: DidMethod.Iden3,
blockchain: Blockchain.Polygon,
networkId: NetworkId.Mumbai,
seed: seedPhraseIssuer,
revocationOpts: {
type: CredentialStatusType.Iden3ReverseSparseMerkleTreeProof,
id: rhsUrl
}
});
expect(issuerAuthCredential).not.to.be.undefined;

const claimReq: 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.Iden3ReverseSparseMerkleTreeProof,
id: rhsUrl
}
};
const issuerCred = await idWallet.issueCredential(issuerDID, claimReq);

await credWallet.save(issuerCred);

const proofReq: ZeroKnowledgeProofRequest = {
id: 1,
circuitId: CircuitId.AtomicQuerySigV2,
optional: false,
query: {
allowedIssuers: ['*'],
type: claimReq.type,
context:
'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-nonmerklized.jsonld',
credentialSubject: {
documentType: {
$eq: 99
}
}
}
};

const transactionData: ContractInvokeTransactionData = {
contract_address: 'test_address',
method_id: '123',
chain_id: 80001
};

const ciRequestBody: ContractInvokeRequestBody = {
reason: 'reason',
transaction_data: transactionData,
scope: [proofReq as ZeroKnowledgeProofRequest]
};

const id = uuid.v4();
const ciRequest: ContractInvokeRequest = {
id,
typ: MediaType.PlainMessage,
type: PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE,
thid: id,
body: ciRequestBody
};

const msgBytes = byteEncoder.encode(JSON.stringify(ciRequest));
const authRes = await contractRequest.handleContractInvokeRequest(userDID, msgBytes);

expect(authRes.length).to.be.equal(1);
expect(authRes[0]).to.be.equal('txhash1');
});


});

0 comments on commit 553d631

Please sign in to comment.