For the complete documentation index, see llms.txt. This page is also available as Markdown.

Step-by-Step dApp

Now put a web UI on the dApp you published. This chapter builds a React frontend that calls your enclave's functions through the runner — the browser submits a payload, the network executes it in your enclave, and the decrypted result comes back to the page. If you haven't published a dApp yet, start with Build & publish your first dApp.

Project Setup

To initiate the creation of a new React app using npx create-react-app, follow these steps:

  1. Ensure that you have Node.js and npm (Node Package Manager) installed on your system.

  2. Open your terminal or command prompt.

  3. Execute the following command:

npx create-react-app my-app

Replace "my-app" with your desired name for the React app. This command will establish a new directory named "my-app" and configure a basic React application structure within it.

  1. After the process completes, navigate to the newly created directory:

cd my-app
  1. Launch the development server:

npm start

This action will start the development server and automatically open your React app in a web browser. You can now commence building your React application by making changes to the files within the "src" directory.

Utilizing npx create-react-app presents a swift and straightforward method for initializing a new React project with all the essential configurations and dependencies, freeing you to concentrate on developing your app without concerning yourself with the initial setup.

Ethernity Cloud Runner package installation

To begin developing with the Ethernity Cloud Runner, you can easily set up your environment by installing the package using npm:

$ npm install @ethernity-cloud/runner --save

This command will install the Ethernity Cloud Runner package and save it as a dependency in your project. With the package installed, you're ready to start utilizing the Ethernity Cloud Runner functionality and explore its capabilities for your application development.

Ethernity Cloud Runner usage and integration

This comprehensive guide explains the seamless integration of the Ethernity Cloud Runner module into your React application, empowering developers to execute Python tasks. The following sections elaborate on the integration process:

  1. Import Statements:

    Begin by editing /src/App.js and by importing the essential modules and styles. Import ./App.css for styling, and the pivotal pieces from the @ethernity-cloud/runner package: the default EthernityCloudRunner class plus ECRunner, ECStatus, and ECAddress from the enums entry point.

    These are what you use to interact with the runner, pick the enclave image, react to task status, and select the network.

  1. Defining Code to be Executed:

    The Ethernity Cloud Runner allows users to execute tasks using different programming languages and frameworks. Currently, the runner supports two main templates: Python and Node.js. Users can define the code to be executed within these templates to perform specific tasks on the Ethernity Cloud ecosystem.

    Python Template:

    In the Python template, users can write their code in Python programming language.

    Below there is an example of Python code that returns

    Node.js Template: For those who prefer JavaScript, the Node.js template offers a powerful option.

    Below there is an example of Node.js code that computes the sum of two numbers:

    To use either template, users need to provide the code in the corresponding programming language that defines the specific task they want to execute. As you can see, theecld.result function is specially used inside a Ethernity Cloud Runner tasks. When executing a task, this function allows the task code to send the result back to the Ethernity Cloud ecosystem.

  2. ecld.result is the way to return a task's result — the same call as the bare ecldResult(...) (Python: ecld_result). The older ___etny_result___ still works, unchanged. It encodes any value automatically (JSON / text / base64) and can attach your dApp's persistent state to theManaging dApp State (ESR).

    Because there is no output console of the code that is being process, this special function plays a crucial role in ensuring that the results of executed tasks are safely recorded and sent to the user performing the task request. For our example we are using the following nodejs code:

  3. App Function Component:

    Define the App function component, which plays a pivotal role in rendering the entire application.

  1. Execute Task Function:

Within the App function, define the executeTask function as an asynchronous function that triggers upon clicking the "Execute task" button.

  1. Runner Initialization:

The first crucial step involves creating an instance of the EthernityCloudRunner. Initialize the runner by constructing:

Called with no arguments, the runner targets the Bloxberg testnet and uses the browser wallet (MetaMask via window.ethereum).

Selecting a network. The constructor takes the network's token contract address as its first argument (import the addresses from @ethernity-cloud/runner/enums). Ethernity Cloud supports the following networks:

Network
Type
Chain ID
Address enum

Bloxberg

mainnet

8995

ECAddress.BLOXBERG.MAINNET_ADDRESS

Bloxberg

testnet

8995

ECAddress.BLOXBERG.TESTNET_ADDRESS

Polygon

mainnet

137

ECAddress.POLYGON.MAINNET_ADDRESS

Polygon Amoy

testnet

80002

ECAddress.POLYGON.TESTNET_ADDRESS

IoTeX

testnet

4690

