Clique supports clients to make arbitrary TLS calls from smart contracts in a verifiable format. For generic TLS calls, we have provided the generic clique_httpsRequest Built-In task. Users can create queries for the clique_httpsRequest task to obtain the results of TLS calls. Users can also create more complex tasks of Schema type to utilize the clique_httpsRequest task.
clique_httpsRequest
Here is the manifest file for the clique_httpsRequest task:
spec-version = "1"
name = "clique_httpsRequest"
type = "BuiltIn"
proof-type = ["TEE"]
[types.Transformation]
from = { type = "string", description = "json pointer to field in response" }
soltype = { type = "string", description = "solidity type" }
[input]
url = { type = "string", description = "Request url" }
encoding = { type = "Transformation[]", description = "encoding format" }
[output]
response = { type = "bytes", description = "ABI encoded" }
clique_httpsRequest is a built-in task, which means users can directly use this task within the Clique Network without the need to publish it additionally.
This task has two output parameters:
url: The URL to be accessed for this TLS call. The URL needs to return parseable results in JSON format.
encoding: Indicates how to extract data from the returned JSON result. Here we use an array of custom types (Transformation) as the input parameter. The Transformation custom type contains two fields: from is a JSON pointer for extracting data from JSON, and soltype is the Solidity type into which the extracted data should be encoded.
This task has only one return value: response. The response is data encoded in Solidity ABI format, with the encoding format specified by the input parameter encoding. After obtaining the result of the TLS call, the smart contract can decode the data using ABI decoding to retrieve the information.
Define the custom typeTransformation for the clique_httpsRequest task. The name of the structure is not important, but the content of the structure must be consistent with the custom type inclique_httpsRequest task.
The names of the other structures to be defined next are not important; users can define names as they wish.
Define the decoded result of the TLS call. The clique_httpsRequest task will return the encoded result, which will be decoded according to this structure.
Create the Transformation structure needed in the input parameters, using JSON Pointer to specify how to extract data from the JSON result, and determine how to encode the extracted data. The result data will be encoded in the order specified by the Transformation array.
Each time a query is created, a different ID needs to be specified. If the content of the query is exactly the same, Clique Network will not create a new query.
Use the Clique Contract SDK to create a query and wait for the callback function to execute.
function callback(bytes calldata _response) external {
Response memory response = abi.decode(_response, (Response));
Result memory result = abi.decode(response.response, (Result));
emit CallbackInvoked(result);
}
Define the callback function and decode the result of the TLS call within the callback function.
Make TLS Calls from Client SDK
Although the primary use case for TLS Calls is in smart contracts, it is also supported off-chain. Users can use the Clique Client SDK to call the clique_httpsRequest task.
For example, use our Rust SDK:
Add this dependency to your Cargo.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"] }
use clique_client_sdk::CliqueClient;
use serde_json::json;
#[tokio::main]
async fn main() {
let endpoint = "https://localhost:8000";
let client = CliqueClient::new(endpoint).unwrap();
let id = 1;
let url = "https://jsonplaceholder.typicode.com/users";
let encoding = json!([
{"from": "/0/id", "soltype": "int16"},
{"from": "/0/name", "soltype": "string"},
{"from": "/0/address/geo/lat", "soltype": "string"}
]);
let json_query = json!({
"id": id,
"method": "clique_httpsRequest",
"params": {"url": url, "encoding": encoding },
"input_types": {"url": "string", "encoding": "Transformation[]"},
"custom_types": {"Transformation": {"from": "string", "soltype": "string"}}
});
let result = client.run_query(json_query).await.unwrap();
}
Make TLS Calls through Schema Task
In addition to directly using the clique_httpsRequest task, users can also customize their own Schema tasks and indirectly use clique_httpsRequest within these Schema tasks to construct more complex queries.
Here is a simple example of a Schema task's manifest file. After defining the manifest file, users need to first publish it to the Clique Network using Clique CLI, and then create the corresponding query to use it.
specVersion = "1"
name = "yourOrganization_customRequest"
type = "Schema"
proof-type = ["TEE"]
[types.Transformation]
from = { type = "string", description = "json pointer to field in response" }
soltype = { type = "string", description = "solidity type" }
[input]
url = { type = "string", description = "Request url" }
encoding = { type = "Transformation[]", description = "encoding format" }
[output]
response = { ref = "$tasks.clique_httpsRequest.response" }
[[tasks]]
name = "clique_httpsRequest"
proof-preference = "TEE"
[tasks.input]
url = "$input.url"
encoding = "$input.encoding"