# primus > This file contains all documentation content in a single document following the llmstxt.org standard. ## Developer Hub ![image](../pics/Banner-2.png) ## Developer Hub Primus offers a [Dev Hub](https://dev.primuslabs.xyz) where developers can easily configure verified internet data and utilize zkTLS capabilities across various application scenarios, such as executing zkTLS protocols in a web-based DApp and implicitly running zkTLS in a backend server. As a developer, two main features you need to be involved with: **1. Create Data Verification Templates** We provide a streamlined process to help you quickly locate and identify the network requests required for data verification. This straightforward process enables seamless integration of verified data without the need to understand complex algorithm implementations or intricate system configurations. By creating a **Data Verification Template** (“Template” for short), you can define the data source URL and the network request containing the verified data. The request URL is essential when initiating a zkTLS process. You can create different templates to meet various application needs. When **integrating with web-based DApp**, you only need to configure the **template ID** (which can be flexibly replaced based on requirements) to complete the data verification process. All templates you create are visible and usable only by you. However, you can also publish them to the **Templates Market** to support other developers. **2. Create Projects** We offer a developer-friendly integration approach that allows you to create **a unique pair of appID and appSecret** for each project. The appID and appSecret are used to manage and authenticate the project’s associated entities. Please note that the appSecret is only visible once when you create the project. We're excited to see what you'll build using our Developer Hub and the zkTLS SDK. If you need any help, feel free to contact us through our [Discord Community](https://discord.com/invite/pdrNxRrApX). --- ## DVC (Data Verification and Computation) ![image](../pics/Banner-2.png) ## Introduction DVC (Data Verification and Computation) mode is a workflow where: 1. one uses zkTLS to verify the correctness and authenticity of HTTPS requests and responses by proving the encrypted TLS transcript directly, without executing any business logic itself. 2. one uses zkVM to consume and compute the verified private data for business logic execution. The advantages of the DVC pattern are clear: user data privacy is strongly protected, while the value or insights derived from the data can be extracted and consumed through an external zkVM program. This separation keeps the workflow clean, modular, and easy to maintain. Moreover, the output of the zkVM programm, a.k.a., a zkSNARK proof, can be publicly verified through zk verifier contract on-chain. ## The Reference Implementation Developers can check the details of the [repository](https://github.com/primus-labs/DVC-Intro) for a complete implementation guide. ## Comparison with Native zkTLS Operations The [zkTLS Operations](op.md) is another approah to process with private data, which also provide a certain type of computation in the zkTLS algorithm layer. However, The method of using zkTLS operations provides less public verifiability, since the output of a zkVM circuit, namely a SNARK proof, can be publicly verified on-chain. --- ## Installation ![image](../../pics/Banner-2.png) ## About Primus Network-Core-SDK Network-Core-SDK is a special SDK for builders to integrate with their applications. Unlike the Network-JS-SDK, the Network-Core-SDK does not require the Primus Extension to be installed. This avoids additional steps and user concerns, and can improve the overall user experience in certain scenarios. Network-Core-SDK does not rely on browser-side features such as network request interception provided by the Primus Extension. While Network-JS-SDK uses these capabilities (after installing the Primus Extension) to act as a zkTLS client and communicate with destination data source servers, Network-Core-SDK instead directly initiate zkTLS protocols directly via configured API endpoints and user credentials. Based on the fact that user credentials should be configured and stored at the application backend, typical use cases that Network-Core-SDK can work with include * AI agent program: the agent program can delegate the user to perform transactions and other operations, while zkTLS-based data verification can also be completed by the agent with a pre-configured credential profile. * Proof-of-Reserve application: asset managers/trading firms can provide verifiable, privacy-preserving proofs on underlying assets and balances, with the goal of further improving transparency and credibility without revealing sensitive data. ## Installing the Primus Network-Core-SDK Welcome to the first step in integrating Primus Network-Core-SDK into your project. This guide will walk you through the installation process and help you get started quickly. ### Prerequisites Before you begin, make sure you have: - Node.js(version 18 or later)installed on your system - npm (usually comes with Node.js) or yarn as your package manager ### Installation Steps #### 1. Install the SDK Open your terminal and navigate to your project directory. Then run one of the following commands: - Using npm: ``` npm install --save @primuslabs/network-core-sdk ``` - Using yarn: ``` yarn add --save @primuslabs/network-core-sdk ``` This command will download and install the Primus Network Core SDK and its dependencies into your project. #### 2. Verify Installation To ensure the SDK was installed correctly, you can check your `package.json` file. You should see `@primuslabs/network-core-sdk` listed in the `dependencies` section. ### Importing the SDK After installation, you can import the SDK in your JavaScript or TypeScript files. Here's how: ```javascript const { PrimusNetwork } = require("@primuslabs/network-core-sdk"); ``` ### Next Steps You can refer to the [simple example](../for-backend/simpleexample) to see an example about how to integrate Network Core SDK into your project. If you need further support, feel free to reach out through our [community on Discord](https://discord.com/invite/pdrNxRrApX). --- ## Overview ![image](../../pics/Banner-2.png) ## Overview When integrating data verification solutions into your backend server, you can utilize the **Primus Network Core SDK**. For integrating primus network capabilities with DApps, please refer to the [DApp Integration](../../build/for-dapp/install.md) guide. The Network Core SDK allows you to verify data through **webpage endpoint responses**, with support for repeated verification without additional calls. An authorized token is required to request private data. Primus Core SDK supports two modes: the [Proxy TLS mode](../../primus-network/tech-intro#proxy-model) and the [MPC TLS mode](../../primus-network/tech-intro#mpc-model). You can specify the desired mode by setting the "algorithmType" parameter during SDK integration. ### Interact with Blockchains The Primus zkTLS protocol is compatible with multiple blockchains. We provide smart contracts that can be deployed on various blockchains to verify data proofs generated by users via the Network Core SDK. Currently, support is available for several testnets and mainnets. TODO ### Quick Start for Beginners 1. [Installation](../for-backend/install.md) Get the SDK set up in your project. 2. [Simple Example](../for-backend/simpleexample.md) Understand how to use the Network Core SDK. ### Stay Connected Keep up with the latest Primus developments: - Star our [GitHub Repository](https://github.com/primus-labs/network-core-sdk) - Join our [Discord Community](https://discord.com/invite/pdrNxRrApX) --- ## Simple Example ![image](../../pics/Banner-2.png) ## Simple Example This guide will walk you through the fundamental steps to integrate Primus's Network-Core-SDK and complete a basic data verification process through your server. You can learn about the integration process through this simple [demo](https://github.com/primus-labs/zktls-demo/tree/main/network-core-sdk-example). ### Prerequisites Before you begin, ensure you have: - Installed the SDK (see [Installation Guide](../for-backend/install.md)) ### zkTLS Modes We offer two modes in various user scenarios: 1. proxytls 2. mpctls For more details about these two modes, you can refer to the [Overview](../../primus-network/tech-intro) section. ```javascript // Set zkTLS mode let attestParams = { // ... other parameters attMode: { algorithmType: "proxytls", // optional, default is 'proxytls' }, }; primusNetwork.attest(attestParams); ``` ### Verification Logics By default, the Primus Network-Core-SDK retrieves a plaintext verification result. We offer two types of verification logic to accommodate different requirements: 1. Hashed result Setting example : ```javascript // Set Attestation conditions const responseResolves = [ [ { ...otherParams, op: "SHA256", // optional, default is 'REVEAL_STRING' }, ], ]; const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, }; let attestResult = await primusNetwork.attest(attestParams); ``` 2. Conditions result Setting example : ```javascript // Set Attestation conditions const responseResolves = [ [ { ...otherParams, op: ">", value: "YOUR_CUSTOM_TARGET_DATA_VALUE", }, ], ]; const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, }; let attestResult = await primusNetwork.attest(attestParams); ``` For more details about these two verification logics, you can refer to the [Verification Logics](../../enterprise/zk-tls-sdk/overview.md#verification-logics) section. ### Using Attestations in zkVM After obtaining the attestation through the Hashed Verification Logic, you may use **getAllJsonResponse** to collect the associated HTTP response payloads. These two components — the attestation (***hashed data***) and the HTTP responses (***raw data***) — can then be jointly submitted to the zkVM for further computation. This approach of handling the attestation data in another computing module like zkVM, is a powerful verifiable data usage pattern so-called data verification and computation (DVC). You can refer to this [part](../dvc.md) for more details. ```javascript const responseResolves = [ [ { ...otherParams, op: "SHA256", // optional, default is 'REVEAL_STRING' }, ], ]; const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, getAllJsonResponse: "true", // optional, default is 'false', Must be set to true to allow getAllJsonResponse to return the HTTP response. }; let attestResult = await primusNetwork.attest(attestParams); const allJsonResponse = await primusNetwork.getAllJsonResponse( attestResult[0].taskId ); ``` ### Implementation ```typescript const PRIVATEKEY = "YOUER_PRIVATEKEY"; const address = "0xYOUER_ADDRESS"; const chainId = 84532; // Base Sepolia (or 8453 for Base mainnet) const baseSepoliaRpcUrl = "https://sepolia.base.org"; // (or 'https://mainnet.base.org' for Base mainnet) // The request and response can be customized as needed. const requests = [ { url: "https://www.okx.com/api/v5/public/instruments?instType=SPOT&instId=BTC-USD", method: "GET", header: {}, body: "", }, ]; const responseResolves = [ [ { keyName: "instType", parseType: "json", parsePath: "$.data[0].instType", // op: "SHA256", // optional, default is 'REVEAL_STRING' }, ], ]; const provider = new ethers.providers.JsonRpcProvider(baseSepoliaRpcUrl); const wallet = new ethers.Wallet(PRIVATEKEY, provider); try { const primusNetwork = new PrimusNetwork(); // Initialize the network with wallet const initResult = await primusNetwork.init(wallet, chainId); // Submit task const submitTaskParams = { address, }; let submitTaskResult = await primusNetwork.submitTask(submitTaskParams); console.log("Submit task result:", submitTaskResult); // Compose params for attest const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, // attMode: { // algorithmType: "proxytls", // optional, default is 'proxytls' // }, // getAllJsonResponse: "true", // optional, default is 'false' }; let attestResult = await primusNetwork.attest(attestParams); console.log("Attest result:", attestResult); // Verify and poll task result const verifyParams = { taskId: attestResult[0].taskId, reportTxHash: attestResult[0].reportTxHash, }; const taskResult = await primusNetwork.verifyAndPollTaskResult(verifyParams); console.log("Task result:", taskResult); // const allResponse= await primusNetwork.getAllResponse(attestResult[0].taskId) // console.log('allResponse:', allResponse) } catch (error) { console.error("Unexpected error:", error); throw error; } ``` ### Understanding the Attestation Structure When a successful data verification process is completed, you will receive an attestation from the attestor. For more information about the attestation structure, see the [section](../misc/attestation-structure.md). ### Error Codes We have defined several error codes in the SDK. If an error occurs during the data verification process, you can refer to the [error code list](../../build/misc/error-code.md) for troubleshooting. --- ## Error Code ![image](../../pics/Banner-5.png) ## Error Code We have defined some error codes in the SDK. When an error occurs during the data verification process, you can refer to the following list for troubleshooting. ### 1. General Errors | Error Code | Situation | | ---------- | --------------------------------------------------------------------------------- | | 00000 | Operation too frequent. Please try again later. | | 00001 | Algorithm startup exception. | | 00002 | The verification process timed out. | | 00003 | A verification process is in progress. Please try again later. | | 00004 | The user closes or cancels the verification process. | | 00005 | Wrong SDK parameters. | | 00012 | Invalid Template ID. | | 00013 | Target data missing. Please check that the JSON path of the data in the response from the request URL matches your template. | | 00104 | Not met the verification requirements. | | -500 | Unexpected attestor node program failure. | | -10100 | Task cannot be executed again due to unexpected failure. | | -10101 | This task has already been completed. No need to resubmit. | | -10102 | This task is still in progress. No need to resubmit. | | -10103 | Submission limit reached for this task. Initiate a new task to continue. | | -10104 | Failed to get task details. Please check the attestor node condition or task ID. | | -10105 | Invalid attestation parameters. Please check the connection between the node and the template server. | | -10106 | Attestation template ID mismatch between task and attestor node. | | -10107 | The user wallet address provided during attestation mismatch with submission. | | -10108 | Invalid task ID. Please ensure the submitted ID matches the task. | | -10109 | Task cannot be executed again. Please check your task fees. | | -10110 | Attestor node mismatch. Ensure the node matches the task specification and resubmit. | | -10111 | Task submitted past the allowed time limit (15 minutes). | ### 2. Network Related Errors | Error Code | Situation | | ------------- | ----------------------------------------------------------------------------------------------------------- | | 10001 ~ 10004 | Unstable internet connection. Please try again. | | 20001 | An internal error occurred. | | 20003 | Invalid algorithm parameters. | | 20005 | An internal error occurred. | | 30001 | Response error. Please try again. | | 30002 | Response check error. | | 30004 | Response parse error. | | 40002 | SSL certificate error. | | 50001 | An internal error occurred. | | 50003 | The client encountered an unexpected error. | | 50004 | The client not started. Please try again. | | 50006 | The algorithm server not started. Please try again. | | 50007 | Algorithm execution issues. | | 50008 | Abnormal execution results. | | 50009 | Algorithm service timed out. | | 50010 | Compatibility issues during algorithm execution. | | 50011 | Unsupported TLS version. | | 99999 | Undefined error. | Please contact our [Community](https://discord.com/invite/pdrNxRrApX) for assistance in resolving the issues. --- ## Example ![image](../../pics/Banner-5.png) ## Example This part will help you understand the fundamental steps to integrate Primus Network-JS-SDK and complete a basic data verification process through your application. You can learn about the integration process through this simple [demo](https://github.com/primus-labs/zktls-demo/tree/main/network-sdk-example). ### Prerequisites Before you begin, ensure you have the following: - A valid Template ID. (obtainable from the [Primus Developer Hub](https://dev.primuslabs.xyz)) - The SDK installed. (see [Installation Guide](../for-dapp/install.md) for instructions) ### Key Features #### **1. SDK Initialization** Connect to specified blockchain networks. Function Name: `init` ##### **Parameter Description**: | Parameter Name | Type | Required | Description | | -------------- | ---------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `provider` | `Provider` | Yes | Web3 provider, can be:- An instance of `ethers.providers.JsonRpcProvider`- An instance of `ethers.providers.Web3Provider`- An instance of `ethers.providers.JsonRpcSigner` | | `chainId` | `number` | Yes | The blockchain network ID to connect to. Must be one of [the supported chain IDs](../for-dapp/example#6-list-of-supported-chains) | #### **2. Task Submission** Submit tasks to require an attestation from the network. Function Name: `submitTask` ##### **Parameter Description**: | Parameter Name | Type | Required | Description | | -------------- | -------- | -------- | ------------ | | `templateId` | `string` | Yes | Template ID | | `address` | `string` | Yes | User address | #### **3. Attestation Execution** Execute the zkTLS protocol with the network attestor node, and return an attestation issued by the attestor node. Function Name: `attest` ##### **Parameter Description**: | Parameter Name | Type | Required | Description | | ---------------- | --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `templateId` | `string` | Yes | Template ID | | `address` | `string` | Yes | User address | | `taskId` | `string` | Yes | Task ID | | `taskTxHash` | `string` | Yes | Task transaction hash | | `taskAttestors` | `Array` | Yes | Array of attestor IDs | | `additionParams` | `string` | No | Extended parameters in JSON format. Developers can include custom business parameters (e.g., user IDs, session info),These parameters will be returned with the final results `const additionParams = JSON.stringify({ YOUR_CUSTOM_KEY: "YOUR_CUSTOM_VALUE" })` | | `attMode` | `string` | No | proxytls or mpctls,default is proxytls. you can refer to [Overview](../../primus-network/tech-intro) section for more details. | | `attConditions` | `Array` | No | By default, the zkTLS SDK retrieves a plaintext verification result. We offer two types of verification logic to accommodate different requirements:1.Hashed result `const attConditions = [[{field: "YOUR_CUSTOM_DATA_FIELD",op: "SHA256"}]]`2.Conditions result `const attConditions = [[{field: "YOUR_CUSTOM_DATA_FIELD",op: ">",value: "YOUR_CUSTOM_TARGET_DATA_VALUE"}]]`.you can refer to the [Verification Logics](../../enterprise/zk-tls-sdk/overview.md#verification-logics) and [zkTLS operations](../op.md#how-to-use-the-zktls-operations-in-sdks) sections for more details. | #### **4. Verify & Poll Task Result** Verify and poll task results. The function is additonally provided for any use case that requires to double check the validity of an created attestation through Primus contracts. Function Name: `verifyAndPollTaskResult` ##### **Parameter Description**: | Parameter Name | Type | Required | Description | | -------------- | -------- | -------- | ----------------------------------------------------------- | | `taskId` | `string` | Yes | The ID of the task to poll | | `reportTxHash` | `string` | No | Report transaction hash (optional) | | `intervalMs` | `number` | No | Polling interval in milliseconds, default is 2000 | | `timeoutMs` | `number` | No | Total timeout duration in milliseconds, default is 1 minute | #### **5. Balance Withdrawal** Retrieve the fees for unsettled tasks. Function Name: `withdrawBalance` ##### **Parameter Description**: | Parameter Name | Type | Required | Description | | -------------- | ------------- | -------- | --------------------------------------- | | `tokenSymbol` | `TokenSymbol` | No | Token type to withdraw, default is ETH | | `limit` | `number` | No | Withdrawal amount limit, default is 100 | #### **6. List of Supported Chains** Property Name:`supportedChainIds` Currently supports **Base Sepolia** and **Base mainnet**, additional chains will be added in upcoming releases. ### Using Attestations in zkVM To retrieve a proof validated using hashed verification logic, you may use **getAllJsonResponse** to collect the associated HTTP response payloads. These two components — the attestation (***hashed data***) and the HTTP responses (***raw data***) — can then be jointly submitted to the zkVM for further computation and verification. ```javascript const attestParams = { ...submitTaskParams, ...submitTaskResult, attConditions: [ [ { field: "YOUR_FIELD_NAME", op: "SHA256", }, ], ] allJsonResponseFlag: 'true',// optional, default is 'false', Must be set to true to allow getAllJsonResponse to return the HTTP response. }; let attestResult = await primusNetwork.attest(attestParams); const allJsonResponse = await primusNetwork.getAllJsonResponse( attestResult[0].taskId ); ``` ## Complete Example ```typescript import { PrimusNetwork } from "@primuslabs/network-js-sdk"; async function main() { const provider = window.ethereum; const primusNetwork = new PrimusNetwork(); console.log(primusNetwork.supportedChainIds); // [84532, 8453] try { // 1. Initialize await primusNetwork.init(provider, 84532); // The Base chain changes 84532 to 8453 console.log("SDK initialized"); // 2. Submit task, set TemplateID and user address. const submitTaskParams = { templateId: "YOUR_TEMPLATEID", address: "YOUR_USER_ADDRESS", }; const submitTaskResult = await primusNetwork.submitTask(submitTaskParams); console.log("Task submitted:", submitTaskResult); // 3. Perform attestation const attestParams = { ...submitTaskParams, ...submitTaskResult, // extendedParams: JSON.stringify({ attUrlOptimization: true }), //Optional,optimization the url of attestation. }; const attestResult = await primusNetwork.attest(attestParams); console.log("Attestation completed:", attestResult); // 4. Verify & poll task result const verifyAndPollTaskResultParams = { taskId: attestResult[0].taskId, reportTxHash: attestResult[0].reportTxHash, }; const taskResult = await primusNetwork.verifyAndPollTaskResult( verifyAndPollTaskResultParams ); console.log("Final result:", taskResult); // Optional withdrawal // const settledTaskIds = await primusNetwork.withdrawBalance(); // console.log('Withdrawn:', settledTaskIds ); } catch (error) { console.error("Main flow error:", error); } } main(); ``` ### Understanding the Attestation Structure When a successful data verification process is completed, you will receive an zkTLS attestation (proof) from the attestor. For more information about the attestation structure, see the [section](../misc/attestation-structure.md). ### Error Codes We have defined several error codes in the SDK. If an error occurs during the data verification process, you can refer to the [error code list](../misc/error-code.md) for troubleshooting. --- ## Installation ![image](../../pics/Banner-5.png) ## Installing the Primus Network-JS-SDK Welcome to the first step in integrating Primus Network-JS-SDK into your project! This guide will walk you through the installation process and help you get started quickly. ### Prerequisites Before you begin, make sure you have: - Node.js(version 18 or later)installed on your system - npm (usually comes with Node.js) or yarn as your package manager ### Installation Steps #### 1. Install the SDK Open your terminal and navigate to your project directory. Then run one of the following commands: - Using npm: ``` npm install --save @primuslabs/network-js-sdk ``` - Using yarn: ``` yarn add --save @primuslabs/network-js-sdk ``` This command will download and install the Primus Network SDK and its dependencies into your project. #### 2. Verify Installation To ensure the SDK was installed correctly, you can check your `package.json` file. You should see `@primuslabs/network-js-sdk` listed in the `dependencies` section. ### Importing the SDK After installation, you can import the SDK in your JavaScript or TypeScript files. Here's how: ```javascript import { PrimusNetwork } from "@primuslabs/network-js-sdk" ``` ### Next Steps Congratulations! You've successfully installed the Primus Network SDK. Here's what you can do next: **Quick Start**: Explore our [Example](../for-dapp/example.md) to quickly experience the project in action. If you need further support, feel free to reach out through our [Telegram Group](https://t.me/primuslabs) or [community on Discord](https://discord.com/invite/pdrNxRrApX). --- ## Attestation Structure ![image](../../pics/Banner-2.png) ## Attestation Structure in Primus Network When a successful data verification process is completed, the client will receive a zkTLS attestation issued by the network attestor. The attestation is defined with the following structure. ```json [ { "attestor": "ATTESTOR_ADDRESS", // attestor's address "taskId": "TASK_ID", // the task id "attestation": { "recipient": "YOUR_USER_ADDRESS", // user's wallet address "request": [ { "url": "REQUEST_URL", // request url "header": "REQUEST_HEADER", // request header "method": "REQUEST_METHOD", // request method "body": "REQUEST_BODY" // request body } ], "responseResolve": [ { "oneUrlResponseResolve": [ { "keyName": "VERIFY_DATA_ITEMS", // the "verify data items" you set in the template "parseType": "", "parsePath": "DARA_ITEM_PATH" // json path of the data for verification } ] } ], "data": "{ACTUAL_DATA}", // actual data items in the request, stringified JSON object "attConditions": "[RESPONSE_CONDITIONS]", // response conditions, stringified JSON object "timestamp": TIMESTAMP_OF_VERIFICATION_EXECUTION, // timestamp of execution "additionParams": "", // additionParams from zkTLS sdk } } ] ``` --- ## Error Code ![image](../../pics/Banner-2.png) ## Error Code This document lists the error codes defined in the SDK. When an error occurs, please refer to this list for troubleshooting. **Note:** If an error persists or the table suggests contacting us, please provide both the **Error Code** and **Subcode** (if present) to the [Primus Team](https://t.me/primuslabs). ### 1. General Errors | Error Code | Situation | | ---------- | ------------------------------------------------------------ | | 00000 | Too many requests. Please try again later. | | 00001 | Failed to start the algorithm. Please refresh the page, then try again. | | 00003 | Verification is in progress. Please try again later. | | 00004 | Verification was cancelled by the user. | | 00005 | Invalid SDK parameters. | | 00006 | Extension not detected. Please install and enable [Primus Extension (Chrome Web Store)](https://chromewebstore.google.com/detail/primus/oeiomhmbaapihbilkfkhmlajkeegnjhe), then try again. | | 00012 | Invalid template ID. | | 00104 | Verification requirements not met. | ### 2. zkTLS Related Errors | Error Code | Situation | | ----------------------- | ------------------------------------------------------------ | | 00002 | The verification process timed out. Please try again later. | | 00013 | No verifiable data detected. Please confirm login status and account details. | | 00014 | The verification process timed out due to a connection interruption. Please try again later. | | 10001 | Unstable internet connection. Please try again later. | | 10002 | Network connection interrupted during attestation. Please try again later. | | 10003 | Connection to the attestation server was interrupted during processing. Please try again later. | | 10004 | Connection to the data source server was interrupted during processing. Please try again later. | | 20001/20002/20004/20005 | Internal runtime error. Contact Primus Team for assistance. | | 20003 | Invalid algorithm parameters. | | 30001 | Response error. Please try again later. *Note: May include subcodes. If contacting Primus Team, provide both code and subcode (if present).* | | 30002 | Response validation error. Please try again later. | | 30003 | Response parsing error. Please try again later. | | 30004 | JSON parsing error. Contact Primus Team for assistance. | | 30005 | HTML parsing error. Contact Primus Team for assistance. | | 30006 | Preset path key not found in the response. Contact Primus Team for assistance. | | 40001 | Internal error: FileNotExistException. Contact Primus Team for assistance. | | 40002 | SSL certificate error. Contact Primus Team for assistance. | | 50000 | Internal algorithm error. Contact Primus Team for assistance. *Note: May include subcodes. If contacting Primus Team, provide both code and subcode (if present).* | | 50003 | The client encountered an unexpected error. Please try again later. | | 50004 | The client did not start correctly. Please try again later. | | 50006 | Algorithm server not started. Please try again later. | | 50009 | Algorithm service timed out. Please try again later. | | 50011 | Unsupported TLS version. Contact Primus Team for assistance. | | 99999 | Undefined error. Please try again later. | ### 3. Network-Related Errors | Error Code | **Display in SDK** | | ---------- | ------------------------------------------------------------ | | 00015 | Invalid algorithm parameters. | | -500 | Unexpected attester node service failure. Please try again later. | | -10101 | This task has already been completed. No need to resubmit. | | -10102 | This task is still in progress. No need to resubmit. | | -10103 | Submission attempt limit reached (15 attempts) for this task. Start a new task to continue. | | -10104 | Failed to fetch task details. Please check network status or task ID, then try again later. | | -10105 | Invalid attestation parameters. Please check the connection between the node and template server. | | -10106 | Attestation template ID mismatch between task and server. | | -10107 | Attestation template ID mismatch in submission. | | -10108 | Invalid task ID. Please check and ensure the submitted ID matches the task. | | -10109 | Task was terminated due to a network fee issue. Please start a new task. | | -10110 | Attester node mismatch. Please ensure the node matches the task requirements and resubmit. | | -10111 | Submission time limit reached (15 minutes). Start a new task to continue. | Please contact our [Community](https://t.me/primuslabs) for assistance in resolving the issues. --- ## Mutual TLS ![image](../pics/Banner-2.png) ## Introduction mTLS (Mutual Transport Layer Security) is a security mechanism in which both the client and the server authenticate each other using X.509 certificates during the TLS handshake. Primus zkTLS SDKs support mTLS by allowing the client certificate to be examined during the handshake phase. ## Using mTLS in the Network-Core-SDK Using mTLS in the SDKs is straightforward. Developers simply provide the client certificate and corresponding private key via the `mTLS` parameter, and then invoke the `attest` function. For platform independence, the certificate and private key should be provided as strings. ```javascript // Compose params for attest const mTLS = { clientKey: fs.readFileSync(CLIENT_KEY).toString(), clientCrt: fs.readFileSync(CLIENT_CRT).toString(), } const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, mTLS }; let attestResult = await primusNetwork.attest(attestParams); ``` You can check this [demo example](https://github.com/primus-labs/zktls-demo/tree/main/network-core-sdk-mtls-example) for more details. --- ## Handling Multiple URLs ![image](../pics/Banner-2.png) ## 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* support the multiple URLs aggregation. ## The Usage in 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`** ```javascript // 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. ```javascript // 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`. ```javascript 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' } ] ``` --- ## zkTLS Operations ![image](../pics/Banner-2.png) ## The Issue of Handling Private Data Traditional zkTLS algorithms provide data authenticity for applications. In this model, the zkTLS client ultimately receives an attestation from the attestor, where the embedded raw data and its corresponding signature together prove that a zkTLS session was executed correctly and successfully verified by the attestor. In many scenarios, offering the raw data is not considered as a good option if privacy is preferred. Handling the data computation within the attestation is a proper approach. Primus SDKs offers zkTLS operations to further adapt to the privacy-preserving applications. ## Supported zkTLS Operations Using comparison operations expressed as boolean conditions within the zkTLS attestation is an effective way to handle private data securely. During attestation generation, various comparison operators can be applied to specific data fields. Each comparison produces a boolean result—true or false—indicating whether the condition is satisfied. The supported comparison operators within Primus SDKs include: * '**>**' (greater than): verifies if the data item is greater than a target value * '**=**' (greater than or equal to): verifies if the data item is greater than or equal to a target value * '**1.Hashed result `const attConditions = [[{field: "YOUR_CUSTOM_DATA_FIELD",op: "SHA256"}]]`2.Conditions result `const attConditions = [[{field: "YOUR_CUSTOM_DATA_FIELD",op: ">",value: "YOUR_CUSTOM_TARGET_DATA_VALUE"}]]`. | #### 2. Network-Core-SDK When using Primus Network-Core-SDK, You can simple enable the comparison and hash operations in the zkTLS attestation generation, by the following example code. ```javascript // Set Attestation conditions const responseResolves = [ [ { ...otherParams, op: ">", value: "YOUR_CUSTOM_TARGET_DATA_VALUE", }, ], ]; const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, }; let attestResult = await primusNetwork.attest(attestParams); ``` ```javascript const responseResolves = [ [ { ...otherParams, op: "SHA256", // optional, default is 'REVEAL_STRING', if you want to hide multiple data fields, use `SHA256_EX` op code. }, ], ]; const attestParams = { ...submitTaskParams, ...submitTaskResult, requests, responseResolves, }; let attestResult = await primusNetwork.attest(attestParams); ``` ## Comparison with DVC Pattern zkTLS operations natively support performing data computations directly over the attestation. In contrast, the DVC (Data Verification and Computation) pattern leverages a zkVM to shift the computation into a zkVM circuit. While zkTLS operations offer a level of privacy comparable to DVC, they provide less public verifiability and trustlessness, since the output of a zkVM circuit, namely a SNARK proof, can be publicly verified on-chain. Even so, zkTLS remains an efficient and architecturally simple approach for enabling application-level privacy. --- ## Overview ![image](../pics/Banner-5.png) ## Overview Here we'll explain about how to create off-data verification applications with **Primus Network SDKs**. Note all applications using Primus network SDKs are interacted with Primus Network, a.k.a., decentralized attestors, where the attestations are generated in a decentralized process with a high hardware security level. Please note Primus Labs also offers [zkTLS enterprise solutions](../enterprise/zk-tls-sdk/overview.md) and [Lightweight Web SDK](../enterprise/page-sdk/overview.md) for different use cases and requirements, particularly for builders where decentralization is not a mandatory requirement. With the vision of creating a decentralized data verification and computation network, Primus Labs provides two types of Network SDKs for different applications to leverage the zkTLS capability from the network attestors. - For web-based applications, we recommend to use the **Network-JS-SDK** (see the [DApp Integration Guide](../build/for-dapp/example.md) ). This is the most straightforward tool that allows end users to create zkTLS attestations through this SDK. Note the end user is required to install [Primus extension](primus-extension/overview.md) to perform the zkTLS session with the network attestor. - For backend integration of zkTLS features, we recommend to use the **Network-Core-SDK** (see the [Backend Integration Guide](../build/for-backend/simpleexample.md)). Note in the backend integration situation, the developer usually proves their off-chain data in their built application, and the Primus extension is not required. Typical scenarios include proof of reserves, in which a configured web page periodically proves that the stablecoin issuer holds sufficient collateral across off-chain platforms. ## How to Choose The Correct Primus SDK? ![image](../pics/sdk-options.png) --- ## Connect data source # Connect data source The browser extension is a wholly user-controlled application. It provides the easiest way to access and fetch your data from various websites, such as social connections or assets information (with your login permission). You'll find easy access points on both the Home page and the Data Source page. ![proofs](../../../pics/5-Empty-homepage.jpg) ![proofs](../../../pics/6-Data-source-list.jpg) Clicking on a data source card takes you to the website's login page. Once you log in, a confirmation window will appear in the bottom right corner. Clicking "confirm" initiates the data fetching process, which happens entirely locally on your device. Primus servers are not involved in this process. The data is fetched directly to your locally installed extension. Remember, deleting the browser extension also removes the fetched data, as it's stored locally and cannot be recovered. ![proofs](../../../pics/7-connect-data.gif) Once you've connected and fetched data, you can view and manage it in the details page. This includes deleting individual data points at any time. For data sources that support attestation, the details page offers a "Create attestation" section for easy creation. It's important to note that data connections rely on your website login session. If your session expires, a red info icon will appear on the data source card. To ensure real-time data updates, simply reconnect through the source again. --- ## Create attestations # Create attestations The attestation page lets you create different attestations about your data. Currently supports: - Asset Verification: Attest your asset balance or token holdings on an exchange. - Humanity Verification: Attest your KYC completion status on an exchange or ownership of a social media account. - Social Connections: Attest your followers number from social media. To create attestations on the attestation page, you'll need a web3 wallet. The connected wallet address will be used to generate your attestation and act as your ID for web3 projects to verify if you meet their attestation requirements. ![proofs](../../../pics/10-zkAttestation-empty.jpg) All attestations leverage MPC-TLS and ZKP techniques to ensure your data remains anonymous and up-to-date throughout the process. Creating attestation relies on the network situation, so a good internet connection is recommended. If you encounter any error messages (e.g., connection issues, data format errors), feel free to check our FAQ content or reach out to us on Discord chanel for assistance. ![proofs](../../../pics/11-attestation.gif) After completing an attestation, a successful attestation result card will appear on the attestation page. This card displays details about your attestation: - Attested information: Specific details verified during the attestation process (e.g., asset balance, followers count). - Attest data source account: The account associated with the data source you connected. - Created wallet address: The web3 wallet address used to generate your attestation. - Attest address: The attestation issuer’s address. ![proofs](../../../pics/12-attestations.jpg) --- ## Data dashboard # Data dashboard A highlight feature of the browser extension is the data analysis dashboard. It provides an aggregate view, allowing you to clearly and efficiently track changes in your connected assets and social data on a single page. ![proofs](../../../pics/8-dashboard.jpg) The Dashboard page offers a categorized data inventory, providing a in-time overview of all your connected data and categorized by type. In the “Assets Details” part, You can easily understand your asset status through portfolio distribution, token distribution, and on-chain asset distribution. All data will be updated every 5 minutes. ![proofs](../../../pics/9-data-dashboard.gif) The 0.3.0 and above version connects to a wide range of 12 different asset and social data sources, allowing you to manage all your data in one convenient location! Can't find the one you need? Contact us and become a developer to contribute to our upcoming Developer Platform and help us expand the possibilities! --- ## Earn achievements # Earn achievements Primus's reward points program launches with this version! Earn rewards by completing tasks listed on the Achievements page. The more you participate, the more you can achieve. ![proofs](../../../pics/20-Achievements-empty.jpg) No worries if you switch computers or browsers! Simply connect the same web3 wallet (the address is shown in the Settings page as your Account) to your new Primus browser extension. Your points and completed tasks will automatically sync, so you can pick up right where you left off! All your earned points are displayed in detail within the Achievements page's rewards history. ![proofs](../../../pics/21-Achievements-history.jpg) Here's how you earn points for attestations and campaigns: - Submitted attestations: Primus records attestations submitted to Linea, Scroll, or Arbitrum blockchains after April 1, 2024. - Campaign participation: - This update automatically tracks points for three events you've already completed: Lucky Draw, Scroll zkAttestation, and Early Bird NFT Rewards. If you participated in any of these events using your connected wallet, you'll receive points after clicking the "Campaign Participation" task. - For other events, we're still working on integrating activity tracking from smart contracts. We'll announce progress and award points for those events soon. --- ## Manage data # Manage data Your data, your control. Everything you do within the PADO extension stays on your computer only, for maximum privacy and control over your information. Easily manage and delete your connected data whenever you want. ![proofs](../../../pics/22-delete-data-source.gif) Unsubmitted attestations are stored locally and won't be available after deletion. ![proofs](../../../pics/23-delete-attestation.gif) --- ## Participate events # Participate events Primus has several on-going attestation campaigns for you to participate in and earn rewards. Head over to the Events page to discover current campaigns and start earning. ![proofs](../../../pics/14-Events-list.png) Click into each campaign, you will find detailed tasks and should complete in succession. Take the **Linea Voyage Campaign** as an example: ** Task 1 **: Follow Primus social media. - In this task, you have to follow Primus’s twitter account and join the Primus Discord server, all of this is a must. ![proofs](../../../pics/15-Linea-task-1.gif) ** Task 2 **: Complete an attestation with a KYC verified account on Binance. - As demanded by the Linea, this task will links your connected wallet address to the KYCed Binance account used as a uniqueness requirements. ![proofs](../../../pics/16-Linea-task-2.gif) ** Task 3 **: Submit to Linea. - By clicking submit to Linea, the extension will activate your MetaMask wallet to switch to the Linea mainnet (if needed) and submit a transaction. This might involve signing a confirmation in your MetaMask wallet. - After successful submission, you will see an attestation card in the attestation page with a Linea icon and an event tag on the lower right corner. - **Important**: Make sure you complete this event through the Events page or through the events banner. Otherwise, your attestation will not be correctly tagged and verified by Linea. ![proofs](../../../pics/17-Linea-attestation.jpg) ** Task 4 **: Check status on Linea event page. - This task will direct you to the Linea PoH event page("poh.linea.build"). - If you connect the same wallet used on the extension, you will see a green checkmark around the PADO card. - **Note**: Completing additional 2 tasks in Group B on the Linea PoH event page is required to fully participate in the Linea PoH campaign. ![proofs](../../../pics/18-linea-poh.png) For any questions, you can refer to the "Frequently Asked Questions" section at the bottom of the page. ![proofs](../../../pics/19-FAQ.jpg) --- ## Settings # Settings The Settings page lets you customize your preferences: - Asset Currency: Choose your preferred currency to view your asset values. (USD is currently selected). - Data Refresh Rate: Set how often your data updates to keep your information fresh. (10 minutes is currently selected). - Password Management: Set or change your password for secure access. ![proofs](../../../pics/24-Settings.jpg) **Your Account**: The Settings page displays your account information. This is typically the first web3 wallet address you connected to the browser extension. Primus uses this address to track your reward points. ![proofs](../../../pics/25-Settings-account.jpg) --- ## Sign in # Sign in Upon installing or updating the Chrome browser extension to the latest version, you'll be guided through an onboarding flow to discover its exciting new features. Whether you're new or updating from a previous version, this flow will help you get started. ![proofs](../../../pics/extension-sign-in.png) At the end of the onboarding flow, you can enter a referral code received from other users to earn extra reward points. If you don’t have a referral code at first, you can still enter it later on the Achievements page through the task “Sign-in using a referral code” and claim your points. ![proofs](../../../pics/extension-landing-referral.png) After signing in, you will land on the Home page, which provides a quick overview to help you see everything at a glance. --- ## Start # Start We will guide through the main function of Primus browser extension. **Download** The Primus browser extension, downloadable from the Chrome Web Store (versions greater than 0.3.0), is currently compatible with Chrome and Edge browsers. Support for other browsers is planned for the future. **For Mac users** Search PADO in the Chrome Web Store, click the “Add to Chrome” button, the extension will install automatically. For the MetaMask wallet, remember to download from the chrome web store as well, make sure you update the MetaMask to the version above 11.8.0. ![proofs](../../../pics/2-mac-download.gif) **For Edge users** Please use the Edge browser in windows, other browsers may face compatibility issues. Search PADO in the Chrome Web Store, click the “Get” button, the extension will install automatically. For the MetaMask wallet, remember to download from the chrome web store as well, make sure you update the MetaMask to the version above 11.8.0. ![proofs](../../../pics/3-windows-download.gif) --- ## Submit attestation on-chain # Submit attestation on-chain To allow web3 projects or dapps to verify your attestations, you need to submit them on-chain. The extension currently supports five blockchains: Linea, BNB Chain, opBNB, Arbitrum, and Scroll. We're constantly expanding this network, giving you more flexibility for your attestations! Once submitted, a blockchain icon will appear in the bottom right corner of your attestation result card, indicating the network it's recorded. Remember, each attestation can only be submitted to one blockchain network once. ![proofs](../../../pics/13-submission.gif) --- ## Main Functions ![image](../../pics/Banner-2.png) ## Main Functions This guide walks you through the main functions of the Primus Extension. All functions are listed on the left navigation bar in the extension. ![proofs](../../pics/extension-homepage-new.png) ### 1. Attestataion #### (1) Create attestation The **attestation** function allows you to create verifiable proofs from various types of internet data. Currently supported options include: - **Asset Verification**: Attest your asset balance, token holdings, or 30-day spot trading volume on an exchange. - **Humanity Verification**: Attest your KYC completion status on an exchange or prove ownership of a social media account. - **Social Connections**: Attest your follower count on social media platforms. To start a verification, first connect your Web3 wallet. The connected wallet address will be used to generate your attestation and serve as your identity for Web3 projects that require verification. This function leverages zkTLS techniques to ensure your data remains anonymous and up-to-date throughout the verification process. A stable internet connection is required. If you encounter errors (e.g., network issues or data format problems), please reach out to us on our Discord channel for assistance. #### (2) Submit proof on-chian To allow web3 projects or dApps to verify your attestations, you need to submit them on-chain. The extension currently supports the following blockchains: - Linea - BNB Chain - opBNB - Arbitrum - Scroll Once submitted, a blockchain icon will appear in the bottom-right corner of your attestation card, indicating the network where it’s recorded. Note: Each attestation can only be submitted to one blockchain network once. ### 2. Events Primus hosts several ongoing attestation campaigns that let you participate and earn rewards from different projects. Simply click on each campaign to view its detailed tasks, which should be completed in sequence. When you complete a data verification process through a campaign, an event tag will appear in the lower-right corner of your attestation card. This tag is also submitted on-chain as proof of your participation. For further questions, refer to the “FAQ” section at the bottom of the page. ### 3. Achievements The Primus extension reward program is available starting from version 0.3.0. You can earn rewards by completing tasks listed on the Achievements page. All earned points and rewards are displayed in detail in your Rewards History section. After the launch of [Primus AlphaNet](https://app.primuslabs.xyz/), all points accumulated from the extension have been recorded. You can now participate in new events through Primus AlphaNet. ### 4. Settings Customize your preferences from the Settings page: - Password Management: Set or change your password for secure access. **Note**: The account information displayed is the first web3 wallet address you connected to this extension. Primus uses this address to track your reward points. --- ## Prerequisites ![image](../../pics/Banner-2.png) ## Prerequisites The Primus Extension is a **Chrome-based extension** and should be installed directly from the Chrome Web Store. The official link is [Primus Extension](https://chromewebstore.google.com/detail/pado/oeiomhmbaapihbilkfkhmlajkeegnjhe). This extension is currently compatible with both **Chrome** and **Edge** browsers. Support for other browsers is planned for the future. For the web3 wallet, remember to download MetaMask from the Chrome Web Store, and make sure you update to version 11.8.0 or above. --- ## About Demo ![image](../../../pics/Banner-5.png) # About Demo ## Overview Here, we will introduce the steps for using the [Primus NETWORK SDK](/data-computation/build-with-primus/for-developers/sdk) with examples. ## Preparations - **Node.js >= 18** **MetaMask** (if the chain is `ethereum` or `holesky`) - Ensure you have enough `ETH` in your wallet for gas and computation fees. - EverPay - Ensure you have enough `ETH` in EverPay to cover storage fees. You can refer to the [SDK Documentation](/data-computation/build-with-primus/for-developers/sdk#instantiate-client) for more information. **ArConnect** (if the chain is `ao`) - Ensure you have enough `wAR` in your wallet. ## How to run demo - clone the repo ```shell git clone https://github.com/pado-labs/pado-network-sdk.git cd pado-network-sdk cd demo ``` - install packages ```shell npm install ``` - run demo ```shell npm run dev ``` - The demo will be served at http://localhost:5173. ## Usage ### Installation ```shell npm install --save @padolabs/pado-network-sdk ``` ### Init Client #### chain is `ao` Make sure that you have installed the [Arconnect](https://chromewebstore.google.com/detail/arconnect/einnioafmpimabjcddiinlhmijaionap) in chrome and that you have enough AR ```javascript const wallet = window.arweaveWallet; const padoNetworkClient = new PadoNetworkContractClient('ao', wallet, 'arweave'); ``` #### chain is `ethereum` or `holesky` Make sure you have installed `MetaMask` in Chrome and have enough `ETH` to cover computation and gas fees, as well as enough `ETH` in `EverPay` to pay for storage. ```javascript const wallet = window.ethereum; const padoNetworkClient = new PadoNetworkContractClient('holesky', wallet, 'arseeding'); ``` ### Data Provider #### Upload Data ##### prepare data ```javascript // data in Uint8Array format const data = new Uint8Array(fileContent); //for example //const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); //or read from file ``` ##### tag for the data ```javascript // tag for the data, you can save filename and subffix here const dataTag = {'name': 'test','subffix':'txt'}; ``` ##### price for the data ###### if chainName is `holesky` or `ethereum` ```javascript //this means price of the data is 0.0000001ETH const priceInfo = { price: 1_000_000_000_000, symbol: 'ETH' }; ``` ###### if chainName is `ao` > ``` > NOTE: Currently, only wAR(the Wrapped AR in AO) is supported. In the example, 200000000 means 0.0002 wAR. > ``` ```javascript // price for the data const priceInfo = { price: '200000000', symbol: 'wAR' }; ``` ###### dataPermissions ```javascript //The addresses of the checkers. If you have no checkers, you can pass an empty array. const dataPermissions=[] ``` ###### encryption schema ```javascript //Parameters required for data encryption //n: Number of nodes involved in the computing //t: Minimum number of nodes required to report task results //Make sure that, n>=t>1 //Default is: {t:2,n:3} const schema = { t:2, n:3 } ``` ###### upload data ```javascript const dataId = await padoNetworkClient.uploadData(data, dataTag, priceInfo, dataPermissions, schema); ``` If everything is fine and there are no exceptions, you will get the `dataId`, and you can query the data you uploaded based on that ID. #### Retrieve the withdrawable balance and proceed with the withdrawal. When data is purchased, the data provider is able to receive a token reward, you can check the withdrawable balance and withdraw it in the following ways. > ***Note:*** > > Currently, `getBalance` and `withdrawToken` are only supported on the ***Holesky*** and ***Ethereum*** chains is supported, and only ***ETH*** is supported. ##### Get balance ```javascript const balance = await padoNetworkClient.getBalance(address, 'ETH'); console.log(balance.locked.toString()); console.log(balance.free.toString()); const transaction = await padoNetworkClient.withdrawToken(metamaskAddress, 'ETH', balance.free); console.log(transaction); ``` ### Data User #### Generate key pair You should generates a pair of public and secret keys for encryption and decryption. ```javascript import {Utils} from "@padolabs/pado-network-sdk"; const keyInfo = await new Utils().generateKey(); ``` #### Submit task Here, you need a [dataId](#data_id), which is returned by the Data Provider through the [`uploadData`](#upload_data). ```javascript const taskId = await padoNetworkClient.submitTask(TaskType.DATA_SHARING, userDataId, keyInfo.pk) ``` This will return a task id which used for getting the result. #### Get task result ```javascript //If you don't get the result after the timeout(default 60000 milesconds), a timeout error will be returned and you can re-call this method until you get the result. //Ensure that the keyInfo is the same object as the parameter passed to submitTask const data = await padoNetworkClient.getTaskResult(taskId, keyInfo.sk); ``` If nothing goes wrong, you will get the `data` of the Data Provider. The data type returned is Uint8Array, you can do further processing. --- ## FAQ ![image](../../../pics/Banner-5.png) # FAQ ## "Error: connect ENETUNREACH" or "Error: connect ETIMEDOUT" appears while using Arweave? ```log TypeError: fetch failed at Object.fetch (node:internal/deps/undici/undici:11372:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) ... cause: AggregateError ... code: 'ETIMEDOUT', [errors]: [ Error: connect ETIMEDOUT 118.184.26.113:443 at createConnectionError (node:net:1634:14) at Timeout.internalConnectMultipleTimeout (node:net:1685:38) at listOnTimeout (node:internal/timers:575:11) at process.processTimers (node:internal/timers:514:7) { errno: -110, code: 'ETIMEDOUT', syscall: 'connect', address: '118.184.26.113', port: 443 }, Error: connect ENETUNREACH 2a03:2880:f102:183:face:b00c:0:25de:443 - Local (:::0) at internalConnectMultiple (node:net:1176:40) at Timeout.internalConnectMultipleTimeout (node:net:1687:3) at listOnTimeout (node:internal/timers:575:11) at process.processTimers (node:internal/timers:514:7) { errno: -101, code: 'ENETUNREACH', syscall: 'connect', address: '2a03:2880:f102:183:face:b00c:0:25de', port: 443 } ``` This is usually a network or proxy issue. There is a way to set up a proxy. - Copy the following code into a js file such as `proxy.js`. ```js import { ProxyAgent } from 'undici'; if (process.env.HTTPS_PROXY) { const proxyAgent = new ProxyAgent(process.env.HTTPS_PROXY); const nodeFetch = globalThis.fetch globalThis.fetch = function (url, options) { return nodeFetch(url, { ...options, dispatcher: proxyAgent }) } } ``` - Add `import "./proxy.js"` to your `.ts` script. - Export `HTTPS_PROXY=your-proxy` in your terminal where you want to run the script. ## "ConnectTimeoutError: Connect Timeout Error" appears while using Arweave? ```log Error while trying to download chunked data for ... TypeError: fetch failed at Object.fetch (node:internal/deps/undici/undici:11118:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) ... cause: ConnectTimeoutError: Connect Timeout Error ... code: 'UND_ERR_CONNECT_TIMEOUT' ... ``` This is usually a network or proxy issue. It's handled the same way as **Error: connect ENETUNREACH**. ## "Error: Unable to get transaction offset: Not Found" appears while trying to download chunked data from Arweave? ```log Error while trying to download chunked data for JqcyW81tMRZj3VWI7aQaTcGVhYaryGcnBFOkjSQrIKE Error: Unable to get transaction offset: Not Found at Chunks.getTransactionOffset (..../node_modules/arweave/node/chunks.js:38:15) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Chunks.downloadChunkedData (..../node_modules/arweave/node/chunks.js:56:32) at async Transactions.getData (..../node_modules/arweave/node/transactions.js:120:20) at async getDataFromAR (..../node_modules/@padolabs/pado-ao-sdk/dist/padoarweave.js:46:18) at async getResult (..../node_modules/@padolabs/pado-ao-sdk/dist/index.js:149:20) at async main (..../dist/data_consumer.js:37:25) Falling back to gateway cache for JqcyW81tMRZj3VWI7aQaTcGVhYaryGcnBFOkjSQrIKE ``` This is because data uploaded to Arweave by the data provider has not been packaged yet. You'll have to wait a while before you try again. - `Unable to get transaction offset: Not Found` means this transaction isn't done yet. (Also, this transaction is not yet visible in https://viewblock.io/arweave). - `Falling back to gateway cache for ...` means that the data is fetched from the gateway cache. --- ## Introduction ![image](../../../pics/Banner-5.png) ## Introduction Developers can use [Primus Network SDK](/data-computation/build-with-primus/for-developers/sdk) to create confidential dApps and send confidential computation tasks on Ethereum or AO. ### Data-Sharing Computation Primus builds the computation network from simple use cases to a comprehensive suite. Currently, the peer-to-peer data-sharing is supported, which provides a secure and practical way to transfer accessability of the private data from the data owner to a third party. In particular, it completes the following peer-to-peer data-sharing process. 1. Alice encrypts her private text/image/video, and stores it on a storage blockchain, e.g., Arweave. 2. Bob sees the metadata information about Alice's data from a data marketplace, and completes a token transfer through the smart contract, e.g., either Ethereum smart contracts or AO processes. 3. Primus network runs a confidential computation, and the result will be private data owned by Alice and encrypted by Bob's public key. Bob downloads the encrypted data and decrypts it locally to recover the plain data file. The core technique within this data-sharing paradigm primarily involves linear homomorphic encryption. Initially, the content encryption key **K** for the private data is split into multiple shares, with each share encrypted using the public keys of three distinct workers. During the confidential computation phase, all key shares are decrypted and subsequently re-encrypted using Bob's public key. These re-encrypted ciphertexts are then linearly combined to produce a single ciphertext that securely encrypts **K** with Bob's public key. A threshold encryption scheme is employed to enhance network robustness. One can also find more technical details in the [post](https://medium.com/@padolabs/a-quick-glance-at-zkfhe-computation-on-ao-75bc73c9518c) and the [repository](https://github.com/pado-labs/threshold-zk-LHE). ### Main Components The data sharing and incentive workflow allows data providers to share their data securely and privately with data users. Key components are listed as follows: 1. **Primus SDK** Through the SDK developers can upload a user's encrypted data, and decrypt the ciphertext data. The github link: [Primus SDK](https://github.com/pado-labs/pado-network-sdk). 2. **Primus Contract** Primus Contract, which mainly manages data, nodes, verifiable confidential computing tasks and related results. The contract also handles computation costs. The github link of Ethereum: [Primus Network Contracts](https://github.com/pado-labs/pado-network-contracts). The github link of AO: [Primus AO Process](https://github.com/pado-labs/pado-ao-process). 3. **Primus Node** Primus Node is an environment that truly performs verifiable confidential computations. Mainly to obtain verifiable confidential computing tasks, execute tasks, and report results. The github link: [Primus Node](https://github.com/pado-labs/pado-network/tree/main/padonode). The [WASM wrapper](https://github.com/pado-labs/pado-network/blob/main/lib/lhe/README.md) for [threshold-zk-LHE](https://github.com/pado-labs/threshold-zk-LHE). ### Workflow ![Primus-Network](../../../pics/build-with-pado/pado-network-v2.png) 1. **Register Primus Node** After the Primus Node is started, it shall be registered in the Worker Management Contract. The registered information includes name, description, public key, owner address, etc. 2. **Upload data** Data Providers can upload encrypted data through dapp based on the Primus SDK and set data prices at the time of upload. The data encrypted by the FHE algorithm and the Primus Node public key will be uploaded to Arweave, and the data information will be registered to the Data Management Contract. 3. **Submit task** Data users can submit computation tasks with their public keys through dapp based on Primus SDK, and pay certain computation fees and data usage fees. The computation tasks will be submitted to the Task Management Contract. 4. **Task execution** Primus Node obtains computing tasks from the Task Management Contract and storage blockchain, uses the LHE algorithm to compute the tasks, and reports the results to the Task Management Contract and storage blockchain after computation. Task Management Contract verifies the results. After completing the verification, the fee is distributed to the data provider and Primus Nodes. 5. **Get Result** Data users obtain encrypted data from Arweave, obtain task results and related information from the contracts and storage blockchain, and then use the LHE algorithm with their private key in the SDK to decrypt the results. --- ## SDK ![image](../../../pics/Banner-5.png) # SDK :::note *Currently only the Ethereum holesky test network and AO are supported, and the Ethereum main network and other networks will be gradually supported in the future.* ::: ## Overview The pado-network-sdk helps developers use Primus Network, which provides trustless and confidential computing capabilities. You can learn more about [Introduction](/data-computation/build-with-primus/for-developers/introduction). ## Quick Start - [A Demo](/data-computation/build-with-primus/for-developers/demo) ## Usage ### Installation #### Install package by npmx ```shell npm install --save @padolabs/pado-network-sdk ``` #### import wasm Introduce `lhe.js` into the HTML file as follows: ```html ``` If you meet the following error in your browser's console: ```shell _stream_writable.js:57 Uncaught ReferenceError: process is not defined at node_modules/readable-stream/lib/_stream_writable.js (_stream_writable.js:57:18) at __require2 (chunk-BYPFWIQ6.js?v=4d6312bd:19:50) ``` You can refer to project using vite. [link](https://github.com/pado-labs/pado-ao-demo/blob/main/vite.config.ts) ### Getting Started #### Utils ##### Generate Key Generate public-private key pairs for submitting tasks and retrieving task results. ``` generateKey(param_obj?: any): Promise; ``` - Example ```javascript import {Utils} from "@padolabs/pado-network-sdk"; //The generated key pair will be used for submitTask() and `getTaskResult() const keyInfo = await new Utils().generateKey(); ``` #### PadoNetworkContractClient ##### Import Client ```javascript import {PadoNetworkContractClient} from '@padolabs/pado-network-sdk' ``` ##### Instantiate Client The constructor for the `PadoNetworkContractClient`. ```javascript constructor(chainName: ChainName, wallet: any, storageType: StorageType = StorageType.ARSEEDING); ``` **Parameters** - **chainName:** The blockchain the client wants to connect to. Learn more about [ChainName](#chain_name_enum) - **wallet:** The wallet that interacts with the blockchain. - **storageType (optional):** The storage option the client wants to use for data. The ***default*** is `StorageType.ARSEEDING`. Learn more about [StorageType](#storage_type_enum) ***Note:*** > - By default, `StorageType` is `ARWEAVE` when `chainName` is `ao`, and `ARSEEDING` when `chainName` is `holesky` or `ethereum`. > > - When using **ARSEEDING** as storage, user need to ***deposit ETH*** to ***EverPay*** to cover storage, computation, data, and other costs. You can learn more about EverPay at: > - **Homepage:** https://everpay.io/ > - **Docs:** https://docs.everpay.io/en/docs/guide/overview > - **Deposit:** https://app.everpay.io/deposit/ethereum-eth-0x0000000000000000000000000000000000000000 > - When using **ARWEAVE** as storage, user will pay AR to cover storage, computation, data, and other costs by ArConnect. | chainName | storageType | Wallet | | --------- | ----------- | ------------------------------- | | ao | ARWEAVE | window.arweaveWallet(ArConnect) | | holesky | ARSEEDING | window.ethereum(metamask) | | ethereum | ARSEEDING | window.ethereum(metamask) | - **Returns** - **Example ** ```javascript const chainName = 'holesky'; const storageType = StorageType.ARSEEDING; //if chainName is holesky or ethereum, wallet should be window.ethereum; //if chainName is ao, wallet should be window.arweaveWallet; const wallet = window.ethereum; const padoNetworkClient = new PadoNetworkContractClient(chainName, wallet, storageType); ``` ##### Upload Data Uploading data to the storage chain. ``` uploadData(data: Uint8Array, dataTag: CommonObject, priceInfo: PriceInfo, permissionCheckers?: string[], encryptionSchema?: EncryptionSchema): Promise; ``` - **Parameters** - **data:** The data to be uploaded, which should be of type `Uint8Array`. - **dataTag:** The data's metadata object. **Note: Please use an object format, not a string.** - **priceInfo:** The data price symbol. Leran more bout [PriceInfo](#price_info_enum) Different `chainName` values correspond to different symbols. | chainName | symbol | minimum price(1 means) | | --------- | ------------------------- | ---------------------- | | ao | wAR(the Wrapped AR in AO) | 0.000000000001 wAR | | holesky | ETH | 1 wei | | ethereum | ETH | 1 wei | - **permissionCheckers(optional)**: The addresses of the checkers. The default is an empty array. Learn more about [IDataPermission](#solidity_data_permission) - **encryptionSchema(optional)**: Parameters used by the algorithm. The default is: ```json { t: '2', n: '3' } ``` - **Returns** - **`dataId`**: A unique identifier for the data. - **Example** ```javascript //padoNetworkClient is the object instantiated in the previous section const data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); const dataTag = { 'filename': 'testFileName' }; const priceInfo = { price: '200000000', symbol: 'wAR' }; //No data permission check by default const dataId = await padoNetworkClient.uploadData(data, dataTag, priceInfo); //If you want to set data permission checking contracts const permissionCheckers = ['0x.....','0x.......'] const dataId = await padoNetworkClient.uploadData(data, dataTag, priceInfo, permissionCheckers); ``` ##### Submit Task Submit a task to the PADO Network. You must pay both the data fee corresponding to the `data provider` and the computing fee for the `workers`. ```javascript submitTask(taskType: TaskType, dataId: string, dataUserPk: string): Promise; ``` - **Parameters** - **taskType:** The type of the task. Just support `TaskType.DATA_SHARING` now. Leran more about [TaskType](#task_type_enum) - **dataId:** The `dataId` returned by the `uploadData` interface. - **dataUserPk:** The The user's public key generated by generateKey of Utils.. - **Returns** - **`taskId`**: The ID of the task. - **Example** ```javascript const userDataId = 'returned by the uploadData'; const taskId = await padoNetworkClient.submitTask(TaskType.DATA_SHARING, userDataId, keyInfo.pk); ``` ***Note:*** > keyInfo is generated at [Generate Key](#generate_key) ##### Get Task Result Get the result of the task. ```javascript getTaskResult(taskId: string, dataUserSk: string, timeout?: number): Promise; ``` - **Parameters** - **taskId**: taskId returned by `submitTask` - **dataUserSk**: The user's secret key generated by generateKey of Utils - **timeout(optional)**: The timeout in milliseconds for getting the result, if you wait longer than this time a `timeout` exception will be thrown. ***Default 60000(60 seconds).*** - **Returns** - **Uint8Array**: The result of the task in plain text. - **Example** ```javascript const taskId = 'returned by the getTaskResult'; const timeout = 20000;//milliseconds //The format of data is Uint8Array, you should handle this data additionally, such as saving it to a file etc. const data = await padoNetworkClient.getTaskResult(taskId, keyInfo.sk, timeout); ``` ***Note*** > You need to make sure that the dataUserSk used and the dataUserPk used by the [submitTask](#submit_task) are part of the same key pair. keyInfo is generated at [Generate Key](#generate_key) ##### Get balance can withdraw Get the balance of your wallet that can be withdrawn ``` getBalance(userAddress: Address, tokenSymbol: string): Promise; ``` - **Parameters** - **userAddress**: Address to search - **tokenSymbol**: What token to search for. Now is `ETH` - **Returns** - **Balance**: The token of the address. Leran more about [Balance](#balance_info) - **Example** ```javascript const balance = await padoNetworkClient.getBalance(address, 'ETH'); console.log(balance.locked.toString()); //The amount of free can be withdrawn console.log(balance.free.toString()); ``` ##### Withdraw token Withdraw token. ```typescript withdrawToken(toAddress: Address, tokenSymbol: string, amount: Uint256): Promise; ``` - **Parameters** - **toAddress**: Address to receive token - **tokenSymbol**: Which token to withdraw. Now is `ETH` - **amoun**: The amount you want to withdraw needs to be less than `free` above. - **Returns** - **Transaction**: Transaction infomation. - **Example** ```javascript const amount = balance.free; debugger const transaction = await padoNetworkClient.withdrawToken(address, 'ETH', amount); console.log(transaction); ``` #### Type And Enum ##### KeyInfo ```javascript type KeyInfo = { //publick key pk: string; //private key sk: string; }; ``` ##### ChainName ```javascript type ChainName = 'ao' | 'holesky' | 'ethereum'; ``` ##### StorageType ```javascript enum StorageType { ARWEAVE = "arweave", ARSEEDING = "arseeding" } ``` ##### PriceInfo ```javascript /** * Price of data * if symbol is 'wAR'(chainName is ao), a price of 1 means that the data price is 0.000000000001 wAR. * if symbol is 'ETH'(chainName is holesky or ethereum),a price of 1 means that the data price is 1wei * price: The price of data * symbol: The token symbol of price */ interface PriceInfo { price: string; symbol: string; } ``` ##### TaskType ```javascript enum TaskType{ DATA_SHARING = 'dataSharing' } ``` #### Balance ```javascript type Balance = { free: Uint256; locked: Uint256; } ``` #### Solidity: IDataPermission Developers should implement the [IDataPermission](https://github.com/pado-labs/pado-network-contracts/blob/main/contracts/interface/IDataPermission.sol) contract to create custom checking logic. Data provider can assign a `checker contract address` for data permission checking while uploading data. When task submitted by a data user, the `Primus Network Contract` requests permission from the assigned contract and then decides whether to continue or terminate the task based on the results returned. ![](../../../pics/build-with-pado/sdk-permission.png) - IDataPermission.sol ```solidity interface IDataPermission { /** * @notice Check whether data user can buy the data * @param dataUser The data user to buy the data. * @param dataId The data id. * @return Return true if the data user can buy the data, else false. */ function isPermitted(address dataUser, bytes32 dataId) external returns (bool);; } ``` An example for checking data whitelisting can be found at [WhiteListDataPermission](https://github.com/pado-labs/pado-network-sdk/blob/main/demo/contracts/WhiteListDataPermission.sol) --- ## AO Worker Guides ![image](../../../pics/Banner-5.png) ## AO Worker Guides ### Software/Hardware Requirement - vCPUs: 2+ - Memory: 4GiB+ - Storage: 100GiB+ ### Install Please reference to official documentation: [Install Docker Engine](https://docs.docker.com/engine/install/). Next, pull the image: ```shell docker pull padolabs/pado-network:latest ``` Clone [pado-labs/pado-worker-setup](https://github.com/pado-labs/pado-worker-setup): ```sh git clone https://github.com/pado-labs/pado-worker-setup.git cd pado-worker-setup/pado-node ``` ### Basic Configurations Copy `./config-files/.env.ao` into `./.env`. Edit the `./.env` and update the values for your own setups. #### Node Info Set a name to identify yourself, these will be used on the node itself and will be shown on performance metrics in the future. ```sh NODE_NAME="Your Node Name" NODE_DESCRIPTION="Your Node Name's Description" ``` #### Arweave Wallet If you don't have an Arweave wallet, you can install one from [ArConnect](https://www.arconnect.io/download), and then export the wallet from ArConnect and store it to somewhere. Next, fill in the file path of the Arweave wallet, ```sh AR_WALLET_PATH='/path/to/your/arwallet.json' ``` #### LHE Key The LHE key is used for data sharing, use the following command to generate it. ```sh bash ./run.sh generate-lhe-key [--key-name ] ``` The default output is `./keys/default.lhe.key.json`, you can specify the key name via `--key-name `. **IMPORTANT!** Don't lose this file and save it to a safe place! Next, fill in the file path of the LHE key you have generated. ```sh LHE_KEY_PATH='/path/to/your/lhe.key.json' ``` ### Register to Primus AO Process **NOTE:** *Please contact [Primus Labs](https://discord.com/invite/pdrNxRrApX) to add your wallet address to the WHITELIST before being able to successfully register!* Once the configuration is complete, you can run: ```sh bash ./run.sh ao:register ``` In general, you only need to perform the registry step once. ### Run Task Once successfully registered, you can start the task program. If necessary, e.g. in a production environment, it is recommended to start the program as a background process. ```sh bash ./run.sh task [] ``` It will start a container named `pado-network[-name]` in the background. Some logs will output to `./logs/*.log`. You can Stop/Start/Restart/Remove the container by running `docker stop/start/restart/rm pado-network[-name]`. ### Add New Workers **NOTE:** *Add New Workers is optional. If you want to execute Ethereum and AO tasks at the same time, you can execute the following command. Otherwise, you do not need to execute the following command.* #### Add EigenLayer Worker Step 1: Reference `./config-files/.env.holesky`(Holesky), mainly copy and append the following options and their value to `.env`: ```sh ENABLE_EIGEN_LAYER ETH_RPC_URL REGISTRY_COORDINATOR_ADDRESS ROUTER_ADDRESS ECDSA_KEY_FILE ECDSA_KEY_PASSWORD BLS_KEY_FILE BLS_KEY_PASSWORD ``` Step 2: Set your own `ECDSA_KEY_FILE`, `ECDSA_KEY_PASSWORD`, `BLS_KEY_FILE`, `BLS_KEY_PASSWORD`. Reference [Register as Operator on EigenLayer](/data-computation/build-with-primus/for-workers/eigenlayer-operator-guides#register-as-operator-on-eigenlayer) and [ECDSA and BLS Key](/data-computation/build-with-primus/for-workers/eigenlayer-operator-guides#ecdsa-and-bls-key). Step 3: Deposit some ETH to everPay. Reference [Storage](/data-computation/build-with-primus/for-workers/eigenlayer-operator-guides#storage). Step 4: Register to Primus AO Process. Reference [Register to Primus AVS](/data-computation/build-with-primus/for-workers/eigenlayer-operator-guides#register-to-pado-avs). Step 5: Remove the old container and re-run the task. Reference [Run Task](#run-task). You can see the full configuration options from `./config-files/.env.holesky-and-ao`. --- ## EigenLayer Operator Guides ![image](../../../pics/Banner-5.png) ## EigenLayer Operator Guides :::note *Currently only the Ethereum holesky test network and AO are supported, and the Ethereum main network and other networks will be gradually supported in the future.* ::: ### Software/Hardware Requirement - vCPUs: 2+ - Memory: 4GiB+ - Storage: 100GiB+ ### Install Please reference to official documentation: [Install Docker Engine](https://docs.docker.com/engine/install/). Next, pull the image: ```shell docker pull padolabs/pado-network:latest ``` Clone [pado-labs/pado-worker-setup](https://github.com/pado-labs/pado-worker-setup): ```sh git clone https://github.com/pado-labs/pado-worker-setup.git cd pado-worker-setup/pado-node ``` ### Register as Operator on EigenLayer **NOTE**: *You may skip this section if you are already a registered operator on the EigenLayer testnet and mainnet.* This setup step focuses on generating ecdsa key, bls key, and registering yourself as an operator on EigenLayer. Complete the following steps according to [EigenLayer guide](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-installation): - [Install EigenLayer CLI](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-installation#cli-installation). - [Generate ECDSA and BLS keypair](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-installation#create-and-list-keys). You can also import existing ECDSA and BLS keys. - **Fund some ETH to the ECDSA address** above generated. These ETH will be used to cover the gas cost for operator registration and doing task in the subsequent steps. - [Register on EigenLayer as an operator](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-installation#operator-configuration-and-registration). ### Basic Configurations For the Ethernet Testnet(Holesky), copy `./config-files/.env.holesky` into `./.env`. Edit the `./.env` and update the values for your own setups. **NOTE**: *If you plan to operate on Mainnet, then copy `.env.mainnet` instead of `.env.holesky`*. #### Node Info Set a name to identify yourself, these will be used on the node itself and will be shown on performance metrics in the future. ```sh NODE_NAME="Your Node Name" NODE_DESCRIPTION="Your Node Name's Description" ``` #### ECDSA and BLS Key Fill in the file path and password of the ECDSA and BLS key you have generated according to [Register as Operator on EigenLayer](#register-as-operator-on-eigenlayer). ```sh ECDSA_KEY_FILE=/path/to/keyname.ecdsa.key.json ECDSA_KEY_PASSWORD='' BLS_KEY_FILE=/path/to/keyname.bls.key.json BLS_KEY_PASSWORD='' ``` #### LHE Key The LHE key is used for data sharing, use the following command to generate it. ```sh bash ./run.sh generate-lhe-key [--key-name ] ``` The default output is `./keys/default.lhe.key.json`, you can specify the key name via `--key-name `. **IMPORTANT!** Don't lose this file and save it to a safe place! Next, fill in the file path of the LHE key you have generated. ```sh LHE_KEY_PATH='/path/to/your/lhe.key.json' ``` ### Storage Storing data on a contract is expensive, so we are currently using [Arweave](https://www.arweave.org/) as the storage blockchain which is cheaper to store data. By default, we can use Arweave directly. However, the Arweave ecosystem itself has [some issues](https://web3infra.dev/docs/arseeding/introduction/lightNode/#why-we-need-arseeding). In order **not** to suffer from these issues, we using [Arseeding](https://web3infra.dev/docs/arseeding/introduction/lightNode) instead. In order to use Arseeding, we need to first transfer/deposit some mainnet ETH to [everPay](https://app.everpay.io/), **which wallet corresponds to the ecdsa key previously mentioned above**. **Alternatively**, you can also deposit on EverPay with the following command: ```sh # here set your ethereum wallet path export WALLET_PATH=/path/to/your/ethereum/wallet.json # bash ./utils.sh everpay:deposit --chain --symbol --amount # e.g.: # bash ./utils.sh everpay:deposit --chain ethereum --symbol ETH --amount 0.0003 ``` Meanwhile, you can check the balance on EverPay by: ```sh bash ./utils.sh everpay:balance --account [--symbol ] ``` ### Register to Primus AVS If you have registered as an operator on the EigenLayer, you can register to the AVS of Primus. **NOTE:** *Please contact [Primus Labs](https://discord.com/invite/pdrNxRrApX) to add your wallet address to the WHITELIST before being able to successfully register!* The following parameters are relevant. All have default values, you may set them according to your actual needs. ```sh # Time after which the operator's signature becomes invalid. Default: 3600 OPERATOR_SIGNATURE_EXPIRY_SECONDS= # The operator socket. Default: "" OPERATOR_SOCKET_IP_PORT= ``` Next, register the operator to AVS by: ```sh # special a quorum id or quorum id list split by comma. e.g.: # bash ./run.sh el:register 0 # bash ./run.sh el:register 0,1 bash ./run.sh el:register [--quorum-id-list ] ``` **NOTE**: The Primus AVS now only supports quorum ids of `0`. The default value of `quorum-id-list` is `0`. In general, you only need to perform the registry step once. Once you have successfully registered to avs, you can get the operator id by: ```sh bash ./run.sh el:get-operator-id ``` ### Metrics (Optional) **NOTE:** *If you want to [monitor](#monitoring-optional) some metrics, you should set `NODE_ENABLE_METRICS` to `true` to enable it*. Metrics can be enabled/disabled by setting `NODE_ENABLE_METRICS` to `true/false`. The default value is `false`. You can also set a port by `NODE_METRICS_PORT` for the metrics service, which defaults to `9094`. ### Run Task Once successfully registered, you can start the task program. ```sh bash ./run.sh task [] ``` It will start a container named `pado-network[-name]` in the background. Some logs will output to `./logs/*.log`. You can Stop/Start/Restart/Remove the container by running `docker stop/start/restart/rm pado-network[-name]`. ### Monitoring (Optional) If you have enabled [Metrics](#metrics-optional), you can start monitoring by following the steps below. #### Switch folder Switch to the `pado-worker-setup/monitoring` folder. #### Configurations Config `./prometheus.yml`: ```yaml - job_name: "pado-node" scrape_interval: 5s static_configs: # FORMAT container:port # container: pado-node container name # port: NODE_METRICS_PORT - targets: ["pado-network:9094"] ``` Note: - contrainer: If the node started with a name, such as `bash ./run.sh task somename`, you should update the **container** to `pado-network-somename`. The default value is `pado-network`. - port: set by `NODE_METRICS_PORT`. The default value is `9094`. #### Usage - Start ```sh docker compose up -d ``` Ensure Prometheus is run in the same Docker network as Primus Network Node. Run the following command for this purpose: ```sh docker network connect pado-network prometheus ``` You should be able to navigate to `http://host:3000` and login with `admin/admin` (default). - Stop ```sh docker compose stop ``` ### Add New Workers (Optional) **NOTE:** *Add New Workers is optional. If you want to execute Ethereum and AO tasks at the same time, you can execute the following command. Otherwise, you do not need to execute the following command.* #### Add AO Worker Step 1: Switch to the `pado-worker-setup/pado-node` folder. Reference `./config-files/.env.ao`, mainly copy and append the following options and their value to `.env`: ```sh ENABLE_AO AO_DATAREGISTRY_PROCESS_ID AO_NODEREGISTRY_PROCESS_ID AO_TASKS_PROCESS_ID AR_WALLET_PATH ``` Step 2: Set your own `AR_WALLET_PATH`. Reference [Arweave Wallet](/data-computation/build-with-primus/for-workers/ao-worker-guides#arweave-wallet). Step 3: Register to Primus AO Process. Reference [Register to Primus AO Process](/data-computation/build-with-primus/for-workers/ao-worker-guides#register-to-pado-ao-process). Step 4: Remove the old container and re-run the task. Reference [Run Task](#run-task). You can see the full configuration options from `./config-files/.env.holesky-and-ao`. ### Utilities Utilities are tool scripts that does not need to be executed during startup. #### Worker Withdraw As a worker, you'll get some tokens for each task you complete. Before executing the following script, switch to the `pado-worker-setup/pado-node` folder. You can get the balance(free, locked) by: ```sh bash ./run.sh worker:balance ``` and withdraw by (If no amount is specified, the entire free balance is withdrawn): ```sh bash ./run.sh worker:withdraw [--amount ] ``` --- ## Overview ![image](../../pics/Banner-5.png) ## Overview Here we'll explain everything about how to become a Primus worker, and how to create privacy-preserving applications with Primus' SDK as a developer. The Primus worker is an essential role within Primus network, and undertakes the important responsibility of providing idle computing power for cryptographic computation such as zkFHE. The capability can be invoked by developers via Primus SDK. Different types of worker guides are provided to facilitate zkFHE computations on multiple public blockchains like Ethereum and AO. In particular, Primus has integrated with EigenLayer and you may [register to Primus AVS](/data-computation/build-with-primus/for-workers/eigenlayer-operator-guides) and become an EigenLayer operator to run the zkFHE node. The SDK is the standard way to use zkFHE technique provided by Primus workers. It adopts iterative update, currently supports peer-to-peer data-sharing computation based on linear homomorphic encryption (LHE), and will gradually increase ZK-based verifiability and various FHE computation types in the future. --- ## Data Computation Network ![image](../pics/Banner-5.png) ## Data Computation Network ### Overview The potential value of data is increasingly recognized by enterprises and individuals. People's daily behavioral data provides corrections and feedback for different technology products, creating economic value and social impact. The effective mining of data value and the avoidance of individual privacy violations as much as possible are the main pain points in the process of data monetization. Existing systems built from either zero-knowledge proofs, multi-party computations or other privacy-enhancing techniques cannot fully resolve the paradox of privacy protection and utilization of sensitive data, and various computational issues during data processing require further reliable integrity measures. Leveraging the benefits of traceability and programmability from blockchain-like techniques, Primus' zkFHE protocol enables an open infrastructure for librating data value with verifiable and confidential data processes while individual and organization developers can selectively contribute with either security, functional scalability and effectivity to the network. The core advantages of zkFHE lie in its natural abilities from both zero-knowledge proofs and fully homomorphic encryptions, to perform customizable computations on encrypted data, with the correctness guaranteed by validity proofs for the whole computation circuits. The validity proofs solids the whole computation framework with cryptographic and computational trustlessness to facilitate the necessary security requirements of applications. ### Roles in Data Computation Network #### Data Provider A *data provider* is an individual or organization that provides computing data to Primus Network. The data from the data provider is encrypted by the FHE algorithm and then uploaded to decentralized storage blockchains such as Arweave and Filecoin. A data provider can receive a portion of the computation fee for the data usage. #### Worker A *worker* is a node of Primus data computation network, providing computing resources, running the zkFHE algorithm on encrypted data, and providing with a confidential computing environment and resources. A worker needs to generate a zero-knowledge proof while computing. A worker also needs to provide the Data Encryption Public Key to a data provider to encrypt the data, and meanwhile, it needs to re-encrypt the confidential computation results into results that only the caller can decrypt. zkFHE algorithm naturally guarantees data confidentiality and computation integrity. Workers can earn computation fees from the successful execution of a computation task. #### Caller A *caller* is an individual or organization that uses the computation capability and data resources of the network. The caller can specify the encrypted data uploaded by the data provider to initiate a computation task and obtain the result from the task execution. Caller shall pay for the computation service. ### Network Architecture With comprehensive consideration of decentralization, security and scalability, the network is designed to separate consensus and computation for scalability. Workers mainly use the zkFHE algorithm to run confidential computations and generate proofs for integrity assurance. The proofs are verified through Primus contracts. Meanwhile, multiple modules including worker management, data management, task management, fee management, and worker incentives, compose Primus contracts. #### Components of Primus Data Computation Network **Worker** As mentioned [here](#001), workers are the key components that support confidential computation tasks to maintain the network liveness. **Primus Contracts** Primus Contracts are a collection of blockchain-like smart contracts deployed in multiple blockchains, including Ethereum, L2s, AO, and others. Primus Contracts consist of multiple modules including worker management, data management, task management, fee management, worker incentives, etc. **Primus Network SDK** Primus Network SDK is a collection of developer tools. Developers can leverage the data computation capability of Primus Network through this SDK and implement various privacy-centric applications that can be alive in the Network. **Primus Scan** Primus Scan is a user interface for exploring the information of Primus data computation network. Through Primus Scan, one can find the details about workers, computable data, tasks, etc. #### Logical Architecture The following figures show the logical architecture within the network. ![Logical Architecture of Primus](../pics/Primus_network_arch.png) #### Workflow According to the classification of data encryption keys, the patterns of FHE algorithms execution within Primus data computation network, can be divided into the following three categories. One may find more explanation about the three types of [application modes](/data-computation/use-cases/overview#use-case-variants) that adapt to different types of callers. * Threshold FHE: Use the shared public generated by multiple Workers to encrypt data. Note this is a technical representative of joint-worker mode. * Single-Key FHE: Use the user's own key to encrypt data. Note this is a technical representative of single-user mode. * Multi-Key FHE: Use the public keys of multiple Workers to encrypt data. Note this is a technical representative of selective multi-worker mode. We emphasis the name of "Multi-Key FHE" here is differ from the Multi-Key FHE algorithm in academia. Core workflow can be divided into three categories accordingly. ##### 1. Threshold FHE Core Workflow ![Network Workflow](../pics/technical-overview/fhe-mode.png) **Worker Registration** An eligible worker must be registered with the worker management module of Primus contracts. Confidential computation tasks shall only be dispatched to successfully registered workers. The registered information includes name, description, owner address, machine resources, RPC address and port, worker's public key, etc. **Task Submission and Data Encryption Public Key Generation** A caller can submit a confidential computing task through an application developed based on Primus Network SDK. To launch a confidential computation task, it is essential to pay the required fees for the computation and data resources. When a caller initiates a task, he shall publish his own public key, for which the final encrypted computation result is only derivable with regard to the private key paired to that public key. Then the Primus Network SDK forwards the `submit_task` request to the task management module. The task management module selects a group of workers who generate the data encryption public keys, and another group of workers who execute the task. In practice, the two worker groups can be the same. The first group of workers returns the data encryption public keys to the task management contract. **Data Upload** A data provider uses Primus Network SDK to obtain the data encryption public keys required by the task from the task management module. The data provider uses the FHE algorithm with those data encryption public keys to encrypt the data and upload the ciphertexts to a storage blockchain such as Arweave. **zkFHE Computation** The Workers who are designated to execute the task shall get the task information from the task management module, and also retrieve the encrypted data from the storage blockchain. They execute the zkFHE computation and output both the encrypted result and a validity proof. **Re-encryption of Result** The Workers who generate the data encryption public keys shall re-encrypt the encrypted result after the task execution, using the caller's public key, so that only the caller can decrypt the result correctly. **Proof Verification and Fee Settlement** After the task execution, workers upload the encrypted result with the validity proof to the task management module. After the task management module successfully verifies the proof, it will invoke the fee management module for fee settlement. The fee will be distributed to the data providers and workers according to the requirements specified in the task. **Decryption of Result** The caller uses its own private key through the FHE algorithm of Primus Network SDK for decryption, and obtains the raw result. ##### 2. Single-Key FHE Core Workflow Single-Key FHE core workflow is similar to the Threshold FHE core workflow, with the following main differences: * The Caller and Data Provider are the same person. * When selecting Workers, you only need to select the Workers that execute the task, not the Workers that generate the data encryption key. This is because the Single-Key FHE uses the user's own key to encrypt data. * The Result Re-encryption process is not required because the data is encrypted using its own key. ##### 3. Multi-Key FHE Core Workflow **Register Worker** The Multi-Key FHE register worker process is the same as Threshold FHE Register Worker. **Get Workers Public Keys and Upload Data** Data Provider submits data upload request to Task Management of Primus contracts. The Task Management selects which Workers' public keys will be used to encrypt the data, and these workers will be responsible for executing tasks based on this data. And Data Provider uses Primus Network SDK to obtain the Workers' public keys required by the data upload request from Task Management of Primus contacts. Then Data Provider use the FHE algorithm of Primus Network SDK and the Workers' public keys to encrypt the data and upload it to Storage Blockchain such as Arweave and Filecoin. **Submit Task** Caller can submit a confidential computing task through an application developed based on Primus Network SDK. Initiating a confidential computing task requires paying a certain amount of computing and data fees. When Caller initiates a task, it will pass its own Caller Public Key, and the final encrypted computation result is only the private key corresponding to the Caller Public Key can be decrypted. **zkFHE Computing** The Multi-Key zkFHE Computing process is the same as Threshold zkFHE Computing, but run different zkFHE algorithms. **Proof Verify and Fee Settlement** The Multi-Key FHE Proof Verify and Fee Settlement process is the same as Threshold FHE Proof Verify and Fee Settlement. **Decrypt Result** The Multi-Key FHE Decrypt Result process is the same as Threshold FHE Decrypt Result. --- ## Confidential ERC-20 # Confidential ERC-20 Coming soon... --- ## Confidential DeFi # Confidential DeFi Darkpool is one of the significant trade models used in traditional finance. A dark pool is a financial trading venue where investors can buy and sell financial instruments, such as equities and derivatives, without revealing their trading intention. When an investor submits a buy or sell order into the dark pool the order is not disclosed for other market participants to view. Rather, the order will wait “in the dark” until it is either removed by the owner, or until a matching counterparty order is discovered, at which point a trade will execute between the buyer and the seller (the exact mechanism used for matching orders varies between venues). Protocols were introduced for three auction mechanisms commonly used in financial markets: (i) a continuous double auction (CDA), where buyers and sellers can post bids and offers at any time and a limit order book is used to perform continuous matching; (ii) a periodic double auction, where buyers and sellers first submit bids and offers during an open auction period before a single clearing price is calculated for all matches; and (iii) a periodic volume match, where orders submitted during the open period contain a value for quantity only (i.e., orders contain no limit price) and all matches trade at a single price determined by some external reference value (e.g., the current mid-price on the primary exchange). --- ## Blind Auction ![image](../../imgs/blind_auction.png) # Blind Auction A blind auction is a type of auction where bidders submit their bids without knowing the bids of other participants. The highest bidder typically wins the auction, but the process of submitting bids and determining the winner can vary. Key characteristics of a blind auction include: 1. Sealed Bids: Bids are submitted in a sealed manner, meaning that no bidder knows the amount bid by others. 2. One-Time Submission: Bidders submit their bids once, without any opportunity to adjust their bids based on others' offers. 3. Winner Determination: The auctioneer opens all bids simultaneously after the submission period ends and determines the winner based on the highest bid (or other predefined criteria). Integrating blind auctions with blockchain and smart contracts offers significant improvements in terms of security, transparency, and trust, making it an attractive option for various industries and applications. However, the privacy of blind auction is unable to be achieved without cryptographic techniques. ## FHE-based Blind Auction We explain a basic solution that integrates blind auction with zkFHE network. ### Setup The blind auction contract communicates with zkFHE network and requires a subset of zkFHE nodes to create a shared public key **PK**. ### Bidding Phase Bid Submission: Participants submit their bids in a sealed manner. This can be achieved by encrypting each bid with the shared public key **PK**. Deposit/Collateral: Participants may be required to lock a certain amount of funds or tokens in the smart contract as a guarantee of their bid. ### Bid Closing The bidding phase ends at a predefined time, and no further bids are accepted. Optionally, in some blind auction implementations, participants may need to reveal their bids prior to determining the winner. This can be achieved by threshold decrypting the bids with zkFHE network. ### Winner Determination The zkFHE network evaluates all submitted bids according to the auction rules and this can be achieved by homomorphically comparing and sorting the bids. For example, it identifies the highest bid in a first-price sealed-bid auction or the second-highest bid in a Vickrey auction. The winning bid shall be revealed by threshold decrypting the bid. The blind auction contract announces the winner and the winning bid. This information is recorded on the blockchain for transparency. ![alt text](../../../pics/auction.png) --- ## Confidential Transaction ![image](../../imgs/confidential_transaction.png) # Confidential Transaction ***Confidential transactions*** (CT) in blockchain are a cryptographic method used to enhance privacy by keeping the details of transactions hidden from the public while still allowing verification of the transaction's validity. Key Features of confidential transactions include: * Hidden Transaction Amounts: Confidential Transactions conceal the amounts being transferred in a transaction, ensuring that only the sender and receiver know the actual amounts. This is achieved through cryptographic techniques that obfuscate the amounts while still allowing network nodes to validate the transaction. * Verifiable Transactions: Despite hiding the transaction amounts, CTs allow network participants to verify the validity of transactions. This means that nodes can ensure no new money is created out of thin air (i.e., no double-spending) without knowing the exact amounts involved. ![alt text](../../../pics/ct.png ) ## Setup At the beginning, the confidential transaction dApp shall communicate with zkFHE network and require a subset of zkFHE nodes to create a shared public key **PK**. Note the account balances are encrypted as unsigned integers. ## Mint Minting tokens can be implemented by encrypting the mint amount with the shared public key, and added to the encrypted account balance. Note an account registration is also enabled by encrypting the first minted tokens as the account balance. ## Burn Note if the confidential transaction application is intended to handle an external plain token asset, i.e., wrapping the public asset into a private asset, we shall allow the private asset to be burned for a withdrawal on the plain asset. Furthermore, any obfuscation measure like a random mint/burn is meaningless because the functions performed on the plain asset will always disclose the amount. The burnt amount shall be homomorphically subtracted from the encrypted account balance. Also, the burnt amount shall be threshold decrypted and revealed to reduce the value from the total supply. ## Transfer Transferring tokens involves several steps to ensure security and confidentiality. Initially, the encrypted amount to be transferred is verified as a positive value. Then we shall confirm that the sender’s balance is sufficient to cover the amount, preventing overspending. Finally, the transfer is completed by homomorphically subtracting the amount from the sender’s balance and adding it to the recipient’s balance. ## View Account Balance To enable a user to view his balance, the dApp instructs the zkFHE network to re-encrypt the balance from the network's shared public key to the user's public key. This is achieved directly through a simple view function. However, this view function requires authentication by having the user provide a signature when calling the contract method, ensuring the network can verify the user’s ownership of the balance. --- ## Dark Pool ![image](../../imgs/dark_pool.png) # Dark Pool A blockchain-based dark pool is a private financial exchange designed for trading securities, derivatives, or other financial instruments while maintaining high levels of privacy and anonymity. Unlike traditional exchanges where order books and trade details are publicly visible, dark pools operate in secrecy, revealing minimal information to the public. By integrating blockchain technology, these dark pools enhance trustless and programmability through smart contracts and decentralized protocols. One major concern is that implementing the core features to protect the transaction information remains a big challenge. ## FHE-based Solution With FHE and zkFHE, the dark pool can be enabled allowing participants to trade without disclosing their identities or the specifics of their orders. We explain the key steps of the idea. ### Initial Setup Let's assume a dApp ``DP`` provides the core features of a dark pool. At the beginning, the dApp shall communicate with zkFHE network and require a subset of zkFHE nodes to create a shared public key **PK**. ### Order Submission For each new order, the participant shall request an encryption computation prior to submitting it to the dark pool. This can be achieved by encrypting the order field with **PK**. This includes encrypting details such as asset type, quantity, and price. For example, ``Enc(price, PK)`` is part of the encrypted order, where ``price`` is a *signed number* representing a buy order or a sell order. ### Matching and Execution The matching process shall be designed to match buy and sell orders based on parameters such as price and quantity. This can be enabled by periodically requesting a matching computation from zkFHE network. Typical computations for matching orders on the same asset type are: ``` delta_price = Enc(price1, PK) + Enc(price2, PK) matched = Compare(delta_price, zero); // an encrypted boolean value ``` The operations check if the buy and sell orders can match the deal by comparing the signed addition value with the encrypted zero, and threshold decrypting `matched` to check the truth. ### Account Settlement Once matching orders are found, the matched quantities are ``mq= Min(Enc(quantity1, PK), Enc(quantity2, PK))``. The dark pool executes the trades by adjusting the encrypted balances of the participants with `mq`. The execution process involves updating encrypted account balances with homomorphically addition or subtraction without decrypting any data. ![alt text](../../../pics/darkpool.png ) A practical dark pool system will be more complicated than the above idea. However, we can still believe that it is possible to fully implement a feature-complete and low-latency on-chain dark pool application using (zk)FHE techniques. --- ## On-Chain Games ![image](../../imgs/game.png) # On-Chain Games The primary benefit of FHE is its ability to improve application privacy, which can significantly increase the appeal of certain gaming scenarios. The combination of zkFHE with games can enhance gaming experiences by either enabling the necessary privacy measures for simulating the desktop games on-chain, or creating "fog-of-war" versions, adding an element of surprise and excitement to games with variants and different rules, thereby increasing the overall enjoyment and engagement for players. Below, highlight a common example of such variations. ## On-Chain Poker Most Poker games can be built on-chain if we take appropriate measures like FHE to provide privacy as in offline games. [**Blackjack**](https://en.wikipedia.org/wiki/Blackjack), also known as 21, is a popular casino card game. The basic rules are straightforward. The goal is to beat the dealer by either: * Having a hand value that is closer to 21 than the dealer's hand without going over 21, or * The dealer's hand going over 21 (busting) while your hand does not. The card rules are quite simple. Number cards (2-10) are worth their face value. Face cards (Jack, Queen, King) are worth 10 points each. Aces (A) can be worth either 1 or 11 points, depending on which value helps the hand more without exceeding 21. Each round of the game has some flexible rules, including double down, surrendering, splitting cards, etc., which are beyond the scope of this example. We explain the (zk)FHE integrated process. ![alt text](../../../pics/game1.png) ### Game Setup The Blackjack dApp integrates with zkFHE network and requests a shared public key **PK** from a certain zkFHE working group. Note here we suggest using a threshold-FHE algorithm to provide the card value privacy. ### Initial Round Like in the plain game, each player including the dealer is allocated two cards via the dApp service. The first card (called the "hole") of the dealer's will be dealt face down by encrypting with the shared public key **PK** and then distributing it. ### Player's Round Each player will be allocated a new card if he wants until he feels the hand value is enough close to 21. If the hand value is over 21, the play busts and loses this round. ### Dealer's Turn If the dealer's hand value is a ***blackjack***, i.e., a combination of A and J/Q/K/10, he shall reveal it immediately and win the round before moving to the next round. Note this can be achieved by homomorphically comparing the first card value with the "J/Q/K/10" or "Ace" depending on the other card value, and then revealing it publicly by threshold decrypting the card. --- ## What is Threshold-FHE? # What is Threshold-FHE? Unlike Single-Key FHE and Multi-Key FHE, Threshold-FHE is another variant of FHE schemes that is used heavily in Web3. In short, Threshold-FHE combines both FHE and threshold cryptography, to enable secure computations on encrypted data in a distributed manner. Here’s how it works: **Data Encryption**: Data is encrypted using a fully homomorphic encryption scheme. **Distribution of Decryption Key**: The decryption key is split into multiple shares and distributed among several parties using threshold cryptography. **Secure Computation**: Encrypted data can be processed (e.g., computations can be performed on it) without decrypting it. This computation is possible due to the homomorphic properties of the encryption. **Threshold Decryption**: To decrypt the result of the computation, a minimum threshold of parties (e.g., t out of n) must cooperate to combine their key shares. This ensures that no single party can decrypt the data alone, enhancing security. Threshold-FHE can be very useful, especially when working with native blockchain applications like DeFi, Game, Governance, etc. --- ## Confidential Voting ![image](../../imgs/confidential_voting.png) # Confidential Voting Confidential voting is a privacy-preserving voting system that can provide privacy on voting choices and other side information. In the world of decentralized governance, tools like Snapshot and Tally have become essential for managing proposals and voting. Snapshot offers off-chain voting with results stored on IPFS or Arweave, while Tally provides a fully on-chain solution utilizing ERC20 and ERC721 token contracts. By combining the strengths of both systems and incorporating the zkFHE technique, we can design a secure, decentralized voting system that offers both confidentiality and integrity. ## Snapshot [Snapshot](https://snapshot.org/#/) allows anyone to create a voting proposal by confirming the block height corresponding to the proposal. Users' voting power is calculated based on their token balance at that block height. They can vote (for, against, abstain) and the results are calculated once the voting period ends. Proposal and voting information can be stored on IPFS (or Arweave). Additionally, users can delegate or withdraw their voting power to/from other addresses within the domain. ## Tally [Tally](https://www.tally.xyz/)’s DAO voting system relies on token and governor contracts. The token contract (ERC20 or ERC721) is a prerequisite for the governor contract, which manages proposals and voting. Users submit proposals by sending transactions to the governor contract and vote on active proposals through on-chain transactions. Tally ensures all voting information is recorded on-chain, offering transparency and security. Similar to Snapshot, Tally allows delegation of voting power. ## A zkFHE Solution By leveraging zkFHE computation and integrating the features of Snapshot or Tally, we can create a confidential voting dApp ``CV`` that combines on-chain or off-chain governance with enhanced security and confidentiality. The dApp shall integrate with the zkFHE network with proper approaches initially. The key steps are creating a proposal, voting and tallying. ![alt text](../../../pics/voting.png ) **Proposal Creation**: Any user can create a proposal through ``CV``, and publish it on-chain (Tally) or off-chain (Snapshot). The metadata of the proposal shall specify the voting strategy. The dApp ``CV`` communicates with Primus' contracts and requires a subset of zkFHE nodes to create a shared public key **PK** for that proposal. **User Voting**: A user chooses a voting option ``m1`` a the created proposal. Meanwhile, he uses **PK** to encrypt with the option ``m1`` and sends the encrypted vote ``Enc(m1, PK)``. **Tally and Publish** On receiving enough encrypted votes, the dApp shall tally up on that proposal. This can be achieved by performing a homomorphic computation on all the votes, i.e., ``` C = Compute(Enc(m1,PK),Enc(m2,PK),...Enc(m99,PK)) ``` Note the vote ``m1`` can be a simple boolean value for a "yes" or "no" option, or it can be a weighted vote that can be linearly computed as ``m1=a1*b1``, where ``a1`` is the token quantities and ``b1`` is the vote option. Note we cannot hide the token quantities as the snapshot block height is public, and token balances can be queried from block data, exposing the voting power. The ciphertext ``C`` is an encryption of the voting result, which can be threshold decrypted to recover the plain result ``R``. ## Advantages * Integration with Existing Frameworks The proposed solution can integrate with both Tally and Snapshot, enabling both on-chain and off-chain governance with confidential voting. Delegation of voting power can also be enabled through standard application logic within the solution. * Enhanced Security and Decentralization: Compared to a traditional ZKP-based [solution](https://medium.com/@horizenlabs-tech/protecting-voter-privacy-in-daos-5fbddb295ae5), the above approach eliminates the need for a central tallying authority, reducing centralization risks. --- ## Overview ![image](../../pics/Banner-5.png) # Overview The adoption of FHE algorithms can be categorized into different types, due to the diversity of FHE algorithms and use patterns. ## FHE Variants Literately, there are different types of FHE algorithms, according to the key numbers, including: * **Single-Key FHE:** it refers to an FHE scheme where all the homomorphic operations are performed using the same encryption key. This means that the same key is used to both encrypt the data and perform computations on the encrypted data. In a single-key FHE system, there is only one encryption key that is used to encrypt data, perform homomorphic operations, and ultimately decrypt the data. This simplifies the key management process as there is no need to handle multiple keys. * **Threshold FHE:** it combines both FHE and threshold cryptography, to enable secure computations on encrypted data in a distributed manner. In a threshold FHE protocol, a group of nodes work together to create a shared public key, and each node possesses the a part of the decryption key. Any homomorphic computation shall be performed on the ciphertext that is encrypted from the shared public key. The computation result can be threshold decrypted by a subset of the group. ## Use Case Variants Within Primus' zkFHE network, all callers (applications) can invoke the FHE computation from the Primus workers. In general, there are three types of application modes that adapt to different types of callers. You can explore further workflow details of these three modes in the [technical section](https://docs.padolabs.org/technical-overview/understand-pado-network). * **Single-User Mode:** There could be one or many pieces of data supplied by one user in a FHE computation task, and all pieces of input data are encrypted with the user's public key. Note this is a standard way of FHE-based outsourced computation where the user only delegates the encrypted computation and leverages the computing power of zkFHE network. * **Joint-Worker Mode:** There could be one or many pieces of data supplied by multiple users in a FHE computation task, all pieces of input data are encrypted with a shared public key which is produced by a group of Primus workers. Node this is a typical usage of Threshold FHE under Primus' network. * **Selective Multi-Worker Mode:** There could be one or many pieces of data supplied by one or multiple users, and all pieces of input data are encrypted with different workers' public key. Like in the Joint-worker mode, the group of workers are selected by the caller in advance. Note in most cases, any piece of user data is NOT recommended to be encrypted with any worker's public key, which could increase the privacy leakage risk. --- ## Peer-to-Peer Data Sharing ![image](../../imgs/data_sharing.png) # Peer-to-Peer Data Sharing ## Background Centralized platforms such as YouTube, Instagram, TikTok, and Patreon have been the backbone of the Creator Economy thus far. These platforms provide creators with avenues to generate revenue via advertising, sponsorships, and fan support. However, they come with inherent drawbacks, including platform dependency, revenue sharing, and limited content ownership. On the other hand, the existing Web3 creator platform fails to achieve censorship-resistance and data value sharing, due to the lack of data confidentiality measurement on transparent blockchains. Such an issue makes a creator unwilling or unable to share a worthy plain file with a paid customer through blockchains. A straightforward way is to create a peer-to-peer data-sharing application on the blockchain with cryptography-ensured confidentiality. Within such a use case, the process of data-sharing is completely processed via smart contracts, by which the transaction atomicity is achieved. To achieve confidentiality, the data shall be encrypted and stored on decentralized storage, and further be accessed by the paid customer after the FHE computation on the encrypted data. ## A Multi-key FHE Solution The general process of peer-to-peer data sharing is shown in the following figure. We discuss the process that is integrated with Primus' zkFHE network on the task level. It is important that the data provider does not use their own encryption key. Allowing the provider to use their secret key would involve them in the sharing process and create an additional dependency. On the other hand, we shall not allow a single third party with his public key to run the outsourced encryption, which breaks the data confidentiality. A decent approach is to let the data provider encrypt data with a couple of public keys from a certain group to minimize the trust assumption. This is where Multi-key FHE is applied. ![alt text](../../../pics/usecase-datasharing.png) ### Encrypt Data Let's assume there is a dApp that provides the peer-to-peer data-sharing feature for its end-users. The data provider uses the dApp and requires a group of public keys from the zkFHE network and uses that public key set to encrypt the data. Here we suggest a hybrid encryption shall be applied, i.e., use a secret key **K** to encrypt the data content with a symmetric encryption algorithm and use different public keys to encrypt the shares of **K** with (zk)FHE algorithms. The data provider then stores all the ciphertexts into a storage system, which can be either a storage blockchain or a centralized storage service. ### Share Encrypted Data A data consumer uses the dApp and sends some crypto assets to the dApp contract. In addition, the data consumer shall also send his public key to the dApp contract for decrypting the shared result which can only be accessed by himself. The dApp contract shall assign the computation task with the consumer's public key, to the computation network and requires FHE computation for the encrypted data-sharing. After the computation execution, the result will be a new ciphertext that encrypts the data with the consumer's public key. The data consumer can receive that result and decrypt it locally to recover the plain data. --- ## What is Multi-Key FHE? # What is Multi-Key FHE? Multi-key FHE allows computations on ciphertexts encrypted under different public keys. Specifically, given ciphertexts encrypted under different public keys, it is possible to homomorphically evaluate a function f on these ciphertexts to obtain an encrypted result. This result can be jointly decrypted by the holders of the corresponding private keys. --- ## Confidential Payment ![image](../../imgs/confidential_payment.png) # Confidential Payment The feasibility of processing encrypted transaction data makes zkFHE naturally suitable for creating confidential transactions on the blockchain. There are a couple of technical solutions to doing so by recuriting FHE as a building block. An auditable anonymous and confidential payment (AACP) system uses zkFHE to provide necessary features including: * Confidentiality: meaning the payload data of the transaction cannot be revealed. * Anonymous: meaning the sender and the receiver of the transaction are not identified in the financial system. * auditability: meaning the transaction shall be fully administrable to a specific entity, to facilitates comprehensive compliance audits while ensuring the security of user funds. Such a payment system can be deployed on programmable blockchains, and it is particularly suitable for B2B payment. A rough idea of deploying such a sysytem is as the following. ![confidential_payment](../../../pics/confidential-payment.png) * **System setup** The auditor generates a global FHE key pair `(PK,SK)`, where `PK` is used as the global parameter, and `SK` is used for auditing. * **User registration**: The user chooses a uniformly random address secret key `a_sk`. The auditor can also requre KYC of the user for registration. * **Mint**: Two ways can be used for mint, either the auditor initial a special transaction to mint the token for the user, or the user sends a public transaction to the smart contract. * **Transfer**: The sender requests a credential from the auditor. The addresses, amount, and balance information will be encrypted. The encrypted transaction will be processed under off-chain FHE computation. * **Audit**: The auditor have the ability to uncover the payment transactions and balances of all users within the system. However, the auditor can not steal the assets from the users. --- ## Confidential DePin # Confidential DePin Coming soon... --- ## Oblivious Message Retrieval ![image](../../imgs/oblivious_message_retrival.png) # Oblivious Message Retrieval Anonymous message delivery systems, such as private messaging services and privacy-preserving payment systems, require a method for recipients to retrieve their messages without revealing metadata or allowing messages to be linked back to them. The challenge lies in ensuring that the process of retrieving messages does not expose any identifying information or communication patterns. One naive solution is for recipients to download all posted messages and individually scan for those addressed to them. While this method maintains privacy, it is highly inefficient, resulting in excessive communication and computation costs, particularly as the system scales up. This approach would quickly become impractical with a large number of users and messages, leading to significant network congestion and high processing demands on each recipient's device. Oblivious message retrieval (OMR), proposed by Ziyu and Eran in their [paper](https://eprint.iacr.org/2021/1256.pdf), is a cryptographic protocol that can address such privacy leakages. # Using OMR in a Private Blockchain A private blockchain like Zcash, keeps the contents of every transaction hidden from all but the counterparties to the transaction, using cryptographic protocols utilizing encryption and zero-knowledge proofs. However, the current Zcash lightwallet architecture faces several challenges: performance issues for wallet users, privacy leaks through metadata exposure when using *lightwalletd*, and inefficiencies in data retrieval. Downloading all transactions to maintain privacy is impractical due to large blockchain sizes, leading to high bandwidth and computational costs. Light wallets perform computationally intensive trial decryption for each shielded transaction and require additional data from lightwalletd to construct new transactions, further exposing metadata. OMR can improve the metadata privacy of a private blockchain by combining it with fully homomorphic encryptions (FHE). ![alt text](image-1.png) At a high level, this is how a Zcash implementation featuring OMR might operate. * A user generates a Zcash address that includes a new clue key `PVW.pk`. * The sender creates a shielded transaction, plus a clue ciphertext, which is an encryption to a vector of 0s with the recipient's clue key `PVM.pk`. Note in practice, the size is about 1KB of additional data per shielded output. * To detect and receive any pertaining transactions, the user generates a detection key and registers that with an OMR-supporting Zcash full node. The node uses that detection key to scan all the shielded transactions on the chain and their attached clue ciphertexts. The scanning involves taking all the transactions, including the clue ciphertexts, and fully-homomorphically, trying to use the detection key to decrypt the clue ciphertexts associated with the shielded transactions. * Note the decryption key is a BFV encryption of the clue private key `PVW.sk`, and such a homomorphic decryption will output a result that is an encryption of a bit vector (a Pertinency Vector) `PV`, for which if this transaction is pertinent to this recipient, then `PV` will encrypt of 0s, and if the transaction is impertinent, then `PV` will encrypt of random bits. * By linearly operating the bit vector `PV` with all the transaction payloads, the resulting message digest will be retrieved by the user. * The user decrypts the digest to get the plain payload of all the pertaining transactions. Both PVW and BFV are homomorphic encryption schemes used in the OMR protocol, where the sender encrypts the clue using PVW scheme and clues are decrypted homomorphically to generate pertinency ciphertexts using BFV scheme. This technique of switching encryption scheme is generally known as *transciphering*. --- ## Privacy-Preserving AI ![image](../../imgs/PPML.png) # Privacy-Preserving AI ## The Privacy Issues of AI Industry The key privacy problems in AI and machine learning areas are multifaceted and involve concerns related to data collection, model training, inference, and deployment. Here are some of the primary privacy issues: * **Data Collection and Storage:** AI systems often require large amounts of personal data, which can include sensitive information such as medical records, financial data, and personal communications. The collection, storage, and use of this data raise significant privacy concerns. For instance, data collected for one purpose may be repurposed for another, which can violate privacy expectations and regulations. Data Anonymization is another problem during the collection and storage phases. Even when data is anonymized, there is a risk of re-identification, where anonymized data can be matched with other data sources to reveal individuals' identities. * **Model Training and Deployment:** During the training process, models can inadvertently memorize and leak sensitive information from the training data. This can happen through overfitting or improper handling of the data. During the model usage, attackers can infer sensitive information about the training data by querying the model. For example, membership inference attacks determine whether a specific data point is part of the training set. * **Data Breaches and Security:** AI systems are susceptible to data breaches and cyber-attacks, which can result in unauthorized access to sensitive data. Meanwhile, protecting the models themselves from theft or tampering is crucial, as compromised models can be used to leak or manipulate sensitive data. * **Regulatory Compliance:** Ensuring compliance with regulations like the General Data Protection Regulation (GDPR) and the California Consumer Privacy Act (CCPA) is complex. These regulations impose strict requirements on data privacy, user consent, and data usage. Managing data privacy across different jurisdictions with varying regulations can be challenging for global AI applications. ## Solutions Fully homomorphic encryption is essential in AI and machine learning to enable secure and privacy-preserving data processing. FHE allows computation on encrypted data without the need to decrypt it, ensuring that sensitive information remains hidden throughout the entire data processing pipeline. By using FHE, AI and machine learning workflows can harness the potential of shared data in a secure and inclusive manner, safeguarding privacy while maximizing the insights gained from multiple data sources. This aligns with the increasing public demand for privacy preservation. FHE addresses the critical need to train AI models with encrypted data sets without exposing the secret key, providing a security gap when processing data and ensuring security and privacy at rest, in transit, and during processing. Furthermore, FHE enables practical and efficient privacy-preserving machine learning (PPML) training and facilitates the development of privacy-preserving AI models, which is highly relevant in the context of increasingly stringent privacy regulations and the societal demand for privacy protection. The potential of FHE in securing machine learning workflows lies in its ability to maintain data security and privacy at every stage of processing, thereby fostering trust and confidence in AI and machine learning applications. ![alt text](../../../pics/PPAI.png ) ### Privacy-Preserving Model Inference Fully Homomorphic Encryption (FHE) enables privacy-preserving model inference by allowing users to encrypt their private data before sending it to a public AI model hosted by a service provider. Here’s how it works: Users encrypt their private data locally using FHE, ensuring it remains confidential during transmission. The encrypted data is then sent to the service provider with the AI model. The service provider, equipped with FHE capabilities, computes on the encrypted data directly. This means the AI model can perform inference and generate encrypted results without accessing the plaintext data. After computation, the service provider sends back the encrypted result to the user. Using their private decryption key, the user decrypts the result to obtain the inference outcome. Throughout this process, the user’s original data remains encrypted, ensuring data privacy and compliance with regulations. FHE for privacy-preserving model inference offers benefits like end-to-end data privacy and trust between users and service providers. However, challenges include computational demands and secure management of encryption keys. As encryption technologies evolve, FHE holds promise for enhancing data security and enabling safe deployment of AI in sensitive applications. ### Federated Learning Federated Learning (FL) is a distributed machine learning approach that allows for the training of a global model across multiple decentralized devices holding local data, without sharing the data itself. This technique preserves data privacy by keeping the data on local devices and only sharing model updates with a central server, which aggregates these updates to refine the global model. This process iteratively improves the global model through repeated cycles of local training and central aggregation, making it ideal for scenarios where data privacy and security are critical. FL is particularly useful in applications such as healthcare, finance, mobile and IoT services, and smart cities. It enables collaborative model training while adhering to data protection regulations and reducing the risk of data breaches. Despite its advantages, Federated Learning faces challenges such as privacy and security concerns. Combining Federated Learning (FL) with Fully Homomorphic Encryption (FHE) can enhance privacy and security in distributed machine learning. In this approach, model updates are encrypted using FHE before being transmitted to the aggregator. FHE allows computations to be performed on encrypted data, so the aggregator can aggregate the encrypted model updates without ever decrypting them. This ensures that sensitive information remains confidential throughout the process. --- ## What is Single-Key FHE? # What is Single-Key FHE? Single-key Fully Homomorphic Encryption (FHE) refers to an FHE scheme where all the homomorphic operations are performed using the same encryption key. This means that the same key is used to both encrypt the data and perform computations on the encrypted data. Here’s a more detailed explanation: Key Characteristics of Single-Key FHE include: **Single Encryption Key:** In a single-key FHE system, there is only one encryption key that is used to encrypt data, perform homomorphic operations, and ultimately decrypt the data. This simplifies the key management process as there is no need to handle multiple keys. **Homomorphic Operations:** The core feature of FHE is the ability to perform arbitrary computations on ciphertexts, which results in a ciphertext that, when decrypted, matches the result of the operations as if they were performed on the plaintext. Single-key FHE maintains this capability using the same encryption key for all steps. Security: Single-key FHE is useful in scenarios where a single entity needs to perform computations on encrypted data while ensuring privacy, such as secure data storage and processing. Typical applications are cloud computing and secure out-sourced data processing. --- ## Attestation Structure ![image](../pics/Banner-2.png) ## Attestation Structure When a successful data verification process is completed, the client will receive a zkTLS attestation issued by the attestor. The attestation is defined with the following structure. You may find the attestation structure is a little bit different from the network-based [attestation](../build/misc/attestation-structure.md). ```json { "recipient": "YOUR_USER_ADDRESS", // user's wallet address "request": { "url": "REQUEST_URL", // request url "header": "REQUEST_HEADER", // request header "method": "REQUEST_METHOD", // request method "body": "REQUEST_BODY" // request body }, "reponseResolve": [ { "keyName": "VERIFY_DATA_ITEMS", // the "verify data items" you set in the template "parseType": "", "parsePath": "DARA_ITEM_PATH" // json path of the data for verification } ], "data": "{ACTUAL_DATA}", // actual data items in the request, stringified JSON object "attConditions": "[RESPONSE_CONDITIONS]", // response conditions, stringified JSON object "timestamp": TIMESTAMP_OF_VERIFICATION_EXECUTION, // timestamp of execution "additionParams": "", // additionParams from zkTLS sdk "attestors": [ // information of the attestors { "attestorAddr": "ATTESTOR_ADDRESS", // the address of the attestor "url": "https://primuslabs.org" // the attestor's url } ], "signatures": [ "SIGNATURE_OF_THIS_VERIFICATION" // attestor's signature for this verification ] } ``` --- ## Installation ![image](../../pics/Banner-2.png) ## Installing the Primus Core SDK Welcome to the first step in integrating Primus zkTLS-Core-SDK into your project. This guide will walk you through the installation process and help you get started quickly. ### Prerequisites Before you begin, make sure you have: - Node.js(version 18 or later)installed on your system - npm (usually comes with Node.js) or yarn as your package manager ### Installation Steps #### 1. Install the SDK Open your terminal and navigate to your project directory. Then run one of the following commands: - Using npm: ``` npm install --save @primuslabs/zktls-core-sdk ``` - Using yarn: ``` yarn add --save @primuslabs/zktls-core-sdk ``` This command will download and install the Primus zkTLS-Core-SDK and its dependencies into your project. #### 2. Verify Installation To ensure the SDK was installed correctly, you can check your `package.json` file. You should see `@primuslabs/zktls-core-sdk` listed in the `dependencies` section. ### Importing the SDK After installation, you can import the SDK in your JavaScript or TypeScript files. Here's how: ```javascript const { PrimusCoreTLS } = require("@primuslabs/zktls-core-sdk"); ``` ### Next Steps You can refer to the [simple example](../core-sdk/simpleexample.md) to see an example about how to integrate the SDK into your project. If you need further support, feel free to reach out through our [community on Discord](https://discord.com/invite/pdrNxRrApX). --- ## Introduction ![image](../../pics/Banner-2.png) :::note This section covers **enterprise integration** using Primus’ proprietary Attestor for zkTLS applications running in backend. For development on the Primus Network, refer [here](../../build/for-backend/install.md). ::: ## Overview When integrating data verification solutions into your backend server, you can utilize the **zkTLS-Core-SDK**. For integrating zkTLS capabilities with DApps, please refer to the [DApp Integration](../zk-tls-sdk/overview.md) guide. The SDK allows you to verify data through **webpage endpoint responses**, with support for repeated verification without additional calls. An authorized token or other type of user credential is required to access user private data. To integrate, **create a project** in the [Primus Developer Hub](https://dev.primuslabs.xyz) to obtain a paired appID and appSecret. Then, configure these credentials in your backend server to utilize the Core SDK and APIs. Primus zkTLS-Core-SDK supports two modes: the [Proxy TLS mode](../../primus-network/tech-intro#proxy-model) and the [MPC TLS mode](../../primus-network/tech-intro#mpc-model). You can specify the desired mode by setting the "algorithmType" parameter during SDK integration. For more details on setting up your project, refer to the [Developer Hub](../../build/developer-hub.md). ### How it Works Here's a simplified flow of how the Primus zkTLS-Core-SDK works on your server: **1. Create Project:** Create a project on the [Primus Developer Hub](https://dev.primuslabs.xyz) to obtain a paired appID and appSecret, then configure them in your backend server. **2. Configure Verification Parameters:** Ensure that two key parameters, including the request parameters and response data paths, are configured correctly. Refer to the [simple example](../core-sdk/simpleexample.md) for guidance. **3. Execute zkTLS Protocol:** Invoke the zkTLS protocol via your server to initiate the data verification process. **4. Verify Data Verification Result:** Your server retrieves the verification result from the Core SDK and validates Primus' signature to ensure trustworthiness. **5. Execute Business Logic:** Based on the verification result, your server executes the relevant business logic, such as submitting the proof on-chain or triggering other operations. ### Interact with Blockchains The Primus zkTLS protocol is compatible with multiple blockchains. We provide smart contracts that can be deployed on various blockchains to verify data proofs generated by users via the SDK. Currently, support is available for several testnets and mainnets. For more details, refer to the [on-chain interactions](../onchain-interaction/overview.md) section. ### Quick Start for Beginners 1. [Installation](../core-sdk/install.md) Get the SDK set up in your project. 2. [Simple Example](../core-sdk/simpleexample.md) Understand how to use the Core SDK. ### Stay Connected Keep up with the latest Primus developments: - Star our [GitHub Repository](https://github.com/primus-labs/zktls-core-sdk) - Join our [Discord Community](https://discord.com/invite/pdrNxRrApX) --- ## Simple Example ![image](../../pics/Banner-2.png) ## Simple Example This guide will walk you through the fundamental steps to integrate Primus's zkTLS-Core-SDK and complete a basic data verification process through your server. You can learn about the integration process through this simple [demo](https://github.com/primus-labs/zktls-demo/tree/main/core-sdk-example). ### Prerequisites Before you begin, ensure you have: - Installed the SDK (see [Installation Guide](../core-sdk/install.md)) ### zkTLS Modes We offer two modes in various user scenarios: 1. proxytls 2. mpctls For more details about these two modes, you can refer to the [Overview](../../primus-network/tech-intro) section. ```javascript // Set zkTLS mode, default is proxy mode. primusZKTLS.setAttMode({ algorithmType: "proxytls", }); ``` ### Implementation You can get the `PRIMUS_APP_ID` and `PRIMUS_APP_SECRET` from the [Primus Developer Hub](https://dev.primuslabs.xyz). ```typescript const { PrimusCoreTLS } = require("@primuslabs/zktls-core-sdk"); async function primusProofTest() { // Initialize parameters, the init function is recommended to be called when the program is initialized. const appId = "PRIMUS_APP_ID"; const appSecret= "PRIMUS_APP_SECRET"; const zkTLS = new PrimusCoreTLS(); const initResult = await zkTLS.init(appId, appSecret); console.log("primusProof initResult=", initResult); // Set request and responseResolves. const request ={ url: "YOUR_CUSTOM_URL", // Request endpoint. method: "REQUEST_METHOD", // Request method. header: {}, // Request headers. body: "" // Request body. }; // The responseResolves is the response structure of the url. // For example the response of the url is: {"data":[{ ..."instFamily": "","instType":"SPOT",...}]}. const responseResolves = [ { keyName: 'CUSTOM_KEY_NAME', // According to the response keyname, such as: instType. parsePath: 'CUSTOM_PARSE_PATH', // According to the response parsePath, such as: $.data[0].instType. } ]; // Generate attestation request. const generateRequest = zkTLS.generateRequestParams(request, responseResolves); // Set zkTLS mode, default is proxy mode. (This is optional) generateRequest.setAttMode({ algorithmType: "proxytls" }); // Start attestation process. const attestation = await zkTLS.startAttestation(generateRequest); console.log("attestation=", attestation); const verifyResult = zkTLS.verifyAttestation(attestation); console.log("verifyResult=", verifyResult); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // do your own business logic. } else { // If failed, define your own logic. } } ``` ### Understanding the Attestation Structure When a successful data verification process is completed, you will receive a zkTLS attestation (proof) from the attestor. For more information about the attestation structure, see the [section](../attestation-structure.md). ### Submit Attestation On-chain (optional) To submit the verified data result (proof) to the blockchain, you’ll need to invoke the appropriate smart contract method. For detailed instructions, please refer to the [onchain interactions](../onchain-interaction/overview.md). ### Error Codes We have defined several error codes in the SDK. If an error occurs during the data verification process, you can refer to the [error code list](../../build/misc/error-code.md) for troubleshooting. --- ## DVC (Data Verification and Computation) ![image](../pics/Banner-2.png) ## Introduction DVC (Data Verification and Computation) mode is a workflow where: 1. one uses zkTLS to verify the correctness and authenticity of HTTPS requests and responses by proving the encrypted TLS transcript directly, without executing any business logic itself. 2. one uses zkVM to consume and compute the verified private data for business logic execution. The advantages of the DVC pattern are clear: user data privacy is strongly protected, while the value or insights derived from the data can be extracted and consumed through an external zkVM program. This separation keeps the workflow clean, modular, and easy to maintain. Moreover, the output of the zkVM programm, a.k.a., a zkSNARK proof, can be publicly verified through zk verifier contract on-chain. ## The Reference Implementation Developers can check the details of the [repository](https://github.com/primus-labs/DVC-Intro) for a complete implementation guide. ## Comparison with Native zkTLS Operations The [zkTLS Operations](op.md) is another approah to process with private data, which also provide a certain type of computation in the zkTLS algorithm layer. However, The method of using zkTLS operations provides less public verifiability, since the output of a zkVM circuit, namely a SNARK proof, can be publicly verified on-chain. --- ## Error Code ![image](../pics/Banner-2.png) ## Error Code This document lists the error codes defined in the SDK. When an error occurs, please refer to this list for troubleshooting. **Note:** If an error persists or the table suggests contacting us, please provide both the **Error Code** and **Subcode** (if present) to the [Primus Team](https://t.me/primuslabs). ### 1. General Errors | Error Code | Situation | | ---------- | ------------------------------------------------------------ | | 00000 | Too many requests. Please try again later. | | 00001 | Failed to start the algorithm. Please refresh the page, then try again. | | 00003 | Verification is in progress. Please try again later. | | 00004 | Verification was cancelled by the user. | | 00005 | Invalid SDK parameters. | | 00006 | Extension not detected. Please install and enable [Primus Extension (Chrome Web Store)](https://chromewebstore.google.com/detail/primus/oeiomhmbaapihbilkfkhmlajkeegnjhe), then try again. | | 00012 | Invalid template ID. | | 00104 | Verification requirements not met. | ### 2. zkTLS Related Errors | Error Code | Situation | | ----------------------- | ------------------------------------------------------------ | | 00002 | The verification process timed out. Please try again later. | | 00013 | No verifiable data detected. Please confirm login status and account details. | | 00014 | The verification process timed out due to a connection interruption. Please try again later. | | 10001 | Unstable internet connection. Please try again later. | | 10002 | Network connection interrupted during attestation. Please try again later. | | 10003 | Connection to the attestation server was interrupted during processing. Please try again later. | | 10004 | Connection to the data source server was interrupted during processing. Please try again later. | | 20001/20002/20004/20005 | Internal runtime error. Contact Primus Team for assistance. | | 20003 | Invalid algorithm parameters. | | 30001 | Response error. Please try again later. *Note: May include subcodes. If contacting Primus Team, provide both code and subcode (if present).* | | 30002 | Response validation error. Please try again later. | | 30003 | Response parsing error. Please try again later. | | 30004 | JSON parsing error. Contact Primus Team for assistance. | | 30005 | HTML parsing error. Contact Primus Team for assistance. | | 30006 | Preset path key not found in the response. Contact Primus Team for assistance. | | 40001 | Internal error: FileNotExistException. Contact Primus Team for assistance. | | 40002 | SSL certificate error. Contact Primus Team for assistance. | | 50000 | Internal algorithm error. Contact Primus Team for assistance. *Note: May include subcodes. If contacting Primus Team, provide both code and subcode (if present).* | | 50003 | The client encountered an unexpected error. Please try again later. | | 50004 | The client did not start correctly. Please try again later. | | 50006 | Algorithm server not started. Please try again later. | | 50009 | Algorithm service timed out. Please try again later. | | 50011 | Unsupported TLS version. Contact Primus Team for assistance. | | 99999 | Undefined error. Please try again later. | ### 3. Account & Subscription Errors | Error Code | Situation | | ---------- | ---------------------- | | -1002001 | Invalid app ID. | | -1002002 | Invalid app secret. | | -1002003 | Trial quota exhausted. | | -1002004 | Subscription expired. | | -1002005 | Quota exhausted. | Please contact our [Community](https://t.me/primuslabs) for assistance in resolving the issues. --- ## Handling Multiple URLs ![image](../pics/Banner-2.png) ## 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. The *zktls-js-sdk* can be configured to support multiple URLs as well. This feature is available upon request; please contact the Primus team. ## The Usage in 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. ```javascript 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. ```javascript // 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. ```javascript 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' ] } ``` --- ## Overview ![image](../../pics/Banner-2.png) ## Overview The Enterprise Solutions of Primus zkTLS protocol are compatible with multiple blockchains. We provide smart contracts that can be deployed on different blockchains to verify data proofs generated through the Enterprise zkTLS SDKs. ### How to Interact 1. Your dApp requests proofs from the user using the zkTLS SDK in the front end. 2. Submit the proof to your smart contract. 3. Verify the proof on-chain via the smart contract. 4. Extract relevant data from the verified proof. 5. Use the extracted data in your business logic. ## Contract Code in GitHub We already published the smart contract code on GitHub, you can refer to it [here](https://github.com/primus-labs/zktls-contracts). ## Quick Start ### EVM Blockchains You can find example smart contracts for quick integration in the [Quick Start for EVM blockchains](overview.md#evm-blockchains). #### Mainnets ##### Linea | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xe6a7E3d26B898e96fA8bC00fFE6e51b25Dc24d6a | ##### BNB Chain | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xF3C20A5216d669C521ffe3724C1439aE0897aC33 | ##### Arbitrum | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x982Cef8d9F184566C2BeC48c4fb9b6e7B0b4A58B | ##### Scroll | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x06c3c00dc556d2493A661E6a929d3E17f5F097a4 | ##### opBNB | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xadd538D8C857072eFC29C4c05F574c68f94137eF | ##### Taiko | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Camp | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Base | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Xlayer | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Polygon | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x151cb5eD5D10A42B607bB172B27BDF6F884b9707 | #### Testnets ##### Sepolia | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Holesky | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xB3d8DDDc793F75a930313785e5d1612747093f25 | ##### BNB Chain Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xBc074EbE6D39A97Fb35726832300a950e2D94324 | ##### opBNB Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Taiko Hekla Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Scroll Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x5267380F548EEcA48E57Cd468a66F846e1dEfD6e | ##### Base Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Monad Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x1Ad7fD53206fDc3979C672C0466A1c48AF47B431 | ##### Pharos Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Sophon Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x7068da2522c3Ba1f24594ce20E7d7A8EF574E89f | ##### Unichain Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Xlayer Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Polygon Amoy Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ### Starknet You can find example smart contracts for quick integration in the [Quick Start for Starknet](quickstart.md#straknet-blockchains). ##### Starknet Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x00f24a364a932e6eeb8b7a9ed6d2337baaa78dcffa3a6d54e5e1b6c1c227deaa | ### SUI #### Mainnet | ID | Address | | -------- | ------------------------------------------ | | Package ID | 0xcbe9ca8cee83ee454cbc114b8f9825b49ed945f89e6ef4f26a07417a10525f42 | | Object ID | 0x08edfc73afa9ce6b5ac3211c5dcfe52837325fedce491f06812aece0ce21d0fd | #### Testnet | ID | Address | | -------- | ------------------------------------------ | | Package ID | 0x16af016d8516f0d0a64f38786b0cbdb7687032415b8995e5487d0b2e3e0f67f2 | | Object ID | 0x45470ee02c709409e9debd73320df48fc77a7e7ac9f891bf5a80cf7ec0fd37ad | If you have further needs for other blockchains, please contact us through our [Community](https://discord.com/invite/pdrNxRrApX) for support. --- ## Quick Start ![image](../../pics/Banner-2.png) ## EVM Blockchains This section walks you through deploying and integrating a Primus contract into your Solidity project. ### Install the Contract When setting up your smart contract project, you need to pull out the smart contract library first. - Using Hardhat: `npm install @primuslabs/zktls-contracts` - Using Foundry: `forge install primus-labs/zktls-contracts` ### Deploy a Smart Contract Deploy the following contract to any EVM-compatible network of your choice. For this walkthrough, we'll use Ethereum as an example. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // if you are using foundry, you can use the following conf: // you can edit import information like this in your local project remappings.txt: // @primuslabs/zktls-contracts=lib/zktls-contracts/ import { IPrimusZKTLS, Attestation } from "@primuslabs/zktls-contracts/src/IPrimusZKTLS.sol"; contract AttestorTest { address public primusAddress; constructor(address _primusAddress) { // Replace with the network you are deploying on primusAddress = _primusAddress; } function verifySignature(Attestation calldata attestation) public view returns(bool) { IPrimusZKTLS(primusAddress).verifyAttestation(attestation); // Business logic checks, such as attestation content and timestamp checks // do your own business logic return true; } } ``` ### On-chain Interactions The following code helps developers interact with the [Test example](../zk-tls-sdk/test.md) or [Production example](../zk-tls-sdk/production.md) contracts on-chain. This can be done using the zkTLS SDK after completing the smart contract development and deployment. ```javascript .... .... //start attestation process const attestation = await primusZKTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // Do your own business logic // Interacting with Smart Contracts // Set contract address and ABI const contractData = {"YOUR_CONTRACT_ABI_JSON_DATA"}; const abi = contractData.abi; const contractAddress = "YOUR_CONTRACT_ADDRESS_YOU_DEPLOYED"; // Use ethers.js connect to the smart contract const provider = new ethers.providers.JsonRpcProvider("YOUR_RPC_URL"); const contract = new ethers.Contract(contractAddress, abi, provider); try { // Call verifyAttestation func const tx = await contract.verifySignature(attestation); console.log("Transaction:", tx); } catch (error) { console.error("Error in verifyAttestation:", error); } } else { //not the primus sign, error business logic } ``` ## Straknet Blockchains This section walks you through deploying and integrating a Primus contract into your cairo project. ### Install the Contract When setting up your smart contract project, you need to reference the Primus contract library first. Make the following configuration in the Scarb.toml file. ``` [dependencies] primus_zktls = { git = "https://github.com/primus-labs/zktls-starknet-contracts.git" } ``` ### Deploy a Smart Contract Deploy the following contract to Starknet. For this walkthrough. ```rust use primus_zktls::IPrimusZKTLS::Attestation; #[starknet::interface] pub trait IAttestorTest { fn verifySignature(self: @TState, attestation: Attestation) -> bool; } #[starknet::contract] mod AttestorTest { use primus_zktls::IPrimusZKTLS::{ Attestation, IPrimusZKTLSDispatcher, IPrimusZKTLSDispatcherTrait, }; use starknet::ContractAddress; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { address: ContractAddress, } #[constructor] fn constructor(ref self: ContractState, _primusAddress: ContractAddress) { // Replace with the network you are deploying on self.address.write(_primusAddress); } #[abi(embed_v0)] impl IAttestorTest of super::IAttestorTest { fn verifySignature(self: @ContractState, attestation: Attestation) -> bool { IPrimusZKTLSDispatcher { contract_address: self.address.read() } .verifyAttestation(attestation); // Business logic checks, such as attestation content and timestamp checks // do your own business logic return true; } } } ``` ### On-chain Interactions The following code helps developers interact with the [Test example](../zk-tls-sdk/test.md) or [Production example](../zk-tls-sdk/production.md) contracts on-chain. This can be done using the zkTLS SDK after completing the smart contract development and deployment. ```javascript .... .... //start attestation process const attestation = await primusZKTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // Do your own business logic // Interacting with Smart Contracts // Set contract address and ABI // Use starknet.js connect to the cairo contract const account = YOUR_ACCOUNT_OBJECT; const rpcUrl = "YOUR_RPC_NODE_URL"; const contractAddress = "YOUR_CONTRACT_ADDRESS_YOU_DEPLOYED"; const provider = new RpcProvider({ nodeUrl: rpcUrl }); const compiledContract = await provider.getClassAt(contractAddress); const abi = compiledContract.abi; const contract = new Contract(abi, contractAddress, provider); contract.connect(account); try { // Call verifyAttestation func // hexStringToByteArray is to convert hex string signature to byte array attestation.signatures[0] = hexStringToByteArray(attestation.signatures[0]); const tx = await contract.verifySignature(attestation); console.log("Transaction:", tx); } catch (error) { console.error("Error in verifyAttestation:", error); } } else { //not the primus sign, error business logic } ``` --- ## zkTLS Operations ![image](../pics/Banner-2.png) ## The Issue of Handling Private Data Traditional zkTLS algorithms provide data authenticity for applications. In this model, the zkTLS client ultimately receives an attestation from the attestor, where the embedded raw data and its corresponding signature together prove that a zkTLS session was executed correctly and successfully verified by the attestor. In many scenarios, offering the raw data is not considered as a good option if privacy is preferred. Handling the data computation within the attestation is a proper approach. Primus SDKs offers zkTLS operations to further adapt to the privacy-preserving applications. ## Supported zkTLS Operations Using comparison operations expressed as boolean conditions within the zkTLS attestation is an effective way to handle private data securely. During attestation generation, various comparison operators can be applied to specific data fields. Each comparison produces a boolean result—true or false—indicating whether the condition is satisfied. The supported comparison operators within Primus SDKs include: * '**>**' (greater than): verifies if the data item is greater than a target value * '**=**' (greater than or equal to): verifies if the data item is greater than or equal to a target value * '**", value: "YOUR_CUSTOM_TARGET_DATA_VALUE", }, ], ]; request.setAttConditions(attConditions); ``` ## Comparison with DVC Pattern zkTLS operations natively support performing data computations directly over the attestation. In contrast, the DVC (Data Verification and Computation) pattern leverages a zkVM to shift the computation into a zkVM circuit. While zkTLS operations offer a level of privacy comparable to DVC, they provide less public verifiability and trustlessness, since the output of a zkVM circuit, namely a SNARK proof, can be publicly verified on-chain. Even so, zkTLS remains an efficient and architecturally simple approach for enabling application-level privacy. --- ## Code Example ![image](../../pics/Banner-2.png) ## Test Example The appSecret from Primus Developer Hub needs to sign the proof request parameters. For security reasons, appSecret cannot be configured on the Page side. The Test Example configures appSecret in the Page code to better illustrate the process. This Test Example guide will walk you through the fundamental steps to integrate Primus's zkTLS Page Core SDK and complete a basic data verification process through your Page. You can learn about the integration process through this simple [demo](https://github.com/primus-labs/zktls-demo/blob/main/page-core-sdk-example/src/testprimus.js). ### Implementation ```javascript import { PrimusPageCoreTLS } from "@primuslabs/zktls-page-core-sdk" async function primusProofTest() { // Initialize parameters, the init function is recommended to be called when the program is initialized. const appId = "PRIMUS_APP_ID"; const appSecret= "PRIMUS_APP_SECRET"; const zkTLS = new PrimusPageCoreTLS(); const initResult = await zkTLS.init(appId, appSecret); console.log("primusProof initResult=", initResult); // Set request and responseResolves. const request ={ url: "YOUR_CUSTOM_URL", // Request endpoint. method: "REQUEST_METHOD", // Request method. header: {}, // Request headers. body: "" // Request body. }; // The responseResolves is the response structure of the url. // For example the response of the url is: {"data":[{ ..."instFamily": "","instType":"SPOT",...}]}. const responseResolves = [ { keyName: 'CUSTOM_KEY_NAME', // According to the response keyname, such as: instType. parsePath: 'CUSTOM_PARSE_PATH', // According to the response parsePath, such as: $.data[0].instType. } ]; // Generate attestation request. const generateRequest = zkTLS.generateRequestParams(request, responseResolves); // Set zkTLS mode, default is proxy model. (This is optional) generateRequest.setAttMode({ algorithmType: "proxytls" }); // Transfer request object to string. const generateRequestStr = generateRequest.toJsonString(); // Sign request. const signedRequestStr = await zkTLS.sign(generateRequestStr); // Start attestation process. const attestation = await zkTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); const verifyResult = zkTLS.verifyAttestation(attestation); console.log("verifyResult=", verifyResult); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // do your own business logic. } else { // If failed, define your own logic. } } ``` ## Production Example The Production Example and Test Example processes are the same. The difference is that the appSecret is stored on your server, and when signing the attestation request parameters, the parameters are passed to your server, which signs them and then passes them to the extension. ### zkTLS Models We offer two modes in various user scenarios: 1. proxytls 2. mpctls ```javascript // Set zkTLS mode, default is proxy model. generateRequest.setAttMode({ algorithmType: "proxytls", }); ``` ### Extra Data Developers can include custom additional parameters as auxiliary data when submitting an attestation request. These parameters will be returned alongside the proof results. For example, developers can pass the user's ID or other business-related parameters. ```javascript // Set additionParams. const additionParams = JSON.stringify({ YOUR_CUSTOM_KEY: "YOUR_CUSTOM_VALUE", YOUR_CUSTOM_KEY2: "YOUR_CUSTOM_VALUE2", }); generateRequest.setAdditionParams(additionParams); ``` ### Frontend Implementation Extension does not require appSecret parameter to initialize SDK. ```javascript import { PrimusPageCoreTLS } from "@primuslabs/zktls-page-core-sdk" async function primusProofTest() { // Initialize parameters, the init function is recommended to be called when the program is initialized. const appId = "PRIMUS_APP_ID"; const zkTLS = new PrimusPageCoreTLS(); const initResult = await zkTLS.init(appId); console.log("primusProof initResult=", initResult); // Set request and responseResolves. const request ={ url: "YOUR_CUSTOM_URL", // Request endpoint. method: "REQUEST_METHOD", // Request method. header: {}, // Request headers. body: "" // Request body. }; // The responseResolves is the response structure of the url. // For example the response of the url is: {"data":[{ ..."instFamily": "","instType":"SPOT",...}]}. const responseResolves = [ { keyName: 'CUSTOM_KEY_NAME', // According to the response keyname, such as: instType. parsePath: 'CUSTOM_PARSE_PATH', // According to the response parsePath, such as: $.data[0].instType. } ]; // Generate attestation request. const generateRequest = zkTLS.generateRequestParams(request, responseResolves); // Set zkTLS mode, default is proxy model. (This is optional) generateRequest.setAttMode({ algorithmType: "proxytls" }); // Transfer request object to string. const generateRequestStr = generateRequest.toJsonString(); // Get signed resopnse from backend. const response = await fetch(`http://YOUR_URL:PORT?YOUR_CUSTOM_PARAMETER=${encodeURIComponent(generateRequestStr)}`); const responseJson = await response.json(); const signedRequestStr = responseJson.signResult; // Start attestation process. const attestation = await zkTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); const verifyResult = zkTLS.verifyAttestation(attestation); console.log("verifyResult=", verifyResult); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // do your own business logic. } else { // If failed, define your own logic. } } ``` ### Server Implementation The server is mainly responsible for obtaining the attestation parameters generated by the extension, and then using appSecret to sign the proof parameters. ```javascript const express = require("express"); const cors = require("cors"); const { PrimusPageCoreTLS } = require("@primuslabs/zktls-page-core-sdk"); const app = express(); const port = YOUR_PORT; // Just for test, developers can modify it. app.use(cors()); // Listen to the client's signature request and sign the attestation request. app.get("/primus/sign", async (req, res) => { const appId = "YOUR_APPID"; const appSecret = "YOUR_SECRET"; // Create a PrimusZKTLS object. const zkTLS = new PrimusPageCoreTLS(); // Set appId and appSecret through the initialization function. await zkTLS.init(appId, appSecret); // Sign the attestation request. const signParams = decodeURIComponent(req.query.signParams); console.log("signParams=", signParams); const signResult = await zkTLS.sign(signParams); console.log("signResult=", signResult); // Return signed result. res.json({ signResult }); }); app.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); }); ``` --- ## Installation ![image](../../pics/Banner-2.png) ## Installation We will go through the developer flow for the installation and usage of page core sdk. ### Installation Steps Open your terminal and navigate to your project directory. Then run one of the following commands: - Using npm: ```text npm install --save @primuslabs/zktls-page-core-sdk ``` - Using yarn: ```text yarn add --save @primuslabs/zktls-page-core-sdk ``` ### Importing the SDK After installation, you can import the SDK in your JavaScript or TypeScript files. Here's how: ```javascript import { PrimusPageCoreTLS } from "@primuslabs/zktls-page-core-sdk" ``` ## Project Config The Primus Page Core SDK algorithm must be run in a separate js tag and must support SharedArrayBuffer, so the following configuration is required. ### vite.config.js When the page is compiled, copy the 4 files directly to the extension build directory. `vite.config.js` needs to add the following configuration. You can refer to [demo vite.config.js](https://github.com/primus-labs/zktls-demo/blob/main/page-core-sdk-example/vite.config.js). ```javascript export default defineConfig({ plugins: [ react(), viteStaticCopy({ targets: [ { src: 'node_modules/@primuslabs/zktls-page-core-sdk/dist/algorithm/client_plugin.wasm', dest: './' }, { src: 'node_modules/@primuslabs/zktls-page-core-sdk/dist/algorithm/client_plugin.worker.js', dest: './' }, { src: 'node_modules/@primuslabs/zktls-page-core-sdk/dist/algorithm/client_plugin.js', dest: './' }, { src: 'node_modules/@primuslabs/zktls-page-core-sdk/dist/algorithm/primus_zk.js', dest: './' } ] }) ], server: { headers: { // to support SharedArrayBuffer 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp' } }, optimizeDeps: { esbuildOptions: { // Enable esbuild polyfill plugins plugins: [ NodeModulesPolyfillPlugin() ] }, include: ['react', 'react-dom'], force: true, }, }) ``` ### Index html You need to import two js files in your index html. ```html ...... ...... ``` --- ## Introduction ![image](../../pics/Banner-2.png) ## Overview The [**Primus page core SDK**](https://github.com/primus-labs/zktls-page-core-sdk) is a wrapped zkTLS algorithm, designed for developers who want to build applications **without relying on the Primus Extension**. This SDK allows web pages to directly invoke the Primus zkTLS algorithm interface and generate zkTLS attestations (proofs) by interacting with a Primus Attestor. The differences of page core SDK with other SDKs are demonstrated in this [figure](../../build/overview.md#how-to-choose-the-correct-primus-sdk). While the Primus Page Core SDK streamlines the user experience by eliminating the dependency on the Primus Extension, the resulting web application still needs user credentials to access the underlying data source, as the zkTLS protocol is initiated from the client side. ## How it Works Here's a simplified flow of how the Primus Page Core SDK works on your project: **1. Create Project:** Create a project on the [Primus Developer Hub](https://dev.primuslabs.xyz/) to obtain a paired appID and appSecret, then configure them in your project. **2. Configure Verification Parameters:** Ensure that two key parameters, including the request parameters and response data paths, are configured correctly. Refer to the Test Example for guidance. **3. Execute zkTLS Protocol:** Invoke the zkTLS protocol to initiate the data verification process. **4. Verify Data Verification Result:** Your Page retrieves the verification result from the Page Core SDK and validates Primus' signature to ensure trustworthiness. **5. Execute Business Logic:** Based on the verification result, your page executes the relevant business logic, such as submitting the proof on-chain or triggering other operations. --- ## Error Code ![image](../../pics/Banner-2.png) ## Error Code We have defined some error codes in the SDK. When an error occurs during the data verification process, you can refer to the following list for troubleshooting. ### 1. General Errors | Error Code | Situation | | ---------- | --------------------------------------------------------------------------------- | | 00000 | Operation too frequent. Please try again later. | | 00001 | Algorithm startup exception. | | 00002 | The verification process timed out. | | 00003 | A verification process is in progress. Please try again later. | | 00004 | The user closes or cancels the verification process. | | 00005 | Wrong SDK parameters. | | 00012 | Invalid Template ID. | | 00013 | Target data missing. Please check that the JSON path of the data in the response from the request URL matches your template. | | 00104 | Not met the verification requirements. | | -1002001 | Invalid App ID. | | -1002002 | Invalid App Secret. | ### 2. zkTLS Related Errors | Error Code | Situation | | ------------- | ----------------------------------------------------------------------------------------------------------- | | 10001 ~ 10004 | Unstable internet connection. Please try again. | | 20001 | An internal error occurred. | | 20003 | Invalid algorithm parameters. | | 20005 | An internal error occurred. | | 30001 | Response error. Please try again. | | 30002 | Response check error. | | 30004 | Response parse error. | | 40002 | SSL certificate error. | | 50001 | An internal error occurred. | | 50003 | The client encountered an unexpected error. | | 50004 | The client not started. Please try again. | | 50006 | The algorithm server not started. Please try again. | | 50007 | Algorithm execution issues. | | 50008 | Abnormal execution results. | | 50009 | Algorithm service timed out. | | 50010 | Compatibility issues during algorithm execution. | | 50011 | Unsupported TLS version. | | 99999 | Undefined error. | Please contact our [Community](https://discord.com/invite/pdrNxRrApX) for assistance in resolving the issues. --- ## Example&Parameters ![image](../../pics/Banner-2.png) ## Data Verification Capabilities Example In this initial version, the data source URL, attestation data fields, and supported blockchains are pre-configured. **A future developer platform will allow customization.** ## Data Verification Capabilities ### 1.Attestable Details #### (1)Internet Data | Data Sources | Attestation Data Fields | Input Value | Attestation Result | | --- | --- | --- | --- | | [https://www.binance.com](https://www.binance.com/) | Asset balance in the Spot account| USD value, numeric, minimum value of 0.000001, restricted to a 6-decimal-place number | if the "attestation content" is greater than "input value" | | | Token holding in the Spot account | Token name, alphabet | if the "input value" is equivalent to more than USD 0.1 | | | Spot 30-day trade volume | USD value, numeric, minimum value of 0.000001, restricted to a 6-decimal-place number |if the "attestation content" is greater than "input value" | | | KYC Status | N/A | if the "attestation content" passed basic KYC verification | | | Account ownership| N/A | if the "attestation content" owns the associated account | | [https://www.okx.com](https://www.okx.com/) |Total asset balance | USD value, numeric, minimum value of 0.000001, restricted to a 6-decimal-place number | if the "attestation content" is greater than "input value" | | | Token holding | Token name, alphabet | if the "input value" is equivalent to more than USD 0.1 | | | Spot 30-day trade volume | USD value, numeric, minimum value of 0.000001, restricted to a 6-decimal-place number | if the "attestation content" is greater than "input value" | | | KYC Status | N/A | if the "attestation content" passed basic KYC verification | | [https://www.tiktok.com](https://www.tiktok.com/) | Account ownership | N/A | if the "attestation content" owns the associated account| | [https://www.x.com](https://www.x.com/) | Account ownership | N/A | if the "attestation content" owns the associated account | | | Social connections | Followers number, numeric, minimum value of 0 | value of 0 if the "attestation content" is greater than "input value" | #### (2)Web3 Data Integrate the [Brevis'](https://docs.brevis.network/) SDK to enable on-chain transaction proof, allowing verification of whether a user has had on-chain transactions on the BNB Chain since July 2024. ### 2.Supported Blockchains For the attestation contract, we currently deployed EAS and Verax attestation schemas to the following blockchains: - Linea - BNB Chain - opBNB - Arbitrum - Scroll If you have further needs for other blockchains, please contact us through our [community](https://discord.com/invite/pdrNxRrApX) for support. ------------------------------------------------------------------------------ ### ## Parameters Details ### 1. chainID (number) The ID of the blockchain to which you want users to submit their proof. ``` console.log(sdkInstance.supportedChainList); // text: 'BlockChainName', value: chainID // Output: [ // {text: 'Linea', value: 59144 }, // {text: 'BNB Chain', value: 56 }, // {text: 'opBNB', value: 204 }, // {text: 'Arbitrum', value: 42161 }, // {text: 'Scroll', value: 534352 }, // {text: 'Sepolia', value: 11155111 }, // {text: 'BNB Testnet', value: 97 }, // {text: 'opBNB Testnet', value: 5611 }, // {text: 'Scroll Sepolia', value: 534351 }, // ] ``` :::note To test your integration and business workflow, simply input the chainID parameter using one of the four test networks we support: Sepolia, BSC Testnet, opBNB Testnet, and Scroll Sepolia. ::: ### 2.walletAddress (string) The wallet address of the user. This address will be used as an index for queries on the blockchain. ### 3.attestationTypeID (string) We have assigned different IDs to each attestation type, which can be transmitted to initialize the associated data verification process. ``` console.log(sdkInstance.supportedAttestationTypeList); // text: 'A function of an application.', value: 'attestationTypeID' // Output: [ // {text: 'binance kyc status', value: '1' }, // {text: 'binance account ownership', value: '2' }, // {text: 'x account ownership', value: '3' }, // {text: 'okx kyc status', value: '4' }, // {text: 'tiktok account ownership', value: '6' }, // {text: 'binance assets balance', value: '9' }, // {text: 'binance token holding', value: '10' }, // {text: 'okx assets balance', value: '11' }, // {text: 'okx token holding', value: '12' }, // {text: 'X social connections', value: '15' }, // {text: 'binance spot 30d trade vol', value: '16' }, // {text: 'okx spot 30d trade vol', value: '17' }, // {text: 'On-chain transactions on BNB Chain since 2024 July', value: '101' }, // ] ``` ### 4.attestationParameters (array) #### 4.1 For the attestationTypeID **1, 2, 3, 4, and 6**, you need to transmit a default value [] in attestationParameters, like this: ~~~ { chainID: 56, walletAddress: '0x', attestationTypeID: '1', attestationParameters: [] } ~~~ #### 4.2 For attestationTypeID **9, 10, 11, 12, 15, 16, 17, and 101**, you need to transmit with different inputs. - (1)For attestationTypeID 9 & 11 The attestationParameters should include a USD value (numeric), with a minimum value of 0.000001 and restricted to a 6-decimal-place. If the attestationParameters is set to `['100']`, it will complete a data verification process to verify if the user's **asset balance is greater than USD 100**. ~~~ { chainID: 56, walletAddress: '0x', attestationTypeID: '11', attestationParameters: ['100'], } ~~~ - (2)For attestationTypeID 10 & 12 The attestationParameters should include a token name (alphabet). If the attestationParameters is set to `['USDT']`, it will complete a data verification process to verify if the user holds **USDT equivalent to more than USD 0.1**. ~~~ { chainID: 56, walletAddress: '0x', attestationTypeID: '10', attestationParameters: ['USDT'], } ~~~ - (3)For attestationTypeID 15 The attestationParameters should include a follower number (numeric), with a minimum value of 0. If the attestationParameters is set to `['10']`, it will complete a data verification process to verify if the user has **more than 10 X followers**. ``` { chainID: 56, walletAddress: '0x', attestationTypeID: '15', attestationParameters: ['10'], } ``` - (4)For attestationTypeID 16 & 17 The attestationParameters should include a USD value (numeric), with a minimum value of 0.000001 and restricted to a 6-decimal-place. If the attestationParameters is set to ['500'], it will complete a data verification process to verify if the user's **spot 30-day trade volume is greater than USD 500**. ``` { chainID: 56, walletAddress: '0x', attestationTypeID: '16', attestationParameters: ['500'], } ``` - (5)For attestationTypeID 101 This attestation integrates the [Brevis'](https://docs.brevis.network/) SDK to enable on-chain transaction proof, allowing verification of whether a user has conducted on-chain transactions on the BNB Chain since July 2024. The attestationParameters should include a signature from the user’s wallet address, which needs to be attested to confirm ownership of the address, along with a timestamp indicating the time of the signature. **The input should follow this order: first, ‘user signature’; second, ‘timestamp’**. ``` { chainID: 56, walletAddress: '0x', attestationTypeID: '101', attestationParameters: ['0xxx....', '1728546495272'], } ``` :::note In order to confirm that the user truly owns the address to be attested, you must verify that the transmitted ‘user signature’ was signed from that address. The verification method is: ~~~ import { ethers } from "ethers"; const connectedAddress = '0x' const timestamp = +new Date() + ""; // '1728546495272' const provider = new ethers.providers.Web3Provider(window.ethereum); const typedData = { types: { EIP712Domain: [{ name: "name", type: "string" }], Request: [ { name: "desc", type: "string" }, { name: "address", type: "string" }, { name: "timestamp", type: "string" }, ], }, primaryType: "Request", domain: { name: "PADO Labs", }, message: { desc: "PADO Labs", address: connectedAddress, timestamp, }, }; const userSignature = await provider.send("eth_signTypedData_v4", [ connectedAddress, typedData, ]); console.log("userSignature", userSignature); // 0xxx.... ~~~ ::: --- ## Installation ![image](../../pics/Banner-2.png) ## Installing the Primus zkTLS-JS-SDK Welcome to the first step in integrating Primus zkTLS-JS-SDK into your project. This guide will walk you through the installation process and help you get started quickly. :::note **Free Tier & Quota:** Each **appID** is provisioned with **100 free Proof generations**. To increase your quota, set up a monthly subscription, or request custom enterprise features, please [contact our team](https://t.me/primuslabs). ::: ### Prerequisites Before you begin, make sure you have: - Node.js(version 18 or later)installed on your system - npm (usually comes with Node.js) or yarn as your package manager ### Installation Steps #### 1. Install the SDK Open your terminal and navigate to your project directory. Then run one of the following commands: - Using npm: ``` npm install --save @primuslabs/zktls-js-sdk ``` - Using yarn: ``` yarn add --save @primuslabs/zktls-js-sdk ``` This command will download and install the Primus zkTLS SDK and its dependencies into your project. #### 2. Verify Installation To ensure the SDK was installed correctly, you can check your `package.json` file. You should see `@primuslabs/zktls-js-sdk` listed in the `dependencies` section. ### Importing the SDK After installation, you can import the SDK in your JavaScript or TypeScript files. Here's how: ```javascript import { PrimusZKTLS } from "@primuslabs/zktls-js-sdk"; ``` ### Next Steps Congratulations! You've successfully installed the Primus zkTLS-JS-SDK. Here's what you can do next: 1. **Quick Start**: Explore our [Test Example](../zk-tls-sdk/test.md) to quickly experience the project in action. 2. **Real-World Usage**: Check out the [Production Example](../zk-tls-sdk/production.md) to learn how to use the SDK in a real-world application and create your first proof request. If you need further support, feel free to reach out through our [community on Telegram](https://t.me/primuslabs). --- ## Introduction ![image](../../pics/Banner-2.png) :::note This section covers **enterprise integration** using Primus’ proprietary Attestor for zkTLS applications. For development on the Primus Network, refer [here](../../build/overview.md). ::: ## Overview When integrating data verification solutions with your DApps, especially **web-based DApps**, you can utilize the **Primus zkTLS-JS-SDK**. Note in this type of integration, primus extension is required to enable an user side end-to-end attestation creation. If you prefer a non-extension mode to create a dapp, you can refer to the [part](../page-sdk/overview.md) and integrate with Primus Page Sdk. For server-side integration of zkTLS capabilities, please refer to the [Backend Integration](../core-sdk/overview.md) guide. With the zkTLS-JS-SDK, you can verify any data from the internet, generate proofs, and enable on-chain verifications. To verify custom data from your users, follow these simple steps: - **Create a Template**: Use the [Primus Developer Hub](https://dev.primuslabs.xyz) to easily set up a data verification template. This template includes the target data items, allowing you to test the verification process. - **Create a Project**: Obtain a paired appID and appSecret, then configure them in your DApp to integrate the [zkTLS SDK](../zk-tls-sdk/test.md) and APIs. For more details on creating templates and setting up your project, refer to the [Developer Hub](../../build/developer-hub.md). ### How to Integrate Here's a simplified flow of how Primus zkTLS-JS-SDK integrates with a web-based DApp: **1. Create/Search Template:** Login to the [Primus Developer Hub](https://dev.primuslabs.xyz) to create or search for a Template containing the data you need to verify. This is a key step in integrating the SDK into your DApp. **2. Create Project:** Create a Project on the [Primus Developer Hub](https://dev.primuslabs.xyz) to obtain a paired appID and appSecret, which are required to use the SDK. **3. Configure Verification Parameters:** Ensure the SDK parameters are configured correctly. Refer to the [test example](../zk-tls-sdk/test.md) and the [production example](../zk-tls-sdk/production.md) for guidance. **4. Execute zkTLS Protocol:** Invoke the zkTLS protocol via your DApp to initiate the data verification process. **5. Verify Data Verification Result:** Your DApp retrieves the verification result from the SDK and validates Primus' signature to ensure trustworthiness. **6. Execute Business Logic:** Based on the verification result, your DApp executes the relevant business logic, such as submitting the proof on-chain or triggering other operations. ### Set Verification Patterns #### Verification Modes Primus zkTLS SDK supports two modes: the [Proxy TLS mode](../../primus-network/tech-intro#proxy-model) and the [MPC TLS mode](../../primus-network/tech-intro#mpc-model). You can specify the desired mode by setting the "algorithmType" parameter during SDK integration. #### Verification Logics For each data verification process, you can predefine the verification logic, such as whether the process returns plaintext or hashed text, or whether additional verification conditions need to be incorporated into the data verification process. Supported logics: - **Hashed result** By default, our zkTLS-JS-SDK retrieves a plaintext verification result. If, in some cases, you want to keep the user’s data private, a hashed verification result is preferred. In the hashed result case, a ‘SHA256’ hashed data item will be returned to your DApp. - **Conditions result** For more flexible verification requirements, several different comparison operators can be added to the data items during the verification process, and a true or false result will be returned based on the comparison. The comparison operators include: * '**>**' (greater than): verifies if the data item is greater than a target value * '**=**' (greater than or equal to): verifies if the data item is greater than or equal to a target value * '** ### Stay Connected Keep up with the latest Primus developments: - Star our [GitHub Repository](https://github.com/primus-labs/zktls-js-sdk) - Join our [Discord Community](https://discord.com/invite/pdrNxRrApX) --- ## Production Example ![image](../../pics/Banner-2.png) ## Production Example This guide will walk you through the fundamental steps to integrate Primus's zkTLS-JS-SDK and complete a basic data verification process through your application. You can learn about the integration process through this simple [demo](https://github.com/primus-labs/zktls-demo/tree/main/production-example). :::note Integration in a production environment requires proper server setup and configuration of specific SDK parameters. ::: ### Prerequisites Before you begin, ensure you have the following: - A paired appId and appSecret, along with a selected Template ID. These can be obtained from the [Primus Developer Hub](https://dev.primuslabs.xyz) - The SDK installed. For installation instructions, refer to the [Installation Guide](../zk-tls-sdk/install.md). ### Customized Parameters ```javascript // Generate attestation request. const request = primusZKTLS.generateRequestParams(attTemplateID, userAddress); ``` #### 1. Extra Data Developers can include custom additional parameters as auxiliary data when submitting an attestation request. These parameters will be returned alongside the proof results. For example, developers can pass the user's ID or other business-related parameters. ```javascript // Set additionParams. const additionParams = JSON.stringify({ YOUR_CUSTOM_KEY: "YOUR_CUSTOM_VALUE", YOUR_CUSTOM_KEY2: "YOUR_CUSTOM_VALUE2", }); request.setAdditionParams(additionParams); ``` #### 2. zkTLS Modes We offer two modes in various user scenarios: 1. proxytls 2. mpctls For more details about these two modes, you can refer to [Overview](../../primus-network/tech-intro.md) section. ```javascript // Set zkTLS mode, default is proxy mode. request.setAttMode({ algorithmType: "proxytls", }); ``` #### 3. Device Parameter If your application is intended for use only on PCs, you do not need to include this parameter. However, if your application also runs on mobile devices, you must include this parameter. It is used to detect the user’s device type, such as **Android, iPhone, or PC**. If you want to restrict usage to Android devices only, set the value to 'android'. ```javascript // Set the device parameter to detect the user’s device type when your application supports both PC and mobile. Currently, only Android devices are supported. iOS is coming soon. let platformDevice = "pc"; if (navigator.userAgent.toLocaleLowerCase().includes("android")) { platformDevice = "android"; } else if (navigator.userAgent.toLocaleLowerCase().includes("iphone")) { platformDevice = "ios"; } const initAttestaionResult = await primusZKTLS.init(appId, "", {platform: platformDevice}); ``` #### 4. Verification Logics By default, the zkTLS SDK retrieves a plaintext verification result. We offer two types of verification logic to accommodate different requirements: 1. Hashed result Setting example : ```javascript // Set Attestation conditions request.setAttConditions([ [ { field: 'YOUR_CUSTOM_DATA_FIELD', op: 'SHA256', }, ], ]); ``` 2. Conditions result Setting example : ```javascript // Set Attestation conditions request.setAttConditions([ [ { field: 'YOUR_CUSTOM_DATA_FIELD', op: '>', value: 'YOUR_CUSTOM_TARGET_DATA_VALUE', }, ], ]); ``` For more details about these two verification logics, you can refer to the [Verification Logics](../../enterprise/zk-tls-sdk/overview.md#verification-logics) section. ### Frontend Implementation :::note Integration in a production environment involves configuring some [customized parameters](../zk-tls-sdk/production#customized-parameters). The examples provide default configurations for these parameters, which can be adjusted to suit your specific requirements. ::: ```javascript import { PrimusZKTLS } from "@primuslabs/zktls-js-sdk"; // Initialize parameters, the init function is recommended to be called when the page is initialized. const primusZKTLS = new PrimusZKTLS(); const appId = "YOUR_APPID"; const initAttestaionResult = await primusZKTLS.init(appId); // Set the device parameter to detect the user’s device type when your application supports both PC and mobile. Currently, only Android devices are supported. iOS is coming soon. // let platformDevice = "pc"; // if (navigator.userAgent.toLocaleLowerCase().includes("android")) { // platformDevice = "android"; // } else if (navigator.userAgent.toLocaleLowerCase().includes("iphone")) { // platformDevice = "ios"; // } // const initAttestaionResult = await primusZKTLS.init(appId, "", {platform: platformDevice}); console.log("primusProof initAttestaionResult=", initAttestaionResult); export async function primusProof() { // Set TemplateID and user address. const attTemplateID = "YOUR_TEMPLATEID"; const userAddress = "YOUR_USER_ADDRESS"; // Generate attestation request. const request = primusZKTLS.generateRequestParams(attTemplateID, userAddress); // Set additionParams. (This is optional) const additionParams = JSON.stringify({ YOUR_CUSTOM_KEY: "YOUR_CUSTOM_VALUE", }); request.setAdditionParams(additionParams); // Set zkTLS mode, default is proxy mode. (This is optional) const workMode = "proxytls"; request.setAttMode({ algorithmType: workMode, }); // Set attestation conditions. (These are optional) // 1. Hashed result. // const attConditions = [ // [ // { // field:'YOUR_CUSTOM_DATA_FIELD', // op:'SHA256', // }, // ], // ]; // 2. Conditions result. //const attConditions = [ // [ // { // field: "YOUR_CUSTOM_DATA_FIELD", // op: ">", // value: "YOUR_CUSTOM_TARGET_DATA_VALUE", // }, // ], // ]; // request.setAttConditions(attConditions); // Transfer request object to string. const requestStr = request.toJsonString(); // Get signed resopnse from backend. const response = await fetch(`http://YOUR_URL:PORT?YOUR_CUSTOM_PARAMETER`); const responseJson = await response.json(); const signedRequestStr = responseJson.signResult; // Start attestation process. const attestation = await primusZKTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); // Verify siganture const verifyResult = await primusZKTLS.verifyAttestation(attestation); console.log("verifyResult=", verifyResult); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // do your own business logic. } else { // If failed, define your own logic. } } ``` ### Backend Implementation Here’s a basic example of how to configure and initialize the Primus zkTLS SDK on the backend: ```javascript const express = require("express"); const cors = require("cors"); const { PrimusZKTLS } = require("@primuslabs/zktls-js-sdk"); const app = express(); const port = YOUR_PORT; // Just for test, developers can modify it. app.use(cors()); // Listen to the client's signature request and sign the attestation request. app.get("/primus/sign", async (req, res) => { const appId = "YOUR_APPID"; const appSecret = "YOUR_SECRET"; // Create a PrimusZKTLS object. const primusZKTLS = new PrimusZKTLS(); // Set appId and appSecret through the initialization function. await primusZKTLS.init(appId, appSecret); // Sign the attestation request. console.log("signParams=", req.query.signParams); const signResult = await primusZKTLS.sign(req.query.signParams); console.log("signResult=", signResult); // Return signed result. res.json({ signResult }); }); app.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); }); ``` ### Understanding the Attestation Structure When a successful data verification process is completed, you will receive a zkTLS attestation (proof) from the attestor. For more information about the attestation structure, see the [section](../attestation-structure.md). ### Submit Attestation On-chain (optional) To submit the verified data result (proof) to the blockchain, you’ll need to invoke the appropriate smart contract method. For detailed instructions, please refer to the [onchain interactions](../onchain-interaction/overview.md). ### Error Codes We have defined several error codes in the SDK. If an error occurs during the data verification process, you can refer to the [error code list](../../build/misc/error-code.md) for troubleshooting. --- ## Quick Start ![image](../../pics/Banner-2.png) # Frontend Example: Integrating MPC-TLS SDK in a Application This guide will walk you through the fundamental steps to integrate Primus's proof verification system into your application. :::note _**We need to register your dApps' domain to maintain the whitelist for production usage. If you are only debugging locally, simply follow the steps below to complete the call.** For better tech support, please contact the Primus team through our **[community](https://discord.com/invite/pdrNxRrApX)**._ ::: ## 1. Prerequisites Before you begin, ensure you have: - Installed the SDK (see [Installation Guide](../zk-tls-sdk/install)) ### ## 2. InitAttestation To integrate zk-TLS SDK requires initialization ``` init(appId: string, appSecret?: string): Promise { this.appId = appId this.appSecret = appSecret if (appSecret) { this.isAppServer = true this.isInitialized = true return Promise.resolve(true) } else { this.isInstalled = !!window.primus if (this.isInstalled) { window.postMessage({ target: "padoExtension", origin: "padoZKAttestationJSSDK", name: "initAttestation", }); } else { const errorCode = '00006' return Promise.reject(new ZkAttestationError( errorCode )) } console.time('initAttestationCost') return new Promise((resolve, reject) => { const eventListener = (event: any) => { const { target, name, params } = event.data; if (target === "padoZKAttestationJSSDK") { if (name === "initAttestationRes") { console.log('sdk receive initAttestationRes', event.data) const { result, errorData, data } = params if (result) { this.isInitialized = params?.result if (data?.padoExtensionVersion) { this.padoExtensionVersion = data.padoExtensionVersion } console.timeEnd('initAttestationCost') window?.removeEventListener('message', eventListener); resolve(this.padoExtensionVersion); } else { window?.removeEventListener('message', eventListener); // console.log('sdk-initAttestationRes-errorData:',errorData) if (errorData) { const { code } = errorData reject(new ZkAttestationError(code)) } } } } } window.addEventListener("message", eventListener); }); } } ``` ### ## 3. Start zk-TLS process Note: You can call startAttestation only after the initAttestation method is called. Before starting the data verification process, a few parameters should be configured and transmitted to the MPC-TLS SDK. This configuration is required regardless of how you set up your users' operation steps in you dApp. The parameters should be configured in the following order: - 1.chainID (must) - 2.walletAddress (must) - 3.attestationTypeID (must) - 4.attestationParameters (must, according to different attestationTypeID) Parameters detail you can see: [Parameters details](../zk-tls-sdk/example#paramsDatails) ```javascript try { const startAttestaionResult = await sdkInstance.startAttestation({ chainID: 56, walletAddress: '0x', attestationTypeID: '9', attestationParameters: ['100'], }); console.log(startAttestaionResult); // Output: // { // eip712MessageRawDataWithSignature: // { // types: { // Attest: [ // { // name: "schema", // type: "bytes32", // }, // { // name: "recipient", // type: "address", // }, // { // name: "expirationTime", // type: "uint64", // }, // { // name: "revocable", // type: "bool", // }, // { // name: "refUID", // type: "bytes32", // }, // { // name: "data", // type: "bytes", // }, // { // name: "deadline", // type: "uint64", // }, // ], // }, // primaryType: "Attest", // message: { // schema: "0x", // recipient: "0x", // expirationTime: 0, // revocable: true, // data: "0x", // refUID: // "0x0000000000000000000000000000000000000000000000000000000000000000", // deadline: 0, // }, // domain: { // name: "xxx", // version: "xxx", // chainId: "xxx", // verifyingContract: "0x", // salt: null, // }, // uid: null, // signature: { // v: 28, // r: "0x", // s: "0x", // }, // } // }; console.log("Attest successfully!"); } catch (e) { alert(`Attest failed,code: ${e.code} ,message: ${e.message}`); } ``` ### ## 4. Verify attestation result After receiving the verified result, you need to verify whether the result is trustworthy. - **Parameters** - **startAttestationReturnParams:StartAttestationReturnParams** An object containing the properties of `eip712MessageRawDataWithSignature`, which is the return value of the `startAttestation` method. - **Return:boolean** Whether the signature is successfully verified. - **Example** ```javascript const verifyAttestationResult = sdkInstance.verifyAttestation( startAttestaionResult ); console.log(verifyAttestation); // Output: true ``` ### ## 5. Submit the verified data result (proof) to the blockchain You can only submit the proof to the chainID associated with the configuration in [3.Start MPC-TLS process](../zk-tls-sdk/quickstart#step3). - Parameters - **startAttestationReturnParams:StartAttestationReturnParams** An object containing the properties of `eip712MessageRawDataWithSignature`, which is the return value of the `startAttestation` method. - **wallet:any** The wallet object - **Return:string** Transaction details URL - **Example** ```javascript try { const sendToChainResult = sdkInstance.sendToChain( startAttestaionResult, window.ethereum ); console.log(sendToChainResult); // Output: https://bascan.io/attestation/0x console.log("SendToChain successfully!"); } catch (e) { alert(`SendToChain failed,code: ${e.code} ,message: ${e.message}`); } ``` ### ## 6.Check the submitted proof on-chain After completing the submission, you can find the on-chain details using the corresponding blockchain links below. ### 6.1 Mainnet - Linea Mainnet:[https://lineascan.build/](https://lineascan.build/) - BNB Chain:[https://bascan.io/](https://bascan.io/) - opBNB:[https://scan.sign.global/](https://scan.sign.global/) - Arbitrum:[https://arbitrum.easscan.org/](https://arbitrum.easscan.org/) - Scroll Mainnet:[https://scrollscan.com/](https://scrollscan.com/) ### 6.2 Testnet - Sepolia: [https://sepolia.easscan.org/](https://sepolia.easscan.org/) - BNBTestnet:[ https://testnet.bascan.io/]( https://testnet.bascan.io/) - opBNBTestnet: [https://testnet-scan.sign.global/](https://testnet-scan.sign.global/) - Scroll Sepolia: [https://sepolia.scrollscan.com/](https://sepolia.scrollscan.com/) ### ## Examples of the zkTLS SDK operations Here's a simple example demonstrating how to perform basic operations with the zkTLS SDK. ```javascript import MPCTLSJSSDK from "@padolabs/mpctls-js-sdk"; const sdkInstance = new MPCTLSJSSDK(); try { const initAttestaionResult = await sdkInstance.initAttestation( "yourdAppSymbol" ); // Initialize the SDK console.log(initAttestaionResult); //Output: 0.3.15 console.log(sdkInstance.supportedChainList); // View supported chains console.log(sdkInstance.supportedAttestationTypeList); // View supported attestation types // Generate attestation process const startAttestaionResult = await sdkInstance.startAttestation({ chainID: 56, // Select from the supported chain list walletAddress: "0x", // User's wallet address attestationTypeID: "9", // Select from the supported attestation types attestationParameters: ["100"], // Input the corresponding fields (if needed) according to the selected attestationTypeID }); // Verify attestation result const verifyAttestationResult = await sdkInstance.verifyAttestati(startAttestaionResult); // Upload Proof to Blockchain const sendToChainResult = await sdkInstance.sendToChain( startAttestaionResult, window.ethereum ); console.log("Generated Proof:", startAttestaionResult); console.log("Proof on Chain:", sendToChainResult); console.log("Is Proof Valid:", verifyAttestationResult); } catch (e) { alert(`Failed, code: ${e.code} , message: ${e.message}`); } ``` ---------------------------------------------------------------------- ### ## Error Codes We have defined some error codes in the SDK. When an error occurs during the data verification process, you can refer to the following list for troubleshooting. ### 1. General errors | Error Code | Situation | | ---------- | ----------------------------------------------------------------------------- | | 00001 | The zkTLS algorithm has not been initialized. Please restart the process. | | 00002 | The process did not respond within 5 minutes. | | 00003 | A data verification process is currently being generated. Please try again later. | | 00004 | The user closes or cancels the attestation process. | | 00005 | Wrong parameters! | | 00006 | No extension version 0.3.15 or above was detected as installed. | | 00007 | Insufficient wallet balance. | | 00008 | Failed to submit the proof on-chain. Or other errors in the Wallet operations. | | 00009 | Your dApp is not registered. Please contact the Primus team. | | 99999 | Undefined error. Contact the Primus team for further support | ### 2. Data source related errors | Error Code | Situation | | ---------- | ----------------------------------------------------------------- | | 00102 | Attestation requirements not met. Insufficient assets balance in Binance Spot Account. | | 00104 | Attestation requirements not met. | ### 3. zkTLS related errors | Error Code | Situation | | ------------- | ------------------------------------------------------------------------------------------------------- | | 10001 | The internet condition is not stable enough to complete the data verification flow. Please try again later. | | 10002 | The attestation process has been interrupted due to some unknown network error. Please try again later. | | 10003 | Can't connect attestation server due to unstable internet condition. Please try again later. | | 10004 | Can't connect data source server due to unstable internet condition. Please try again later. | | 20005 | Can't complete the attestation due to some workflow error. Please try again later. | | 30001 ~ 30004 | Can't complete the attestation flow due to response error. Please try again later. | | 50007 | Can't complete the attestation due to algorithm execution issues. | | 50008 | Can't complete the attestation due to abnormal execution results. | | 50009 | The algorithm service did not respond within 5 minutes. | | 50010 | Can't complete the attestation due to some compatibility issues. | | 50011 | Can't complete the attestation due to algorithm version issues. | For any other error codes not mentioned here, please contact our [community](https://discord.com/invite/pdrNxRrApX) for further support. --- ## Overview ![image](../../../pics/Banner-2.png) ## Overview The Primus zkTLS protocol is compatible with multiple blockchains. We provide smart contracts that can be deployed on different blockchains to verify data proofs generated by users through the zkTLS SDK. ### How to Interact 1. Your dApp requests proofs from the user using the zkTLS SDK in the front end. 2. Submit the proof to your smart contract. 3. Verify the proof on-chain via the smart contract. 4. Extract relevant data from the verified proof. 5. Use the extracted data in your business logic. ## Contract Code in GitHub We already published the smart contract code on GitHub, you can refer to it [here](https://github.com/primus-labs/zktls-contracts). ## Quick Start ### EVM Blockchains You can find example smart contracts for quick integration in the [Quick Start for EVM blockchains](quickstart.md#evm-blockchains). #### Mainnets ##### Linea | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xe6a7E3d26B898e96fA8bC00fFE6e51b25Dc24d6a | ##### BNB Chain | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xF24199D5D431bE869af3Da61162CbBb58C389324 | ##### Arbitrum | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x982Cef8d9F184566C2BeC48c4fb9b6e7B0b4A58B | ##### Scroll | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x06c3c00dc556d2493A661E6a929d3E17f5F097a4 | ##### opBNB | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xadd538D8C857072eFC29C4c05F574c68f94137eF | ##### Taiko | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Camp | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Base | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | #### Testnets ##### Sepolia | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Holesky | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xB3d8DDDc793F75a930313785e5d1612747093f25 | ##### BNB Chain Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xBc074EbE6D39A97Fb35726832300a950e2D94324 | ##### opBNB Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Taiko Hekla Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x3760aB354507a29a9F5c65A66C74353fd86393FA | ##### Scroll Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x5267380F548EEcA48E57Cd468a66F846e1dEfD6e | ##### Base Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Monad Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x1Ad7fD53206fDc3979C672C0466A1c48AF47B431 | ##### Pharos Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ##### Sophon Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x7068da2522c3Ba1f24594ce20E7d7A8EF574E89f | ##### Unichain Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ### Starknet You can find example smart contracts for quick integration in the [Quick Start for Starknet](quickstart.md#straknet-blockchains). ##### Starknet Sepolia Testnet | Contract | Address | | -------- | ------------------------------------------ | | Primus | 0x00f24a364a932e6eeb8b7a9ed6d2337baaa78dcffa3a6d54e5e1b6c1c227deaa | ### SUI #### Mainnet | ID | Address | | -------- | ------------------------------------------ | | Package ID | 0xcbe9ca8cee83ee454cbc114b8f9825b49ed945f89e6ef4f26a07417a10525f42 | | Object ID | 0x08edfc73afa9ce6b5ac3211c5dcfe52837325fedce491f06812aece0ce21d0fd | #### Testnet | ID | Address | | -------- | ------------------------------------------ | | Package ID | 0x16af016d8516f0d0a64f38786b0cbdb7687032415b8995e5487d0b2e3e0f67f2 | | Object ID | 0x45470ee02c709409e9debd73320df48fc77a7e7ac9f891bf5a80cf7ec0fd37ad | If you have further needs for other blockchains, please contact us through our [Community](https://discord.com/invite/pdrNxRrApX) for support. --- ## Quick Start ![image](../../../pics/Banner-2.png) ## EVM Blockchains This section walks you through deploying and integrating a Primus contract into your Solidity project. ### Install the Contract When setting up your smart contract project, you need to pull out the smart contract library first. - Using Hardhat: `npm install @primuslabs/zktls-contracts` - Using Foundry: `forge install primus-labs/zktls-contracts` ### Deploy a Smart Contract Deploy the following contract to any EVM-compatible network of your choice. For this walkthrough, we'll use Ethereum as an example. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // if you are using foundry, you can use the following conf: // you can edit import information like this in your local project remappings.txt: // @primuslabs/zktls-contracts=lib/zktls-contracts/ import { IPrimusZKTLS, Attestation } from "@primuslabs/zktls-contracts/src/IPrimusZKTLS.sol"; contract AttestorTest { address public primusAddress; constructor(address _primusAddress) { // Replace with the network you are deploying on primusAddress = _primusAddress; } function verifySignature(Attestation calldata attestation) public view returns(bool) { IPrimusZKTLS(primusAddress).verifyAttestation(attestation); // Business logic checks, such as attestation content and timestamp checks // do your own business logic return true; } } ``` ### On-chain Interactions The following code helps developers interact with the [Test example](../test.md) or [Production example](../production.md) contracts on-chain. This can be done using the zkTLS SDK after completing the smart contract development and deployment. ```javascript .... .... //start attestation process const attestation = await primusZKTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // Do your own business logic // Interacting with Smart Contracts // Set contract address and ABI const contractData = {"YOUR_CONTRACT_ABI_JSON_DATA"}; const abi = contractData.abi; const contractAddress = "YOUR_CONTRACT_ADDRESS_YOU_DEPLOYED"; // Use ethers.js connect to the smart contract const provider = new ethers.providers.JsonRpcProvider("YOUR_RPC_URL"); const contract = new ethers.Contract(contractAddress, abi, provider); try { // Call verifyAttestation func const tx = await contract.verifySignature(attestation); console.log("Transaction:", tx); } catch (error) { console.error("Error in verifyAttestation:", error); } } else { //not the primus sign, error business logic } ``` ## Straknet Blockchains This section walks you through deploying and integrating a Primus contract into your cairo project. ### Install the Contract When setting up your smart contract project, you need to reference the Primus contract library first. Make the following configuration in the Scarb.toml file. ``` [dependencies] primus_zktls = { git = "https://github.com/primus-labs/zktls-starknet-contracts.git" } ``` ### Deploy a Smart Contract Deploy the following contract to Starknet. For this walkthrough. ```rust use primus_zktls::IPrimusZKTLS::Attestation; #[starknet::interface] pub trait IAttestorTest { fn verifySignature(self: @TState, attestation: Attestation) -> bool; } #[starknet::contract] mod AttestorTest { use primus_zktls::IPrimusZKTLS::{ Attestation, IPrimusZKTLSDispatcher, IPrimusZKTLSDispatcherTrait, }; use starknet::ContractAddress; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { address: ContractAddress, } #[constructor] fn constructor(ref self: ContractState, _primusAddress: ContractAddress) { // Replace with the network you are deploying on self.address.write(_primusAddress); } #[abi(embed_v0)] impl IAttestorTest of super::IAttestorTest { fn verifySignature(self: @ContractState, attestation: Attestation) -> bool { IPrimusZKTLSDispatcher { contract_address: self.address.read() } .verifyAttestation(attestation); // Business logic checks, such as attestation content and timestamp checks // do your own business logic return true; } } } ``` ### On-chain Interactions The following code helps developers interact with the [Test example](../test.md) or [Production example](../production.md) contracts on-chain. This can be done using the zkTLS SDK after completing the smart contract development and deployment. ```javascript .... .... //start attestation process const attestation = await primusZKTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // Do your own business logic // Interacting with Smart Contracts // Set contract address and ABI // Use starknet.js connect to the cairo contract const account = YOUR_ACCOUNT_OBJECT; const rpcUrl = "YOUR_RPC_NODE_URL"; const contractAddress = "YOUR_CONTRACT_ADDRESS_YOU_DEPLOYED"; const provider = new RpcProvider({ nodeUrl: rpcUrl }); const compiledContract = await provider.getClassAt(contractAddress); const abi = compiledContract.abi; const contract = new Contract(abi, contractAddress, provider); contract.connect(account); try { // Call verifyAttestation func // hexStringToByteArray is to convert hex string signature to byte array attestation.signatures[0] = hexStringToByteArray(attestation.signatures[0]); const tx = await contract.verifySignature(attestation); console.log("Transaction:", tx); } catch (error) { console.error("Error in verifyAttestation:", error); } } else { //not the primus sign, error business logic } ``` --- ## Suport NetWork ![image](../../../pics/Banner-2.png) # Supported Networks ## Contract Address ### Mainnets #### Ethereum | Contract | Address | | -------- | ------- | | Primus | 0x0000 | #### Linea | Contract | Address | | -------- | ------- | | Primus | 0x0000 | #### BNB | Contract | Address | | -------- | ------- | | Primus | 0x0000 | #### Arbitrum | Contract | Address | | -------- | ------- | | Primus | 0x0000 | #### Scroll | Contract | Address | | -------- | ------- | | Primus | 0x0000 | ### Testnets #### sepolia | Contract | Address | | -------- | ------- | | Primus | 0x0000 | #### bsctestnet | Contract | Address | | -------- | ------- | | Primus | 0x0000 | #### opbnbtestnet | Contract | Address | | -------- | ------- | | Primus | 0x0000 | --- ## Test Example ![image](../../pics/Banner-2.png) ## Test Example This guide will walk you through the fundamental steps to integrate Primus's zkTLS-JS-SDK and complete a basic data verification process through your application. You can learn about the integration process through this simple [demo](https://github.com/primus-labs/zktls-demo/tree/main/test-example). :::note This example demonstrates how developers can create a frontend project and run Primus' data verification process locally for testing purposes. **We strongly recommend not using this method in a formal production environment.** For guidance on configuring a production environment, please refer to the [Production Example](../zk-tls-sdk/production.md) ::: ### Prerequisites Before you begin, make sure you have the following: - A paired appId and appSecret, along with a selected Template ID. These can be obtained from the [Primus Developer Hub](https://dev.primuslabs.xyz) - The SDK installed. For installation instructions, refer to the [Installation Guide](../zk-tls-sdk/install). ### Implementation Here’s a basic example of how to use Primus zkTLS-JS-SDK from the frontend. Note that this implementation is intended for testing purposes only. ```javascript import { PrimusZKTLS } from "@primuslabs/zktls-js-sdk" // Initialize parameters, the init function is recommended to be called when the page is initialized. const primusZKTLS = new PrimusZKTLS(); const appId = "YOUR_APPID"; const appSecret= "YOUR_SECRET"; // Just for testing, appSecret cannot be written in the front-end code const initAttestaionResult = await primusZKTLS.init(appId, appSecret); // Set the device parameter to detect the user’s device type when your application supports both PC and mobile. Currently, only Android devices are supported. iOS is coming soon. // let platformDevice = "pc"; // if (navigator.userAgent.toLocaleLowerCase().includes("android")) { // platformDevice = "android"; // } else if (navigator.userAgent.toLocaleLowerCase().includes("iphone")) { // platformDevice = "ios"; // } // const initAttestaionResult = await primusZKTLS.init(appId, appSecret, {platform: platformDevice}); console.log("primusProof initAttestaionResult=", initAttestaionResult); export async function primusProof() { // Set TemplateID and user address. const attTemplateID = "YOUR_TEMPLATEID"; const userAddress = "YOUR_USER_ADDRESS"; // Generate attestation request. const request = primusZKTLS.generateRequestParams(attTemplateID, userAddress); // Set zkTLS mode, default is proxy mode. (This is optional) const workMode = "proxytls"; request.setAttMode({ algorithmType: workMode, }); // Set attestation conditions. (These are optional) // 1. Hashed result. // const attConditions = [ // [ // { // field:'YOUR_CUSTOM_DATA_FIELD', // op:'SHA256', // }, // ], // ]; // 2. Conditions result. // const attConditions = [ // [ // { // field: "YOUR_CUSTOM_DATA_FIELD", // op: ">", // value: "YOUR_CUSTOM_TARGET_DATA_VALUE", // }, // ], // ]; // request.setAttConditions(attConditions); // Transfer request object to string. const requestStr = request.toJsonString(); // Sign request. const signedRequestStr = await primusZKTLS.sign(requestStr); // Start attestation process. const attestation = await primusZKTLS.startAttestation(signedRequestStr); console.log("attestation=", attestation); // Verify siganture. const verifyResult = await primusZKTLS.verifyAttestation(attestation) console.log("verifyResult=", verifyResult); if (verifyResult === true) { // Business logic checks, such as attestation content and timestamp checks // do your own business logic. } else { // If failed, define your own logic. } } ``` ### zkTLS Modes We offer two modes in various user scenarios: 1. proxytls 2. mpctls For more details about these two modes, you can refer to the [Overview](../../primus-network/tech-intro) section. ```javascript // Set zkTLS mode, default is proxy mode. primusZKTLS.setAttMode({ algorithmType: "proxytls", }); ``` ### Device Parameter If your application is intended for use only on PCs, you do not need to include this parameter. However, if your application also runs on mobile devices, you must include this parameter. It is used to detect the user’s device type, such as **Android, iPhone, or PC**. If you want to restrict usage to Android devices only, set the value to 'android'. ```javascript // Set the device parameter to detect the user’s device type when your application supports both PC and mobile. Currently, only Android devices are supported. iOS is coming soon. let platformDevice = "pc"; if (navigator.userAgent.toLocaleLowerCase().includes("android")) { platformDevice = "android"; } else if (navigator.userAgent.toLocaleLowerCase().includes("iphone")) { platformDevice = "ios"; } const initAttestaionResult = await primusZKTLS.init(appId, appSecret, {platform: platformDevice}); ``` ### Verification Logics By default, the zkTLS-JS-SDK retrieves a plaintext verification result. We offer two types of verification logic to accommodate different requirements: 1. Hashed result Setting example : ```javascript // Set Attestation conditions request.setAttConditions([ [ { field: 'YOUR_CUSTOM_DATA_FIELD', op: 'SHA256', }, ], ]); ``` 2. Conditions result Setting example : ```javascript // Set Attestation conditions request.setAttConditions([ [ { field: 'YOUR_CUSTOM_DATA_FIELD', op: '>', value: 'YOUR_CUSTOM_TARGET_DATA_VALUE', }, ], ]); ``` For more details about these two verification logics, you can refer to the [Verification Logics](../../enterprise/zk-tls-sdk/overview.md#verification-logics) section. ### Submit Attestation On-chain (optional) To submit the verified data result (proof) to the blockchain, you’ll need to invoke the appropriate smart contract method. For detailed instructions, please refer to the [onchain interactions](../onchain-interaction/overview). --- ## Workflows ![image](../../pics/Banner-2.png) # Primus Workflows ![avatar](./../../pics/extensionSDK/mpctls-sdk.png) **The [Primus Extension](https://chromewebstore.google.com/detail/pado/oeiomhmbaapihbilkfkhmlajkeegnjhe) is required to complete the zk-TLS process on the data source page. When using the zk-TLS SDK, prompt users in your dApp to install the latest version (above 0.3.15) of the Extension, as it is required.** **1. Create/Search Template:** Log in to the Primus developer console and create or search for an application template, which is a key step in app creation. **2. Create App:** Use the template to create an app, set its name, and describe the required information for integrating the Primus zkTLS SDK. **3. Configure Verification Parameters:** Ensure the SDK parameters are properly configured before starting the verification process. **4. Redirect to Data Source:** The dApp redirects the user to the data source page. After logging in, a pop-up window will appear in the top-right corner. **5. Start Verification Process:** The user clicks the "Start" button in the pop-up to initiate the verification process. If login is required, complete it first. **6. Execute zk-TLS Protocol:** The zk-TLS protocol completes the privacy-preserving verification during the process. **7. Verify Attestation Result:** The dApp retrieves the result from the SDK and verifies Primus' signature to ensure its trustworthiness. **8. Execute Business Logic:** Based on the verification result, the dApp performs the corresponding business logic, such as submitting the proof on-chain or other operations. --- ## FHE Fundamentals # FHE Fundamentals Fully Homomorphic Encryption (FHE) enables arbitrary computations to be performed directly on encrypted data without revealing the underlying plaintext. Unlike conventional encryption schemes, where data must be decrypted before processing, FHE preserves confidentiality throughout the entire computation lifecycle, making it a foundational technology for privacy-preserving computation. Key concepts in FHE include homomorphic addition and multiplication, bootstrapping, ciphertext noise management, programmable bootstrapping, and modern lattice-based cryptographic assumptions such as Learning With Errors (LWE). These concepts form the basis of most contemporary FHE systems and applications. For readers seeking a comprehensive introduction to FHE, including its mathematical foundations, historical evolution, major schemes, engineering challenges, and real-world applications, we recommend the Primus FHE101 tutorial: https://fhe101.primuslabs.xyz/en/ Interested readers may refer to the FHE101 documentation for a detailed treatment of the subject. --- ## Primus FHE # Primus FHE ## What is FHE? Fully Homomorphic Encryption (FHE) is a form of encryption that allows arbitrary computations to be performed directly on encrypted data, without ever decrypting it. The result of the computation remains encrypted and, when decrypted by the data owner, matches exactly what would have been obtained had the same operations been performed on the plaintext. This property removes the traditional trade-off between using data and protecting it: a party can outsource computation to an untrusted server, cloud, or network, and that party never needs to see the underlying data to process it correctly. The concept dates back to the late 1970s, but it remained a theoretical curiosity until Craig Gentry's 2009 breakthrough, which introduced the first construction supporting unlimited computation on ciphertexts. Since then, FHE schemes (such as BGV, BFV, CKKS, and TFHE) have matured significantly, with steady improvements in efficiency through techniques like bootstrapping, packing, and hardware acceleration. While FHE is still computationally heavier than working on plaintext, it has moved from a purely academic construct to a practical tool used in privacy-preserving machine learning, secure multi-party computation, and confidential data processing. In crypto, FHE lets smart contracts and off-chain compute networks operate directly on encrypted state, enabling use cases like confidential transactions, private DeFi logic, encrypted on-chain voting, and secure computation on sensitive financial or identity data. Because inputs, intermediate state, and outputs never need to be decrypted during processing, privacy is enforced by the cryptography itself rather than by trusting an operator or validator to behave honestly. ## Core Techniques of Primus FHE Primus FHE techniques focus on solving industrial problems and practical applications. In particular, Primus brings FHE to blockchains and smart contracts, enabling secure and private computation on sensitive data. The Primus team has dedicated itself to FHE research and development since 2023, working toward industrial-grade solutions that close the persistent gap between cryptographic theory and practical industry problems. ### FHETransform: Primus FHE Computation Framework The core technical product is **FHETransform**, a framework that powers privacy-preserving computation on EVM-compatible blockchains. It lets developers build confidential smart contracts, whose inputs, state, and outputs stay encrypted end to end, while keeping the decentralization, composability, and security guarantees of the underlying chain. ![FHETransform Architecture](../pics/fhe_arch.png) Conceptually, the architecture of privacy-preserving applications on FHETransform consists of three main components: * Privacy decentralized applications (dApps): Developers write standard smart contracts and use the Primus FHE toolchain to automatically transform them into confidential contracts with FHE support. * On-chain coordination layer: This layer consists of smart contracts deployed on the host blockchain. It performs symbolic execution by manipulating compact ciphertext handles, enforcing access control, coordinating decryption requests, and settling payments. It does not execute any computationally intensive cryptographic operations. * Off-chain execution layer: This layer consists of FHE nodes and the key management service (KMS). It performs the actual cryptographic computation, including encrypting user inputs, executing homomorphic operations over encrypted data, and decrypting results when authorized. The FHE keys are currently managed by the Key Management Service (KMS), including key generation and rotation, with the secret key securely isolated inside a Trusted Execution Environment (TEE). In the long term, the KMS will evolve into a threshold Multi-Party Computation (MPC) network, reducing the trust assumption from relying on a single trusted enclave to requiring only an honest threshold of participating nodes. For further details of FHETransform, readers can refer to the official [documentation](https://fhetransform.primuslabs.xyz). ### zkFHE: A Verifiable FHE Protocol In parallel, Primus is also researching and developing zkFHE, often referred to as *verifiable FHE (vFHE)* that combines the privacy guarantees of FHE with cryptographic proofs of computation correctness. Note zkFHE is not a straightforward combination of zero-knowledge proofs and fully homomoprhic encryption schemes together, but a special type of FHE schemes that support the verification of homomorphic computations. The motivation behind such a protocol is to ensure the correctness of outsourced computations over encrypted data. In practical settings, a computing node may behave maliciously by returning an incorrect computation result while still producing a ciphertext that can be successfully decrypted and treated as the computation result. Without additional verification mechanisms, the client has no reliable way to determine whether the computation was performed correctly or whether the result was arbitrarily fabricated. Traditional FHE schemes provide confidentiality but do not guarantee computational integrity. This lack of verifiability represents a significant limitation for many privacy-preserving applications, where both input data confidentiality and computation correctness are essential. ![zkFHE Flow](../pics/zkfhe_flow.png) zkFHE provides an ideal solution to this challenge. During homomorphic computation, a cryptographic proof is generated alongside the computation result. The client can then verify the proof to ensure that the computation was executed correctly and that the service provider has not tampered with or falsified the result. Primus team has designed a zkFHE protocol named "HasteBoots" in the [paper](https://eprint.iacr.org/2025/261) of Usenix Security 2026. The HasteBoots paper lays the foundation for practical zkFHE, but substantial work remains to transform this research into a scalable and production-ready solution. Addressing challenges in performance, proof generation, and system engineering will require continued innovation and long-term investment. Primus is committed to advancing this vision through ongoing research and development. --- ## Compliant Confidential Transactions ![image](../../pics/Banner-6.png) # Compliant Confidential Transactions ## The Core Tension Confidential transaction systems built on blockchains face a structural conflict: full transparency (the default in most chains) destroys financial privacy, while full opacity (as in many "privacy coin" designs) makes regulatory oversight impossible and invites abuse for money laundering or sanctions evasion. Fully Homomorphic Encryption (FHE) is attractive precisely because it does not force a binary choice. It allows balances and transfer amounts to remain encrypted on-chain while still permitting computation, verification, and, critically, selective decryption by authorized parties. This is what separates an FHE-based design from either a fully transparent ledger or a zero-knowledge "black box". ## Protect the Transaction Privacy A confidential transaction system built on FHE typically follows several stages. - Deposit: a user converts a plaintext balance (e.g., a ERC-20 token) into encrypted form (the new encrypted ERC-20 token) by having an off-chain FHE node encrypt the amount under the system's public key, producing a ciphertext handle that the contract records as the user's balance, while the plaintext never touches the chain. - Transfer (with encrypted ERC-20 token): the sender encrypts the transfer amount locally, submits the ciphertext on-chain, and an off-chain computation node performs homomorphic subtraction on the sender's balance and homomorphic addition on the receiver's balance, writing back two new ciphertext handles without either party's amount or running balance ever being decrypted. - Balance query: a user retrieves their own ciphertext handle and requests authorized decryption (typically via wallet-signature verification) to see their real balance in plaintext, while any other observer sees only an opaque handle and a standard transfer event with no recoverable amount. - Withdraw: the user submits a withdrawal request for an encrypted amount, an authorized decryption confirms it against (and reduces) their ciphertext balance, and the contract releases the equivalent amount (the plain ERC-20 token) in plaintext. ## How FHE Produces the Auditable Confidentiality Layer In the architecture described, value is represented entirely as ciphertext once it enters the privacy system: * Encrypted state, not encrypted messages. Balances themselves are stored on-chain as FHE ciphertext handles rather than plaintext values. This differs from approaches that only encrypt transaction payloads while leaving balances or amounts inferable. * Computation without decryption. Transfers are executed as homomorphic subtraction and addition directly on ciphertexts (balance_from − amount, balance_to + amount), performed off-chain by a dedicated computation node and written back as new ciphertext handles. No party, including the node performing the computation, ever sees the plaintext amount or resulting balances. * Default-deny access. An access-control (ACL) layer governs who may request decryption of any given ciphertext handle. By default, only the asset owner can decrypt their own balance, and on-chain observers including block explorers and other contracts, see only opaque handles and a standard Transfer event with no plain amount. This gives genuine confidentiality at the data layer, not just at the network layer: the privacy guarantee survives even if all on-chain data is public and permanently archived. FHE's core contribution here isn't making data available to regulators. It's making it inaccessible to everyone by default, including infrastructure operators, while preserving a provable, accountable path back to plaintext: the ACL layer adds a regulatory tier where any decryption request requires authorization and is permanently logged on-chain. zkTLS can be further integrated at the front-loads compliance screening, letting users prove they passed the KYC check without revealing their identity. --- ## Privacy Vault in DeFi ![image](../../pics/Banner-6.png) # Privacy Vault in DeFi ## The Problem Public blockchains are transparent by default, and that transparency becomes a liability once real institutional money gets involved. Any deposit made into an onchain lending vault is fully visible to anyone watching the chain. The depositor's address, the exact size of the position, and the precise moment funds moved in or out are all sitting in plain sight. For a retail user moving small amounts, this barely matters. But for an institutional trading desk allocating serious capital, it's a different story entirely: open visibility reveals trading strategy, invites opportunistic front-running, and exposes sensitive details about who is moving what and when. This visibility gap has been a major reason institutions hesitate to commit meaningful capital to public DeFi lending markets, even when the yields on offer are competitive. ## The Solution The fix doesn't come from rebuilding DeFi infrastructure from scratch — it comes from adding a confidential layer on top of what already works. A confidential stablecoin, built using Fully Homomorphic Encryption (FHE), wraps a standard dollar-pegged token so that balances and transfer amounts are encrypted onchain rather than openly readable. Previously, such confidential tokens were mostly useful for holding and moving funds privately — but the next step is giving them a productive role in yield-generating strategies. A confidential vault model lets holders of this encrypted stablecoin tap into the exact same lending strategy as an established, publicly visible vault — same risk profile, same collateral basket, same underlying mechanics — but with deposit sizes kept encrypted. The process is simple: convert a standard stablecoin into its confidential form in one transaction, deposit it into the confidential vault, and earn yield that flows through the underlying lending market exactly as it would for a standard, unshielded deposit. Nothing about the vault's economics changes — only the visibility of who is participating and at what scale. ## Outlook and Challenges This kind of launch is best understood as a template rather than a one-off product. The idea is straightforward: take a proven, battle-tested vault, attach a confidential deposit option, and open the door for institutional capital that wants the yield without broadcasting its playbook to the entire market. Underlying lending networks in this space already manage tens of billions of dollars in deposits, and vault curators routinely oversee billions in assets feeding yield products at major consumer platforms — so the addressable demand for this kind of privacy layer is clearly there. That said, real challenges remain. Confidentiality and regulatory auditability have to coexist, meaning compliance frameworks need to evolve alongside the technology rather than be bolted on afterward. FHE-based systems also carry meaningfully higher computational overhead than plain transactions, which raises questions about scalability as adoption grows. And as a genuinely new financial primitive, the model still needs to prove itself across market cycles and stress scenarios before institutions treat it as a default rather than an experiment. Whether this becomes the standard playbook for confidential DeFi yield — or stays a niche offering — will depend on how well it threads that needle between privacy and trust. --- ## Sealed-Bid Auctions ![image](../../pics/Banner-6.png) # Sealed-Bid Auctions ## The Problem Sealed-bid auctions are a much older and broader pattern than crypto. They're the default mechanism for government procurement contracts, real estate sales, spectrum license allocation, M&A bidding, and public sale / token launch auctions alike. The whole point of the format is that bidders submit one bid each, blind to what everyone else is offering, so the price reflects genuine valuation rather than reactive jockeying. The problem is that "sealed" is often more of a procedural promise than a technical guarantee. In paper-based or centralized processes, the auctioneer (or whoever handles the envelopes) still sees every bid before announcing a winner, leaving room for leaks, favoritism, or a trusted party simply making a mistake. Move the same auction on-chain and the problem flips but doesn't go away: bids sitting in a public mempool are visible to everyone before settlement, and even commit-reveal schemes eventually force every bidder to reveal their number in plaintext. Either way, something leaks — how much you were willing to pay, how aggressive your strategy was, where your true valuation sat — and that invites bid sniping, collusion based on visible patterns, and front-running by anyone watching the process. ## Why FHE Fits This Problem Well Sealed-bid auctions are a good match for FHE precisely because the underlying computation is simple and bounded: find the maximum (or second-highest, for Vickrey-style auctions) among a fixed, known number of encrypted values. Each bidder submits their bid encrypted under the protocol's public key, and a smart contract runs the comparison logic directly on ciphertexts. No bid is ever decrypted individually. Only the final result (the winning price, and which bidder won) goes through threshold decryption, handled by a distributed set of key-holders so no single party can unilaterally decrypt anything. ## A Proven Cryptographic Pattern The comparison-only computation pattern behind this, encrypt every bid, find the max (or second-highest) without decrypting any individual value, then reveal only the result, has a long research lineage in cryptography, well before FHE became practical enough for production use. FHE-based sealed-bid auction protocols, including second-price (Vickrey) constructions designed specifically to keep losing bids permanently secret while still proving the winning price correct, have been studied in the cryptography literature for over two decades. The same approach has also been proposed for spectrum allocation: bidders encrypt their bids under the auctioneer's public key before submission, so that channel assignment can be computed without the auctioneer or any third party ever seeing a bid in the clear. What's changed recently isn't the idea — it's that the underlying encryption schemes have gotten fast enough that "comparison among a bounded, known set of values" is now something you can actually run in a smart contract or a production auction system, rather than only in an academic prototype. --- ## Automating Verification Process # Automating Verification Process Automating manual verification processes represents a transformative opportunity where data proofs can significantly reduce operational costs and improve efficiency. Tasks that traditionally relied on human validation can now be streamlined with zkTLS technology. For instance, an dapp can leverage data proofs to automate the verification of influencer engagement metrics, eliminating the need for screenshots and tedious manual reviews. zkTLS-based data proofs can provide verifiable evidence of such claims, distinguishing genuine influencers from those making exaggerated or false statements. Another compelling use case could be in job marketplaces, where verifying resumes and matching candidates to jobs is often labor-intensive. A large number of applicants include inaccurate information in their applications, forcing companies to rely on extensive background checks, including calls to universities and past employers. Data proofs can automate this process, enabling instant, trustworthy verification and bringing significant disruption to the recruitment industry in a positive way. --- ## Composable Attestations ![image](../pics/Banner-6.png) # Composable Attestations Primus' off-chain attestation can be combined with on-chain attestations to meet the specific requirements of decentralized applications (dApps). In the realm of decentralized finance (DeFi), protocols can establish specific pools with predetermined conditions to cater to authorized users. For example, a user could receive a particular fee discount from a pool created by Uniswap hooks if they provide evidence of their largest swap in Uniswap from [Brevis](https://docs.brevis.network/) and proof of CEX trading statistics from Primus. To enable this composable attestation scenario, users should be able to submit both off-chain and on-chain attestations through the Primus/Brevis frontend. The pool contract can then access these attestations from a public attestation service like EAS and Verax, allowing any dApps and smart contracts to finely access the attestations. When a user interacts with the DeFi frontend, the pool contract verifies the satisfaction of the pre-conditions based on the on-chain and off-chain attestations before proceeding with the user's transactions. Hybrid scenarios also arise in non-DeFi contexts. For instance, individuals can provide proofs of humanity to a dApp to resist Sybil attacks. These proofs should be multi-dimensional to mitigate security risks, often including on-chain analytical results, lightweight KYC proof, and even proof of physical identity. Another example involves a GameFi platform that may require users to provide their off-chain gaming data, such as total playing time, along with on-chain trading data in order to incentivize specific user groups with game rewards. The verification of Primus' off-chain attestations on smart contracts, along with zero-knowledge proofs of users' on-chain behaviors, is crucial for these hybrid use cases. Fortunately, Primus' off-chain attestations and any on-chain attestations from third-parties can be technically decoupled, providing Primus' builders with the flexibility to integrate with all zero-knowledge coprocessors. ![avatar](./../pics/composable-att.png) --- ## Decentralized Creator Economy ![image](../pics/Banner-6.png) # Decentralized Creator Economy Under the paradigm of Web3, the relationship between creators, users, and value distribution will be redefined, ushering in a new era for the creator economy. Freed from the grip of centralized platforms, creators will have complete ownership of their works and data, no longer subject to hefty commissions imposed by centralized entities. They can escape unfair censorship, showcasing their creative talents and engaging directly with consumers to converse, inspire, and even co-create. Picture a decentralized platform akin to Docsend or TikTok. Creators encrypt their works and upload them to decentralized storage solutions like Arweave or Greenfield. A preview of the work is available on the dapp. Interested users can choose to pay-per-view or opt for a membership to access additional services. In this process, Primus' FHE technology facilitates the swift implementation of encryption and decryption for works. This ensures the privacy and security of works and data stored in a decentralized manner. Collaborating with smart contracts allows for seamless on-chain purchases and sharing. For specific users or members, Primus' attestation service can be utilized to verify their identity before sharing (e.g., sharing a business plan with partners). This is just the beginning—imagine and explore more possibilities with creators. ![avatar](./../pics/creator-economy.png) --- ## Data Quality Control # Data Quality Control Big AI companies need to do reinforcement learning from human feedbacks, to get high-quality labeling on images and other media data to train AIs for accuracy. Some companies usually do this in regions where labor is cheap. Labeling tasks like medical or legal, need expert to complete the job. It is crucial to verify that the labelers have sufficient knowledge and skills to accurately label in these domains, e.g., by proving they are indeed an MD or JD. zkTLS-based data proofs are an efficient way to verify the eligibility of labelers and weed out the bad actors lying about their credentials and providing inaccurate training data in these specific domains. Automating credential verification with data proofs can improve the integrity of AI training data sets but also streamline operations, cutting costs and increasing trust in the data pipeline. --- ## Interoperable and Composable Social Graphs ![image](../pics/Banner-6.png) # Interoperable and Composable Social Graphs Traditional social media platforms like Twitter and Facebook suffer from fragmentation and isolation, with users' social connections being incompatible with other networks. However, Primus presents a groundbreaking solution that empowers social media users to create their own attestations of social behaviors in an authentic and privacy-preserving manner. With Primus, users can generate attestations that validate their social activities in both public and private contexts. For example: * Public social attestations can certify that Alice has amassed over 100,000 Twitter followers. * Private social attestations can verify that Bob has created more than 10 private repositories and made over 100 commits. ## Unlocking Composable Web3 Social Applications Standardized social attestations provided by Primus open up new possibilities for Web3 social applications. These attestations can be leveraged in a composable way to create more meaningful scenarios. By bridging the gaps between fragmented social networks, Primus paves the way for decentralized social platforms through the following key features: * Privacy First: Primus prioritizes privacy by adhering to data minimization principles when sharing information. Users have control over their data and can selectively disclose only the necessary piece of information while keeping the rest private. * Data Authenticity: All exported and composable social relations, i.e., the social attestations, are guaranteed to be authentic and reliable. Primus ensures the integrity of data origin, providing a foundation of trust for social interactions within the network. By leveraging Primus' capabilities, a new generation of innovative and unique social applications can emerge. A more trustworthy and interoperable social network has become a reality, enabling seamless interactions and empowering users with greater control over their social data. ![avatar](./../pics/social.png) --- ## Cross-Platform Fraud Detection ![image](../pics/Banner-6.png) # Cross-Platform Fraud Detection By unifying user information across platforms, Primus offers enhanced fraud prevention capabilities. It ensures the authenticity and integrity of data, reducing incidences of financial crimes or identity theft. For example, despite additional security measures such as 2FA, most airdrop processes face identity theft. With Primus' strategies, reliable identity authentication with multi-dimensional verification from multiple identity providers and attestors is feasible. With additional identity credentials, impersonation could be significantly reduced. --- ## Decentralized Hiring and Dating ![image](../pics/Banner-6.png) # Decentralized Hiring and Dating As Web3 continues to attract more users, diverse application models are emerging, including recruitment platforms and dating applications based on Web3. One outstanding feature of Web3 projects is the global nature of their teams. Geographical restrictions do not apply, and teams can be found across various locations worldwide. With remote work being a prevalent choice, especially among Generation Z, the distributed nature of these projects poses recruitment challenges. To address this, implementing a verification system for identity, academic background, skills, health, credit, etc., enables a quicker and more efficient screening process for suitable candidates. This method not only benefits recruiters but also enhances the applicant's experience by reducing redundant resume submissions and safeguarding personal privacy. Similar verification applications can be employed on dating platforms, tailoring proof requirements to include interests, income, assets, and more. This innovative approach harnesses smart contracts to facilitate the right person finding the right job and people with shared interests connecting romantically. Such applications contribute to the diversification and enjoyment of Web3 applications. ![avatar](./../pics/hiring-dating.png) --- ## Crypto Lending with Proofs of Dynamic Assets ![image](../pics/Banner-6.png) # Crypto Lending with Credit Scores Unlike traditional financial lending, most on-chain loans require collateral from users. In the traditional financial system, credit is a broader form of lending that doesn't necessitate collateral and is based on credit information. However, in the DeFi world, due to the characteristics of trustlessness, permissionlessness, and the lack of KYC, it becomes challenging for DeFi developers to restrict borrowers based on off-chain behavior. While many projects are exploring on-chain credit lending methods, it is undoubtedly a challenging task. The difficulty lies in how to lock off-chain assets and how to effectively recover them. Nevertheless, attempting to enhance the lending rate and asset utilization through a combination of dynamic asset proofs is worth considering. Providers of funds can request borrowers to provide proof of identity, assets, credit, etc., off-chain, and then conduct risk assessments based on on-chain data to increase the original lending rate (e.g., from 70% to a higher ratio like 75%). Simultaneously, borrowers are required to provide proofs of dynamic asset at an agreed frequency. When assets change within a specified range, repayment and liquidation will be triggered. From increasing lending rates to exploring on-chain microcredit lending, the utilization of combined on-chain and off-chain data presents an opportunity to innovate DeFi applications once again. In general, with zkTLS-based data proofs, offchain credit data including FICO scores, income statements, and payment histories can be securely verified onchain in a privacy-preserving way with arbitrary disclosure, and used for onchain credit score verification. Achieving credible onchain credit for our digital identities would enable a wide range of new DeFi products around personalized lending rates, dynamic collateral requirements, and risk-based interest models. Defaults would penalize onchain creditworthiness and reputation of the digital identity. --- ## Crypto On-Ramp and Off-Ramp ![image](../pics/Banner-6.png) # Crypto On-Ramp and Off-Ramp Crypto on-ramp and off-ramp is an intractable issue to the crypto users, due to the fairness, security and compliance problems. With Primus zkTLS technique, one can create a secure end-to-end crypto on and off-ramps solution on the blockchain. Suppose Alice want to buy some crypto tokens with fiat from Bob. The general workflow of such an on/off-ramp protocol can be as the following. - Deploy an on-chain escrow smart contract to securely hold tokens (e.g., USDC, ETH). These tokens are released only after verifying the corresponding off-chain payment. The escrow is pre-funded by Bob. - Alice initiates a payment using platforms like Paypal or similar Web2 payment services. - Using zkTLS, Alice creates a data proof, which validates key transaction details, including sender, recipient, and payment amount. - The verified proof is submitted to the on-chain escrow smart contract, which processes it. Once the proof is confirmed, the escrow releases the tokens directly to Alice's wallet. --- ## Private Dataset for AI Models # Private Dataset for AI Models AI models, especially LLMs, need access to more personalized data to improve the performance, as public datasets are exhausted nowadays. However, the traditional way of using private data like user behavior and transaction history, suffers from privacy and integrity challenges. zkTLS-based data proofs offers a secure and verifiable way to access high-quality private data for AI model training. In particular, data proofs address the issues by allowing AI developers to verify the provenance and authenticity of private data without revealing privacy-compromising details. It enhances the value of data shared for training by making it verifiable, which significantly increases its economic worth. Verifiable data also mitigates the risks of data poisoning or manipulation during the training process. zkTLS-based data proofs have compelling economic implications. They enable users to retain control over their private data, selectively sharing only what they choose in a competitive marketplace where AI developers strive to build the best models. This approach unlocks new opportunities for AI applications in privacy-sensitive fields such as healthcare, parenting, and finance. --- ## Proof of Assets ![image](../pics/Banner-6.png) # Proof of Assets Digital assets, including Bitcoin, ERC-20 tokens, NFTs, and other cryptocurrencies, are revolutionizing the financial landscape. These assets represent value and are recorded on secure distributed ledgers using cryptographic techniques. While proof of on-chain assets can be easily obtained by examining the on-chain data associated with a specific account, proving ownership of off-chain assets has been a challenge due to the opacity of centralized exchanges (CEXs). Primus presents an innovative approach that allows users to prove ownership of their off-chain assets to attestors while leveraging the power of zkTLS and IZK (Interactive Zero-Knowledge Proofs). With Primus, users can establish proof of off-chain assets and obtain attestor signatures, enabling them to present verifiable evidence, i.e., attestations, to third parties. Primus' ability to provide proof of off-chain assets opens up a wide range of use cases within the ecosystem. Here are a few examples: * Alice wants to obtain an undercollateralized loan from a lending protocol. She can leverage Primus to prove to the protocol that she possesses over 10,000 USDT in her CEX account, composed of various cryptocurrencies. This created attestation allows Alice to demonstrate her credit and qualify for the loan. * Bob participates in a Gamefi platform and wants to receive exclusive airdrops such as game props, skins, or other privileges. By using Primus, Bob can prove that he holds a specific amount of Gamefi tokens, enabling him to unlock these rewards based on his ownership. * Cindy is an active on-chain derivatives trader and wants to engage with a derivative protocol. She can provide a zero-knowledge proof using Primus, sharing her trading history and derivative positions without revealing sensitive details. This proof establishes her credibility as a long-term trader and allows the protocol to incentivize her with tokens or other benefits. Primus is a groundbreaking solution that empowers users to prove ownership of off-chain assets securely and verifiably. By leveraging zkTLS, Primus enables users to obtain attestor signatures, establishing proof of ownership (attestations) that can be presented to third parties. With Primus, the potential of off-chain asset proof is unlocked, opening up new opportunities in lending, Gamefi, derivatives, and other areas within the Web3 ecosystem. ![avatar](./../pics/proof-of-asset.png) --- ## Verifiable AI Agent Execution ![image](../pics/Banner-6.png) # Verifiable AI Agent Execution AI agents are increasingly being deployed to perform high-stakes, automated tasks — from executing trades on DeFi protocols to interacting with external data sources and making autonomous decisions. However, agents are inherently non-deterministic: given the same inputs, their outputs may vary, and there is no native mechanism to guarantee that an agent actually performed the steps it claims to have performed. This creates a fundamental trust problem. How can an on-chain protocol, a user, or a third-party verifier confirm that an agent: - Actually called an LLM to generate its decision, rather than returning a hardcoded or manipulated result? - Queried a price oracle before executing an automated trade, as required by protocol rules? - position an buy order at the right point in its execution pipeline? Without answers to these questions, the outputs of AI agents cannot be trusted, and building reliable, accountable systems on top of them becomes impossible. ## The Root of the Problem: Unverifiable Intermediate Steps The core challenge is not verifying the *final* result of an agent, but verifying the *intermediate execution steps* that led to it. An agent may produce a plausible-looking output while having skipped required steps, used stale data, or deviated from its specified behavior entirely. Most of these intermediate steps share a common structure: they are **API calls**. Whether invoking an LLM endpoint, querying a DeFi oracle, fetching off-chain market data, or calling a Web2 service, virtually all agent actions are expressed as HTTP requests over a **TLS-secured connection**. This is precisely where zkTLS becomes applicable. ## How zkTLS Enables Agent Execution Verifiability zkTLS allows a prover to generate a cryptographic proof that a specific HTTPS request was made, and that the server returned a specific response, without revealing the underlying session data or private credentials. Because TLS is the transport layer for nearly all API communication, zkTLS effectively provides a general-purpose mechanism for verifying any API call an agent makes during its execution. The general workflow for a verifiable agent looks like the following: * The agent is assigned a task governed by a specified execution policy (e.g., "query oracle X before executing any trade"). * At each critical step in the execution pipeline, the agent generates a zkTLS proof attesting that the required API call was made and the expected response was received. * These proofs capture the essential parameters of each call — endpoint URL, relevant request fields, and key response values , without leaking sensitive data. * The proofs are submitted to a verification contract or verified off-chain by a verification service, which validates that every required step in the policy was executed in the correct order and with compliant results. * Only after all proofs are verified does the system accept the agent's final output as trustworthy. ## Why This Matters As AI agents take on more autonomous roles in DeFi, DAOs, and automated infrastructure, the ability to verify *how* a result was produced, not just *what* the result is, becomes essential for security, compliance, and accountability. zkTLS provides a practical foundation for this: since agent behavior already manifests as TLS-based API calls, no fundamental changes to agent architecture are required. Verifiability is introduced as an attestation layer over the existing execution flow. This enables a new class of trust-minimized agentic systems where the correctness and compliance of every critical action can be proven on-chain, turning AI agents from opaque black boxes into auditable, accountable participants in decentralized protocols. --- ## Primary Use Cases ![image](../pics/Banner-6.png) # Primary Use Cases Primus' technique enables a compliant and privacy-preserving pattern for which applications can capture the value of users' private data in various aspects. This new pattern opens up a door for Web3 dApps to take the benefits of data analytics and model intelligence in the traditional Internet economy, while still reserving fairness and sovereignty for end users. * Targeted Brand Expansion and Marketing: With Primus' toolkit, businesses can leverage user data to enhance their marketing strategies. The data amalgamation process enables more precise targeting, improving customer acquisition efforts. * Cross-Platform Fraud Detection: By unifying user information across platforms, Primus offers enhanced fraud prevention capabilities. It ensures the authenticity and integrity of data, reducing incidences of financial crimes or identity theft. * Enhanced Ad Distribution: The capacity to compile user data enables businesses to distribute more targeted advertisements, enhancing campaign performance, conversion rates, and ROI. * Credibility Boost on Community and Recruitment Platforms: In addition to fraud detection, Primus also boosts credibility by enabling businesses to showcase verified reputations across community and recruitment platforms. * Personalized AI Assistants: To further enhance user experience, Primus allows the customization of AI assistants through enriched user profiles. This ensures accurate and personalized responses based on individual feedback and preferences. More use cases and the details can be found in this section: | | | | ------------ | ----------- | | [Identity Verification](./verify-digital-identity.md) | lightweight and reusable identity verification | | [Social Networking](./expand-social-graph.md) | interoperable and composable social graphs| | [Provable Assets](./proof-of-assets.md) | privacy-preserving attestation of crypto asset holdings | | [Crypto Lending](./lending.md) | composable off-chain and on-chain attestations | | [Crypto On & Off Ramps](./otc.md) | lending with proofs of dynamic assets | | [Hiring and Dating](./hiring-dating.md) | decentralized matching platforms | | [Enhanced fraud detection](./fraud-detection.md) | enhanced fraud detection on identity crime | | [Composable Attestations](./composable-attestations.md) | composable off-chain and on-chain attestations | | [Creator Economy](./creator-economy.md) | secure creator economy with equipped FHE | --- ## Identity Verification ![image](../pics/Banner-6.png) # Identity Verification Traditional identity verification struggles with privacy concerns, centralized storage risks, high costs, time-consuming processes, data inefficiencies, lack of interoperability, compliance complexities, and fraud risks. zkTLS enables users to prove eligibility without revealing specific details, ensuring seamless privacy compliance. Some typical examples include age-like verification and reusable verification. ![avatar](./../pics/identity.png) ## Age-like Verification Personal information like age, location and nationality, is very sensitive and considered as core factors of identification risks. Primus' zkTLS technique achieves complete data minimization, which only provides the final result after applying the computable condition to the sensitive data. For instance, an age attestation can provide the satisfiability towards a gaming service to ensure age compliance, without disclosing the exact age or birth date. As long as the sensitive data is an input to a computable function, the verification can be well constructed by using ZKP. Other examples include: * one can provide proof of eligible nationality, by cryptographically showing the user's nationality is NOT in the blacklist which may contain a couple of restricted countries and regions. * one can provide proof of qualified address to confirm the user's area falls in the designated region. ## Reusable Verification Proof of Humanity (PoH) is crucial in ensuring that online participants are genuine individuals rather than bots or fake identities. Existing PoH methods, such as CAPTCHA and hCAPTCHA, focus on human verification tests to achieve Sybil resistance for Web3 applications. Primus introduces a new approach to PoH by re-using existing identity/KYC results. For example, consider the case of Alice, an active Twitter user seeking access to a chat service provided by a new decentralized social protocol. Primus can create an attestation for Alice after verifying that she has posted more than 100 tweets within the last quarter. This attestation can then be re-used by the new protocol to ensure Alice's humanity, utilizing the verification results from Primus. Primus' innovative solution enhances Web3 identity systems by reducing trust assumptions and integrating specialized verifiable attestations. By binding these attestations to specific Web2 data sources, Primus ensures authentication and privacy preservation. Additionally, Primus introduces a new type of Proof of Humanity by leveraging existing identity/KYC information, enabling the creation of more secure and trustworthy Web3 applications. **Applications** Try out a sample application powered by Primus: https://app.primuslabs.xyz/home --- ## zkTLS-based Crypto Payment # zkTLS-based Crypto Payment Crypto payment is one of the most compelling applications of blockchain and decentralized technologies. It enables permissionless, censorship-resistant transfer of assets across the globe. With zkTLS, crypto payment can be further simplified and abstracted away from wallet addresses. Instead of requiring a recipient’s wallet address, senders can specify a social account (e.g., email, Twitter, GitHub) as the payment destination. The recipient can later prove ownership of that account via zkTLS and securely claim the tokens into their own wallet. Developers can implement such a payment flow by: - Deploying smart contracts to manage payment records on-chain (from sender to recipient identity). - Mapping social accounts to verifiable claims using zkTLS proofs. - Allowing recipients to generate zero-knowledge proofs to withdraw assets to their preferred address. ![image](../pics/zktls_pay.png) **User Benefits** With zkTLS-based crypto payments, users no longer need to manage or disclose their wallet addresses. Instead, they can receive assets by simply proving ownership of an existing identity—such as a social account or email—without exposing sensitive information on-chain. This approach ensures end-to-end privacy, as the user’s identity remains completely hidden from the public ledger, reducing both privacy risks and friction in participation. The experience is seamless for both Web3-native users and those from traditional Web2 environments, making it significantly easier for anyone to access and benefit from crypto-based systems. By removing the technical complexity often associated with wallet management for newbies, this mechanism lowers the barrier to entry and creates a more intuitive, flexible, and inclusive way to send and receive crypto assets in a peer-to-peer manner. **Applications** Try out a sample payment application powered by zkTLS, built by the Primus team: https://pay.primuslabs.xyz --- ## What is Primus ![image](../pics/Banner-4.png) ## What is Primus Primus (formerly "PADO") is a trust, verification and privacy layer designed for crypto and agent economy. The Primus Network leverages advanced cryptographic techniques to enable secure, permissionless verification and computation tasks in blockchain and AI applications. ### The Problems - As blockchain and decentralized technologies continue to evolve, they encounter critical challenges, including limited on-chain data, fragmentation between Web2 and Web3 systems, and the difficulty mature industries face in leveraging decentralized networks effectively. Traditional systems fail to deliver the privacy, scalability, and interoperability required to overcome these obstacles. - A key issue with AI agents is the absence of transparency and accountability, especially in critical agent sce like DeFi, trading and online shopping. Without verifiable mechanisms, users cannot trust AI’s actions, decisions, or data management, raising concerns about potential manipulation, security vulnerabilities, and privacy breaches. ### Our Solutions The challenges we face today point to one clear solution: a cryptographic layer. This layer securely connects off-chain data and executions with blockchain and AI systems. Primus tackles this by leveraging verification and encrypted computation to introduce verified agent exectuions or verified data into the application workflows, empowering users and developers to build secure, transparent, and accountable systems. Primus also provides developers with easy-to-use APIs. Think of it as a bridge, linking foundational blockchain and AI ecosystems with the diverse applications being built on top. ![Primus Network](../pics/data-verification-computation.jpg) ### Core Technologies Our technology focuses on two key innovations: [zkTLS](../primus-network/tech-intro.md) and zkFHE. zkTLS builds on the Transport Layer Security (TLS) protocol by adding zero-knowledge proofs, so you can verify data authenticity without revealing the data itself. zkFHE takes this a step further, ensuring computations on encrypted data are secure and tamper-proof, even when outsourced. - zkTLS Resources: - [Whitepaper](https://eprint.iacr.org/2023/964) - [QuickSilver](https://eprint.iacr.org/2021/076) - zkFHE Resources: - [GINX](https://eprint.iacr.org/2014/283.pdf) - [FHETransform](https://fhetransform.primuslabs.xyz/) --- ## Why Primus ![image](../pics/Banner-4.png) ## Why You Need Primus? The core strengths of Primus technologies and the Primus network lie in enabling cryptographic verifiability off-chain data and executions, and performing further privacy-preserving computation for the verified result. Beyond these foundations, Primus also delivers a wide range of benefits to developers, ecosystem builders, and network participants: ### **Chain-Agnostic** - Primus’ data verification and computation capabilities are chain-agnostic, enabling dApps across various blockchains to seamlessly interact with cryptographic computations without technical barriers. By bridging the gap between off-chain and on-chain data, Primus empowers blockchain ecosystems to support more diverse and data-driven applications. ### **Openness** - Primus’ core technologies are open and freely accessible to all developers. Additionally, the network incentivizes contributions from a wide range of communities—including cryptography, distributed systems, DeFi, AI, and others—to collaboratively build a trustless and privacy-centric ecosystem. ### **High Performance** - zkTLS: [Primus zkTLS](https://eprint.iacr.org/2023/964) is a state-of-the-art solution that is over 10x faster than existing alternatives and is compatible with diverse environments, from browsers to mobile apps. Powered by the innovative [QuickSilver](https://eprint.iacr.org/2021/076) interactive zero-knowledge proof system, Primus zkTLS sets a new industry standard and is the first solution capable of efficiently proving large-scale content, such as ChatGPT conversations. - zkFHE: Primus zkFHE introduces a groundbreaking protocol with the proving time about 340x faster than existing systems. This advancement makes zkFHE practical for real-world applications, such as confidential voting, auctions, and FHE rollups. --- ## FAQ for AlphaNet ![image](../../pics/Banner-5.png) ## FAQ for AlphaNet Campaign **Q:** How can I complete the tasks? **A:** You can follow the [tutorial](tutorials.md) to complete the tasks. --- **Q:** AlphaNet is live. Where can I see my earlier points from the extension? **A:** The XPs are legacy points that represent the activities in the Primus ecosystem. If the **"Early Bird"** badge appears on the page, it confirms that you earned XPs in the past campaigns, which is still shown in the Primus extension. All your previous XPs are still valid and recorded. However, no new XPs can be earned from UTC 7 am, 16 Oct. The reputation score on the AlphaNet is a different type of points from the legacy XPs, which represents your social reputation off-chain. --- **Q:** How much do I need to pay to verify my X profile and other data? **A:** To generate a zkTLS proof on your X data or other data, You need to deposit approximately **0.000035 ETH** for the task fee, plus a very small amount of **gas fee** on the Base chain. If verification fails, your deposited tokens will be refunded in a short while. --- **Q:** How long will the campaign last? **A:** The campaign is ongoing, with no specific end date announced. --- **Q:** Is my data safely stored on the AlphaNet? **A:** Yes. Your private data is securely stored within the dApp. Thanks to zkTLS technology, no one can access or view your private data during the proof generation process. --- **Q: What should I do with error codes: 10001, 10002, 10003, 10004?** **A:** These error codes always come out with not stable internet connections or bad network conditions. You can switch to another WiFi connection or use a VPN software and retry. Remember to close the browser and re-open it (**this step is very crucial**). --- ## Tutorial for AlphaNet ![image](../../pics/Banner-5.png) ## Tutorial for Primus AlphaNet Campaign This tutorial gives you a step-by-step walkthrough for users to verify their social identities with zkTLS proofs on the Primus AlphaNet Campaign. 1. Go to [https://app.primuslabs.xyz](https://app.primuslabs.xyz), open your browser, click the “Connect Wallet” button, and choose a wallet that you use to log into the dapp. ![image.png](../../pics/tuto1.png) 2. Click the “Enable Extension” button to install the Primus extension from the Chrome Web Store. ![image.png](../../pics/tuto2.png) 3. Choose a task (X/TikTok/Github/Luma/Spotify/...), and click the “Verify Now” link to generate your zkTLS proof. ![image.png](../../pics/tuto3.png) 4. If you select the “X” task, you shall follow the Primus X account (@primus_labs) and repost the tweet before generating your proof. ![image.png](../../pics/tuto4.png) 5. To verify your X profile, you are required to deposit a small amount of $ETH (~0.000035 Base ETH) to pay the Primus Network fee. Note, you also need to pay the gas fee as the proof whill be stored on-chain, which is very minimal on the Base chain for the deposit transaction. If the task fails, the deposited money will be refunded in a short while. ![image.png](../../pics/tuto5.png) 6. The zkTLS proof will be generated automatically on the X page. ![image.png](../../pics/tuto6.png) 7. Once the proof is successfully generated, you will find a green icon shown in your X task card, which represents your counted verified X account status. ![image.png](../../pics/tuto7.png) 1. You can further complete the other tasks to prove your social identities and platform activities to gain more reputation scores. ![image.png](../../pics/tuto8.png) --- ## Attestor Node Guide # Attestor Node Guide This guide explains how to deploy the Primus Network Attestor Node using TEE (provided by [Phala](https://cloud.phala.network/dashboard)) in production environments. ### 1. Supported Chains | Chain | ChainId | Task Contract Address | Support | |-----------------------|---------|--------------------------------------------|---------| | base-mainnet | 8453 | 0x151cb5eD5D10A42B607bB172B27BDF6F884b9707 | ✅ | | base-sepolia | 84532 | 0xC02234058caEaA9416506eABf6Ef3122fCA939E8 | ✅ | | hashkey-chain-testnet | 133 | 0x6588a24D34C881cF10c8DA77e282f6E1fBc262C7 | ✅ | | hashkey-chain-mainnet | 177 | 0x1c5D0d5e0a3e0a5c9B0cDcF5C25A892281e4cd04 | ✅ | | ink-mainnet | 57073 | 0xCE7cefB3B5A7eB44B59F60327A53c9Ce53B0afdE | ✅ | ### 2. Deploy the Node using TEE #### 2.1 Register a Phala Account 1. If you don't have a Phala account, you can register one [here](https://cloud.phala.network/register). #### 2.2 Deploy the Node ##### 1. Visit the [deployment template](https://cloud.phala.network/templates/primus-attestor-node) and click `Deploy` button. ![](images/template_deploy_start.png) ##### 2. Please fill in the required fields: - **Name**: This node's name. - **docker-compose.yml**: Please don't change it - **KMS Provider**: Only supports `Base` - **Node**: `prod9` - **Instance Type**: Use `Large TDX Instance(4 vCPU, 8 GB)` - **Storage**: Larger than `20 GB` - **Operating System**: `dstack-0.5.4.1` - **Encrypted Secrets**: Please set: - `PRIVATE_KEY`. `PRIVATE_KEY` should start with `0x`. `PRIVATE_KEY` acts as the owner of the node, used to report results, and will also be used to [register the node](#3-register-the-node). - `NETWORK_CHAINS`: A **compressed single-line JSON string** (no line breaks). Each element has `rpcUrl`, `taskContractAddress`, and `chainId` — see [Supported Chains](#1-supported-chains). **Example value to paste:** > Here is an example for base mainnet ```jsonk [{"rpcUrl":"https://mainnet.base.org","taskContractAddress":"0x151cb5eD5D10A42B607bB172B27BDF6F884b9707","chainId":8453}] ``` If you edit in expanded form, use this [tool](https://it-tools.tech/json-minify) to minify before pasting. - `IMAGE_TAG`: Please use the tag: `0.1.1-alpha.5`. ![](./images/deploy-parameters.png) ##### 3. Click `Deploy` to start the deployment process. ##### 4. If everything is successful, you will see the following services: ![](./images/start_success.png) ##### 5. Click the `attestor-node` service to view the node's log. You will find the attestor's address in the log. ***Please save this address as you will need it when [registering the node](#3-register-the-node)***. ![](./images/attestor_address.png) ##### 6. Click the `Network` tab to check your `Network Information`. ***Please save this `endpoint` for [registering the node](#3-register-the-node)***. ![](./images/endpoint.png) ##### 7. Copy the `endpoint` from step 7 to your browser and you will see the following information: ![](./images/endpoint-success.png) If you see `Hi, PRIMUS NETWORK!`, it means you have successfully deployed the node. ### 3. Register the Node > ***NOTE: Before managing a node, you must first contact the [primuslabs team](https://discord.gg/YxJftNRxhh) to have the attestor added to the whitelist.*** #### 3.1 Prerequisites Make sure Docker is installed on your system. #### 3.2 Clone and Prepare ```bash git clone https://github.com/primus-labs/primus-network-startup.git cd primus-network-startup chmod +x ./run.sh ``` #### 3.3 Set Environment Variables Based on the chain where your node is located, run the following command: ```bash cp env_files/.env.base-mainnet .env ``` Then set your private key, RPC URL, and other parameters: > Here is an example for base mainnet ```bash PRIVATE_KEY=0x # Rpc for base chain testnet RPC= NODE_CONTRACT_ADDRESS=0x9C1bb8197720d08dA6B9dab5704a406a24C97642 ATTESTOR_ADDRESS= RECIPIENT_ADDRESS= ATTESTOR_URLS= NODE_META_URL= ``` 1. **PRIVATE_KEY**: This private key owns the node and is the same as the [above](#2-please-fill-in-the-required-fields) while deploying the node. We recommend depositing 0.01 ETH(for base chain) to this address. If you set it as the `RECIPIENT_ADDRESS` below, it will automatically receive task fees. This ensures sufficient balance for reporting results. Otherwise, you must manually monitor and maintain the balance. 2. **RPC**: rpc for the chain. 3. **NODE_CONTRACT_ADDRESS**: This is the address of the node contract. You can use the default value from `env_files/.env.base-mainnet`. 4. **ATTESTOR_ADDRESS**: Attestor's address to sign attestations, this address is from above [attestor-node](#5-click-the-attestor-node-service-to-view-the-nodes-log-you-will-find-the-attestors-address-in-the-log). 5. **RECIPIENT_ADDRESS**:Address to receive task fees. This address can be set to the node owner address corresponding to the PRIVATE_KEY above, or to any other address. 6. **ATTESTOR_URLS**: Attestor node domain names. This domain is from [endpoint above](#6-click-the-network-tab-to-check-your-network-information), and remove `https://`, just the domain name like: `dd26063786a0fccd8e4cc499374b4515d4df1e87-18080.dstack-base-prod9.phala.network`.If you have multiple URLs, separate them with commas. 7. **NODE_META_URL**: Attestor node metadata url. The metadata should be a JSON document containing the following fields: ```json { "name": "Your node name", "description": "Introduce your node", "website": "Your website URL", "x": "https://x.com/", "logo": "" } ``` ***MAKE SURE `NODE_META_URL` IS PUBLICLY ACCESSIBLE ON THE INTERNET.*** #### 3.4 Register the Node > ***One chain per run***: Registration applies to **one chain only** (the chain determined by your current `.env` from step 3.3). If you need to register the node on **multiple chains**, repeat **3.3** (set environment variables for the next chain, e.g. `cp env_files/.env. .env` and fill in the values) and **3.4** (run `register`) for each chain. ```bash sudo ./run.sh register ``` > If you want to unregister from the Primus network, run the following command: >```bash >sudo ./run.sh unregister >``` > ***Please note***: Unregistering from the network means you will no longer receive any tasks and will not earn any > income. --- ## Attestor Security ![image](../pics/Banner-5.png) ## Security of Attestor Nodes The security of attestor nodes is critical and must be safeguarded to protect both node maintainers and network clients. A key security concern in the zkTLS protocol is how to enforce the computational integrity of the attestor node. Note this aspect is not covered by the original protocol security. To strengthen attestor security, the Primus network adopts a hardware-based approach. Specifically, [Phala’s TEE technology](https://docs.phala.com/phala-cloud/what-is/what-is-phala-cloud) is integrated with the Primus attestor node software to ensure nodes always execute correctly, while critical assets such as node keys remain protected and securely utilized. ### Key Management The attestor node leverages Phala’s TEE solution, including a secure Key Management Service (KMS), to safeguard node keys throughout their entire lifecycle. These node keys are the most critical assets within the attestor node, primarily used for signing zkTLS sessions and issuing proofs. Key generation is performed exclusively by the KMS inside the TEE, ensuring that the attestor node software never has direct access to the key material. Signing operations can only be performed within TEE, and only after the correct execution of the zkTLS protocol. ### Version Managemnt Another security concern involves the attestor’s DevOps process. To prevent attacks such as code injection or malware hijacking, only official, verified software versions are allowed to be deployed and maintained within the network. This policy is further enforced by TEE, as the entire attestor node software always runs inside the enclave, ensuring runtime integrity and protection against unauthorized modifications. --- ## Attestor Node Guides --- ## PoR Support Chains ![image](../pics/Banner-5.png) ## PoR Support Chains --- ## Overview of zkTLS ![image](../pics/Banner-2.png) ## Overview of zkTLS zkTLS (also known as "web proofs") is a cryptographic technology that verifies the authenticity of TLS data while preserving privacy, all without requiring modifications to the data source servers. This innovation enables the secure utilization of personal data stored in siloed Web2 servers, facilitating seamless and cost-effective cross-platform data flow. ![avatar](./../pics/data-veri-layer.png) In the industry, two primary modes are commonly used for zkTLS: the **MPC mode** and the **Proxy mode**. Each mode presents its own trade-offs in terms of security and performance. Primus addresses these differences by providing unified APIs, allowing developers to choose the most suitable mode based on the specific requirements of their applications. ### MPC Mode In the MPC mode, the attestor and the client collaboratively execute a secure multi-party computation protocol to generate the materials needed to set up a TLS session with the data source server. This ensures that the client cannot control or modify the TLS data before the attestor sends back its share of the session key. The key advantage of Primus' MPC mode is its use of the highly efficient and lightweight interactive zero-knowledge proof system, [QuickSilver](https://eprint.iacr.org/2021/076), developed by the Primus team. QuickSilver significantly reduces both computational and communication overhead, enhancing performance. For more details, please refer to our technical [whitepaper](https://eprint.iacr.org/2023/964). The diagram below illustrates the general workflow of how the MPC mode operates. ![avatar](./../pics/mpc-model.png) ### Proxy Mode In the Proxy mode, the attestor acts as an intermediary between the client and the data source server, forwarding TLS traffic between them. Additionally, the attestor records all ciphertexts exchanged between the client and the server. At the end of the session, the client must prove to the attestor that it knows the plaintext messages underlying the ciphertexts. The Proxy mode can offer better performance than the MPC mode, as it avoids the computational overhead of the multi-party computation protocol. However, it introduces a new network assumption: the attestor must ensure that it is indeed communicating with the intended server, mitigating any potential risks of miscommunication or attacks. Primus’ Proxy mode differs from others in the industry by leveraging the highly efficient [QuickSilver](https://eprint.iacr.org/2021/076) protocol during the proof process. Additionally, it proves the Key Derivation Functions (KDFs) during the TLS connection establishment, which is typically inefficient in zk-SNARK alternatives. This approach also eliminates the need for extra padding, which can be limiting and lack generality. The diagram below illustrates the general workflow of how the Proxy mode operates. ![avatar](./../pics/proxy-model.png) --- ## Understand Primus Network ![image](../pics/Banner-5.png) ## Understand Primus Network Primus network is fundamental layer of the zkTLS protocols that provides decentralized security and robustness, with driving the demand for validating off-chain data and agents. ### Roles of The Network #### 1. Attestor Node An attestor node is a computing node of the Primus network, which forms a secure computation layer for executing zkTLS protocol. The attestor node is designated to run zkTLS tasks with zkTLS software including web version (Primus extension) and mobile versions (Primus AppClips and Primus Instant Apps) on indicated data sources. For [security consideration](./attestor-security.md), the attestor node runs inside a Trusted Execution Environment (TEE), ensuring runtime integrity and providing stronger version control. Any operator of the attestor node is required to stake a certain amount of tokens as collateral to secure his participation in the network activities. The attestor can earn incomes on successfully running the network task. If the zkTLS task is not run correctly, it will also be punished. #### 2. Developer A developer within Primus network builds zkTLS app by utilizing Primus network SDK. #### 3. Client A client is an end user who directly allocates a zkTLS task to the network through a dapp built by a developer. ### Network Architecture and Workflow ![image](../pics/zktls-network-architecture.png) The Primus system contracts act as the core hub and the dispatcher to manage the network activities. They need to handle fee settlement, stakings, rewards, and penalties about zkTLS tasks. In the network, normally a session starts with a task created by a client. The task is sent to the contracts to be processed by the network attestors. Within the task session, a selected attestor will perform a chosen zkTLS protocol (MPC Mode or Proxy Mode) with the client, to verify the web data which is specified in the task (dapp) and issue zkTLS proofs. Another core component is **Primus network SDK**, which is used implicitly in the network activities. The SDK is normally integrated and used by the zkTLS dapps, to send tasks to the contracts and locate the selected attestor. The SDK is the true vehicle to run the zkTLS protocol with the attestor, and create the related zkTLS proofs. ![image](../pics/zktls-coreflow.png) ### Network Economics Clients shall pay task fees with crypto tokens to the verification service provided by the network. The fee shall be paid to the system contracts prior to the task execution. The fees from the executed task will be shared by the attestor which actually runs the zkTLS session with the client, and the protocol. Attestor shall stake a certain number of tokens and waits for a while before it can onboard as an official node. Attestor will have to wait for a certain period to exit the staking before returning the locked funds. ### Penalties If an attestor does not execute the zkTLS protocol honestly and instead arbitrarily signs on the zkTLS session, penalties will apply. The correctness of the protocol execution is validated through TEE attestation. If a node’s instability leads to execution failures or timeouts, the task output must be reported to the system contracts. A pre-defined threshold will determine whether penalties apply: within a given time window, a certain failure rate may be tolerated without punishment, while exceeding a specified timeout rate will trigger penalties. The penalty mechanism is designed as an incremental means of network security, and will not be introduced on the first day of the mainnet launch. In the staging phases, there will be no penalty mechanism, only authorized nodes will be allowed to join the network. When the penalty mechanism is formally introduced, task execution will be verified through TEE attestations, ensuring that correctness of the cryptographic operations can be enforced and validated. ### Network Governance The governance mechanism will primarily be responsible for network upgrades, parameter adjustments, and other key decisions affecting the system. In the early stages, governance will not be activated, allowing the network to focus on stability and adoption. Once introduced, governance will cover parameters such as the minimum staking requirement for attestor nodes, the unbonding period for attestor nodes, the minimum staking requirement for clients, the unbonding period for regular stakers, and the allowable range for the proportion of staking rewards distributed by regular stakers to their delegated attestor nodes. --- ## Glossary ![image](../pics/Banner-1.png) # Glossary | Term | Explanation | | ------------ | ----------- | | **ZKP** | Zero-Knowledge Proofs | | **MPC** | Multi-Party Computation | | **IZK** | Interactive Zero-Knowledge Proof | | **NIZK** | Non-Interactive Zero-Knowledge Proof | | **FHE** | Fully Homomorphic Encryption | | **TLS** | Transport Layer Security | | **ZKFHE** | Fully Homomorphic Encryption with Zero Knowledge Proof Ensured Integrity| | **GC** | Garbled Circuits | | **OT** | Oblivious Transfer | | **2PC** | Two-Party Computation | --- ## Privacy Policy ![image](../pics/Banner-1.png) # Privacy Policy **Update Date: May 1st, 2023** This privacy statement describes how Ideal Function Limited ("the Company", "we", "our") collects, uses, and stores personal information of users ("you", "your") through our products and services, including websites, applications, and APIs (collectively "Products and Services"). By using our services, you agree to the terms of this statement. If you have not yet accessed our Services, we recommend that you review these Terms before doing so. If you do not agree with any part of this privacy statement, please do not use any of our services. **What personal information do we collect?** When you use our Products and Services, we collect the minimum amount of information necessary to fulfill the purposes of the Products and Services. This may include: - Account information: such as the account ID you create and account information you authorize through OAuth. - Contact information: such as your email address. - Technical information: such as the blockchain address you bind, device and browser type, operating system, and other technical data. In addition, we do not collect or store any other personal information about you, and any personal information you obtain from other platforms through our Products and Services will be stored on your local device and will not be collected, analyzed, or tracked by us. We will never ask you to share your private key or wallet mnemonic. Never trust anyone or any website that asks you to enter your private key or wallet seed. **How do we use personal information?** We do not have access to the personal information stored on your local device. The minimal personal information we collect will be used in the following ways: - Use of our Products and Services: To enable you to access and use the Services and to provide and deliver products and services that you may request. - Make better communication: We utilize your personal information to inform you of potential promotions, upcoming events, and other relevant updates about our products and services, as well as those of our carefully selected partners. - Optimize our platform: To optimize your user experience, we may use your information to respond to your comments and questions about the Services and to provide general customer service to you and other users. **How do we share personal information?** We do not share the personal information you provide to us with other organizations without your consent. We only share personal information with third parties under the following circumstances: - Affiliates: We will share personal information with our affiliates to maintain a consistent user experience between the products and services we provide to you. - Business Transfer: When we enter into or negotiate a business transaction, we may share personal information related to the sale or transfer of all or part of our business or assets. These transactions may include any merger, financing, acquisition or bankruptcy transaction or procedure. - Legal reasons: We may share personal information for legal, protection, and security purposes. - Professional Advisors and Service Providers: We may share information with individuals or companies that require information to work for us, including third-party companies and individuals who represent and provide services, as well as lawyers, bankers, auditors, and insurance companies. The personal information we provide in our Products and Services is shared directly by you with other companies or entities you choose, and you can choose to use a clear/privacy-proof method for them to use. **Privacy Rights and Choices** You may access the information you voluntarily provide through your account on the Services, and update or delete such information yourself. You can request [contact@primuslabs.xyz](mailto:contact@primuslabs.xyz) to view, correct or delete information on the server. **Minors** We do not allow individuals under the age of 16 to register for an account. If we become aware that a child or minor under the age of 16 has used our Products and Services, we will use notice to inform them that they may not use the Website, and then we will stop serving that account and delete the information. **Changes to the Privacy Statement** We may update this Privacy Statement from time to time and will post the updated Privacy Statement on our website with the "Last Updated" date at the top. We recommend checking the Privacy Statement periodically for the latest information. Nevertheless, ongoing utilization of our Products or Services subsequent to posting any modified Privacy Policy will signify your acceptance of the revised Terms and Conditions as per the modified Privacy Policy. This Privacy Statement does not apply to any products, services, websites or content that are provided or owned by third parties with their own privacy policies. **Contact Us** If you have any questions or concerns regarding this Privacy Statement, please email us at [contact@primuslabs.xyz](mailto:contact@primuslabs.xyz). --- ## Terms of Use # Terms of Use **Last Updated:** August 14, 2026 Welcome to **Primus** ("we," "us," or "our"). These Terms of Use ("Terms") govern your access to and use of the Primus website, user interface, and associated applications (collectively, the "Interface"). By accessing the Interface or connecting your wallet, you agree that you have read, understood, and accepted these Terms and our [Privacy Policy](/resources/privacy-policy). If you do not agree, please do not use the Interface. ### 1. Interface & Non-Custodial Nature - **Frontend Only**: Primus provides a web-based interface to interact with decentralized blockchain networks, smart contracts, and third-party DeFi vaults. Primus does not operate, control, or own the underlying blockchain networks or third-party DeFi vaults. - **Non-Custodial**: Primus is strictly non-custodial. We never hold, store, or have access to your private keys, seed phrases, or cryptographic assets. You are solely responsible for securing your wallet, managing your private keys, and all transactions signed through it. - **Irreversible Transactions**: All transactions executed through the Interface (including staking, unstaking, decryption, and token transfers) are processed directly on the blockchain and are final and irreversible. ### 2. Confidentiality & Protocol Risks - **Advanced Cryptography**: The Interface and certain DeFi vaults integrated with Primus utilize novel cryptographic techniques and confidential computing technologies (such as Fully Homomorphic Encryption). You acknowledge and accept the inherent risks of novel smart contracts, potential execution delays, and protocol settlement windows. - **Innovative & Emerging Technologies**: You acknowledge that the Interface and the underlying cryptographic mechanics involve innovative, cutting-edge, and emerging technologies. Such technologies may be subject to rapid evolution, system latency, unexpected behavior, or undiscovered technical vulnerabilities. You explicitly assume all risks associated with interacting with these innovative software components. - **Third-Party Vaults**: The Interface may display or route transactions to third-party DeFi vaults, strategies, or protocols (such as Unitas or other providers). Yields, strategies, and risk disclaimers of third-party vaults are governed by their respective owners. Primus makes no warranties regarding third-party protocol performance, security, or yield estimates. - **Protocol Risks**: Primus does not audit, endorse, or guarantee the safety or performance of decentralized blockchain networks and third-party vaults. You accept all risks associated with third-party smart contract bugs, exploits, liquidations, or impermanent losses. ### 3. Eligibility & Compliance By using the Interface, you represent and warrant that: 1. You are at least 18 years of age or the legal age of majority in your jurisdiction. 2. You possess the legal authority to enter into these Terms. 3. You will not use the Interface for any unlawful activity, including money laundering, terrorist financing, or market manipulation. ### 4. No Financial, Legal, or Tax Advice The Interface and its contents are provided for informational and technological utility purposes only and should not be construed as financial, investment, legal, or tax advice. You are solely responsible for conducting your own independent research and assessing the risks of any vault or strategy before interacting with it. ### 5. Limitation of Liability THE INTERFACE IS PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS. TO THE MAXIMUM EXTENT PERMITTED BY LAW, PRIMUS AND ITS CONTRIBUTORS DISCLAIM ALL WARRANTIES AND SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, OR CONSEQUENTIAL LOSSES, INCLUDING LOSS OF ASSETS, DOWNTIME, OR SMART CONTRACT EXPLOITS. ### 6. Governing Law & Dispute Resolution These Terms, and any non-contractual obligations arising out of or in connection with them, shall be governed by and construed in accordance with the laws of the jurisdiction in which the operating entity of Primus is incorporated, without regard to conflict of law principles. Any dispute, controversy, or claim arising out of or in connection with these Terms or the Interface shall be referred to and finally resolved by binding arbitration under the rules of the applicable arbitration institution within such jurisdiction. ### 7. Contact Information If you have any questions or concerns regarding these Terms, please contact us at: contact@primuslabs.xyz --- ## Useful Links ![image](../pics/Banner-1.png) ## Useful Links - zkTLS Resources: - [Whitepaper](https://eprint.iacr.org/2023/964) - [QuickSilver](https://eprint.iacr.org/2021/076) - zkFHE Resources: - [HasteBoots](https://eprint.iacr.org/2025/261) - [GINX](https://eprint.iacr.org/2014/283.pdf) - [FHETransform](https://fhetransform.primuslabs.xyz) - [Primus Extension](https://chromewebstore.google.com/detail/primus-prev-pado/oeiomhmbaapihbilkfkhmlajkeegnjhe) ### Social Links Twitter: https://x.com/primus_labs Discord: https://discord.com/invite/pdrNxRrApX Github: https://github.com/primus-labs Medium: https://medium.com/@primuslabs