# Clique Client SDK

{% hint style="info" %}
This section primarily focuses on integrating the off-chain component of your application with the Clique co-processor. For on-chain integration, refer to[Smart Contract SDK](/build-with-clique/smart-contract-sdk.md)
{% endhint %}

The Clique Client SDK is an open-source library that enables users to interact with the Clique Network.  We currently support Rust, NodeJS, and Web.

* [Rust SDK](https://github.com/CliqueOfficial/clique-protocol-sdk/tree/main/clique-client-sdk)
* [NodeJS SDK](https://www.npmjs.com/package/@cliqueofficial/clique-client-sdk-node)
* [Web SDK](https://www.npmjs.com/package/@cliqueofficial/clique-client-sdk-web)

The SDK facilitates communication between your application clients and the Clique Network. Custom client implementation is also possible. The flowchart below depicts a simple communication process.

<figure><img src="/files/XqxBaRGCrE0TswVLqS8L" alt=""><figcaption></figcaption></figure>

The client SDK executes two primary steps that are outlined in subsequent sections:&#x20;

1. Forward the query and poll results from the network: [Clique Query](/references/clique-query.md)
2. Verify the proof upon receiving the response

### Proof Verification

{% hint style="info" %}
The verification process is automatically handled if you're using the Clique Client SDK.
{% endhint %}

The proofs of each task are aggregated in an aggregation program that runs in our TEE kernel. Roughly, each executor provides a proof (eg. TEE attestation or trusted signatures) for their respective programs. The kernel then aggregates these proofs in its own TEE and produces a remote attestation of the execution results.

To fully understand the verification process, please refer to the official [Intel SGX Remote Attestation Docs](https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/attestation-services.html) here.

### Rust SDK

#### How to Use

Add this dependency to your `Cargo.toml`

```toml
clique-client-sdk = { git = "https://github.com/CliqueOfficial/clique-protocol-sdk" }
serde_json = { version = "1.0", features = ["preserve_order"] }
tokio = { version = "1.38.0", features = ["full"] }
```

Here is an example:

```rust
use std::time::Duration;

use clique_client_sdk::CliqueClient;
use serde_json::json;

#[tokio::main]
async fn main() {
    // The endpoint for the Clique Network
    let endpoint = "https://localhost:8000";
    // Interval for polling the Clique Network to retrieve results
    let polling_interval = Duration::from_millis(500);
    // Maximum number of retries for network errors
    let retry_num = 5;
    // If the user creates a query with the same id, method, and params, 
    // the client will return the result of the existing query when the value is true;
    // otherwise, the client will throw an exception.
    let allow_exist_query = false;
    // Trusted mr_enclaves of clique-kernel
    let trusted_enclaves = Some(vec![
        "5d474d0e8b431764ddf3db67b1028399d42301340ceb4abc840c4dee426e0d9d".to_string(),
    ]);
    // Trusted mr_signers of clique-kernel
    let trusted_signers = Some(vec![
        "6601c448087c060907a3c71f1c10fbae92260bef8ac37258b2314338042dadb4".to_string(),
    ]);

    // Create a CliqueClient with custom configuration for polling interval, retry limit, allow_exist_query, trusted_enclaves, trusted_signers
    let client = CliqueClient::with_config(
        endpoint,
        polling_interval,
        retry_num,
        allow_exist_query,
        trusted_enclaves,
        trusted_signers,
    )
    .unwrap();

    // Alternatively, create a CliqueClient with default configuration
    let _client = CliqueClient::new(endpoint, trusted_enclaves, trusted_signers).unwrap();

    // Create a single query using `serde_json::json`
    let json_query = json!({
        "id": 1,
        "method": "clique_fibonacci",
        "params": {"n": "10"},
        "input_types": {"n": "u256"},
        "custom_types": {}
    });

    // Run the query and wait for the result
    let result = client.run_query(json_query).await.unwrap();
    println!("result: {:?}", result);

    // Create batch query using `serde_json::json`
    let json_query = json!([
        {"id": 2, "method": "clique_fibonacci", "params": {"n": "11"}, "input_types": {"n": "u256"}, "custom_types": {}},
        {"id": 3, "method": "clique_fibonacci", "params": {"n": "12"}, "input_types": {"n": "u256"}, "custom_types": {}}
    ]);

    // Run the query and wait for the result
    let result = client.run_query(json_query).await.unwrap();
    println!("result: {:?}", result);
}
```

### NodeJS SDK

#### How to Use

Add this dependency to your `package.json`:

```sh
pnpm add @cliqueofficial/clique-client-sdk-node
# OR
yarn add @cliqueofficial/clique-client-sdk-node
# OR 
npm install @cliqueofficial/clique-client-sdk-node 
```

Here is an example:

```javascript
const { Client } = require('@cliqueofficial/clique-client-sdk-node');

(async () => {
  const client = new Client({ 
    endpoint: 'http://localhost:8000', 
    pollingInterval: 20, // default value is 20 ms
    retryNumber: 5,  // default value is 5
    allowExistQuery: false, // default value is false. If the user creates a query with the same id, method, and params, the client will return the result of the existing query when the value is true; otherwise, the client will throw an exception.
    trustedEnclaves: ['5d474d0e8b431764ddf3db67b1028399d42301340ceb4abc840c4dee426e0d9d'], // default is undefined. Trusted mr_enclaves of clique-kernel, if the value is undefined, all mr_enclaves will be trusted.
    trustedSigners: ['6601c448087c060907a3c71f1c10fbae92260bef8ac37258b2314338042dadb4'], // default is undefined. Trusted mr_signers of clique-kernel, if the value is undefined, all mr_signers will be trusted.
  });

  // Create single query
  const query = {
    id: 1,
    method: 'clique_fibonacci',
    params: { n: '10' },
    inputTypes: { n: 'u256' },
  };
  // OR batch query
  const query = [
    {
      id: 2,
      method: 'clique_fibonacci',
      params: { n: '11' },
      inputTypes: { n: 'u256' },
    },
    {
      id: 3,
      method: 'clique_fibonacci',
      params: { n: '12' },
      inputTypes: { n: 'u256' },
    },
  ];

  // Run the query and wait for the result
  const response = await client.runQuery(query);
  console.log("runQuery response:", response);
})();
```

### Web SDK

Add this dependency to your `package.json`:

```sh
pnpm add @cliqueofficial/clique-client-sdk-web
# OR
yarn add @cliqueofficial/clique-client-sdk-web
# OR 
npm install @cliqueofficial/clique-client-sdk-web
```

Here is an example:

```javascript
import { Client } from '@cliqueofficial/clique-client-sdk-web';

const client = new Client({ 
  endpoint: 'http://localhost:8000', 
  pollingInterval: 20, // default value is 20 ms
  retryNumber: 5,  // default value is 5
  allowExistQuery: false, // default value is false. If the user creates a query with the same id, method, and params, the client will return the result of the existing query when the value is true; otherwise, the client will throw an exception.
  trustedEnclaves: ['5d474d0e8b431764ddf3db67b1028399d42301340ceb4abc840c4dee426e0d9d'], // default is undefined. Trusted mr_enclaves of clique-kernel, if the value is undefined, all mr_enclaves will be trusted.
  trustedSigners: ['6601c448087c060907a3c71f1c10fbae92260bef8ac37258b2314338042dadb4'], // default is undefined. Trusted mr_signers of clique-kernel, if the value is undefined, all mr_signers will be trusted.
});

// Create single query
const query = {
  id: 1,
  method: 'clique_fibonacci',
  params: { n: '10' },
  inputTypes: { n: 'u256' },
};
// OR batch query
const query = [
  {
    id: 2,
    method: 'clique_fibonacci',
    params: { n: '11' },
    inputTypes: { n: 'u256' },
  },
  {
    id: 3,
    method: 'clique_fibonacci',
    params: { n: '12' },
    inputTypes: { n: 'u256' },
  },
];

// Run the query and wait for the result
const response = await client.runQuery(query);
console.log("runQuery response:", response);

// OR run the query with encryption enabled and wait for the result
const response = await client.runEncryptedQuery(query);
console.log("runEncryptedQuery response:", response);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clique.tech/build-with-clique/clique-client-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
