Skip to content

Query Language

The Atomic Query Signature V2 Circuit and Atomic Query MTP V2 Circuit circuits have been designed as generic circuits to do the zk verification based on users' claims.

The Query Language sits on top of these circuits to provide a simple way for developers to design customised authentication requirements based on someone's credentials. As long as the user holds a credential of a specific type, the Verifier can design a query related to the Credentials based on 6 operators, for example:

  • Must be a verified human to vote for a DAO specific proposal - equals (operator 1).
  • Must have been born before 2000-01-01 to access an adult content website - less-than (operator 2).
  • Must have a monthly salary greater than $1000 to get a loan - greater-than (operator 3).
  • Must be an admin or a hacker of a Dao to enter a platform - ├Čn (operator 4).
  • Must not be a resident of a country in the list of blacklisted countries to operate on an exchange - not-in (operator 5).
  • Must not be a resident of a specific country - not-equal (operator 6).

The query is designed by the Verifier and presented to the user via a QR Code (or deep-linking). Starting from the proof generated by the user as a response to the query, the Verifier is easily able to check if the query is satisfied or not. The Verifier doesn't get access to any user's data.

The Query Language follows the same rules whether the verification is implemented on-chain or off-chain, while the syntax to define these is a bit different. For each of the query presented above, both the on-chain and off-chain way of designing will now be defined.

The entire scripts to set a query are available here: off-chain verification, on-chain verification

Further examples of how to setup customized queries will be released soon!

Equals - Operator 1

Credential Schema

The ProofOfHumanity Schema encodes whether a user has been verified as a human or not. Here's the JSON-LD Context of the Schema Type.

You can create customised schemas, check out this tutorial!

Query

When presented with this query, the user must prove that he/she is a Person.

  const proofRequest: protocol.ZKPRequest = {
      id: 1,
      circuitId: 'credentialAtomicQuerySigV2',
      query: {
        allowedIssuers: ['*'],
        type: 'ProofOfHumanity',
        context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-humanity/proof-of-humanity.jsonld',
        credentialSubject: {
        isHuman: {
          $eq: 1,
        },
        },
      },
    };

// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "324849518749029195374186444632030216125"

// merklized path to field in the W3C credential according to JSONLD schema 
const schemaClaimPathKey = "14815366841010849835350402710291849818496586666144492189460088557509920034090"

const requestId = 1;

const query = {
    schema: schemaBigInt,
    claimPathKey  : schemaClaimPathKey,
    operator: 1,
    value: [1, ...new Array(63).fill(0).map(i => 0)], // for operators 1,2,3,6 only first value matters
    };
// Corresponding QR Code
{
    "id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "typ": "application/iden3comm-plain-json",
    "type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
    "thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "body": {
        "reason": "airdrop participation",
        "transaction_data": {
            "contract address" : "<add your contract address here>", // replace with your contract address
            "method_id": "b68967e2",
            "chain_id": 80001,
            "network": "polygon-mumbai"
        },
        "scope": [
            {
                "id": 1,
                "circuitId": "credentialAtomicQuerySigV2OnChain",
                "query": {
                    "allowedIssuers": [
                        "*"
                    ],
                    "context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-humanity/proof-of-humanity.jsonld",
                    "credentialSubject": {
                        "isHuman": {
                            "$eq": 1
                        }
                    },
                    "type": "ProofOfHumanity"
                }
            }
        ]
    }
}

Less-than - Operator 2

Credential Schema

The KYCAgeCredential Schema encodes the date of birth of the credential subject. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she has been born before 2001/01/01.

  const proofRequest: protocol.ZKPRequest = {
      id: 1,
      circuitId: 'credentialAtomicQuerySigV2',
      query: {
        allowedIssuers: ['*'],
        type: 'KYCAgeCredential',
        context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
        credentialSubject: {
        birthday: {
          $lt: 20010101,
        },
        },
      },
    };

// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "267831521922558027206082390043321796944"

// merklized path to field in the W3C credential according to JSONLD schema 
const schemaClaimPathKey = "20376033832371109177683048456014525905119173674985843915445634726167450989630"

const requestId = 1;

const query = {
    schema: schemaBigInt,
    claimPathKey  : schemaClaimPathKey,
    operator: 1,
    value: [1, ...new Array(63).fill(0).map(i => 0)],  // for operators 1,2,3,6 only first value matters
    };
