# Making Arbitrary TLS Calls (TLS Oracle)

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:

```toml
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.

### Make TLS Calls from Smart Contracts

Here is a smart contract example, initiating a TLS call to <https://jsonplaceholder.typicode.com/users> and extracting data.

This URL will return JSON data in the following format:

```json
[
    {
        "id": 1,
        "name": "Leanne Graham",
        "username": "Bret",
        "email": "Sincere@april.biz",
        "address": {
            "street": "Kulas Light",
            "suite": "Apt. 556",
            "city": "Gwenborough",
            "zipcode": "92998-3874",
            "geo": {
                "lat": "-37.3159",
                "lng": "81.1496"
            }
        },
        "phone": "1-770-736-8031 x56442",
        "website": "hildegard.org",
        "company": {
            "name": "Romaguera-Crona",
            "catchPhrase": "Multi-layered client-server neural-net",
            "bs": "harness real-time e-markets"
        }
    },
    ...
]
```

In the following example, we will use TLS Call to extract `id`, `name`, `lat`, and the entire JSON array from the returned JSON result.

```solidity
pragma solidity ^0.8.22;

import {ICliqueTaskManager} from "../src/ICliqueTaskManager.sol";

struct Transformation {
    string from;
    string soltype;
}

struct Params {
    string url;
    Transformation[] encoding;
}

struct Response {
    bytes response;
}

struct Result {
    uint32 id;
    string name;
    string geoLat;
    string[] array;
}

contract HttpsRequest {
    address public immutable _manager;

    event CallbackInvoked(Result);

    constructor(address manager) {
        _manager = manager;
    }

    function callback(bytes calldata _response) external {
        Response memory response = abi.decode(_response, (Response));
        Result memory result = abi.decode(response.response, (Result));
        emit CallbackInvoked(result);
    }

    function run(uint32 id) public {
        Transformation[] memory transformations = new Transformation[](4);
        transformations[0] = Transformation({from: "/0/id", soltype: "uint32"});
        transformations[1] = Transformation({from: "/0/name", soltype: "string"});
        transformations[2] = Transformation({from: "/0/address/geo/lat", soltype: "string"});
        transformations[3] = Transformation({from: "", soltype: "string[]"});

        Params memory params = Params({
            url: "https://jsonplaceholder.typicode.com/users",
            encoding: transformations
        });

        ICliqueTaskManager.Task memory task = ICliqueTaskManager.Task(
            id,
            "clique_httpsRequest",
            abi.encode(params)
        );
        ICliqueTaskManager(_manager).createNewTask{value: 0.05 ether}(
            abi.encode(task),
            this.callback.selector
        );
    }
}
```

Let's break down the example.

```solidity
import {ICliqueTaskManager} from "../src/ICliqueTaskManager.sol";
```

Import the Clique Contract SDK here.

```solidity
struct Transformation {
    string from;
    string soltype;
}
```

Define the custom type`Transformation` 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 in`clique_httpsRequest` task.&#x20;

The names of the other structures to be defined next are not important; users can define names as they wish.

```solidity
struct Params {
    string url;
    Transformation[] encoding;
}
```

Define the input parameters according to the input type of the `clique_httpsRequest` task.

```solidity
struct Response {
    bytes response;
}
```

Define the output parameters according to the output type of the `clique_httpsRequest` task.

```solidity
struct Result {
    uint32 id;
    string name;
    string geoLat;
    string[] array;
}
```

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.

```solidity
Transformation[] memory transformations = new Transformation[](4);
transformations[0] = Transformation({from: "/0/id", soltype: "uint32"});
transformations[1] = Transformation({from: "/0/name", soltype: "string"});
transformations[2] = Transformation({from: "/0/address/geo/lat", soltype: "string"});
transformations[3] = Transformation({from: "", soltype: "string[]"});
```

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.

```solidity
Params memory params = Params({
    url: "https://jsonplaceholder.typicode.com/users",
    encoding: transformations
});
```

Construct the input parameters.

```solidity
ICliqueTaskManager.Task memory task = ICliqueTaskManager.Task(
    id,
    "clique_httpsRequest",
    abi.encode(params)
);
```

Construct the `clique_httpsRequest` query.&#x20;

{% hint style="info" %}
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.
{% endhint %}

```solidity
ICliqueTaskManager(_manager).createNewTask{value: 0.05 ether}(
    abi.encode(task),
    this.callback.selector
);
```

Use the Clique Contract SDK to create a query and wait for the callback function to execute.

```solidity
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](/build-with-clique/clique-client-sdk.md) to call the `clique_httpsRequest` task.

For example, use our Rust SDK:

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"] }
```

```rust
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](/build-with-clique/clique-cli.md), and then create the corresponding query to use it.

```toml
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"
```


---

# 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/sample-task-tutorials/making-arbitrary-tls-calls-tls-oracle.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.
