This section primarily focuses on integrating the off-chain component of your application with the Clique co-processor. For on-chain integration, refer toSmart Contract SDK
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.
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.
The client SDK executes two primary steps that are outlined in subsequent sections:
Forward the query and poll results from the network: Clique Query
Verify the proof upon receiving the response
Proof Verification
The verification process is automatically handled if you're using the Clique Client SDK.
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.
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:
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:
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:
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:
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:
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);