Skip to content

Commit

Permalink
Added compatibility with the new credentials issuer (#10)
Browse files Browse the repository at this point in the history
* expose transit state details

* bump version

* update generating bjj sig proof

* remove log

* rearrange loading details from states, to ensure that proof is generating by specific hash and block

* bump version aplying

* fix changelog

* update changelog

* Update CHANGELOG.md

* Update CHANGELOG.md

---------

Co-authored-by: Ihor Diachenko <[email protected]>
  • Loading branch information
lukachi and ihordiachenko authored Oct 19, 2023
1 parent c3ad8cd commit fe77620
Show file tree
Hide file tree
Showing 14 changed files with 539 additions and 425 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.6.0] - 2023-10-19
### Changed
- `@rarimo/rarime`:
- expose transit state details on `createProof`
- update `IssuerData` and `BJJSignatureProof2021` classes for compatibility with the new issuer
- use the state at a specific block when generating the proofs to prevent possible conflicts


## [0.5.0] - 2023-10-13
### Added
- `@rarimo/rarime`: get credentials method
Expand Down Expand Up @@ -60,7 +68,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Implemented `@rarimo/rarime-connector` and `@rarimo/rarime` packages

[Unreleased]: https://github.com/rarimo/rarime/compare/0.5.0...HEAD
[Unreleased]: https://github.com/rarimo/rarime/compare/0.6.0...HEAD
[0.6.0]: https://github.com/rarimo/rarime/compare/0.5.0...0.6.0
[0.5.0]: https://github.com/rarimo/rarime/compare/0.4.0...0.5.0
[0.4.0]: https://github.com/rarimo/rarime/compare/0.3.2...0.4.0
[0.3.2]: https://github.com/rarimo/rarime/compare/0.3.1...0.3.2
Expand Down
2 changes: 1 addition & 1 deletion packages/connector/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rarimo/rarime-connector",
"version": "0.5.0",
"version": "0.6.0",
"description": "Facilitates interaction between a DApp and RariMe MetaMask snap",
"repository": {
"type": "git",
Expand Down
10 changes: 10 additions & 0 deletions packages/connector/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,17 @@ export type StateInfo = {
lastUpdateOperationIndex: string;
};

export type UpdateStateDetails = {
stateRootHash: string;
gistRootDataStruct: {
root: string | number;
createdAtTimestamp: string | number;
};
proof: string;
};

export type ZKPProofResponse = {
updateStateDetails: UpdateStateDetails;
updateStateTx?: TransactionRequest;
zkpProof: ZKProof;
statesMerkleData?: {
Expand Down
2 changes: 1 addition & 1 deletion packages/connector/src/version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "0.5.x"
"version": "0.6.x"
}
2 changes: 1 addition & 1 deletion packages/site/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "site",
"version": "0.5.0",
"version": "0.6.0",
"private": true,
"license": "(MIT-0 OR Apache-2.0)",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions packages/snap/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rarimo/rarime",
"version": "0.5.0",
"version": "0.6.0",
"description": "RariMe is a MetaMask Snap that safely holds any of your credentials and allows you to prove your identity without revealing any personal data. Powered by Rarimo Protocol and Zero-Knowledge Proof technology.",
"repository": {
"type": "git",
Expand Down Expand Up @@ -45,7 +45,7 @@
"@metamask/snaps-jest": "0.35.2-flask.1",
"@metamask/snaps-types": "0.32.2",
"@metamask/snaps-ui": "0.32.2",
"@rarimo/rarime-connector": "0.5.0",
"@rarimo/rarime-connector": "0.6.0",
"buffer": "6.0.3",
"ethers": "5.7.2",
"intl": "1.2.5",
Expand Down
4 changes: 2 additions & 2 deletions packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"version": "0.5.0",
"version": "0.6.0",
"description": "Securely store and manage all of your identity credentials. Use them across chains with ZK-protected privacy guarantees.",
"proposedName": "RariMe",
"repository": {
"type": "git",
"url": "https://github.com/rarimo/rarime.git"
},
"source": {
"shasum": "dZLJw4DpoiXgAjwOHLIbhjOhBw1riUDGcjvzVaJu/oE=",
"shasum": "qwGl3IBgzNUUd5bsWem1tyy3cSNIBqyFNtTV+29xsdY=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
11 changes: 9 additions & 2 deletions packages/snap/src/helpers/credential-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,15 @@ export const getPreparedCredential = async (credential: W3CCredential) => {
};
};

export const loadDataByUrl = async (url: string) => {
const response = await fetch(url);
export const loadDataByUrl = async (
url: string,
endianSwappedCoreStateHash?: string,
) => {
const response = await fetch(
endianSwappedCoreStateHash
? `${url}?state=${endianSwappedCoreStateHash}`
: url,
);

if (!response.ok) {
const message = `An error has occured: ${response.status}`;
Expand Down
4 changes: 2 additions & 2 deletions packages/snap/src/helpers/model-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class IssuerData {
mtp?: Proof;

credentialStatus?: CredentialStatus;

updateUrl!: string;
}

export class Iden3SparseMerkleTreeProof {
Expand All @@ -40,8 +42,6 @@ export class BJJSignatureProof2021 {
signature!: string;

coreClaim!: string;

issuerProofUpdateUrl!: string;
}

export class CircuitClaim {
Expand Down
26 changes: 23 additions & 3 deletions packages/snap/src/helpers/proof-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* eslint-disable camelcase */
/* eslint-disable @typescript-eslint/prefer-for-of */
import { Hex, Signature } from '@iden3/js-crypto';
import { Claim, DID, MerklizedRootPosition } from '@iden3/js-iden3-core';
import {
Claim,
DID,
fromLittleEndian,
MerklizedRootPosition,
} from '@iden3/js-iden3-core';
import {
Hash,
NodeAux,
Expand Down Expand Up @@ -151,9 +156,20 @@ export const buildTreeState = (
rootOfRoots: newHashFromHex(rootOfRoots),
});

export const convertEndianSwappedCoreStateHashHex = (hash: string) => {
const convertedStateHash = fromLittleEndian(
Hex.decodeString(hash.slice(2)),
).toString(16);

return convertedStateHash?.length < 64
? `0x0${convertedStateHash}`
: `0x${convertedStateHash}`;
};

export const newCircuitClaimData = async (
credential: W3CCredential,
coreClaim: Claim,
coreStateHash: string,
): Promise<CircuitClaim> => {
const circuitClaim = new CircuitClaim();
circuitClaim.claim = coreClaim;
Expand All @@ -162,7 +178,10 @@ export const newCircuitClaimData = async (
const smtProof = getIden3SparseMerkleTreeProof(credential.proof!);

if (smtProof) {
const data = await loadDataByUrl(smtProof.id);
const data = await loadDataByUrl(
smtProof.id,
convertEndianSwappedCoreStateHashHex(coreStateHash),
);

circuitClaim.incProof = {
proof: data.mtp,
Expand All @@ -181,7 +200,8 @@ export const newCircuitClaimData = async (
const decodedSignature = Hex.decodeString(sigProof.signature);
const signature = Signature.newFromCompressed(decodedSignature);
const issuerAuthClaimIncMtp = await loadDataByUrl(
sigProof.issuerProofUpdateUrl,
sigProof.issuerData.updateUrl,
convertEndianSwappedCoreStateHashHex(coreStateHash),
);
const rs: RevocationStatus = await getRevocationStatus(
sigProof.issuerData.credentialStatus!,
Expand Down
59 changes: 44 additions & 15 deletions packages/snap/src/helpers/state-v2-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
StateProof,
StateV2__factory,
} from '../types';
import { ILightweightStateV2 } from '../types/contracts/LightweightStateV2';
import {
getChainInfo,
getProviderChainInfo,
Expand All @@ -24,18 +25,22 @@ export const getGISTProof = async ({
rpcUrl,
contractAddress,
userId,
rootHash,
}: {
rpcUrl: string;
contractAddress: string;
userId: string;
rootHash?: string;
}): Promise<StateProof> => {
const rawProvider = new providers.JsonRpcProvider(rpcUrl, 'any');

const contractInstance = StateV2__factory.connect(
contractAddress,
rawProvider,
);
const data = await contractInstance.getGISTProof(userId);
const data = rootHash
? await contractInstance.getGISTProofByRoot(userId, rootHash)
: await contractInstance.getGISTProof(userId);

return {
root: BigInt(data.root.toString()),
Expand Down Expand Up @@ -124,11 +129,22 @@ export const loadDataFromRarimoCore = async <T>(
return await response.json();
};

export const getUpdateStateTx = async (
accountId: string,
chainInfo: ChainInfo,
type UpdateStateDetails = {
stateRootHash: string;
gistRootDataStruct: ILightweightStateV2.GistRootDataStruct;
proof: string;
};

export const getCoreOperationByIndex = async (index: string) => {
return loadDataFromRarimoCore<OperationResponse>(
`/rarimo/rarimo-core/rarimocore/operation/${index}`,
);
};

export const getUpdateStateDetails = async (
state: StateInfo,
): Promise<TransactionRequest> => {
operation: OperationResponse,
): Promise<UpdateStateDetails> => {
let operationProof;
do {
try {
Expand All @@ -137,17 +153,13 @@ export const getUpdateStateTx = async (
);
} catch (e) {
if (e instanceof FetcherError && e.response.status === 400) {
await new Promise((resolve) => setTimeout(resolve, 30000));
await new Promise((resolve) => setTimeout(resolve, 30_000));
} else {
throw e;
}
}
} while (!operationProof);

const operationResponse = await loadDataFromRarimoCore<OperationResponse>(
`/rarimo/rarimo-core/rarimocore/operation/${state.lastUpdateOperationIndex}`,
);

const decodedPath = operationProof?.path?.map((el: string) =>
utils.arrayify(el),
);
Expand All @@ -164,14 +176,31 @@ export const getUpdateStateTx = async (
[decodedPath, decodedSignature],
);

return {
stateRootHash: operation.operation.details.stateRootHash,
gistRootDataStruct: {
root: operation.operation.details.GISTHash,
createdAtTimestamp: Number(operation.operation.details.timestamp),
},
proof,
};
};

export const getUpdateStateTx = async (
accountId: string,
chainInfo: ChainInfo,
state: StateInfo,
operation: OperationResponse,
updateStateDetails?: UpdateStateDetails,
): Promise<TransactionRequest> => {
const { stateRootHash, gistRootDataStruct, proof } =
updateStateDetails ?? (await getUpdateStateDetails(state, operation));

const contractInterface = LightweightStateV2__factory.createInterface();

const txData = contractInterface.encodeFunctionData('signedTransitState', [
operationResponse.operation.details.stateRootHash,
{
root: operationResponse.operation.details.GISTHash,
createdAtTimestamp: Number(operationResponse.operation.details.timestamp),
},
stateRootHash,
gistRootDataStruct,
proof,
]);
return {
Expand Down
Loading

0 comments on commit fe77620

Please sign in to comment.