ECAddress.IOTEX.TESTNET_ADDRESS

Ethereum Sepolia

testnet

11155111

ECAddress.SEPOLIA.TESTNET_ADDRESS

LitVM LiteForge

testnet

4441

ECAddress.LITVM.TESTNET_ADDRESS

The IoTeX, Sepolia, and LitVM testnets share a single ECLD token address, so the runner reads the chain ID from your wallet/provider to tell them apart. When you connect a browser wallet or pass a provider, this is automatic. If you drive the runner with a raw private key instead, pass the network's chain ID as the third constructor argument (and an rpcUrl in the wallet options) so the correct chain is selected:

Make sure the enclave image you pass to runner.run(...) (step 8) belongs to the same network — the ECRunner enum is keyed by network, e.g. ECRunner.IOTEX.PYNITHY_RUNNER_TESTNET for IoTeX or ECRunner.BLOXBERG.PYNITHY_RUNNER_TESTNET for Bloxberg.

  1. Decentralized Storage Initialization:

Next, initialize the Ethernity Cloud Runner's decentralized storage by specifying the IPFS address where it will communicate with the IPFS network.

For this integration, you have multiple options to initialize the storage:

  • Ethernity Cloud IPFS Server (Recommended for Development):

Utilize the default IPFS address 'https://ipfs.ethernity.cloud' provided by Ethernity Cloud, which serves as an efficient option for development purposes. It ensures seamless initialization with the specified IPFS address, allowing you to focus on task execution without managing your own IPFS infrastructure.

  • Custom IPFS Server:

Alternatively, if you have your own IPFS server set up or prefer to use a different IPFS address, you can provide the desired IPFS address to the runner.initializeStorage(ipfsAddress) method. This option empowers you to leverage any IPFS infrastructure that suits your specific requirements.

  • Other Decentralized Storage Solutions:

Ethernity Cloud Runner offers the flexibility to integrate with various decentralized storage solutions beyond IPFS. While IPFS is the default and recommended option, you can explore other decentralized storage systems based on your needs and preferences.

  1. Events subscription:

The runner is an EventTarget. As a task moves through its lifecycle it dispatches CustomEvents named by the task status, so you subscribe using the ECStatus values:

  • ECStatus.DEFAULT ("Running") — progress updates while the task is encrypting, being submitted, matched, and processed.

  • ECStatus.SUCCESS ("Success") — the task finished and a result is available.

  • ECStatus.ERROR ("Error") — something failed.

Each event's detail carries { message, status, progress }, where progress is a human-readable phase label (one of the ECEvent values, e.g. "In Progress", "Downloading result", "Finished").

By subscribing to these three status events, developers can follow the execution phase-by-phase (via e.detail.progress) and fetch the final result with await runner.getResult() once ECStatus.SUCCESS fires.

  1. Task Execution:

The heart of the integration is the await runner.run(...) line, which initiates task execution. The function signature is run(resources, secureLockEnclave, code, nodeAddress = '', trustedZoneEnclave):

  • Resources: An object describing the resources the task needs — taskPrice (in the network's token), cpu, memory (GB), storage (GB), bandwidth, duration, and validators.

  • Enclave image (secureLockEnclave): The enclave image to execute the task, taken from the network-keyed ECRunner enum. Two templates are available per network:

    • Python: ECRunner.<NETWORK>.PYNITHY_RUNNER_TESTNET

    • Node.js: ECRunner.<NETWORK>.NODENITHY_RUNNER_TESTNET

      where <NETWORK> matches the network you selected in step 5 (BLOXBERG, POLYGON, IOTEX, SEPOLIA, LITVM). Mainnet variants drop the _TESTNET suffix.

  • Code: The code to execute as the task (preserve proper indentation for Python).

  • Node Address (Optional): Provide an EC node's wallet address to auto-approve the order on that node; omit it (empty string) to have the order matched and manually approved by any available node.

    • Manual Approval: Omitting the node address lets the network match and approve the task.

    • Automatic Approval: Passing a node address targets that node for a seamless, quick execution.

  1. Rendering the Button

  1. Final application code

  1. Application styling

Now, navigate to the src/App.css file and proceed to enhance its content by adding the following CSS classes:

In conclusion, the above-mentioned code elegantly integrates the Ethernity Cloud Runner into your React app, enabling seamless execution of Python/Node.js code snippets while facilitating interaction with the IPFS network for efficient data storage and retrieval. As a professional developer, you can now leverage this integration to enhance your React applications with powerful decentralized task execution capabilities.

Last updated