Skip to content

feat: add support of submitZKPResponseCrossChain #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
92b719b
feat: add support of submitZKPResponseCrossChain
volodymyr-basiuk Aug 15, 2024
14a4080
fix unit test
volodymyr-basiuk Aug 15, 2024
977d0f2
submitZKPResponseV2 new method abi
volodymyr-basiuk Aug 16, 2024
bf4379e
add email-verified integration test
volodymyr-basiuk Aug 19, 2024
330c60f
add prepareContractInvokeRequestTxData
volodymyr-basiuk Aug 19, 2024
a49cd9f
fix typo
volodymyr-basiuk Aug 19, 2024
75e4f13
refactor OnChainStateInfo
volodymyr-basiuk Aug 19, 2024
5f6d22f
Merge branch 'main' into feat/cross-chain-verify
volodymyr-basiuk Aug 20, 2024
1547dc6
fix: getStateContractAndProviderForId - throw error if no config for …
volodymyr-basiuk Aug 20, 2024
6b6ed85
merge
volodymyr-basiuk Aug 20, 2024
106945f
merge(2)
volodymyr-basiuk Aug 20, 2024
c18284e
changes messages and empty did
daveroga Aug 21, 2024
403e3ca
add all required eth configs
volodymyr-basiuk Aug 21, 2024
324d9ef
fix chain id
volodymyr-basiuk Aug 21, 2024
1e174e4
rename getGistRootStatePubSignals -> getStatesInfo
volodymyr-basiuk Aug 22, 2024
0157850
update id and idType for identity and global messages
daveroga Aug 22, 2024
7a7a987
merge master
volodymyr-basiuk Aug 25, 2024
f66639a
fix build
volodymyr-basiuk Aug 25, 2024
5366fc5
Merge branch 'feat/cross-chain-verify-id-fields' into feat/cross-chai…
daveroga Aug 26, 2024
9085fcb
add resolve gist and state cache
daveroga Aug 26, 2024
881d0cb
resolve VP type comments
volodymyr-basiuk Aug 27, 2024
20d15f7
format
volodymyr-basiuk Aug 27, 2024
ee7af79
rm unused import
volodymyr-basiuk Aug 27, 2024
8e545c7
update submitZKPResponseV2 final version
daveroga Aug 27, 2024
5b3ac93
back to uint64 requestId
daveroga Aug 28, 2024
9375f80
merged main changes
daveroga Aug 29, 2024
f7104e0
merge branch main 1.18.0
daveroga Aug 29, 2024
c34065f
rm chain config check for input preparation
volodymyr-basiuk Aug 30, 2024
eb12d84
send 1 tx in submit v2
volodymyr-basiuk Aug 30, 2024
10b8fa0
fix payload
daveroga Aug 30, 2024
c521063
control sometimes error in estimateGas
daveroga Sep 2, 2024
38392df
cache gist and state resolution
daveroga Sep 2, 2024
cb56401
fix errors and local variables
daveroga Sep 2, 2024
f361abf
prepareZKPResponseTxData interface changes
volodymyr-basiuk Sep 2, 2024
3b9fd92
format
volodymyr-basiuk Sep 2, 2024
82aea54
fix unit mock
volodymyr-basiuk Sep 2, 2024
755b7f7
add CONTRACT_INVOKE_RESPONSE_MESSAGE_TYPE
volodymyr-basiuk Sep 2, 2024
cf7c4ef
fix typo
volodymyr-basiuk Sep 2, 2024
376b8b9
fix mock
volodymyr-basiuk Sep 2, 2024
dff3bef
fix prepare v2
volodymyr-basiuk Sep 2, 2024
d3759c8
cleanup
volodymyr-basiuk Sep 3, 2024
875d217
FunctionSignatures enum
volodymyr-basiuk Sep 3, 2024
08f5bfd
fix unit tests
volodymyr-basiuk Sep 3, 2024
a006077
resolveDidDocument
volodymyr-basiuk Sep 3, 2024
17ffc65
prepareTxArgsSubmitV1/2
volodymyr-basiuk Sep 4, 2024
924b818
fix unit mock
volodymyr-basiuk Sep 4, 2024
cb1bd47
import fixes
volodymyr-basiuk Sep 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@0xpolygonid/js-sdk",
"version": "1.17.8",
"version": "1.18.0",
"description": "SDK to work with Polygon ID",
"main": "dist/node/cjs/index.js",
"module": "dist/node/esm/index.js",
Expand Down
15 changes: 14 additions & 1 deletion src/circuits/atomic-query-mtp-v2-on-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
bigIntArrayToStringArray,
existenceToInt,
getNodeAuxValue,
IStateInfoPubSignals,
StatesInfo,
prepareCircuitArrayValues,
prepareSiblingsStr
} from './common';
Expand Down Expand Up @@ -240,7 +242,7 @@ interface atomicQueryMTPV2OnChainCircuitInputs {
* @class AtomicQueryMTPV2OnChainPubSignals
* @extends {BaseConfig}
*/
export class AtomicQueryMTPV2OnChainPubSignals extends BaseConfig {
export class AtomicQueryMTPV2OnChainPubSignals extends BaseConfig implements IStateInfoPubSignals {
requestID!: bigint;
userID!: Id;
issuerID!: Id;
Expand Down Expand Up @@ -322,4 +324,15 @@ export class AtomicQueryMTPV2OnChainPubSignals extends BaseConfig {

return this;
}

/** {@inheritDoc IStateInfoPubSignals.getStatesInfo} */
getStatesInfo(): StatesInfo {
return {
states: [
{ id: this.issuerID, state: this.issuerClaimIdenState },
{ id: this.issuerID, state: this.issuerClaimNonRevState }
],
gists: [{ id: this.userID, root: this.gistRoot }]
};
}
}
17 changes: 15 additions & 2 deletions src/circuits/atomic-query-sig-v2-on-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
bigIntArrayToStringArray,
existenceToInt,
getNodeAuxValue,
IStateInfoPubSignals,
prepareCircuitArrayValues,
prepareSiblingsStr
prepareSiblingsStr,
StatesInfo
} from './common';
import { byteDecoder, byteEncoder } from '../utils';

Expand Down Expand Up @@ -312,7 +314,7 @@ export class AtomicQuerySigV2OnChainCircuitInputs {
* @class AtomicQuerySigV2OnChainPubSignals
* @extends {BaseConfig}
*/
export class AtomicQuerySigV2OnChainPubSignals extends BaseConfig {
export class AtomicQuerySigV2OnChainPubSignals extends BaseConfig implements IStateInfoPubSignals {
requestID!: bigint;
userID!: Id;
issuerID!: Id;
Expand Down Expand Up @@ -397,4 +399,15 @@ export class AtomicQuerySigV2OnChainPubSignals extends BaseConfig {

return this;
}

/** {@inheritDoc IStateInfoPubSignals.getStatesInfo} */
getStatesInfo(): StatesInfo {
return {
states: [
{ id: this.issuerID, state: this.issuerAuthState },
{ id: this.issuerID, state: this.issuerClaimNonRevState }
],
gists: [{ id: this.userID, root: this.gistRoot }]
};
}
}
17 changes: 15 additions & 2 deletions src/circuits/atomic-query-v3-on-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
bigIntArrayToStringArray,
prepareSiblingsStr,
getNodeAuxValue,
prepareCircuitArrayValues
prepareCircuitArrayValues,
IStateInfoPubSignals,
StatesInfo
} from './common';
import { BJJSignatureProof, CircuitError, GISTProof, Query, TreeState, ValueProof } from './models';
import { Hash, Proof, ZERO_HASH } from '@iden3/js-merkletree';
Expand Down Expand Up @@ -420,7 +422,7 @@ interface AtomicQueryV3OnChainCircuitInputs {
* @beta
* AtomicQueryV3OnChainPubSignals public inputs
*/
export class AtomicQueryV3OnChainPubSignals extends BaseConfig {
export class AtomicQueryV3OnChainPubSignals extends BaseConfig implements IStateInfoPubSignals {
requestID!: bigint;
userID!: Id;
issuerID!: Id;
Expand Down Expand Up @@ -515,4 +517,15 @@ export class AtomicQueryV3OnChainPubSignals extends BaseConfig {

return this;
}

/** {@inheritDoc IStateInfoPubSignals.getStatesInfo} */
getStatesInfo(): StatesInfo {
return {
states: [
{ id: this.issuerID, state: this.issuerState },
{ id: this.issuerID, state: this.issuerClaimNonRevState }
],
gists: [{ id: this.userID, root: this.gistRoot }]
};
}
}
33 changes: 33 additions & 0 deletions src/circuits/common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Hex } from '@iden3/js-crypto';
import { Hash, ZERO_HASH, Proof, swapEndianness } from '@iden3/js-merkletree';
import { TreeState } from './models';
import { Id } from '@iden3/js-iden3-core';

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
Expand Down Expand Up @@ -226,3 +227,35 @@ export function getProperties(obj: object): object {
}
return result;
}

/**
* states info from pub signals
*
* @public
* @type StatesInfo
*/
export type StatesInfo = {
states: {
id: Id;
state: Hash;
}[];
gists: {
id: Id;
root: Hash;
}[];
};

/**
* state pub signals
*
* @public
* @interface IStatePubSignals
*/
export interface IStateInfoPubSignals {
/**
* return object with state params
*
* @returns {OnChainStateInfo}
*/
getStatesInfo(): StatesInfo;
}
3 changes: 3 additions & 0 deletions src/iden3comm/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export const PROTOCOL_MESSAGE_TYPE = Object.freeze({
// ContractInvokeRequestMessageType is type for request of contract invoke request
CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE:
`${IDEN3_PROTOCOL}proofs/1.0/contract-invoke-request` as const,
// ContractInvokeResponseMessageType is type for response of contract invoke request
CONTRACT_INVOKE_RESPONSE_MESSAGE_TYPE:
`${IDEN3_PROTOCOL}proofs/1.0/contract-invoke-response` as const,
// CredentialOnchainOfferMessageType is type of message with credential onchain offering
CREDENTIAL_ONCHAIN_OFFER_MESSAGE_TYPE: `${IDEN3_PROTOCOL}credentials/1.0/onchain-offer` as const,
// ProposalRequestMessageType is type for proposal-request message
Expand Down
124 changes: 105 additions & 19 deletions src/iden3comm/handlers/contract-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { CircuitId } from '../../circuits/models';
import { IProofService } from '../../proof/proof-service';
import { PROTOCOL_MESSAGE_TYPE } from '../constants';
import { BasicMessage, IPackageManager, ZeroKnowledgeProofResponse } from '../types';
import { ContractInvokeRequest } from '../types/protocol/contract-request';
import { ContractInvokeRequest, ContractInvokeResponse } from '../types/protocol/contract-request';
import { DID, ChainIds } from '@iden3/js-iden3-core';
import { IOnChainZKPVerifier } from '../../storage';
import { FunctionSignatures, IOnChainZKPVerifier } from '../../storage';
import { Signer } from 'ethers';
import { processZeroKnowledgeProofRequests } from './common';
import { AbstractMessageHandler, IProtocolMessageHandler } from './message-handler';
Expand All @@ -17,15 +17,15 @@ import { AbstractMessageHandler, IProtocolMessageHandler } from './message-handl
*/
export interface IContractRequestHandler {
/**
* unpacks contract invoker request
* unpacks contract invoke request
* @beta
* @param {Uint8Array} request - raw byte message
* @returns `Promise<ContractInvokeRequest>`
*/
parseContractInvokeRequest(request: Uint8Array): Promise<ContractInvokeRequest>;

/**
* handle contract invoker request
* handle contract invoke request
* @beta
* @param {did} did - sender DID
* @param {Uint8Array} request - raw byte message
Expand Down Expand Up @@ -91,9 +91,11 @@ export class ContractRequestHandler
ctx: ContractMessageHandlerOptions
): Promise<BasicMessage | null> {
switch (message.type) {
case PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE:
await this.handleContractInvoke(message as ContractInvokeRequest, ctx);
return null;
case PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE: {
const ciMessage = message as ContractInvokeRequest;
const txHashResponsesMap = await this.handleContractInvoke(ciMessage, ctx);
return this.createContractInvokeResponse(ciMessage, txHashResponsesMap);
}
default:
return super.handle(message, ctx);
}
Expand All @@ -102,7 +104,7 @@ export class ContractRequestHandler
private async handleContractInvoke(
message: ContractInvokeRequest,
ctx: ContractMessageHandlerOptions
): Promise<Map<string, ZeroKnowledgeProofResponse>> {
): Promise<Map<string, ZeroKnowledgeProofResponse[]>> {
if (message.type !== PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE) {
throw new Error('Invalid message type for contract invoke request');
}
Expand All @@ -127,11 +129,31 @@ export class ContractRequestHandler
{ ethSigner, challenge, supportedCircuits: this._supportedCircuits }
);

return this._zkpVerifier.submitZKPResponse(
ethSigner,
message.body.transaction_data,
zkpResponses
);
const methodId = message.body.transaction_data.method_id.replace('0x', '');
switch (methodId) {
case FunctionSignatures.SumbitZKPResponseV2:
return this._zkpVerifier.submitZKPResponseV2(
ethSigner,
message.body.transaction_data,
zkpResponses
);
case FunctionSignatures.SumbitZKPResponseV1: {
const txHashZkpResponseMap = await this._zkpVerifier.submitZKPResponse(
ethSigner,
message.body.transaction_data,
zkpResponses
);
const response = new Map<string, ZeroKnowledgeProofResponse[]>();
for (const [txHash, zkpResponse] of txHashZkpResponseMap) {
response.set(txHash, [zkpResponse]);
}
return response;
}
default:
throw new Error(
`Not supported method id. Only '${FunctionSignatures.SumbitZKPResponseV1} and ${FunctionSignatures.SumbitZKPResponseV2} are supported.'`
);
}
}

/**
Expand All @@ -151,8 +173,45 @@ export class ContractRequestHandler
}

/**
* handle contract invoker request
* creates contract invoke response
* @private
* @beta
* @param {ContractInvokeRequest} request - ContractInvokeRequest
* @param { Map<string, ZeroKnowledgeProofResponse[]>} responses - map tx hash to array of ZeroKnowledgeProofResponses
* @returns `Promise<ContractInvokeResponse>`
*/
private async createContractInvokeResponse(
request: ContractInvokeRequest,
responses: Map<string, ZeroKnowledgeProofResponse[]>
): Promise<ContractInvokeResponse> {
const response: ContractInvokeResponse = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change responses and response to more meaningfull

id: request.id,
thid: request.thid,
type: PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_RESPONSE_MESSAGE_TYPE,
from: request.to,
to: request.from,
body: {
transaction_data: request.body.transaction_data,
reason: request.body.reason,
scope: []
}
};
for (const [txHash, zkpResponses] of responses) {
for (const zkpResponse of zkpResponses) {
response.body.scope.push({
txHash,
...zkpResponse
});
}
}
return response;
}

/**
* handle contract invoke request
* supports only 0xb68967e2 method id
* @beta
* @deprecated
* @param {did} did - sender DID
* @param {ContractInvokeRequest} request - contract invoke request
* @param {ContractInvokeHandlerOptions} opts - handler options
Expand All @@ -165,10 +224,37 @@ export class ContractRequestHandler
): Promise<Map<string, ZeroKnowledgeProofResponse>> {
const ciRequest = await this.parseContractInvokeRequest(request);

return this.handleContractInvoke(ciRequest, {
senderDid: did,
ethSigner: opts.ethSigner,
challenge: opts.challenge
});
if (ciRequest.body.transaction_data.method_id !== FunctionSignatures.SumbitZKPResponseV1) {
throw new Error(`please use handle method to work with other method ids`);
}

if (ciRequest.type !== PROTOCOL_MESSAGE_TYPE.CONTRACT_INVOKE_REQUEST_MESSAGE_TYPE) {
throw new Error('Invalid message type for contract invoke request');
}

const { ethSigner, challenge } = opts;
if (!ethSigner) {
throw new Error("Can't sign transaction. Provide Signer in options.");
}

const { chain_id } = ciRequest.body.transaction_data;
const networkFlag = Object.keys(ChainIds).find((key) => ChainIds[key] === chain_id);

if (!networkFlag) {
throw new Error(`Invalid chain id ${chain_id}`);
}
const verifierDid = ciRequest.from ? DID.parse(ciRequest.from) : undefined;
const zkpResponses = await processZeroKnowledgeProofRequests(
did,
ciRequest?.body?.scope,
verifierDid,
this._proofService,
{ ethSigner, challenge, supportedCircuits: this._supportedCircuits }
);
return this._zkpVerifier.submitZKPResponse(
ethSigner,
ciRequest.body.transaction_data,
zkpResponses
);
}
}
13 changes: 12 additions & 1 deletion src/iden3comm/types/protocol/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,16 @@ export type ZeroKnowledgeProofRequest = {
export type ZeroKnowledgeProofResponse = {
id: number;
circuitId: string;
vp?: object;
vp?: VerifiablePresentation;
} & ZKProof;

/** VerifiablePresentation represents structure of Verifiable Presentation */
export type VerifiablePresentation = {
'@context': string | (string | object)[];
'@type': string;
verifiableCredential: {
'@context': string | string[];
'@type': string | string[];
credentialSubject: JsonDocumentObject;
};
};
Loading