Skip to main content

Handling Multiple URLs

image

The Problem

In many use cases, one may want to create an aggregated attestation for multiple request URLs. For example, you can generate one zkTLS attestation which contains both the token A's USDT price and token B's USDT price from an exchange market data service.

Primus zkTLS tools including network-core-sdk and zktls-core-sdk support the multiple URLs aggregation. Note

The Usage

1. Network-Core-SDK

The adoption of multiple urls in network-core-sdk is quite simple, you're only required to define the multiple URLs and related resolves in the array structures of requests and responseResolves paramters respectively in the attestParams.

The Defined Requests and ResponseResolves

// contruct the requests and responseResolves for multiple urls 
const requests = [
{
url: "https://www.okx.com/api/v5/market/index-tickers?instId=BTC-USDT",
method: "GET",
header: {},
body: "",
},

{
url: "https://www.okx.com/api/v5/market/index-tickers?instId=SOL-USDT",
method: "GET",
header: {},
body: "",
}
];

const responseResolves = [
[
{
keyName: "btc-idxPx",
parseType: "json",
parsePath: "$.data[0].idxPx"
},
{
keyName: "btc-high24h",
parseType: "json",
parsePath: "$.data[0].high24h"
},
],
[
{
keyName: "sol-idxPx",
parseType: "json",
parsePath: "$.data[0].idxPx"

},
]

];

Encode the attestParams*

Add the requests and the responseResolves in the attestParams, and then call the attest() function.

// add the requests and responseResolves in the attestParams, and then execute the attest() function
const attestParams = {
...submitTaskParams,
...submitTaskResult,
requests,
responseResolves,
};
let attestResult = await primusNetwork.attest(attestParams);

The Attestation Structure

The returned attestation contains the data field, where the first part of the data are returned from the first request URL, including btc-high24h and btc-idexPx, and the second part of the data are returned from the second request URL, including sol-idxPx.

Attest result: [
{
attestation: {
recipient: '0x8F0D4188307496926d785fB00E08Ed772f3be890',
request: [Array],
responseResolves: [Array],
data: '{"btc-high24h":"89622.8","btc-high24h.count":"1","btc-idxPx":"89016.4","btc-idxPx.count":"1","sol-idxPx":"126.23","sol-idxPx.count":"1"}', // the verified raw data to be processed
attConditions: '',
timestamp: 1766377317483,
additionParams: '{"algorithmType":"proxytls"}'
},
attestor: '0x0de886e31723e64aa72e51977b14475fb66a9f72',
signature: '0x3d28a1d67690b625e57e232cfdcb7829e35cee50ac63094c881e5435068d678e7dd7e4f50c0512e198ac90af06d139da27599993e5aa22584207485ade7bc3f71b',
reportTxHash: '0xf1ccb79d8a6d7b829ebe7d601a4120da877654dd60bfc119cbac8cc9aa36bc39',
taskId: '0x5ea66847c66388c528398e4cf86a7856541a768ab209636306e6af5d149f53ae',
attestationTime: 15094,
attestorUrl: 'd511b29f688cd0c2d7d9ec3e148e51b63a5390cf-18080.dstack-base-prod7.phala.network'
}
]

2. zkTLS-Core-SDK

The adoption of multiple urls in zkTLS-Core-SDK is a little bit different from the usage in Network-Core-SDK.

The Defined Requests and ResponseResolves

Note this part is the same as the use in Network-Core-SDK.

let request = [
{
url: "https://www.okx.com/api/v5/public/instruments?instType=SPOT&instId=BTC-USD",
method: "GET",
header: {},
body: "",
},
{
url: "https://www.okx.com/api/v5/public/time",
method: "GET",
header: {},
body: "",
}
];

const responseResolves = [
[
{
keyName: "instType",
parseType: "json",
parsePath: "$.data[0].instType"
}
],
[
{
keyName: "time",
parseType: "json",
parsePath: "$.data[0].ts",
}
]
];

Encode the attestParams

You can use the following code segement to add the requests and the responseResolves in the attestation parameters, and then call the startAttestation() function.

// Generate attestation request.
const generateRequest = zkTLS.generateRequestParams(request, responseResolves);
// Start attestation process.
const attestation = await zkTLS.startAttestation(generateRequest);

The Attestation Structure

Note the returned attestation encoding is different from the above multi-URL attestation in the usage of Network-Core-SDK.

Specifically, multi-URL requests and their response resolutions are encoded as two-dimensional arrays. In the returned attestation, the data contains all the requested data fields for both URLs, like in the Network-Core-SDK.

The request and responseResolve params for the first request URL appears directly in the attestation payload, while the related params for second request URL are wrapped and presented within the additionalParams field.

attestation= {
recipient: '0x0000000000000000000000000000000000000000',
request: {
url: 'https://www.okx.com/api/v5/market/index-tickers?instId=BTC-USDT',
header: '',
method: 'GET',
body: ''
},
reponseResolve: [
{
keyName: 'btc-idxPx',
parseType: '',
parsePath: '$.data[0].idxPx'
},
{
keyName: 'btc-high24h',
parseType: '',
parsePath: '$.data[0].high24h'
}
],
data: '{"sol-idxPx.count":"1","btc-high24h":"89622.8","btc-high24h.count":"1","sol-idxPx":"126.37","btc-idxPx":"89083.8","btc-idxPx.count":"1"}', // the data for two requests, the `count` field can be ignored
attConditions: '[{"op":"REVEAL_STRING","field":"$.data[0].idxPx"},{"op":"REVEAL_STRING","field":"$.data[0].high24h"},{"op":"REVEAL_STRING","field":"$.data[0].idxPx"}]',
timestamp: 1766389694836,
additionParams: '{"algorithmType":"proxytls","requests[1].url":"https://www.okx.com/api/v5/market/index-tickers?instId=SOL-USDT","requests[1].method":"GET","requests[1].body":"","requests[1].header":"","reponseResolves[1][0].keyName":"sol-idxPx","reponseResolves[1][0].parseType":"","reponseResolves[1][0].parsePath":"$.data[0].idxPx"}', // the additonal params for the request param and responseResolve param in the second URL
attestors: [
{
attestorAddr: '0xdb736b13e2f522dbe18b2015d0291e4b193d8ef6',
url: 'https://primuslabs.xyz'
}
],
signatures: [
'0xc4b714d23c28866c503b3d7b9caa637b65c21f962f6cf38dc6b2c91a5c837504048a9ffecd5b5e8f63dbb3d8ee40f075fd19667b7789b88bcc884d38d5669b6a1b'
]
}