// Corresponding QR Code
{
    "id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "typ": "application/iden3comm-plain-json",
    "type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
    "thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "body": {
        "reason": "airdrop participation",
        "transaction_data": {
            "contract address" : "<add your contract address here>",
            "method_id": "b68967e2",
            "chain_id": 80001,
            "network": "polygon-mumbai"
        },
        "scope": [
            {
                "id": 1,
                "circuitId": "credentialAtomicQuerySigV2OnChain",
                "query": {
                    "allowedIssuers": [
                        "*"
                    ],
                    "context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
                    "credentialSubject": {
                        "birthday": {
                            "$lt": 20010101
                        }
                    },
                    "type": "KYCAgeCredential"
                }
            }
        ]
    }
}

Greater-than - Operator 3

Credential Schema

The EmployeeData Schema encodes the monthly salary of the credential subject. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that his/her monthly salary is greater than $1000.

  const proofRequest: protocol.ZKPRequest = {
      id: 1,
      circuitId: 'credentialAtomicQuerySigV2',
      query: {
        allowedIssuers: ['*'],
        type: 'EmployeeData',
        context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/employee-data/employee-data.jsonld',
        credentialSubject: {
        monthlySalary: {
          $gt: 1000,
        },
        },
      },
    };

// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "215529050624769177581695011121804343416"

// merklized path to field in the W3C credential according to JSONLD schema 
const schemaClaimPathKey = "18323209396655941018370955962714740724727867245625378697671016248362870463698"

const requestId = 1;

const query = {
    schema: schemaBigInt,
    claimPathKey  : schemaClaimPathKey,
    operator: 3, // operator
    value: [1000, ...new Array(63).fill(0).map(i => 0)],
};
{
    "id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "typ": "application/iden3comm-plain-json",
    "type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
    "thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "body": {
        "reason": "airdrop participation",
        "transaction_data": {
            "contract address" : "<add your contract address here>",
            "method_id": "b68967e2",
            "chain_id": 80001,
            "network": "polygon-mumbai"
        },
        "scope": [
            {
                "id": 1,
                "circuitId": "credentialAtomicQuerySigV2OnChain",
                "query": {
                    "allowedIssuers": [
                        "*"
                    ],
                    "context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/employee-data/employee-data.jsonld",
                    "credentialSubject": {
                        "monthlySalary": {
                            "$gt": 1000
                        }
                    },
                    "type": "EmployeeData"
                }
            }
        ]
    }
}

In - Operator 4

Credential Schema

The ProofOfDaoRole Schema encodes the role of someone inside a DAO. Each role is identified by a code as described in the Schema Vocab.

Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she is either an Admin or a Hacker of a DAO (which corresponds to value 4 and 5).

  const proofRequest: protocol.ZKPRequest = {
      id: 1,
      circuitId: 'credentialAtomicQuerySigV2',
      query: {
        allowedIssuers: ['*'],
        type: 'ProofOfDaoRole',
        context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-dao-role/proof-of-dao-role.jsonld',
        credentialSubject: {
        role: {
          $in: [4, 5],
        },
        },
      },
    };

// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "80689572245316684375295691372009959153"

// merklized path to field in the W3C credential according to JSONLD schema 
const schemaClaimPathKey = "19483179179477598314891505360164348442915562939736565831310034495973163044179"

const requestId = 1;

const query = {
    schema: schemaBigInt,
    claimPathKey  : schemaClaimPathKey,
    operator: 4, // operator
    value: [4, 5, ...new Array(62).fill(0).map(i => 0)],
};
// Corresponding QR Code
{
    "id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "typ": "application/iden3comm-plain-json",
    "type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
    "thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "body": {
        "reason": "airdrop participation",
        "transaction_data": {
            "contract address" : "<add your contract address here>",
            "method_id": "b68967e2",
            "chain_id": 80001,
            "network": "polygon-mumbai"
        },
        "scope": [
            {
                "id": 1,
                "circuitId": "credentialAtomicQuerySigV2OnChain",
                "query": {
                    "allowedIssuers": [
                        "*"
                    ],
                    "context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-dao-role/proof-of-dao-role.jsonld",
                    "credentialSubject": {
                        "role": {
                            "$in": [4, 5]
                        }
                    },
                    "type": "ProofOfDaoRole"
                }
            }
        ]
    }
}

Not-in - Operator 5

Credential Schema

