diff --git a/package.json b/package.json index 452bab31..d953aa7b 100644 --- a/package.json +++ b/package.json @@ -59,5 +59,20 @@ "packageManager": "yarn@3.2.1", "engines": { "node": ">=16.0.0" + }, + "resolutions": { + "rarimo-js-sdk-monorepo-root": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk", + "@rarimo/bridge": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/bridge", + "@rarimo/client": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/client", + "@rarimo/nft-checkout": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/nft-checkout", + "@rarimo/provider": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/provider", + "@rarimo/providers-evm": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/providers-evm", + "@rarimo/providers-near": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/providers-near", + "@rarimo/providers-solana": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/providers-solana", + "@rarimo/react-nft-checkout": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/react-nft-checkout", + "@rarimo/react-provider": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/react-provider", + "@rarimo/shared": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/shared", + "@rarimo/swap": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/swap", + "@rarimo/zkp-iden3": "portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/zkp-iden3" } } diff --git a/packages/snap/package.json b/packages/snap/package.json index 86f930f9..22d87736 100644 --- a/packages/snap/package.json +++ b/packages/snap/package.json @@ -62,6 +62,7 @@ "@noble/hashes": "^1.3.3", "@noble/secp256k1": "1.7.1", "@rarimo/rarime-connector": "2.1.0-rc.3", + "@rarimo/zkp-iden3": "*", "base64-js": "^1.5.1", "bech32": "^2.0.0", "buffer": "6.0.3", diff --git a/packages/snap/snap.manifest.json b/packages/snap/snap.manifest.json index 5f8fc118..a347b3a3 100644 --- a/packages/snap/snap.manifest.json +++ b/packages/snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/rarimo/rarime.git" }, "source": { - "shasum": "7bsozDwYAOD2TjXCs29INb7vtKXR4BccEF5wHXh6Wpk=", + "shasum": "Ms7L0rMmYYffBfujJZ8pCOsb1Uhda71snhVKmMTWIbI=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/snap/src/types/storage.ts b/packages/snap/src/types/storage.ts index 0b7d9880..8f4b69f4 100644 --- a/packages/snap/src/types/storage.ts +++ b/packages/snap/src/types/storage.ts @@ -1,7 +1,7 @@ import type { ChainInfo } from '@rarimo/rarime-connector'; +import type { W3CCredential } from '@rarimo/zkp-iden3'; import type { StorageKeys } from '@/enums'; -import type { W3CCredential } from '@/zkp/types'; export type StorageMap = { [StorageKeys.identity]: { diff --git a/packages/snap/src/zkp/auth-zkp.ts b/packages/snap/src/zkp/auth-zkp.ts deleted file mode 100644 index 64069d5f..00000000 --- a/packages/snap/src/zkp/auth-zkp.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { fromBigEndian } from '@iden3/js-iden3-core'; -import { proving, Token } from '@iden3/js-jwz'; -import type { SaveCredentialsRequestParams } from '@rarimo/rarime-connector'; -import * as uuid from 'uuid'; - -import { config } from '@/config'; -import { defaultMTLevels, defaultMTLevelsOnChain } from '@/zkp/const'; -import { - getGISTProof, - getNodeAuxValue, - getProviderChainInfo, - getRarimoEvmRpcUrl, - getRarimoStateContractAddress, - getFileBytes, - prepareSiblingsStr, - toGISTProof, -} from '@/zkp/helpers'; -import type { Identity } from '@/zkp/identity'; -import type { W3CCredential } from '@/zkp/types'; - -export class AuthZkp { - identity: Identity = {} as Identity; - - offer: SaveCredentialsRequestParams = {} as SaveCredentialsRequestParams; - - verifiableCredentials: W3CCredential[] = []; - - constructor(identity: Identity, offer: SaveCredentialsRequestParams) { - this.identity = identity; - this.offer = offer; - } - - async getVerifiableCredentials(): Promise { - const credentials: W3CCredential[] = []; - - for (let index = 0; index < this.offer.body.Credentials.length; index++) { - const guid = uuid.v4(); - - const claimDetails = { - id: this.offer?.id ?? guid, - typ: this.offer?.typ || 'application/iden3-zkp-json', - type: 'https://iden3-communication.io/credentials/1.0/fetch-request', - threadID: this.offer?.threadID ?? guid, - body: { - id: this.offer?.body.Credentials[index].id, - }, - from: this.offer.to, - to: this.offer.from, - }; - - const token2 = new Token( - proving.provingMethodGroth16AuthV2Instance, - JSON.stringify(claimDetails), - this.#prepareInputs.bind(this), - ); - - const [wasm, provingKey] = await Promise.all([ - getFileBytes(config.CIRCUIT_AUTH_WASM_URL), - getFileBytes(config.CIRCUIT_AUTH_FINAL_KEY_URL), - ]); - - const jwzTokenRaw = await token2.prove(provingKey, wasm); - - const resp = await fetch(this.offer.body.url, { - method: 'post', - body: jwzTokenRaw, - }); - - if (resp.status !== 200) { - throw new Error( - `could not fetch W3C credential, ${this.offer?.body.Credentials[index].id}`, - ); - } - const data = await resp.json(); - - credentials.push(data.body.credential); - } - this.verifiableCredentials = credentials; - - return credentials; - } - - async #prepareInputs(messageHash: Uint8Array): Promise { - const messageHashBigInt = fromBigEndian(messageHash); - - const providerChainInfo = await getProviderChainInfo(); - - const signature = this.identity.privateKey.signPoseidon(messageHashBigInt); - const gistInfo = await getGISTProof({ - rpcUrl: getRarimoEvmRpcUrl(providerChainInfo.id), - contractAddress: getRarimoStateContractAddress(providerChainInfo.id), - userId: this.identity.identityIdBigIntString, - }); - - const gistProof = toGISTProof(gistInfo); - const globalNodeAux = getNodeAuxValue(gistProof.proof); - const nodeAuxAuth = getNodeAuxValue(this.identity.authClaimNonRevProof); - - const preparedInputs = { - authClaim: this.identity.coreAuthClaim.marshalJson(), - authClaimIncMtp: this.identity.authClaimIncProofSiblings, - authClaimNonRevMtp: prepareSiblingsStr( - this.identity.authClaimNonRevProof, - defaultMTLevels, - ), - authClaimNonRevMtpAuxHi: nodeAuxAuth.key.string(), - authClaimNonRevMtpAuxHv: nodeAuxAuth.value.string(), - authClaimNonRevMtpNoAux: nodeAuxAuth.noAux, - challenge: messageHashBigInt.toString(), - challengeSignatureR8x: signature.R8[0].toString(), - challengeSignatureR8y: signature.R8[1].toString(), - challengeSignatureS: signature.S.toString(), - claimsTreeRoot: this.identity.treeState.claimsRoot, - genesisID: this.identity.identityIdBigIntString, - revTreeRoot: this.identity.treeState.revocationRoot, - rootsTreeRoot: this.identity.treeState.rootOfRoots, - state: this.identity.treeState.state, - profileNonce: '0', - gistRoot: gistProof.root.string(), - gistMtp: prepareSiblingsStr(gistProof.proof, defaultMTLevelsOnChain), - gistMtpAuxHi: globalNodeAux?.key.string(), - gistMtpAuxHv: globalNodeAux?.value.string(), - gistMtpNoAux: globalNodeAux.noAux, - }; - - return new TextEncoder().encode(JSON.stringify(preparedInputs)); - } -} diff --git a/packages/snap/src/zkp/const/general.ts b/packages/snap/src/zkp/const/general.ts deleted file mode 100644 index 12ddd17d..00000000 --- a/packages/snap/src/zkp/const/general.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Operators } from '@/zkp/enums'; - -export const defaultMTLevels = 40; // max MT levels, default value for identity circuits -export const defaultValueArraySize = 64; // max value array size, default value for identity circuits -export const defaultMTLevelsOnChain = 64; // max MT levels on chain, default value for identity circuits -export const defaultMTLevelsClaimsMerklization = 32; // max MT levels of JSON-LD merklization on claim - -export const QueryOperators = { - $noop: Operators.NOOP, - $eq: Operators.EQ, - $lt: Operators.LT, - $gt: Operators.GT, - $in: Operators.IN, - $nin: Operators.NIN, - $ne: Operators.NE, -}; diff --git a/packages/snap/src/zkp/const/index.ts b/packages/snap/src/zkp/const/index.ts deleted file mode 100644 index 12bc2fe5..00000000 --- a/packages/snap/src/zkp/const/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './general'; diff --git a/packages/snap/src/zkp/enums/index.ts b/packages/snap/src/zkp/enums/index.ts deleted file mode 100644 index dbda281b..00000000 --- a/packages/snap/src/zkp/enums/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './proof'; diff --git a/packages/snap/src/zkp/enums/proof.ts b/packages/snap/src/zkp/enums/proof.ts deleted file mode 100644 index dc5a675f..00000000 --- a/packages/snap/src/zkp/enums/proof.ts +++ /dev/null @@ -1,14 +0,0 @@ -export enum ProofType { - BJJSignature = 'BJJSignature2021', - Iden3SparseMerkleTreeProof = 'Iden3SparseMerkleTreeProof', -} - -export enum Operators { - NOOP = 0, // No operation, skip query verification in circuit - EQ = 1, - LT = 2, - GT = 3, - IN = 4, - NIN = 5, - NE = 6, -} diff --git a/packages/snap/src/zkp/handlers/CheckStateContractSync.ts b/packages/snap/src/zkp/handlers/CheckStateContractSync.ts index c61d1ae5..16d60828 100644 --- a/packages/snap/src/zkp/handlers/CheckStateContractSync.ts +++ b/packages/snap/src/zkp/handlers/CheckStateContractSync.ts @@ -2,11 +2,14 @@ import type { RPCMethods, SnapRequestsResponses, } from '@rarimo/rarime-connector'; +import { checkIfStateSynced } from '@rarimo/zkp-iden3'; -import { checkIfStateSynced } from '@/zkp/helpers'; +import { getProviderChainInfo } from '@/zkp/helpers'; export const checkStateContractSync = async (): Promise< SnapRequestsResponses[RPCMethods.CheckStateContractSync] > => { - return checkIfStateSynced(); + const chainInfo = await getProviderChainInfo(); + + return checkIfStateSynced(chainInfo.id); }; diff --git a/packages/snap/src/zkp/handlers/CreateIdentity.ts b/packages/snap/src/zkp/handlers/CreateIdentity.ts index 3932ea1f..a8bbd90c 100644 --- a/packages/snap/src/zkp/handlers/CreateIdentity.ts +++ b/packages/snap/src/zkp/handlers/CreateIdentity.ts @@ -5,12 +5,12 @@ import type { SnapRequestParams, SnapRequestsResponses, } from '@rarimo/rarime-connector'; +import { Identity, isDidSupported } from '@rarimo/zkp-iden3'; import { utils } from 'ethers'; import { StorageKeys } from '@/enums'; import { snapStorage } from '@/helpers'; -import { genPkHexFromEntropy, isDidSupported } from '@/zkp/helpers'; -import { Identity } from '@/zkp/identity'; +import { genPkHexFromEntropy } from '@/zkp/helpers'; export const createIdentity = async ({ request, diff --git a/packages/snap/src/zkp/handlers/CreateProof.ts b/packages/snap/src/zkp/handlers/CreateProof.ts index b6cdfc9b..0726ff1a 100644 --- a/packages/snap/src/zkp/handlers/CreateProof.ts +++ b/packages/snap/src/zkp/handlers/CreateProof.ts @@ -7,23 +7,26 @@ import type { SnapRequestsResponses, } from '@rarimo/rarime-connector'; import { CircuitId } from '@rarimo/rarime-connector'; - -import { StorageKeys } from '@/enums'; -import { snapStorage } from '@/helpers'; -import type { TextField } from '@/types'; -import { isValidCreateProofRequest } from '@/typia-generated'; +import type { GetStateInfoResponse, MerkleProof } from '@rarimo/zkp-iden3'; import { + ZkpGen, + Identity, checkIfStateSynced, getCoreOperationByIndex, - getProviderChainInfo, getRarimoCoreUrl, loadDataFromRarimoCore, parseDidV2, +} from '@rarimo/zkp-iden3'; + +import { StorageKeys } from '@/enums'; +import { snapStorage } from '@/helpers'; +import type { TextField } from '@/types'; +import { isValidCreateProofRequest } from '@/typia-generated'; +import { + getSnapFileBytes, VCManager, + getProviderChainInfo, } from '@/zkp/helpers'; -import { Identity } from '@/zkp/identity'; -import type { GetStateInfoResponse, MerkleProof } from '@/zkp/types'; -import { ZkpGen } from '@/zkp/zkp-gen'; export const createProof = async ({ request, @@ -129,15 +132,18 @@ export const createProof = async ({ const identity = await Identity.create(identityStorage.privateKeyHex); - const zkpGen = new ZkpGen(identity, createProofRequest, vc); + const chainInfo = await getProviderChainInfo(); - // ================ LOAD STATE DETAILS ===================== + const zkpGen = new ZkpGen(identity, createProofRequest, vc, { + chainId: chainInfo.id, + loadingCircuitCb: getSnapFileBytes, + }); - const chainInfo = await getProviderChainInfo(); + // ================ LOAD STATE DETAILS ===================== const rarimoCoreUrl = getRarimoCoreUrl(chainInfo.id); - const isSynced = await checkIfStateSynced(); + const isSynced = await checkIfStateSynced(chainInfo.id); const did = parseDidV2(issuerDid); @@ -146,14 +152,17 @@ export const createProof = async ({ const issuerHexId = `0x0${issuerId.bigInt().toString(16)}`; const stateData = await loadDataFromRarimoCore( + chainInfo.id, `/rarimo/rarimo-core/identity/state/${issuerHexId}`, ); const merkleProof = await loadDataFromRarimoCore( + chainInfo.id, `/rarimo/rarimo-core/identity/state/${issuerHexId}/proof`, stateData.state.createdAtBlock, ); const operation = await getCoreOperationByIndex( + chainInfo.id, stateData.state.lastUpdateOperationIndex, ); diff --git a/packages/snap/src/zkp/handlers/SaveCredentials.ts b/packages/snap/src/zkp/handlers/SaveCredentials.ts index 50443adc..902db4b2 100644 --- a/packages/snap/src/zkp/handlers/SaveCredentials.ts +++ b/packages/snap/src/zkp/handlers/SaveCredentials.ts @@ -5,13 +5,16 @@ import type { SnapRequestParams, SnapRequestsResponses, } from '@rarimo/rarime-connector'; +import { AuthZkp, Identity } from '@rarimo/zkp-iden3'; import { StorageKeys } from '@/enums'; import { snapStorage } from '@/helpers'; import { isValidSaveCredentialsOfferRequest } from '@/typia-generated'; -import { AuthZkp } from '@/zkp/auth-zkp'; -import { VCManager } from '@/zkp/helpers'; -import { Identity } from '@/zkp/identity'; +import { + getProviderChainInfo, + getSnapFileBytes, + VCManager, +} from '@/zkp/helpers'; export const saveCredentials = async ({ request, @@ -60,7 +63,12 @@ export const saveCredentials = async ({ const identity = await Identity.create(identityStorage.privateKeyHex); - const authProof = new AuthZkp(identity, offer); + const currentChain = await getProviderChainInfo(); + + const authProof = new AuthZkp(identity, offer, { + chainId: currentChain.id, + loadingCircuitCb: getSnapFileBytes, + }); const credentials = await authProof.getVerifiableCredentials(); diff --git a/packages/snap/src/zkp/helpers/common-helpers.ts b/packages/snap/src/zkp/helpers/common-helpers.ts index 60f71cc4..b9927488 100644 --- a/packages/snap/src/zkp/helpers/common-helpers.ts +++ b/packages/snap/src/zkp/helpers/common-helpers.ts @@ -1,17 +1,9 @@ +import { getChainInfo } from '@rarimo/zkp-iden3'; import { providers } from 'ethers'; -import { config, HOSTNAMES_WHITELIST, SUPPORTED_CHAINS } from '@/config'; +import { HOSTNAMES_WHITELIST } from '@/config'; import type { ChainInfo } from '@/types'; -export const getChainInfo = (chainId: number): ChainInfo => { - const chainInfo = SUPPORTED_CHAINS[chainId]; - if (!chainInfo) { - throw new Error(`ChainId ${chainId} not supported`); - } - - return chainInfo; -}; - export const getProviderChainInfo = async (): Promise => { const provider = new providers.Web3Provider( ethereum as any as providers.ExternalProvider, @@ -21,20 +13,6 @@ export const getProviderChainInfo = async (): Promise => { return getChainInfo(network.chainId); }; -export const getRarimoEvmRpcUrl = (chainId: number) => { - return config.RARIMO_EVM_RPC_URL[SUPPORTED_CHAINS[chainId].rarimoNetworkType]; -}; - -export const getRarimoCoreUrl = (chainId: number) => { - return config.RARIMO_CORE_URL[SUPPORTED_CHAINS[chainId].rarimoNetworkType]; -}; - -export const getRarimoStateContractAddress = (chainId: number) => { - return config.RARIMO_STATE_CONTRACT_ADDRESS[ - SUPPORTED_CHAINS[chainId].rarimoNetworkType - ]; -}; - export const getHostname = (origin: string): string => { return new URL(origin).hostname; }; @@ -42,18 +20,3 @@ export const getHostname = (origin: string): string => { export const isOriginInWhitelist = (origin: string) => { return HOSTNAMES_WHITELIST.includes(getHostname(origin)); }; - -export const uniqBy = (arr: any[], predicate: string) => { - return [ - ...arr - .reduce((map, item) => { - const key = - item === null || item === undefined ? item : item[predicate]; - - map.has(key) || map.set(key, item); - - return map; - }, new Map()) - .values(), - ]; -}; diff --git a/packages/snap/src/zkp/helpers/credential-helpers.ts b/packages/snap/src/zkp/helpers/credential-helpers.ts index 935d8e36..fba8714f 100644 --- a/packages/snap/src/zkp/helpers/credential-helpers.ts +++ b/packages/snap/src/zkp/helpers/credential-helpers.ts @@ -1,9 +1,10 @@ -import type { Claim } from '@iden3/js-iden3-core'; import type { CreateProofRequestParams, ProofQuery, SaveCredentialsRequestParams, } from '@rarimo/rarime-connector'; +import type { W3CCredential } from '@rarimo/zkp-iden3'; +import { Identity } from '@rarimo/zkp-iden3'; import { sha256 } from 'ethers/lib/utils'; import type { DocumentNode } from 'graphql/language'; @@ -12,24 +13,18 @@ import VerifiableRuntimeCompositeV2 from '../../../ceramic/composites/Verifiable import { StorageKeys } from '@/enums'; import { snapStorage } from '@/helpers'; -import { ProofType } from '@/zkp/enums'; import { CeramicProvider } from '@/zkp/helpers/ceramic-helpers'; import { genPkHexFromEntropy } from '@/zkp/helpers/identity-helpers'; -import { getCoreClaimFromProof } from '@/zkp/helpers/proof-helpers'; -import { Identity } from '@/zkp/identity'; import type { ClearVcMutation, ClearVcMutationVariables, CreateVcMutationVariables, - CredentialStatus, GetAllVerifiableCredentialsQuery, GetAllVerifiableCredentialsQueryVariables, GetVerifiableCredentialsByClaimIdQuery, GetVerifiableCredentialsByClaimIdQueryVariables, GetVerifiableCredentialsByQueryHashQuery, GetVerifiableCredentialsByQueryHashQueryVariables, - RevocationStatus, - W3CCredential, GetVerifiableCredentialsByClaimIdAndQueryHashQueryVariables, GetVerifiableCredentialsByClaimIdAndQueryHashQuery, } from '@/zkp/types'; @@ -562,97 +557,3 @@ export const migrateVCsToLastCeramicModel = async () => { }), ); }; - -export const getRevocationStatus = async ( - credStatus: CredentialStatus, -): Promise => { - const data = await fetch(credStatus.id); - - return await data.json(); -}; - -export const findNonRevokedCredential = async ( - creds: W3CCredential[], -): Promise<{ - cred: W3CCredential; - revStatus: RevocationStatus; -}> => { - for (const cred of creds) { - const revStatus = await getRevocationStatus(cred.credentialStatus); - if (revStatus.mtp.existence) { - continue; - } - return { cred, revStatus }; - } - throw new Error('all claims are revoked'); -}; - -const getCoreClaimFromCredential = async ( - credential: W3CCredential, -): Promise => { - const coreClaimFromSigProof = getCoreClaimFromProof( - credential.proof!, - ProofType.BJJSignature, - ); - - const coreClaimFromMtpProof = getCoreClaimFromProof( - credential.proof!, - ProofType.Iden3SparseMerkleTreeProof, - ); - - if ( - coreClaimFromMtpProof && - coreClaimFromSigProof && - coreClaimFromMtpProof.hex() !== coreClaimFromSigProof.hex() - ) { - throw new Error( - 'core claim representations is set in both proofs but they are not equal', - ); - } - - if (!coreClaimFromMtpProof && !coreClaimFromSigProof) { - throw new Error('core claim is not set in credential proofs'); - } - - const coreClaim = coreClaimFromMtpProof ?? coreClaimFromSigProof!; - - return coreClaim; -}; - -export const getPreparedCredential = async (credential: W3CCredential) => { - const { cred: nonRevokedCred, revStatus } = await findNonRevokedCredential([ - credential, - ]); - - const credCoreClaim = await getCoreClaimFromCredential(nonRevokedCred); - - return { - credential: nonRevokedCred, - revStatus, - credentialCoreClaim: credCoreClaim, - }; -}; - -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}`; - throw new Error(message); - } - - return await response.json(); -}; - -export const isVCsV2 = (vcs: W3CCredential[]) => { - return vcs.every((vc) => { - return vc.issuer.includes('readonly'); - }); -}; diff --git a/packages/snap/src/zkp/helpers/error-helper.ts b/packages/snap/src/zkp/helpers/error-helper.ts deleted file mode 100644 index 7f11840e..00000000 --- a/packages/snap/src/zkp/helpers/error-helper.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class FetcherError extends Error { - public name = 'FetcherError'; - - public response: Response; - - constructor(resp: Response) { - super(); - this.response = resp; - } -} diff --git a/packages/snap/src/zkp/helpers/file-helpers.ts b/packages/snap/src/zkp/helpers/file-helpers.ts index 46189f2d..6ac8761e 100644 --- a/packages/snap/src/zkp/helpers/file-helpers.ts +++ b/packages/snap/src/zkp/helpers/file-helpers.ts @@ -1,8 +1,3 @@ -export const readBytesFile = async (path: string) => { - const response = await fetch(path); - return new Uint8Array(await response?.arrayBuffer?.()); -}; - export const getSnapFileBytes = async (path: string) => { const response = await snap.request({ method: 'snap_getFile', @@ -20,11 +15,3 @@ export const getSnapFileBytes = async (path: string) => { return bytes; }; - -export const getFileBytes = async (path: string) => { - try { - return await readBytesFile(new URL(path).href); - } catch (error) { - return await getSnapFileBytes(path); - } -}; diff --git a/packages/snap/src/zkp/helpers/identity-helpers.ts b/packages/snap/src/zkp/helpers/identity-helpers.ts index 61194b2b..e3c986d1 100644 --- a/packages/snap/src/zkp/helpers/identity-helpers.ts +++ b/packages/snap/src/zkp/helpers/identity-helpers.ts @@ -1,39 +1,3 @@ -import { Hex, PrivateKey } from '@iden3/js-crypto'; -import { DID } from '@iden3/js-iden3-core'; - -export const initPrivateKey = (hexString?: string): string => { - let arr; - if (hexString) { - arr = Hex.decodeString(hexString); - } else { - arr = new Uint8Array(32); - window.crypto.getRandomValues(arr); - - return initPrivateKey(new PrivateKey(arr).hex()); - } - return new PrivateKey(arr).hex(); -}; - -export const parseDidV2 = (did: string): DID => { - const splitted = did.split(':'); - - return DID.parse(`did:iden3:readonly:${splitted[splitted.length - 1]}`); -}; - -export const isDidSupported = (identityId: string): boolean => { - try { - const parsed = DID.parse(identityId); - - const id = DID.idFromDID(parsed); - - const parts = DID.decodePartsFromId(id); - - return !DID.isUnsupported(parts.method, parts.blockchain, parts.networkId); - } catch (error) { - return false; - } -}; - export const genPkHexFromEntropy = async (salt?: string) => { const entropy = await snap.request({ method: 'snap_getEntropy', diff --git a/packages/snap/src/zkp/helpers/index.ts b/packages/snap/src/zkp/helpers/index.ts index d76fea4a..a3000ec4 100644 --- a/packages/snap/src/zkp/helpers/index.ts +++ b/packages/snap/src/zkp/helpers/index.ts @@ -1,9 +1,5 @@ export * from './identity-helpers'; export * from './file-helpers'; -export * from './state-v2-helpers'; export * from './credential-helpers'; -export * from './json-query-helpers'; -export * from './proof-helpers'; -export * from './model-helpers'; export * from './common-helpers'; export * from './ceramic-helpers'; diff --git a/packages/snap/src/zkp/helpers/json-query-helpers.ts b/packages/snap/src/zkp/helpers/json-query-helpers.ts deleted file mode 100644 index 89b619bf..00000000 --- a/packages/snap/src/zkp/helpers/json-query-helpers.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* eslint-disable @typescript-eslint/no-parameter-properties */ -import type { ProofQuery } from '@rarimo/rarime-connector'; - -import type { W3CCredential } from '@/zkp/types'; - -export enum SearchError { - NotDefinedQueryKey = 'not defined query key', - NotDefinedComparator = 'not defined comparator', -} - -export type FilterOperatorMethod = - | '$noop' - | '$eq' - | '$in' - | '$nin' - | '$gt' - | '$lt' - | '$ne'; - -export type FilterOperatorFunction = (a: any, b: any) => boolean; - -const comparatorOptions: { - [v in FilterOperatorMethod]: FilterOperatorFunction; -} = { - $noop: () => true, - $eq: (a, b) => a === b, - $in: (a: string, b: string[]) => b.includes(a), - $nin: (a: string, b: string[]) => !b.includes(a), - $gt: (a: number, b: number) => a > b, - $lt: (a: number, b: number) => a < b, - $ne: (a, b) => a !== b, -}; - -type PathObject = { [key: string]: any }; - -export const resolvePath = ( - object: PathObject, - path: string, - defaultValue = null, -) => path.split('.').reduce((o, p) => (o ? o[p] : defaultValue), object); - -export class FilterQuery { - constructor( - public path: string, - public operatorFunc: FilterOperatorFunction, - public value: any, - public isReverseParams = false, - ) {} - - execute(credential: W3CCredential): boolean { - if (!this.operatorFunc) { - throw new Error(SearchError.NotDefinedComparator); - } - const credentialPathValue = resolvePath(credential, this.path); - if (credentialPathValue === null || credentialPathValue === undefined) { - return false; - } - - if (this.isReverseParams) { - return this.operatorFunc(this.value, credentialPathValue); - } - return this.operatorFunc(credentialPathValue, this.value); - } -} - -export const StandardJSONCredentialsQueryFilter = ( - query: ProofQuery, -): FilterQuery[] => { - return Object.keys(query).reduce((acc: FilterQuery[], queryKey) => { - const queryValue = query[queryKey as keyof ProofQuery]; - switch (queryKey) { - case 'claimId': - return acc.concat( - new FilterQuery('id', comparatorOptions.$eq, queryValue), - ); - case 'allowedIssuers': { - const [first] = (queryValue as string[]) ?? []; - if (first && first === '*') { - return acc; - } - return acc.concat( - new FilterQuery('issuer', comparatorOptions.$in, queryValue), - ); - } - case 'type': - return acc.concat( - new FilterQuery('type', comparatorOptions.$in, queryValue, true), - ); - case 'context': - return acc.concat( - new FilterQuery('@context', comparatorOptions.$in, queryValue, true), - ); - case 'credentialSubjectId': - return acc.concat( - new FilterQuery( - 'credentialSubject.id', - comparatorOptions.$eq, - queryValue, - ), - ); - case 'schema': - return acc.concat( - new FilterQuery( - 'credentialSchema.id', - comparatorOptions.$eq, - queryValue, - ), - ); - case 'skipClaimRevocationCheck': - return acc; - case 'credentialSubject': { - const queryVal = queryValue as { [key: string]: any }; - const reqFilters = Object.keys(queryVal).reduce( - (arr: FilterQuery[], fieldKey) => { - const fieldParams = queryVal[fieldKey]; - const res = Object.keys(fieldParams).map((comparator) => { - const value = fieldParams[comparator]; - const path = `credentialSubject.${fieldKey}`; - return new FilterQuery( - path, - comparatorOptions[comparator as FilterOperatorMethod], - value, - ); - }); - return arr.concat(res); - }, - [], - ); - - return acc.concat(reqFilters); - } - default: - throw new Error(SearchError.NotDefinedQueryKey); - } - }, []); -}; diff --git a/packages/snap/src/zkp/helpers/model-helpers.ts b/packages/snap/src/zkp/helpers/model-helpers.ts deleted file mode 100644 index 2f16d422..00000000 --- a/packages/snap/src/zkp/helpers/model-helpers.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { Claim as CoreClaim, Id } from '@iden3/js-iden3-core'; -import { Proof } from '@iden3/js-merkletree'; - -import type { ProofType } from '@/zkp/enums'; -import type { - BJJSignatureProof, - CredentialStatus, - State, - TreeState, -} from '@/zkp/types'; - -export class IssuerData { - id!: string; - - state!: State; - - authCoreClaim?: string; - - mtp?: Proof; - - credentialStatus?: CredentialStatus; - - updateUrl!: string; -} - -export class Iden3SparseMerkleTreeProof { - type!: ProofType; - - issuerData!: IssuerData; - - mtp!: Proof; - - coreClaim!: string; - - id!: string; -} - -export class BJJSignatureProof2021 { - type!: ProofType; - - issuerData!: IssuerData; - - signature!: string; - - coreClaim!: string; -} - -export class CircuitClaim { - issuerId!: Id; - - claim!: CoreClaim; - - signatureProof!: BJJSignatureProof; - - incProof!: { - proof: Proof; - treeState: TreeState; - }; -} - -export class ValueProof { - path: bigint; - - value?: bigint; - - mtp: Proof; - - constructor() { - this.path = BigInt(0); - this.value = BigInt(0); - this.mtp = new Proof(); - } -} - -export class Query { - slotIndex!: number; - - values!: bigint[]; - - operator!: number; - - valueProof?: ValueProof; -} diff --git a/packages/snap/src/zkp/helpers/proof-helpers.ts b/packages/snap/src/zkp/helpers/proof-helpers.ts deleted file mode 100644 index 6c7b8fef..00000000 --- a/packages/snap/src/zkp/helpers/proof-helpers.ts +++ /dev/null @@ -1,589 +0,0 @@ -/* eslint-disable camelcase */ -/* eslint-disable @typescript-eslint/prefer-for-of */ -import { Hex, Signature } from '@iden3/js-crypto'; -import { - Claim, - DID, - fromLittleEndian, - MerklizedRootPosition, -} from '@iden3/js-iden3-core'; -import type { MtValue } from '@iden3/js-jsonld-merklization'; -import { - getDocumentLoader, - Merklizer, - Path, -} from '@iden3/js-jsonld-merklization'; -import type { NodeAux } from '@iden3/js-merkletree'; -import { Hash, Proof, ZERO_HASH } from '@iden3/js-merkletree'; -import type { ProofQuery } from '@rarimo/rarime-connector'; - -import { QueryOperators } from '@/zkp/const'; -import { ProofType } from '@/zkp/enums'; -import { - getRevocationStatus, - loadDataByUrl, -} from '@/zkp/helpers/credential-helpers'; -import { parseDidV2 } from '@/zkp/helpers/identity-helpers'; -import { - BJJSignatureProof2021, - CircuitClaim, - Iden3SparseMerkleTreeProof, - Query, - ValueProof, -} from '@/zkp/helpers/model-helpers'; -import type { - GISTProof, - JSONSchema, - MTProof, - NodeAuxValue, - QueryWithFieldName, - RevocationStatus, - StateProof, - TreeState, - W3CCredential, -} from '@/zkp/types'; - -export const extractProof = (proof: { - [key: string]: any; -}): { claim: Claim; proofType: ProofType } => { - if (proof instanceof Iden3SparseMerkleTreeProof) { - return { - claim: new Claim().fromHex(proof.coreClaim), - proofType: ProofType.Iden3SparseMerkleTreeProof, - }; - } - - if (proof instanceof BJJSignatureProof2021) { - return { - claim: new Claim().fromHex(proof.coreClaim), - proofType: ProofType.BJJSignature, - }; - } - - if (typeof proof === 'object') { - const defaultProofType = proof.type; - if (!defaultProofType) { - throw new Error('proof type is not specified'); - } - const coreClaimHex = proof.coreClaim; - if (!coreClaimHex) { - throw new Error( - `coreClaim field is not defined in proof type ${defaultProofType}`, - ); - } - return { - claim: new Claim().fromHex(coreClaimHex), - proofType: defaultProofType as ProofType, - }; - } - - throw new Error('proof format is not supported'); -}; - -export const getCoreClaimFromProof = ( - credentialProof: object | any[], - proofType: ProofType, -): Claim | null => { - if (Array.isArray(credentialProof)) { - for (const proof of credentialProof) { - const { claim, proofType: extractedProofType } = extractProof(proof); - if (proofType === extractedProofType) { - return claim; - } - } - } else if (typeof credentialProof === 'object') { - const { claim, proofType: extractedProofType } = - extractProof(credentialProof); - if (extractedProofType === proofType) { - return claim; - } - } - return null; -}; - -export const getBJJSignature2021Proof = ( - credentialProof: object | any[], -): BJJSignatureProof2021 | null => { - const proofType: ProofType = ProofType.BJJSignature; - if (Array.isArray(credentialProof)) { - for (const proof of credentialProof) { - const { proofType: extractedProofType } = extractProof(proof); - if (proofType === extractedProofType) { - return proof as BJJSignatureProof2021; - } - } - } else if (typeof credentialProof === 'object') { - const { proofType: extractedProofType } = extractProof(credentialProof); - if (extractedProofType === proofType) { - return credentialProof as BJJSignatureProof2021; - } - } - return null; -}; - -export const getIden3SparseMerkleTreeProof = ( - credentialProof: object | any[], -): Iden3SparseMerkleTreeProof | null => { - const proofType: ProofType = ProofType.Iden3SparseMerkleTreeProof; - if (Array.isArray(credentialProof)) { - for (const proof of credentialProof) { - const { proofType: extractedProofType } = extractProof(proof); - if (proofType === extractedProofType) { - return proof as Iden3SparseMerkleTreeProof; - } - } - } else if (typeof credentialProof === 'object') { - const { proofType: extractedProofType } = extractProof(credentialProof); - if (extractedProofType === proofType) { - return credentialProof as Iden3SparseMerkleTreeProof; - } - } - return null; -}; - -export const buildTreeState = ( - state: string, - claimsTreeRoot: string, - revocationTreeRoot: string, - rootOfRoots: string, -): TreeState => ({ - state: Hash.fromHex(state), - claimsRoot: Hash.fromHex(claimsTreeRoot), - revocationRoot: Hash.fromHex(revocationTreeRoot), - rootOfRoots: Hash.fromHex(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 => { - const circuitClaim = new CircuitClaim(); - circuitClaim.claim = coreClaim; - - const issuerDid = parseDidV2(credential.issuer); - - circuitClaim.issuerId = DID.idFromDID(issuerDid); - - const smtProof = getIden3SparseMerkleTreeProof(credential.proof!); - - if (smtProof) { - const data = await loadDataByUrl( - smtProof.id, - convertEndianSwappedCoreStateHashHex(coreStateHash), - ); - - circuitClaim.incProof = { - proof: data.mtp, - treeState: buildTreeState( - data.issuer.state, - data.issuer.claimsTreeRoot, - data.issuer.revocationTreeRoot, - data.issuer.rootOfRoots, - ), - }; - } - - const sigProof = getBJJSignature2021Proof(credential.proof!); - - if (sigProof) { - const decodedSignature = Hex.decodeString(sigProof.signature); - const signature = Signature.newFromCompressed(decodedSignature); - const issuerAuthClaimIncMtp = await loadDataByUrl( - sigProof.issuerData.updateUrl, - convertEndianSwappedCoreStateHashHex(coreStateHash), - ); - const rs: RevocationStatus = await getRevocationStatus( - sigProof.issuerData.credentialStatus!, - ); - - const issuerAuthNonRevProof: MTProof = { - treeState: buildTreeState( - rs.issuer.state!, - rs.issuer.claimsTreeRoot!, - rs.issuer.revocationTreeRoot!, - rs.issuer.rootOfRoots!, - ), - proof: rs.mtp, - }; - if (!sigProof.issuerData.mtp) { - throw new Error('issuer auth credential must have a mtp proof'); - } - - if (!sigProof.issuerData.authCoreClaim) { - throw new Error('issuer auth credential must have a core claim proof'); - } - - circuitClaim.signatureProof = { - signature, - issuerAuthIncProof: { - proof: issuerAuthClaimIncMtp.mtp, - treeState: buildTreeState( - issuerAuthClaimIncMtp.issuer.state!, - issuerAuthClaimIncMtp.issuer.claimsTreeRoot!, - issuerAuthClaimIncMtp.issuer.revocationTreeRoot!, - issuerAuthClaimIncMtp.issuer.rootOfRoots!, - ), - }, - issuerAuthClaim: new Claim().fromHex(sigProof.issuerData.authCoreClaim), - issuerAuthNonRevProof, - }; - } - - return circuitClaim; -}; - -export const prepareSiblingsStr = ( - proof: Proof | { siblings: Hash[] }, - levels: number, -): string[] => { - const siblings = - proof instanceof Proof ? proof.allSiblings() : proof.siblings; - - // Add the rest of empty levels to the siblings - for (let i = siblings.length; i < levels; i++) { - siblings.push(ZERO_HASH); - } - return siblings.map((s) => - typeof s === 'string' ? s : s.bigInt().toString(), - ); -}; - -export const parseRequest = async (req?: { - [key: string]: any; -}): Promise => { - if (!req) { - const query = new Query(); - query.operator = QueryOperators.$eq; - return { query, fieldName: '' }; - } - - const entries = Object.entries(req); - if (entries.length > 1) { - throw new Error(`multiple requests not supported`); - } - - const [fieldName, fieldReq] = entries[0]; - - const fieldReqEntries = Object.entries(fieldReq); - - if (fieldReqEntries.length > 1) { - throw new Error(`multiple predicates for one field not supported`); - } - - const isSelectiveDisclosure = fieldReqEntries.length === 0; - const query = new Query(); - - if (isSelectiveDisclosure) { - return { query, fieldName, isSelectiveDisclosure }; - } - - let operator = 0; - const values: bigint[] = new Array(64).fill(BigInt(0)); - const [kv, value] = fieldReqEntries[0]; - const key = kv as keyof typeof QueryOperators; - if (!QueryOperators[key]) { - throw new Error(`operator is not supported by lib`); - } - operator = QueryOperators[key]; - if (Array.isArray(value)) { - for (let index = 0; index < value.length; index++) { - values[index] = BigInt(value[index]); - } - } else { - values[0] = BigInt(value); - } - - query.operator = operator; - query.values = values; - - return { query, fieldName }; -}; - -export const merklize = async ( - credential: W3CCredential, -): Promise => { - const crdntl = { ...credential }; - delete crdntl.proof; - return await Merklizer.merklizeJSONLD(JSON.stringify(crdntl)); -}; - -export const prepareMerklizedQuery = async ( - query: ProofQuery, - credential: W3CCredential, -): Promise => { - const parsedQuery = await parseRequest(query.credentialSubject); - - const loader = getDocumentLoader(); - let schema: object; - try { - schema = (await loader(credential['@context'][2])).document; - } catch (e) { - throw new Error( - `can't load credential schema ${credential['@context'][2]}`, - ); - } - - let path: Path = new Path(); - if (parsedQuery.fieldName) { - path = await Path.getContextPathKey( - JSON.stringify(schema), - credential.type[1], - parsedQuery.fieldName, - ); - } - path.prepend(['https://www.w3.org/2018/credentials#credentialSubject']); - - const mk = await merklize(credential); - const { proof, value: mtValue } = await mk.proof(path); - - const pathKey = await path.mtEntry(); - parsedQuery.query.valueProof = new ValueProof(); - parsedQuery.query.valueProof.mtp = proof; - parsedQuery.query.valueProof.path = pathKey; - parsedQuery.query.valueProof.mtp = proof; - const mtEntry = await mtValue?.mtEntry(); - parsedQuery.query.valueProof.value = mtEntry; - - // for merklized credentials slotIndex in query must be equal to zero - // and not a position of merklization root. - // it has no influence on check in the off-chain circuits, but it aligns with onchain verification standard - parsedQuery.query.slotIndex = 0; - - if (!parsedQuery.fieldName || parsedQuery.isSelectiveDisclosure) { - const resultQuery = parsedQuery.query; - resultQuery.operator = QueryOperators.$eq; - resultQuery.values = [mtEntry!]; - return resultQuery; - } - - return parsedQuery.query; -}; - -export const getFieldSlotIndex = ( - field: string, - schemaBytes: Uint8Array, -): number => { - const schema: JSONSchema = JSON.parse(new TextDecoder().decode(schemaBytes)); - if (!schema?.$metadata?.serialization) { - throw new Error('serialization info is not set'); - } - - switch (field) { - case schema.$metadata?.serialization?.indexDataSlotA: - return 2; - case schema.$metadata?.serialization?.indexDataSlotB: - return 3; - case schema.$metadata?.serialization?.valueDataSlotA: - return 6; - case schema.$metadata?.serialization?.valueDataSlotB: - return 7; - default: - throw new Error(`field ${field} not specified in serialization info`); - } -}; - -export const stringByPath = ( - obj: { [key: string]: any }, - path: string, -): string => { - const parts = path.split('.'); - - let value = obj; - for (let index = 0; index < parts.length; index++) { - const key = parts[index]; - if (!key) { - throw new Error('path is empty'); - } - value = value[key]; - if (value === undefined) { - throw new Error('path not found'); - } - } - return value.toString(); -}; - -export const buildQueryPath = async ( - contextURL: string, - contextType: string, - field: string, -): Promise => { - let resp; - try { - resp = await (await fetch(contextURL)).json(); - } catch (error) { - throw new Error(`context not found: ${error.message}`); - } - - const path = await Path.getContextPathKey( - JSON.stringify(resp), - contextType, - field, - ); - path.prepend(['https://www.w3.org/2018/credentials#credentialSubject']); - return path; -}; - -export const verifiablePresentationFromCred = async ( - w3cCred: W3CCredential, - requestObj: ProofQuery, - field: string, -): Promise => { - const mz = await merklize(w3cCred); - - const contextType = stringByPath(requestObj, 'type'); - - const contextURL = stringByPath(requestObj, 'context'); - - const path = await buildQueryPath(contextURL, contextType, field); - - const { value } = await mz.proof(path); - - return value; -}; - -export const prepareNonMerklizedQuery = async ( - query: ProofQuery, - credential: W3CCredential, -): Promise => { - const loader = getDocumentLoader(); - - let schema: object; - try { - schema = (await loader(credential.credentialSchema.id)).document; - } catch (e) { - throw new Error( - `can't load credential schema ${credential['@context'][2]}`, - ); - } - - if ( - query.credentialSubject && - Object.keys(query.credentialSubject).length > 1 - ) { - throw new Error('multiple requests are not supported'); - } - - const parsedQuery = await parseRequest(query.credentialSubject); - parsedQuery.query.slotIndex = getFieldSlotIndex( - parsedQuery.fieldName, - new TextEncoder().encode(JSON.stringify(schema)), - ); - - if (parsedQuery.isSelectiveDisclosure) { - const mzValue = await verifiablePresentationFromCred( - credential, - query, - parsedQuery.fieldName, - ); - const resultQuery = parsedQuery.query; - resultQuery.operator = QueryOperators.$eq; - resultQuery.values = [await mzValue!.mtEntry()]; - return resultQuery; - } - - return parsedQuery.query; -}; - -export const toCircuitsQuery = async ( - query: ProofQuery, - credential: W3CCredential, - coreClaim: Claim, -): Promise => { - const mtPosition = coreClaim.getMerklizedPosition(); - - return mtPosition === MerklizedRootPosition.None - ? prepareNonMerklizedQuery(query, credential) - : prepareMerklizedQuery(query, credential); -}; - -export const prepareCircuitArrayValues = ( - arr: bigint[], - size: number, -): bigint[] => { - if (arr.length > size) { - throw new Error( - `array size ${arr.length} is bigger max expected size ${size}`, - ); - } - - // Add the empty values - for (let i = arr.length; i < size; i++) { - arr.push(BigInt(0)); - } - - return arr; -}; - -export const getNodeAuxValue = (p: Proof | undefined): NodeAuxValue => { - // proof of inclusion - if (p?.existence) { - return { - key: ZERO_HASH, - value: ZERO_HASH, - noAux: '0', - }; - } - - // proof of non-inclusion (NodeAux exists) - if (p?.nodeAux?.value !== undefined && p?.nodeAux?.key !== undefined) { - return { - key: p.nodeAux.key, - value: p.nodeAux.value, - noAux: '0', - }; - } - // proof of non-inclusion (NodeAux does not exist) - return { - key: ZERO_HASH, - value: ZERO_HASH, - noAux: '1', - }; -}; - -const newProofFromData = ( - existence: boolean, - allSiblings: Hash[], - nodeAux?: NodeAux, -): Proof => { - return new Proof({ - existence, - nodeAux, - siblings: allSiblings, - }); -}; - -export const toGISTProof = (smtProof: StateProof): GISTProof => { - let existence = false; - let nodeAux; - - if (smtProof.existence) { - existence = true; - } else if (smtProof.auxExistence) { - nodeAux = { - key: Hash.fromBigInt(smtProof.auxIndex), - value: Hash.fromBigInt(smtProof.auxValue), - }; - } - - const allSiblings: Hash[] = smtProof.siblings.map((s) => Hash.fromBigInt(s)); - - const proof = newProofFromData(existence, allSiblings, nodeAux); - - const root = Hash.fromBigInt(smtProof.root); - - return { - root, - proof, - }; -}; diff --git a/packages/snap/src/zkp/helpers/state-v2-helpers.ts b/packages/snap/src/zkp/helpers/state-v2-helpers.ts deleted file mode 100644 index afe7df78..00000000 --- a/packages/snap/src/zkp/helpers/state-v2-helpers.ts +++ /dev/null @@ -1,214 +0,0 @@ -/* eslint-disable camelcase */ -import type { TransactionRequest } from '@ethersproject/providers'; -import type { ILightweightStateV2 } from '@rarimo/rarime-connector'; -import { - LightweightStateV2__factory, - StateV2__factory, -} from '@rarimo/rarime-connector'; -import { providers, utils } from 'ethers'; - -import type { ChainInfo } from '@/types'; -import { - getChainInfo, - getProviderChainInfo, - getRarimoCoreUrl, - getRarimoEvmRpcUrl, - getRarimoStateContractAddress, -} from '@/zkp/helpers/common-helpers'; -import { FetcherError } from '@/zkp/helpers/error-helper'; -import type { - StateInfo, - OperationResponse, - OperationProof, - StateProof, -} from '@/zkp/types'; - -export const getGISTProof = async ({ - rpcUrl, - contractAddress, - userId, - rootHash, -}: { - rpcUrl: string; - contractAddress: string; - userId: string; - rootHash?: string; -}): Promise => { - const rawProvider = new providers.JsonRpcProvider(rpcUrl, 'any'); - - const contractInstance = StateV2__factory.connect( - contractAddress, - rawProvider, - ); - const data = rootHash - ? await contractInstance.getGISTProofByRoot(userId, rootHash) - : await contractInstance.getGISTProof(userId); - - return { - root: BigInt(data.root.toString()), - existence: data.existence, - siblings: data.siblings?.map((sibling) => BigInt(sibling.toString())), - index: BigInt(data.index.toString()), - value: BigInt(data.value.toString()), - auxExistence: data.auxExistence, - auxIndex: BigInt(data.auxIndex.toString()), - auxValue: BigInt(data.auxValue.toString()), - }; -}; - -// getRarimoGISTRoot returns the latest GIST root from the Rarimo state contract -export const getRarimoGISTRoot = async ({ - rpcUrl, - contractAddress, -}: { - rpcUrl?: string; - contractAddress?: string; -} = {}): Promise => { - const providerChainInfo = await getProviderChainInfo(); - - const _rpcUrl = rpcUrl ?? getRarimoEvmRpcUrl(providerChainInfo.id); - const _contractAddress = - contractAddress ?? getRarimoStateContractAddress(providerChainInfo.id); - - const rawProvider = new providers.JsonRpcProvider(_rpcUrl, 'any'); - - const contractInstance = StateV2__factory.connect( - _contractAddress, - rawProvider, - ); - - const root = await contractInstance.getGISTRoot(); - - return BigInt(root.toString()); -}; - -// getCurrentChainGISTRoot returns the GIST root from a lightweight state contract deployed on the current chain -export const getCurrentChainGISTRoot = async (): Promise => { - const provider = new providers.Web3Provider( - ethereum as any as providers.ExternalProvider, - ); - const network = await provider.getNetwork(); - const chainInfo = getChainInfo(network.chainId); - - const contractInstance = LightweightStateV2__factory.connect( - chainInfo.stateContractAddress, - provider, - ); - const root = await contractInstance.getGISTRoot(); - return BigInt(root.toString()); -}; - -// checkIfStateSynced returns true if the GIST root from the Rarimo state contract matches the GIST root from the current chain -export const checkIfStateSynced = async (): Promise => { - /* - NOTE: for now we assume that the state must be synced if the GIST roots don't match - some more sophisticated logic could be added here in the future - */ - const rarimoGISTRoot = await getRarimoGISTRoot(); - const currentChainGISTRoot = await getCurrentChainGISTRoot(); - return rarimoGISTRoot === currentChainGISTRoot; -}; - -export const loadDataFromRarimoCore = async ( - url: string, - blockHeight?: string, -): Promise => { - const providerChainInfo = await getProviderChainInfo(); - - const rarimoCoreUrl = getRarimoCoreUrl(providerChainInfo.id); - - const response = await fetch(`${rarimoCoreUrl}${url}`, { - headers: { - 'Content-Type': 'application/json', - ...(blockHeight && { 'X-Cosmos-Block-Height': blockHeight }), - }, - }); - - if (!response.ok) { - throw new FetcherError(response); - } - - return await response.json(); -}; - -type UpdateStateDetails = { - stateRootHash: string; - gistRootDataStruct: ILightweightStateV2.GistRootDataStruct; - proof: string; -}; - -export const getCoreOperationByIndex = async (index: string) => { - return loadDataFromRarimoCore( - `/rarimo/rarimo-core/rarimocore/operation/${index}`, - ); -}; - -export const getUpdateStateDetails = async ( - state: StateInfo, - operation: OperationResponse, -): Promise => { - let operationProof; - do { - try { - operationProof = await loadDataFromRarimoCore( - `/rarimo/rarimo-core/rarimocore/operation/${state.lastUpdateOperationIndex}/proof`, - ); - } catch (error) { - if (error instanceof FetcherError && error.response.status === 400) { - await new Promise((resolve) => setTimeout(resolve, 5_000)); - } else { - throw error; - } - } - } while (!operationProof); - - const decodedPath = operationProof?.path?.map((el: string) => - utils.arrayify(el), - ); - const decodedSignature = operationProof?.signature - ? utils.arrayify(operationProof?.signature) - : undefined; - - if (decodedSignature?.[64] !== undefined) { - decodedSignature[64] += 27; - } - - const proof = utils.defaultAbiCoder.encode( - ['bytes32[]', 'bytes'], - [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 => { - const { stateRootHash, gistRootDataStruct, proof } = - updateStateDetails ?? (await getUpdateStateDetails(state, operation)); - - const contractInterface = LightweightStateV2__factory.createInterface(); - - const txData = contractInterface.encodeFunctionData('signedTransitState', [ - stateRootHash, - gistRootDataStruct, - proof, - ]); - return { - to: chainInfo.stateContractAddress, - from: accountId, - chainId: chainInfo.id, - data: txData, - }; -}; diff --git a/packages/snap/src/zkp/identity.ts b/packages/snap/src/zkp/identity.ts deleted file mode 100644 index c5e86647..00000000 --- a/packages/snap/src/zkp/identity.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Hex, PrivateKey } from '@iden3/js-crypto'; -import { - Claim, - ClaimOptions, - DID, - fromBigEndian, - idenState, - SchemaHash, -} from '@iden3/js-iden3-core'; -import type { Proof } from '@iden3/js-merkletree'; -import { hashElems, InMemoryDB, Merkletree } from '@iden3/js-merkletree'; - -import { config } from '@/config'; -import { defaultMTLevels } from '@/zkp/const'; -import { initPrivateKey, prepareSiblingsStr } from '@/zkp/helpers'; - -export type TreeState = { - state: string; - claimsRoot: string; - revocationRoot: string; - rootOfRoots: string; -}; - -export class Identity { - privateKeyHex = '' as string; - - did: DID = {} as DID; - - authClaimIncProofSiblings: string[] = []; - - authClaimNonRevProof: Proof = {} as Proof; - - treeState: TreeState = {} as TreeState; - - coreAuthClaim: Claim = {} as Claim; - - public static async create(privateKeyHex?: string): Promise { - const identity = new Identity(privateKeyHex); - - await identity.createIdentity(); - - return identity; - } - - constructor(privateKeyHex?: string) { - this.privateKeyHex = initPrivateKey(privateKeyHex); - } - - public get privateKey() { - return new PrivateKey(Hex.decodeString(this.privateKeyHex)); - } - - public get didString() { - return this.did.string(); - } - - public get identityIdBigIntString() { - const id = DID.idFromDID(this.did); - - return String(id.bigInt()); - } - - async createIdentity() { - this.coreAuthClaim = this.createCoreAuthClaim(); - - const authResponse = this.coreAuthClaim.hiHv(); - - const uint8array1 = new TextEncoder().encode('claims'); - const uint8array2 = new TextEncoder().encode('revocations'); - const uint8array3 = new TextEncoder().encode('roots'); - - const storage1 = new InMemoryDB(uint8array1); - const storage2 = new InMemoryDB(uint8array2); - const storage3 = new InMemoryDB(uint8array3); - - const claimsTree = new Merkletree(storage1, true, 32); - const revocationsTree = new Merkletree(storage2, true, 32); - const rootsTree = new Merkletree(storage3, true, 32); - - await claimsTree.add(authResponse.hi, authResponse.hv); - - const claimsTreeRoot = await claimsTree.root(); - const revocationsTreeRoot = await revocationsTree.root(); - const rootsTreeRoot = await rootsTree.root(); - - const identity = idenState( - claimsTreeRoot.bigInt(), - revocationsTreeRoot.bigInt(), - rootsTreeRoot.bigInt(), - ); - - this.did = DID.newFromIdenState(config.ID_TYPE, identity); - - const authClaimIncProof = await claimsTree.generateProof( - this.coreAuthClaim.hIndex(), - claimsTreeRoot, - ); - - const authClaimIncProofSiblings = prepareSiblingsStr( - authClaimIncProof.proof, - defaultMTLevels, - ); - - const authClaimNonRevProof = await revocationsTree.generateProof( - this.coreAuthClaim.getRevocationNonce(), - revocationsTreeRoot, - ); - - this.authClaimIncProofSiblings = authClaimIncProofSiblings; - this.authClaimNonRevProof = authClaimNonRevProof.proof; - - const stateHash = hashElems([ - claimsTreeRoot.bigInt(), - revocationsTreeRoot.bigInt(), - rootsTreeRoot.bigInt(), - ]); - - this.treeState = { - state: stateHash.string(), - claimsRoot: claimsTreeRoot.string(), - revocationRoot: revocationsTreeRoot.string(), - rootOfRoots: rootsTreeRoot.string(), - }; - } - - createCoreAuthClaim() { - const hash = SchemaHash.newSchemaHashFromHex( - config.AUTH_BJJ_CREDENTIAL_HASH, - ); - const revNonce = new Uint8Array(64); - const key = this.privateKey.public(); - - return Claim.newClaim( - hash, - ClaimOptions.withIndexDataInts(key.p[0], key.p[1]), - ClaimOptions.withRevocationNonce(fromBigEndian(revNonce)), - ); - } -} diff --git a/packages/snap/src/zkp/types/credential-types.ts b/packages/snap/src/zkp/types/credential-types.ts deleted file mode 100644 index b762fbbe..00000000 --- a/packages/snap/src/zkp/types/credential-types.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable jsdoc/check-tag-names */ -import type { Proof } from '@iden3/js-merkletree'; - -export type CredentialStatus = { - id: string; - type: string; - revocationNonce?: number; - statusIssuer?: CredentialStatus; -}; - -export type CredentialSchema = { - id: string; - type: string; -}; - -export type W3CCredential = { - id: string; - '@context': string[]; - type: string[]; - expirationDate?: string; - issuanceDate?: string; - credentialSubject: { [key: string]: object | string | number }; - credentialStatus: CredentialStatus; - issuer: string; - credentialSchema: CredentialSchema; - proof?: { [key: string]: any } | any[]; -}; - -export type Issuer = { - state?: string; - rootOfRoots?: string; - claimsTreeRoot?: string; - revocationTreeRoot?: string; -}; - -export type RevocationStatus = { - mtp: Proof; - issuer: Issuer; -}; diff --git a/packages/snap/src/zkp/types/index.ts b/packages/snap/src/zkp/types/index.ts index 669f6de1..acae838c 100644 --- a/packages/snap/src/zkp/types/index.ts +++ b/packages/snap/src/zkp/types/index.ts @@ -1,4 +1 @@ export * from './graphql'; -export * from './credential-types'; -export * from './proof-types'; -export * from './state-types'; diff --git a/packages/snap/src/zkp/types/proof-types.ts b/packages/snap/src/zkp/types/proof-types.ts deleted file mode 100644 index cbeffd8d..00000000 --- a/packages/snap/src/zkp/types/proof-types.ts +++ /dev/null @@ -1,86 +0,0 @@ -import type { Signature } from '@iden3/js-crypto'; -import type { Claim } from '@iden3/js-iden3-core'; -import type { Hash, Proof } from '@iden3/js-merkletree'; - -import type { Query } from '@/zkp/helpers'; - -export type State = { - txId?: string; - blockTimestamp?: number; - blockNumber?: number; - rootOfRoots: string; - claimsTreeRoot: string; - revocationTreeRoot: string; - value: string; - status?: string; -}; - -export type TreeState = { - state: Hash; - claimsRoot: Hash; - revocationRoot: Hash; - rootOfRoots: Hash; -}; - -export type ClaimNonRevStatus = { - treeState: TreeState; - proof: Proof; -}; - -export type MTProof = { - proof: Proof; - treeState?: TreeState; -}; - -export type BJJSignatureProof = { - signature: Signature; - issuerAuthClaim?: Claim; - issuerAuthIncProof: MTProof; - issuerAuthNonRevProof: MTProof; -}; - -export type QueryWithFieldName = { - query: Query; - fieldName: string; - isSelectiveDisclosure?: boolean; -}; - -export type SerializationSchema = { - indexDataSlotA: string; - indexDataSlotB: string; - valueDataSlotA: string; - valueDataSlotB: string; -}; - -export type SchemaMetadata = { - uris: { [key: string]: string }; - serialization?: SerializationSchema; -}; - -export type JSONSchema = { - $metadata: SchemaMetadata; - $schema: string; - type: string; -}; - -export type NodeAuxValue = { - key: Hash; - value: Hash; - noAux: string; -}; - -export type StateProof = { - root: bigint; - existence: boolean; - siblings: bigint[]; - index: bigint; - value: bigint; - auxExistence: boolean; - auxIndex: bigint; - auxValue: bigint; -}; - -export type GISTProof = { - root: Hash; - proof: Proof; -}; diff --git a/packages/snap/src/zkp/types/state-types.ts b/packages/snap/src/zkp/types/state-types.ts deleted file mode 100644 index 65b01c76..00000000 --- a/packages/snap/src/zkp/types/state-types.ts +++ /dev/null @@ -1,47 +0,0 @@ -export type MerkleProof = { - proof: string[]; -}; - -export type StateInfo = { - index: string; - hash: string; - createdAtTimestamp: string; - createdAtBlock: string; - lastUpdateOperationIndex: string; -}; - -export type GetStateInfoResponse = { - state: StateInfo; -}; - -export type OperationProof = { - path: string[]; - signature: string; -}; - -export enum OperationStatus { - Signed = 'SIGNED', - Initialized = 'INITIALIZED', - Approved = 'APPROVED', - NotApproved = 'NOT_APPROVED', -} - -export type Operation = { - index: string; - operationType: string; - details: { - '@type': string; - contract: string; - chain: string; - GISTHash: string; - stateRootHash: string; - timestamp: string; - }; - status: OperationStatus; - creator: string; - timestamp: string; -}; - -export type OperationResponse = { - operation: Operation; -}; diff --git a/packages/snap/src/zkp/zkp-gen.ts b/packages/snap/src/zkp/zkp-gen.ts deleted file mode 100644 index 10f8817b..00000000 --- a/packages/snap/src/zkp/zkp-gen.ts +++ /dev/null @@ -1,556 +0,0 @@ -import type { Signature } from '@iden3/js-crypto'; -import { Hex } from '@iden3/js-crypto'; -import { fromLittleEndian } from '@iden3/js-iden3-core'; -import type { ZKProof } from '@iden3/js-jwz'; -import { proving } from '@iden3/js-jwz'; -import type { CreateProofRequest } from '@rarimo/rarime-connector'; -import { CircuitId } from '@rarimo/rarime-connector'; - -import { config } from '@/config'; -import { - defaultMTLevels, - defaultMTLevelsClaimsMerklization, - defaultMTLevelsOnChain, - defaultValueArraySize, -} from '@/zkp/const'; -import type { CircuitClaim, Query } from '@/zkp/helpers'; -import { - buildTreeState, - getGISTProof, - getNodeAuxValue, - getPreparedCredential, - getProviderChainInfo, - getRarimoEvmRpcUrl, - getRarimoStateContractAddress, - getFileBytes, - newCircuitClaimData, - prepareCircuitArrayValues, - prepareSiblingsStr, - toCircuitsQuery, - toGISTProof, -} from '@/zkp/helpers'; -import type { Identity } from '@/zkp/identity'; -import type { - ClaimNonRevStatus, - GISTProof, - NodeAuxValue, - W3CCredential, -} from '@/zkp/types'; - -export class ZkpGen { - identity: Identity = {} as Identity; - - verifiableCredential: W3CCredential = {} as W3CCredential; - - subjectProof: ZKProof = {} as ZKProof; - - proofRequest: CreateProofRequest = {} as CreateProofRequest; - - circuitClaimData: CircuitClaim = {} as CircuitClaim; - - query: Query = {} as Query; - - nodeAuxIssuerAuthNonRev: NodeAuxValue = {} as NodeAuxValue; - - nodeAuxNonRev: NodeAuxValue = {} as NodeAuxValue; - - nodAuxJSONLD: NodeAuxValue = {} as NodeAuxValue; - - nonRevProof: ClaimNonRevStatus = {} as ClaimNonRevStatus; - - value: string[] = []; - - timestamp?: number; - - gistProof?: GISTProof; - - challenge?: bigint; - - signatureChallenge?: Signature; - - globalNodeAux?: NodeAuxValue; - - nodeAuxAuth?: NodeAuxValue; - - constructor( - identity: Identity, - proofRequest: CreateProofRequest, - verifiableCredential: W3CCredential, - ) { - this.identity = identity; - this.verifiableCredential = verifiableCredential; - this.proofRequest = proofRequest; - } - - async generateProof(coreStateHash: string, operationGistHash: string) { - const preparedCredential = await getPreparedCredential( - this.verifiableCredential, - ); - - this.circuitClaimData = await newCircuitClaimData( - preparedCredential.credential, - preparedCredential.credentialCoreClaim, - coreStateHash, - ); - - this.query = await toCircuitsQuery( - this.proofRequest.query, - preparedCredential.credential, - preparedCredential.credentialCoreClaim, - ); - - this.nonRevProof = { - proof: preparedCredential.revStatus.mtp, - treeState: buildTreeState( - preparedCredential.revStatus.issuer.state!, - preparedCredential.revStatus.issuer.claimsTreeRoot!, - preparedCredential.revStatus.issuer.revocationTreeRoot!, - preparedCredential.revStatus.issuer.rootOfRoots!, - ), - }; - - this.timestamp = Math.floor(Date.now() / 1000); - - this.nodeAuxIssuerAuthNonRev = getNodeAuxValue( - this.circuitClaimData.signatureProof.issuerAuthNonRevProof.proof, - ); - this.nodeAuxNonRev = getNodeAuxValue(this.nonRevProof.proof); - this.nodAuxJSONLD = getNodeAuxValue(this.query.valueProof!.mtp); - this.value = prepareCircuitArrayValues( - this.query.values, - defaultValueArraySize, - ).map((a) => a.toString()); - - if ( - this.proofRequest.circuitId === CircuitId.AtomicQuerySigV2OnChain || - this.proofRequest.circuitId === CircuitId.AtomicQueryMTPV2OnChain - ) { - const providerChainInfo = await getProviderChainInfo(); - - const gistInfo = await getGISTProof({ - rpcUrl: getRarimoEvmRpcUrl(providerChainInfo.id), - contractAddress: getRarimoStateContractAddress(providerChainInfo.id), - userId: this.identity.identityIdBigIntString, - rootHash: operationGistHash, - }); - this.gistProof = toGISTProof(gistInfo); - - const challenge = fromLittleEndian( - Hex.decodeString(this.proofRequest.accountAddress!.substring(2)), - ).toString(); - this.challenge = BigInt(this.proofRequest.challenge ?? challenge); - - this.signatureChallenge = this.identity.privateKey.signPoseidon( - this.challenge, - ); - - this.globalNodeAux = getNodeAuxValue(this.gistProof.proof); - this.nodeAuxAuth = getNodeAuxValue(this.identity.authClaimNonRevProof); - } - - const circuiInfo = this.getCircuitInfo(); - - const [wasm, provingKey] = await Promise.all([ - getFileBytes(circuiInfo.wasm), - getFileBytes(circuiInfo.finalKey), - ]); - this.subjectProof = await proving.provingMethodGroth16AuthV2Instance.prove( - new TextEncoder().encode(circuiInfo.generateInputFn()), - provingKey, - wasm, - ); - - return this.subjectProof; - } - - getCircuitInfo() { - switch (this.proofRequest.circuitId) { - case CircuitId.AtomicQuerySigV2OnChain: - return { - wasm: config.CIRCUIT_SIG_V2_ON_CHAIN_WASM_URL, - finalKey: config.CIRCUIT_SIG_V2_ON_CHAIN_FINAL_KEY_URL, - generateInputFn: this.generateQuerySigV2OnChainInputs.bind(this), - }; - case CircuitId.AtomicQuerySigV2: - return { - wasm: config.CIRCUIT_SIG_V2_WASM_URL, - finalKey: config.CIRCUIT_SIG_V2_FINAL_KEY_URL, - generateInputFn: this.generateQuerySigV2Inputs.bind(this), - }; - case CircuitId.AtomicQueryMTPV2: - return { - wasm: config.CIRCUIT_MTP_V2_WASM_URL, - finalKey: config.CIRCUIT_MTP_V2_FINAL_KEY_URL, - generateInputFn: this.generateQueryMTPV2Inputs.bind(this), - }; - case CircuitId.AtomicQueryMTPV2OnChain: - return { - wasm: config.CIRCUIT_MTP_V2_ON_CHAIN_WASM_URL, - finalKey: config.CIRCUIT_MTP_V2_ON_CHAIN_FINAL_KEY_URL, - generateInputFn: this.generateQueryMTPV2OnChainInputs.bind(this), - }; - default: - throw new Error( - `circuit with id ${this.proofRequest.circuitId} is not supported by issuer`, - ); - } - } - - generateQuerySigV2OnChainInputs() { - return JSON.stringify({ - /* we have no constraints for "requestID" in this circuit, it is used as a unique identifier for the request */ - /* and verifier can use it to identify the request, and verify the proof of specific request in case of multiple query requests */ - requestID: this.proofRequest.id?.toString || '1', - - userGenesisID: this.identity.identityIdBigIntString, - profileNonce: '0', - - userState: this.identity.treeState.state, - userClaimsTreeRoot: this.identity.treeState.claimsRoot, - userRevTreeRoot: this.identity.treeState.revocationRoot, - userRootsTreeRoot: this.identity.treeState.rootOfRoots, - - authClaim: this.identity.coreAuthClaim.marshalJson(), - - authClaimIncMtp: this.identity.authClaimIncProofSiblings, - - authClaimNonRevMtp: prepareSiblingsStr( - this.identity.authClaimNonRevProof, - defaultMTLevels, - ), - authClaimNonRevMtpAuxHi: this.nodeAuxAuth?.key.string(), - authClaimNonRevMtpAuxHv: this.nodeAuxAuth?.value.string(), - authClaimNonRevMtpNoAux: this.nodeAuxAuth?.noAux, - - challenge: this.challenge?.toString(), - challengeSignatureR8x: this.signatureChallenge?.R8[0].toString(), - challengeSignatureR8y: this.signatureChallenge?.R8[1].toString(), - challengeSignatureS: this.signatureChallenge?.S.toString(), - - gistRoot: this.gistProof?.root.string(), - gistMtp: prepareSiblingsStr( - this.gistProof!.proof, - defaultMTLevelsOnChain, - ), - gistMtpAuxHi: this.globalNodeAux?.key.string(), - gistMtpAuxHv: this.globalNodeAux?.value.string(), - gistMtpNoAux: this.globalNodeAux?.noAux, - - claimSubjectProfileNonce: '0', - - issuerID: this.circuitClaimData.issuerId.bigInt().toString(), - - issuerAuthClaim: - this.circuitClaimData.signatureProof.issuerAuthClaim?.marshalJson(), - issuerAuthClaimMtp: prepareSiblingsStr( - this.circuitClaimData.signatureProof.issuerAuthIncProof.proof, - defaultMTLevels, - ), - issuerAuthClaimsTreeRoot: - this.circuitClaimData.signatureProof.issuerAuthIncProof.treeState?.claimsRoot.string(), - issuerAuthRevTreeRoot: - this.circuitClaimData.signatureProof.issuerAuthIncProof.treeState?.revocationRoot.string(), - issuerAuthRootsTreeRoot: - this.circuitClaimData.signatureProof.issuerAuthIncProof.treeState?.rootOfRoots.string(), - - issuerAuthClaimNonRevMtp: prepareSiblingsStr( - this.circuitClaimData.signatureProof.issuerAuthNonRevProof.proof, - defaultMTLevels, - ), - issuerAuthClaimNonRevMtpNoAux: this.nodeAuxIssuerAuthNonRev.noAux, - issuerAuthClaimNonRevMtpAuxHi: this.nodeAuxIssuerAuthNonRev.key.string(), - issuerAuthClaimNonRevMtpAuxHv: - this.nodeAuxIssuerAuthNonRev.value.string(), - - issuerClaim: this.circuitClaimData.claim.marshalJson(), - isRevocationChecked: '1', - issuerClaimNonRevMtp: prepareSiblingsStr( - this.nonRevProof.proof, - defaultMTLevels, - ), - issuerClaimNonRevMtpNoAux: this.nodeAuxNonRev.noAux, - issuerClaimNonRevMtpAuxHi: this.nodeAuxNonRev.key.string(), - issuerClaimNonRevMtpAuxHv: this.nodeAuxNonRev.value.string(), - issuerClaimNonRevClaimsTreeRoot: - this.nonRevProof.treeState.claimsRoot.string(), - issuerClaimNonRevRevTreeRoot: - this.nonRevProof.treeState.revocationRoot.string(), - issuerClaimNonRevRootsTreeRoot: - this.nonRevProof.treeState.rootOfRoots.string(), - issuerClaimNonRevState: this.nonRevProof.treeState.state.string(), - - issuerClaimSignatureR8x: - this.circuitClaimData.signatureProof.signature.R8[0].toString(), - issuerClaimSignatureR8y: - this.circuitClaimData.signatureProof.signature.R8[1].toString(), - issuerClaimSignatureS: - this.circuitClaimData.signatureProof.signature.S.toString(), - - timestamp: this.timestamp, - - claimSchema: this.circuitClaimData.claim - .getSchemaHash() - .bigInt() - .toString(), - claimPathNotExists: this.query.valueProof?.mtp.existence ? 0 : 1, - claimPathMtp: prepareSiblingsStr( - this.query.valueProof!.mtp, - defaultMTLevelsClaimsMerklization, - ), - claimPathMtpNoAux: this.nodAuxJSONLD.noAux, - claimPathMtpAuxHi: this.nodAuxJSONLD.key.string(), - claimPathMtpAuxHv: this.nodAuxJSONLD.value.string(), - claimPathKey: this.query.valueProof?.path.toString(), - claimPathValue: this.query.valueProof?.value?.toString(), - - slotIndex: this.query.slotIndex, - operator: this.query.operator, - value: this.value, - }); - } - - generateQuerySigV2Inputs() { - return JSON.stringify({ - /* we have no constraints for "requestID" in this circuit, it is used as a unique identifier for the request */ - /* and verifier can use it to identify the request, and verify the proof of specific request in case of multiple query requests */ - requestID: this.proofRequest.id?.toString || '1', - - userGenesisID: this.identity.identityIdBigIntString, - profileNonce: '0', - - claimSubjectProfileNonce: '0', - - issuerID: this.circuitClaimData.issuerId.bigInt().toString(), - - issuerAuthClaim: - this.circuitClaimData.signatureProof.issuerAuthClaim?.marshalJson(), - issuerAuthClaimMtp: prepareSiblingsStr( - this.circuitClaimData.signatureProof.issuerAuthIncProof.proof, - defaultMTLevels, - ), - issuerAuthClaimsTreeRoot: - this.circuitClaimData.signatureProof.issuerAuthIncProof.treeState?.claimsRoot.string(), - issuerAuthRevTreeRoot: - this.circuitClaimData.signatureProof.issuerAuthIncProof.treeState?.revocationRoot.string(), - issuerAuthRootsTreeRoot: - this.circuitClaimData.signatureProof.issuerAuthIncProof.treeState?.rootOfRoots.string(), - - issuerAuthClaimNonRevMtp: prepareSiblingsStr( - this.circuitClaimData.signatureProof.issuerAuthNonRevProof.proof, - defaultMTLevels, - ), - issuerAuthClaimNonRevMtpNoAux: this.nodeAuxIssuerAuthNonRev.noAux, - issuerAuthClaimNonRevMtpAuxHi: this.nodeAuxIssuerAuthNonRev.key.string(), - issuerAuthClaimNonRevMtpAuxHv: - this.nodeAuxIssuerAuthNonRev.value.string(), - - issuerClaim: this.circuitClaimData.claim.marshalJson(), - isRevocationChecked: '1', - issuerClaimNonRevMtp: prepareSiblingsStr( - this.nonRevProof.proof, - defaultMTLevels, - ), - issuerClaimNonRevMtpNoAux: this.nodeAuxNonRev.noAux, - issuerClaimNonRevMtpAuxHi: this.nodeAuxNonRev.key.string(), - issuerClaimNonRevMtpAuxHv: this.nodeAuxNonRev.value.string(), - issuerClaimNonRevClaimsTreeRoot: - this.nonRevProof.treeState.claimsRoot.string(), - issuerClaimNonRevRevTreeRoot: - this.nonRevProof.treeState.revocationRoot.string(), - issuerClaimNonRevRootsTreeRoot: - this.nonRevProof.treeState.rootOfRoots.string(), - issuerClaimNonRevState: this.nonRevProof.treeState.state.string(), - - issuerClaimSignatureR8x: - this.circuitClaimData.signatureProof.signature.R8[0].toString(), - issuerClaimSignatureR8y: - this.circuitClaimData.signatureProof.signature.R8[1].toString(), - issuerClaimSignatureS: - this.circuitClaimData.signatureProof.signature.S.toString(), - - timestamp: this.timestamp, - - claimSchema: this.circuitClaimData.claim - .getSchemaHash() - .bigInt() - .toString(), - claimPathNotExists: this.query.valueProof?.mtp.existence ? 0 : 1, - claimPathMtp: prepareSiblingsStr( - this.query.valueProof!.mtp, - defaultMTLevelsClaimsMerklization, - ), - claimPathMtpNoAux: this.nodAuxJSONLD.noAux, - claimPathMtpAuxHi: this.nodAuxJSONLD.key.string(), - claimPathMtpAuxHv: this.nodAuxJSONLD.value.string(), - claimPathKey: this.query.valueProof?.path.toString(), - claimPathValue: this.query.valueProof?.value?.toString(), - - slotIndex: this.query.slotIndex, - operator: this.query.operator, - value: this.value, - }); - } - - generateQueryMTPV2Inputs() { - return JSON.stringify({ - /* we have no constraints for "requestID" in this circuit, it is used as a unique identifier for the request */ - /* and verifier can use it to identify the request, and verify the proof of specific request in case of multiple query requests */ - requestID: this.proofRequest.id?.toString || '1', - - userGenesisID: this.identity.identityIdBigIntString, - profileNonce: '0', - - claimSubjectProfileNonce: '0', - - issuerID: this.circuitClaimData.issuerId.bigInt().toString(), - - issuerClaim: this.circuitClaimData.claim.marshalJson(), - isRevocationChecked: '1', - issuerClaimNonRevMtp: prepareSiblingsStr( - this.nonRevProof.proof, - defaultMTLevels, - ), - issuerClaimNonRevMtpNoAux: this.nodeAuxNonRev.noAux, - issuerClaimNonRevMtpAuxHi: this.nodeAuxNonRev.key.string(), - issuerClaimNonRevMtpAuxHv: this.nodeAuxNonRev.value.string(), - issuerClaimNonRevClaimsTreeRoot: - this.nonRevProof.treeState.claimsRoot.string(), - issuerClaimNonRevRevTreeRoot: - this.nonRevProof.treeState.revocationRoot.string(), - issuerClaimNonRevRootsTreeRoot: - this.nonRevProof.treeState.rootOfRoots.string(), - issuerClaimNonRevState: this.nonRevProof.treeState.state.string(), - - issuerClaimMtp: prepareSiblingsStr( - this.circuitClaimData.incProof.proof, - defaultMTLevels, - ), - issuerClaimClaimsTreeRoot: - this.circuitClaimData.incProof.treeState?.claimsRoot.string(), - issuerClaimRevTreeRoot: - this.circuitClaimData.incProof.treeState?.revocationRoot.string(), - issuerClaimRootsTreeRoot: - this.circuitClaimData.incProof.treeState?.rootOfRoots.string(), - issuerClaimIdenState: - this.circuitClaimData.incProof.treeState?.state.string(), - - timestamp: this.timestamp, - - claimSchema: this.circuitClaimData.claim - .getSchemaHash() - .bigInt() - .toString(), - claimPathNotExists: this.query.valueProof?.mtp.existence ? 0 : 1, - claimPathMtp: prepareSiblingsStr( - this.query.valueProof!.mtp, - defaultMTLevelsClaimsMerklization, - ), - claimPathMtpNoAux: this.nodAuxJSONLD.noAux, - claimPathMtpAuxHi: this.nodAuxJSONLD.key.string(), - claimPathMtpAuxHv: this.nodAuxJSONLD.value.string(), - claimPathKey: this.query.valueProof?.path.toString(), - claimPathValue: this.query.valueProof?.value?.toString(), - - slotIndex: this.query.slotIndex, - operator: this.query.operator, - value: this.value, - }); - } - - generateQueryMTPV2OnChainInputs() { - return JSON.stringify({ - /* we have no constraints for "requestID" in this circuit, it is used as a unique identifier for the request */ - /* and verifier can use it to identify the request, and verify the proof of specific request in case of multiple query requests */ - requestID: this.proofRequest.id?.toString || '1', - - userGenesisID: this.identity.identityIdBigIntString, - profileNonce: '0', - - userState: this.identity.treeState.state, - userClaimsTreeRoot: this.identity.treeState.claimsRoot, - userRevTreeRoot: this.identity.treeState.revocationRoot, - userRootsTreeRoot: this.identity.treeState.rootOfRoots, - - authClaim: this.identity.coreAuthClaim.marshalJson(), - - authClaimIncMtp: this.identity.authClaimIncProofSiblings, - - authClaimNonRevMtp: prepareSiblingsStr( - this.identity.authClaimNonRevProof, - defaultMTLevels, - ), - authClaimNonRevMtpAuxHi: this.nodeAuxAuth?.key.string(), - authClaimNonRevMtpAuxHv: this.nodeAuxAuth?.value.string(), - authClaimNonRevMtpNoAux: this.nodeAuxAuth?.noAux, - - challenge: this.challenge?.toString(), - challengeSignatureR8x: this.signatureChallenge?.R8[0].toString(), - challengeSignatureR8y: this.signatureChallenge?.R8[1].toString(), - challengeSignatureS: this.signatureChallenge?.S.toString(), - - gistRoot: this.gistProof?.root.string(), - gistMtp: prepareSiblingsStr( - this.gistProof!.proof, - defaultMTLevelsOnChain, - ), - gistMtpAuxHi: this.globalNodeAux?.key.string(), - gistMtpAuxHv: this.globalNodeAux?.value.string(), - gistMtpNoAux: this.globalNodeAux?.noAux, - - claimSubjectProfileNonce: '0', - - issuerID: this.circuitClaimData.issuerId.bigInt().toString(), - - issuerClaim: this.circuitClaimData.claim.marshalJson(), - isRevocationChecked: '1', - issuerClaimNonRevMtp: prepareSiblingsStr( - this.nonRevProof.proof, - defaultMTLevels, - ), - issuerClaimNonRevMtpNoAux: this.nodeAuxNonRev.noAux, - issuerClaimNonRevMtpAuxHi: this.nodeAuxNonRev.key.string(), - issuerClaimNonRevMtpAuxHv: this.nodeAuxNonRev.value.string(), - issuerClaimNonRevClaimsTreeRoot: - this.nonRevProof.treeState.claimsRoot.string(), - issuerClaimNonRevRevTreeRoot: - this.nonRevProof.treeState.revocationRoot.string(), - issuerClaimNonRevRootsTreeRoot: - this.nonRevProof.treeState.rootOfRoots.string(), - issuerClaimNonRevState: this.nonRevProof.treeState.state.string(), - - issuerClaimMtp: prepareSiblingsStr( - this.circuitClaimData.incProof.proof, - defaultMTLevels, - ), - issuerClaimClaimsTreeRoot: - this.circuitClaimData.incProof.treeState?.claimsRoot.string(), - issuerClaimRevTreeRoot: - this.circuitClaimData.incProof.treeState?.revocationRoot.string(), - issuerClaimRootsTreeRoot: - this.circuitClaimData.incProof.treeState?.rootOfRoots.string(), - issuerClaimIdenState: - this.circuitClaimData.incProof.treeState?.state.string(), - - timestamp: this.timestamp, - - claimSchema: this.circuitClaimData.claim - .getSchemaHash() - .bigInt() - .toString(), - claimPathNotExists: this.query.valueProof?.mtp.existence ? 0 : 1, - claimPathMtp: prepareSiblingsStr( - this.query.valueProof!.mtp, - defaultMTLevelsClaimsMerklization, - ), - claimPathMtpNoAux: this.nodAuxJSONLD.noAux, - claimPathMtpAuxHi: this.nodAuxJSONLD.key.string(), - claimPathMtpAuxHv: this.nodAuxJSONLD.value.string(), - claimPathKey: this.query.valueProof?.path.toString(), - claimPathValue: this.query.valueProof?.value?.toString(), - - slotIndex: this.query.slotIndex, - operator: this.query.operator, - value: this.value, - }); - } -} diff --git a/yarn.lock b/yarn.lock index 6d619ee5..fdb48e28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5686,21 +5686,20 @@ __metadata: languageName: node linkType: hard -"@rarimo/client@npm:^2.0.0": - version: 2.0.0 - resolution: "@rarimo/client@npm:2.0.0" +"@rarimo/client@portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/client::locator=rarime-snap-monorepo%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@rarimo/client@portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/client::locator=rarime-snap-monorepo%40workspace%3A." dependencies: "@cosmjs/launchpad": ^0.27.1 "@cosmjs/proto-signing": ^0.32.2 "@cosmjs/stargate": ^0.32.2 "@distributedlab/fetcher": ^1.0.0-rc.13 "@distributedlab/reactivity": ^1.0.0-rc.13 - "@rarimo/shared": ^2.0.0 - checksum: 626c8ab345c1febb55b0161071724a67af551da7f441bf898d3638acadd80db776477c9fd1082fcc313e94f4e2cf86ee49f6628e25d98de2456a2ea3af017449 + "@rarimo/shared": "workspace:^" languageName: node - linkType: hard + linkType: soft -"@rarimo/rarime-connector@2.1.0-rc.3, @rarimo/rarime-connector@workspace:packages/connector": +"@rarimo/rarime-connector@2.1.0-rc.3, @rarimo/rarime-connector@workspace:^, @rarimo/rarime-connector@workspace:packages/connector": version: 0.0.0-use.local resolution: "@rarimo/rarime-connector@workspace:packages/connector" dependencies: @@ -5755,6 +5754,7 @@ __metadata: "@noble/hashes": ^1.3.3 "@noble/secp256k1": 1.7.1 "@rarimo/rarime-connector": 2.1.0-rc.3 + "@rarimo/zkp-iden3": "*" "@types/intl": 1.2.0 "@types/lodash": ^4.14.202 "@types/uuid": 9.0.2 @@ -5783,15 +5783,66 @@ __metadata: languageName: unknown linkType: soft -"@rarimo/shared@npm:^2.0.0": - version: 2.0.0 - resolution: "@rarimo/shared@npm:2.0.0" +"@rarimo/shared@portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/shared::locator=rarime-snap-monorepo%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@rarimo/shared@portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/shared::locator=rarime-snap-monorepo%40workspace%3A." dependencies: "@distributedlab/jac": ^1.0.0-rc.13 "@distributedlab/tools": ^1.0.0-rc.13 - checksum: d52bb3825b7e92e4cd7f450ec0af4622a287fdee0698262a1265ef859794632589a929dcb683df8da34947844e41c01322cec19f1161f89972d13c9f874c6a72 languageName: node - linkType: hard + linkType: soft + +"@rarimo/zkp-iden3@portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/zkp-iden3::locator=rarime-snap-monorepo%40workspace%3A.": + version: 0.0.0-use.local + resolution: "@rarimo/zkp-iden3@portal:/Users/lukachisama/Documents/RARIMO/js-sdk/packages/zkp-iden3::locator=rarime-snap-monorepo%40workspace%3A." + dependencies: + "@apollo/client": ^3.8.7 + "@ceramicnetwork/http-client": 2.27.0 + "@composedb/client": ^0.6.0 + "@cosmjs/amino": ^0.32.2 + "@distributedlab/fetcher": ^1.0.0-rc.13 + "@distributedlab/tools": ^1.0.0-rc.13 + "@ethersproject/abi": 5.0.0 + "@ethersproject/bytes": 5.7.0 + "@ethersproject/keccak256": 5.7.0 + "@ethersproject/providers": 5.7.2 + "@glazed/did-datastore": 0.3.2 + "@iden3/js-crypto": 1.0.3 + "@iden3/js-iden3-core": 1.1.0 + "@iden3/js-jsonld-merklization": 1.1.2 + "@iden3/js-jwz": 1.1.2 + "@iden3/js-merkletree": 1.1.2 + "@leapwallet/buffer-boba": ^0.1.8 + "@leapwallet/parser-parfait": ^0.7.0 + "@noble/hashes": ^1.3.3 + "@noble/secp256k1": 1.7.1 + "@rarimo/client": "workspace:^" + "@rarimo/rarime-connector": "workspace:^" + "@rarimo/shared": "workspace:^" + "@types/lodash": ^4.14.202 + "@types/uuid": 9.0.2 + base64-js: ^1.5.1 + bech32: ^2.0.0 + buffer: 6.0.3 + cosmjs-types: ^0.9.0 + dids: 4.0.4 + ethers: 5.7.2 + graphql: ^16.8.1 + graphql-tag: ^2.12.6 + key-did-provider-ed25519: 3.0.2 + key-did-resolver: 3.0.0 + lodash: ^4.17.21 + long: ^5.2.3 + tslib: ^2.5.0 + uuid: 9.0.0 + peerDependencies: + "@iden3/js-crypto": ^1.0.0-beta.1 + "@iden3/js-iden3-core": 1.0.0-beta.2 + "@iden3/js-jsonld-merklization": ^1.0.0-beta.14 + "@iden3/js-jwz": ^1.0.0-beta.2 + "@iden3/js-merkletree": ^1.0.0-beta.4 + languageName: node + linkType: soft "@redux-saga/core@npm:^1.3.0": version: 1.3.0