Clique Manifest
The Clique Manifest details the metadata for each task including I/O schemas, proof types, and optional [code]or[tasks] sections.
The manifest itself is written in TOML. If you are not familiar with it, you can review this cheatsheet in 5 minutes.
Phantom and Non-Phantom task
The primary distinction between these two types lies in whether the task is dispatched to an executor.
Phantom tasks do not involve execution logic; instead, they focus on transforming arguments that explain how values are passed between tasks. Only Schema is considered a phantom task for now.
Here is an example manifest of a phantom task:
spec-version = "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"Non-Phantom tasks include Dynamic and BuiltIn tasks. BuiltIntasks are maintained by Clique and are currently restricted for other developers. Dynamic tasks, on the other hand, can be built by anyone with the correpsponding evm or wasm bytecode sent to executors in the Clique Network for computation and proof generation. Each Dynamictask must contain a [code] section.
Value Types
In version 1 of the TOML manifest, the following types are supported:
boolstringbytesaddressfloati8,i16,i32,i64,i128,i256u8,u16,u32,u64,u128,u256{type}[]The array type, for example, an array of
string, is denoted asstring[].
custom type
Custom Type
In addition to the basic types, you can add a [types] section to define custom types, specifying the structure of your custom types within it. Currently, custom types only support the use of basic types and do not allow for nested custom types.
For instance, if you wish to add a custom type named Transformation with two fields of type string, you would do the following:
[types.Transformation]
from = { type = "string", description = "json pointer to field in response" }
soltype = { type = "string", description = "solidity type" }Then, you can incorporate your custom type in the [Input] or [Output] sections of your manifest:
[input]
field1 = { type = "Transformation", description = "single custom type" }
field2 = { type = "Transformation[]", description = "an array of the custom type" }Type Mapping
Here is the mapping correspondence between our clique value types and JSON types, Solidity types, as well as Rust types:
bool
bool
bool
bool
string
string
string
String
bytes
hex string with 0x prefix
bytes
Vec<u8>
address
hex string with 0x prefix
address
clique_types::value::Address
{type}[]
array
array
Vec<type>
float
number
Not Supported
f64
i8
number
int8
i8
i16
number
int16
i16
i32
number
int32
i32
i64
number
int64
i64
i128
decimal string
int128
i128
i256
decimal string
int256
clique_types::value::Int256
u8
number
uint8
u8
u16
number
uint16
u16
u32
number
uint32
u32
u64
number
uint64
u64
u128
decimal string
uint128
u128
u256
decimal string
uint256
clique_types::value::Uint256
custom type
object
struct
struct
Built-In variables
$input
$inputThe task input object
$tasks
$tasksThe output of each dependency task. You can reference a task output by its
id.
Manifest Structure
name
Type:
stringUnique identifier for each task in the Clique Network, The recommended format is
{yourNamespace}_{taskName}.
spec-version
Type:
"1"This refers to the spec version of this manifest file, which should be fixed as
"1"for now.
type
Type:
"Schema" | "Dynamic" | "BuiltIn"This refers to the task type. See the Phantom and Non-Phantom section for details. The
BuiltIntask format is only used by Clique right now to publish official tasks, so you should specifyDynamichere.
proof-type
Type:
arrayThis refers to the supported proof type for this task. Currently, only the
"TEE"proof type is supported.
input
Type:
tableThis describes the required arguments for this particular task.
inputwill be validated before the task is actually dispatched to an executor.
input.{field}.type
Type:
stringThis refers to the value type of this field.
input.{filed}.description
Type:
stringField description. Optional.
output
Type:
objectThe data structure returned by this task.
output.{filed}.type
Value type. Required if it's a non-phantom task.
output.{field}.description
Field description. Optional.
output.{field}.ref
Type: reference string
Reference to other field. Required for
Schematask. If therefis specified, refrain from setting thetypeas therefinherently determines thetype.
tasks
Type:
arrayDependencies. Required for
Schematask.
[[tasks.id]]
Type:
stringThe unique id of its dependencies. Use
[[tasks.name]]by default if it's empty.
[[tasks.name]]
Type:
stringName of dependent task.
[[tasks.proof-perference]]
Type:
"TEE"This refers to the preferred proof type for the task, which must be one of the proof types supported by the task.
[[tasks.input]]
Type:
tableTransformation of input or output from others to required parameters.
[code.type]
Type:
"EVM" | "WASM"Specify the type of bytecode.
[code.data]
Type:
stringThis current supports two types of values depending on the VM that's used
evm: Hex-encoded bytecode for evm
wasm: Hex-encoded bytecode for WAT or WASM
[code.abi]
Type:
stringThis is the ABI of the entry point function. Currently it's EVM only.
types
Type:
tableThis refers to the custom types.
types.{custom-type-name}.{field}.type
Type:
stringThis refers to the value type of this field.
types.{custom-type-name}.{field}.description
Type:
stringField description. Optional.
Examples
Here is an exmaple of Dynamic EVM task:
spec-version = "1"
name = "yourOrganization_dynamicTask"
type = "Dynamic"
proof-type = ["TEE"]
[types.MyCustomType]
price = { type = "u64", description = "product price" }
name = { type = "string", description = "product name" }
[input]
boolInput = { type = "bool", description = "bool" }
stringInput = { type = "string", description = "string" }
bytesInput = { type = "bytes", description = "bytes" }
addressInput = { type = "address", description = "address" }
floatInput = { type = "float", description = "float number" }
i8NumberInput = { type = "i8", description = "description is optional" }
u8NumberInput = { type = "u8" }
i16NumberInput = { type = "i16" }
u16NumberInput = { type = "u16" }
i32NumberInput = { type = "i32" }
u32NumberInput = { type = "u32" }
i64NumberInput = { type = "i64" }
u64NumberInput = { type = "u64" }
i128NumberInput = { type = "i128" }
u128NumberInput = { type = "u128" }
i256NumberInput = { type = "i256" }
u256NumberInput = { type = "u256" }
arrayInput = { type = "i64[]", description = "i64 array" }
strArrayInput = { type = "string[]", description = "string array" }
customArrayInput = { type = "MyCustomType[]", description = "custom type array" }
customInput = { type = "MyCustomType", description = "single custom type" }
[output]
numberOutput = { type = "i256", description = "i256 number" }
[code]
type = "EVM"
data = "6080604052348015600f57600..."
abi = '[{"type":"function","name":"evaluate","inputs":...,"outputs":..., ...}]'Here is an exmaple of Dynamic WASM task:
Last updated