The KYCCountryOfResidenceCredential Schema encodes the countryCode of residence of the credential subject according to the ISO Standard. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she is not resident of the countries 840, 120, 340, 509 identified following the ISO Standard.

  const proofRequest: protocol.ZKPRequest = {
      id: 1,
      circuitId: 'credentialAtomicQuerySigV2',
      query: {
        allowedIssuers: ['*'],
        type: 'KYCCountryOfResidenceCredential',
        context: 'https://github.com/iden3/claim-schema-vocab/blob/main/schemas/json-ld/kyc-v4.jsonld',
        credentialSubject: {
        countryCode: {
          $nin: [840, 120, 340, 509],
        },
        },
      },
    };

// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "201134713754279235117373236841506344285"

// merklized path to field in the W3C credential according to JSONLD schema 
const schemaClaimPathKey = "17002437119434618783545694633038537380726339994244684348913844923422470806844"

const requestId = 1;

const query = {
    schema: schemaBigInt,
    claimPathKey  : schemaClaimPathKey,
    operator: 5, // operator
    value: [840, 120, 340, 509, ...new Array(60).fill(0).map(i => 0)],
};
// Corresponding QR Code
{
    "id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "typ": "application/iden3comm-plain-json",
    "type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
    "thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "body": {
        "reason": "airdrop participation",
        "transaction_data": {
            "contract address" : "<add your contract address here>",
            "method_id": "b68967e2",
            "chain_id": 80001,
            "network": "polygon-mumbai"
        },
        "scope": [
            {
                "id": 1,
                "circuitId": "credentialAtomicQuerySigV2OnChain",
                "query": {
                    "allowedIssuers": [
                        "*"
                    ],
                    "context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
                    "credentialSubject": {
                        "countryCode": {
                            "$nin": [840, 120, 340, 509]
                        }
                    },
                    "type": "KYCCountryOfResidenceCredential"
                }
            }
        ]
    }
}

Not-equal - Operator 6

Credential Schema

The KYCCountryOfResidenceCredential Schema encodes the countryCode of residence of the credential subject according to the ISO Standard. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she is not resident of the country 840 identified following the ISO Standard.

  const proofRequest: protocol.ZKPRequest = {
      id: 1,
      circuitId: 'credentialAtomicQuerySigV2',
      query: {
        allowedIssuers: ['*'],
        type: 'KYCCountryOfResidenceCredential',
        context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
        credentialSubject: {
        countryCode: {
          $ne: 840
        },
        },
      },
    };

// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "201134713754279235117373236841506344285"

// merklized path to field in the W3C credential according to JSONLD schema 
const schemaClaimPathKey = "17002437119434618783545694633038537380726339994244684348913844923422470806844"

const requestId = 1;

const query = {
    schema: schemaBigInt,
    claimPathKey  : schemaClaimPathKey,
    operator: 6,
    value: [840, ...new Array(63).fill(0).map(i => 0)], // for operators 1,2,3,6 only first value matters
    };
// Corresponding QR Code
{
    "id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "typ": "application/iden3comm-plain-json",
    "type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
    "thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
    "body": {
        "reason": "airdrop participation",
        "transaction_data": {
            "contract address" : "<add your contract address here>",
            "method_id": "b68967e2",
            "chain_id": 80001,
            "network": "polygon-mumbai"
        },
        "scope": [
            {
                "id": 1,
                "circuitId": "credentialAtomicQuerySigV2OnChain",
                "query": {
                    "allowedIssuers": [
                        "*"
                    ],
                    "context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
                    "credentialSubject": {
                        "countryCode": {
                            "$ne": 840
                        }
                    },
                    "type": "KYCCountryOfResidenceCredential"
                }
            }
        ]
    }
}

Selective Disclosure

Selective Disclosure is a feature provided for the Verifier, which makes it capable of requiring some specific data from the ID Holder. Using a similar approach to the ZK language equal operation, the Verifier sends a verification request for a piece of the Holder's identity. As seen below, the way to make this request is by sending an empty object as a value.

Query

In the example below, the verifier requests the Holder's country code.

Off-chain
const proofRequest: protocol.ZKPRequest = {
    id: 1,
    circuitId: 'credentialAtomicQuerySigV2',
    query: {
        allowedIssuers: ['*'],
        type: 'KYCCountryOfResidenceCredential',
        context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
        credentialSubject: {
            countryCode: {},
        },
    },
};

Allowed Issuers

When we use * in the "allowed issuers" segment (allowedIssuers: ['*']), we mean that we accept any entity that might have provided the credential. Even though this seems to be convenient for testing purposes, it may also be considered risky. Applying due diligence by actually choosing trusted specific issuers should be the best approach. Only in rare cases, a verifier would accept any issuer, so we advise not to use *.