<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DC</title>
    <description>The latest articles on DEV Community by DC (@dc600).</description>
    <link>https://dev.to/dc600</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2900291%2F39cae2b5-c4d4-436f-a982-cad67f3b24ae.jpg</url>
      <title>DEV Community: DC</title>
      <link>https://dev.to/dc600</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dc600"/>
    <language>en</language>
    <item>
      <title>Your Guide to the Prerequisites for Running Nodes on Oasis (Part 2): Stake Requirements and Node Installation</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Wed, 28 Oct 2026 10:27:29 +0000</pubDate>
      <link>https://dev.to/dc600/your-guide-to-the-prerequisites-for-running-nodes-on-oasis-part-2-stake-requirements-and-node-3nk6</link>
      <guid>https://dev.to/dc600/your-guide-to-the-prerequisites-for-running-nodes-on-oasis-part-2-stake-requirements-and-node-3nk6</guid>
      <description>&lt;p&gt;Before you can run a node for a blockchain protocol, there are several things to prepare. In this 4-part series, I discuss the prerequisites for running nodes on Oasis in detail. In &lt;a href="https://dev.to/dc600/your-guide-to-the-prerequisites-for-running-nodes-on-oasis-part-1-hardware-and-cloud-providers-cnb"&gt;part 1&lt;/a&gt;, we learned about hardware and cloud providers. Here, I will cover stake requirements and how to install the Oasis Node.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Stake Requirements&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Based on your node role and whether you are on the mainnet or the testnet, you need to keep in mind the following requirements.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Registration of entity&lt;/strong&gt;&lt;br&gt;
Mainnet: 100 ROSE&lt;br&gt;
Testnet: 100 TEST&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: To get the latest entity registration requirement, you will need to run the command &lt;a href="https://docs.oasis.io/build/tools/cli/network#show-native-token" rel="noopener noreferrer"&gt;oasis network show native-token&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Registration of node&lt;/strong&gt;&lt;br&gt;
Mainnet: 100 ROSE&lt;br&gt;
Testnet: 100 TEST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Size of the validator set&lt;/strong&gt;&lt;br&gt;
Mainnet: 120&lt;br&gt;
Testnet: 110&lt;br&gt;
&lt;strong&gt;Notes&lt;/strong&gt;: The validator set is the consensus committee, and its size is capped by the &lt;a href="https://docs.oasis.io/node/reference/genesis-doc#committee-scheduler" rel="noopener noreferrer"&gt;max_validators committee-scheduler parameter&lt;/a&gt;. To view the current value, you will need to run the command &lt;a href="https://docs.oasis.io/build/tools/cli/network#show-parameters" rel="noopener noreferrer"&gt;oasis network show parameters&lt;/a&gt;.&lt;br&gt;
For mainnet, to find out whether you are eligible to receive a delegation from the Oasis Protocol Foundation, check out the &lt;a href="https://docs.oasis.io/get-involved/delegation-policy" rel="noopener noreferrer"&gt;Delegation Policy&lt;/a&gt;.&lt;br&gt;
For testnet, the &lt;a href="https://faucet.testnet.oasis.io/" rel="noopener noreferrer"&gt;faucet&lt;/a&gt; generates only a limited number of TEST tokens. If you need more, you will need to contact the team on the official Discord in the &lt;a href="https://oasis.io/discord" rel="noopener noreferrer"&gt;testnet channel&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run a Sapphire or Emerald compute node&lt;/strong&gt;&lt;br&gt;
Mainnet: 5,000,000 ROSE + member of the validator set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run a Cipher compute node&lt;/strong&gt;&lt;br&gt;
Mainnet: member of the validator set&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;: The docs list no separate testnet figures.&lt;br&gt;
To get the latest paratime-specific stake requirements, you will need to run the command &lt;a href="https://docs.oasis.io/build/tools/cli/network#show-id" rel="noopener noreferrer"&gt;oasis network show&lt;/a&gt; and specify the &lt;a href="https://docs.oasis.io/node/network/mainnet#paratimes" rel="noopener noreferrer"&gt;paratime ID for mainnet&lt;/a&gt;.&lt;br&gt;
To know who the current top validators are, you can do that either with &lt;a href="https://explorer.oasis.io/mainnet/consensus" rel="noopener noreferrer"&gt;Oasis Explorer&lt;/a&gt; or with the CLI command &lt;a href="https://docs.oasis.io/build/tools/cli/network#show-validators" rel="noopener noreferrer"&gt;oasis network show validators&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As mentioned, requirements vary according to your choice of node role. Here is a snapshot of the role-specific steps to set up a working node from scratch.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6wh2cz32n4nlvt69hq4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6wh2cz32n4nlvt69hq4b.png" alt=" " width="800" height="574"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: There are no specific requirements for non-validator nodes.&lt;/p&gt;

&lt;p&gt;To check whether you meet the requirements for your node role, you will first need to view the balance of your account. You can do that either with Oasis Explorer or with the CLI command &lt;a href="https://docs.oasis.io/build/tools/cli/account#show" rel="noopener noreferrer"&gt;oasis account show&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Installing the Oasis Node&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Oasis Node is a binary created from the &lt;a href="https://github.com/oasisprotocol/oasis-core" rel="noopener noreferrer"&gt;Oasis Core&lt;/a&gt; repository's &lt;a href="https://github.com/oasisprotocol/oasis-core/tree/master/go" rel="noopener noreferrer"&gt;go/&lt;/a&gt; directory. It is a single executable and contains the logic for running your node in various &lt;a href="https://docs.oasis.io/node/#validator-and-paratime-nodes" rel="noopener noreferrer"&gt;roles&lt;/a&gt;. Currently, the Oasis Node is only supported on &lt;strong&gt;x86_64 Linux systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up the working directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need a place to store necessary files before installing the Oasis Node, so that is the first step. In this guide, &lt;code&gt;/node&lt;/code&gt; refers to the working directory.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;/node&lt;/code&gt; directory, start by creating the following subdirectories to allocate specific storage roles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;etc/&lt;/code&gt;: configuration and &lt;code&gt;entity.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data/&lt;/code&gt;: node's data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bin/&lt;/code&gt;: &lt;code&gt;oasis-node&lt;/code&gt; binary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;runtimes/&lt;/code&gt;: paratime &lt;code&gt;.orc&lt;/code&gt; bundles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To establish the directory structure along with the corresponding permissions, you will need to execute this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -m700 -p /node/{etc,bin,runtimes,data}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Creating directories under &lt;code&gt;/&lt;/code&gt; usually requires root privileges. Make sure the account that will run the node owns &lt;code&gt;/node&lt;/code&gt; afterwards, since the &lt;code&gt;700&lt;/code&gt; permissions give access to the owner only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copying the Genesis file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can find the latest Genesis file for &lt;a href="https://docs.oasis.io/node/network/mainnet" rel="noopener noreferrer"&gt;mainnet&lt;/a&gt; and &lt;a href="https://docs.oasis.io/node/network/testnet" rel="noopener noreferrer"&gt;testnet&lt;/a&gt; as part of the network parameters. The next step involves downloading the latest &lt;code&gt;genesis.json&lt;/code&gt; file and copying it to &lt;code&gt;/node/etc/genesis.json&lt;/code&gt; on the server.&lt;/p&gt;

&lt;p&gt;Once done, you can now get the &lt;code&gt;oasis-node&lt;/code&gt; Binary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downloading a binary release&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Oasis Protocol Foundation builds and provides the binaries. Since the Oasis Node is part of the Oasis Core release, start by finding the network parameters linked earlier for the respective mainnet and testnet. Next, follow the Oasis Core version link to its GitHub release, where the downloads are listed under Assets. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building from source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building from source is highly suggested, but the Oasis documentation currently treats it as beyond its scope. You will need to check out &lt;a href="https://docs.oasis.io/core/development-setup/build-environment-setup-and-building" rel="noopener noreferrer"&gt;Oasis Core's Build Environment Setup and Building&lt;/a&gt; documentation for more details. &lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: The code in the current &lt;a href="https://github.com/oasisprotocol/oasis-core/tree/master/" rel="noopener noreferrer"&gt;master&lt;/a&gt; branch may be incompatible with the code used by other nodes on the network. It is thus essential that you use the version specified in the network parameters linked earlier for the respective mainnet and testnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding &lt;code&gt;oasis-node&lt;/code&gt; binary to &lt;code&gt;PATH&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are installing the &lt;code&gt;oasis-node&lt;/code&gt; binary next to your Oasis Node data directory, you will need to copy/symlink it to &lt;code&gt;/node/bin&lt;/code&gt;. Now, if you are installing the binary for the current user, the copy/symlink needs to be to &lt;code&gt;~/.local/bin&lt;/code&gt;. To install it for all users of the system, you have to copy it to &lt;code&gt;/usr/local/bin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Running paratimes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is applicable only if you are &lt;a href="https://docs.oasis.io/node/run-your-node/paratime-node" rel="noopener noreferrer"&gt;running a paratime node&lt;/a&gt;. You will then need to install some additional software packages.&lt;/p&gt;

&lt;p&gt;You will need &lt;a href="https://github.com/projectatomic/bubblewrap" rel="noopener noreferrer"&gt;Bubblewrap&lt;/a&gt; 0.4.1+ to create process sandboxes.&lt;br&gt;
On Ubuntu 20.04+, you can install it with this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install bubblewrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Fedora, use this command instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dnf install bubblewrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This concludes part 2 of the prerequisites series. In the next part, I will discuss system configuration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For technical specs, APIs, architecture, and integration guides, the &lt;strong&gt;&lt;a href="https://docs.oasis.io/" rel="noopener noreferrer"&gt;Oasis documentation&lt;/a&gt;&lt;/strong&gt; is your starting point.&lt;/li&gt;
&lt;li&gt;For direct support on specific issues, the Oasis engineering team and other node operators are available in the &lt;strong&gt;&lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;node-operators channel&lt;/a&gt;&lt;/strong&gt; on the official Discord.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>nodes</category>
      <category>devex</category>
    </item>
    <item>
      <title>Your Guide to the Prerequisites for Running Nodes on Oasis (Part 1): Hardware and Cloud Providers</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Wed, 28 Oct 2026 06:34:53 +0000</pubDate>
      <link>https://dev.to/dc600/your-guide-to-the-prerequisites-for-running-nodes-on-oasis-part-1-hardware-and-cloud-providers-cnb</link>
      <guid>https://dev.to/dc600/your-guide-to-the-prerequisites-for-running-nodes-on-oasis-part-1-hardware-and-cloud-providers-cnb</guid>
      <description>&lt;p&gt;There are various ways to support a blockchain protocol. For example, tech-savvy users sometimes prefer to run nodes. Now, if you are planning to do so, specific hardware and software prerequisites must be in place. In this 4-part series, I will discuss them in detail for running nodes on Oasis. The first part covers hardware and cloud providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Hardware Requirements&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As outlined in the &lt;a href="https://dev.to/dc600/your-guide-to-the-nodes-you-can-run-on-oasis-135n"&gt;introduction to Oasis nodes&lt;/a&gt;, the protocol consists of several distinct node types.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consensus validator or non-validator node&lt;/li&gt;
&lt;li&gt;Sapphire compute or client node&lt;/li&gt;
&lt;li&gt;Emerald compute or client node&lt;/li&gt;
&lt;li&gt;Cipher compute or client node&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this section, I will focus on the minimum and recommended system hardware requirements. Anyone planning to run more than one paratime (Sapphire/Emerald/Cipher) on a single node will need more resources. &lt;/p&gt;

&lt;p&gt;If you configure a system with fewer resources than recommended, you run the risk of being under-provisioned. This can cause proposer node timeouts and synchronization delays. If your node exhausts its memory or storage, the node process is forcefully killed, which can result in state corruption. As a result, you risk losing stake and getting barred from participating in committees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CPUs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consensus validator or non-validator node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 2.0 GHz x86-64 CPU with &lt;a href="https://en.wikipedia.org/wiki/AES_instruction_set" rel="noopener noreferrer"&gt;AES instruction set&lt;/a&gt; support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 2.0 GHz x86-64 CPU with 2 cores/vCPUs with AES instruction set and &lt;a href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2" rel="noopener noreferrer"&gt;Advanced Vector Extensions 2 (AVX2)&lt;/a&gt; support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Emerald compute node and all client nodes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: same as above&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 2.0 GHz x86-64 CPU with 4 cores/vCPUs with AES instruction set and AVX2 support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sapphire/Cipher ParaTime compute node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 2.0 GHz x86-64 CPU with AES instruction set and &lt;a href="https://www.intel.com/content/www/us/en/architecture-and-technology/software-guard-extensions.html" rel="noopener noreferrer"&gt;Intel SGX&lt;/a&gt; support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 2.0 GHz x86-64 CPU with 2 cores/vCPUs with AES instruction set, Intel SGX, and AVX2 support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you are running regular workloads on your node, the minimum resources will suffice. However, if you plan heavier workloads, like a paratime client node behind a public &lt;a href="https://docs.oasis.io/node/web3#hardware" rel="noopener noreferrer"&gt;Web3 gateway&lt;/a&gt;, you will need more cores/vCPUs.&lt;/li&gt;
&lt;li&gt;The reason you need AES instruction set support is that it is required by &lt;a href="https://sites.google.com/view/deoxyscipher" rel="noopener noreferrer"&gt;Deoxys-II-256-128&lt;/a&gt;, a Misuse-Resistant Authenticated Encryption (MRAE) algorithm, for encrypting paratime state.&lt;/li&gt;
&lt;li&gt;The reason you need AVX2 support is to enable faster Ed25519 signature verification. This will speed up node sync.&lt;/li&gt;
&lt;li&gt;You need Intel SGX support only when you are running paratime compute nodes (Sapphire/Cipher). Check out Intel's comprehensive list of &lt;a href="https://www.intel.com/content/www/us/en/architecture-and-technology/software-guard-extensions-processors.html" rel="noopener noreferrer"&gt;processors that support Intel SGX&lt;/a&gt;, and match it with Sapphire and Cipher &lt;a href="https://docs.oasis.io/get-involved/run-node/paratime-node/" rel="noopener noreferrer"&gt;requirements&lt;/a&gt; before proceeding.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consensus validator or non-validator node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 6 GB of ECC RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 8 GB of ECC RAM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Each Emerald/Sapphire/Cipher compute or client node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 12 GB of ECC RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 20 GB of ECC RAM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most scenarios, the nodes, even with less than the minimum amount of memory, will run regular workloads smoothly. To cover the more resource-intensive time points, such as the initial state sync, &lt;a href="https://dgraph.io/docs/badger/" rel="noopener noreferrer"&gt;BadgerDB&lt;/a&gt; migration when upgrading a node to a new major version of the Oasis Core, generating storage checkpoints with BadgerDB, and periodic BadgerDB compactions, your nodes will need more memory than usual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consensus validator or non-validator node&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 400 GB of SSD or NVMe fast storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 700 GB of SSD or NVMe fast storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Emerald compute or client node (in addition to the consensus storage requirements)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 400 GB of SSD or NVMe fast storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 700 GB of SSD or NVMe fast storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sapphire/Cipher compute or client node (in addition to the consensus storage requirements)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 200 GB of SSD or NVMe fast storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 300 GB of SSD or NVMe fast storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Both consensus and paratime states are stored in an embedded BadgerDB database. As BadgerDB is designed to run on SSDs, it is highly recommended not to run a node that stores data on HDDs.&lt;/li&gt;
&lt;li&gt;Both consensus and paratime states accumulate over time. The rate of storage growth varies by transaction count on the network and the paratimes. For example, a consensus non-validator node on the mainnet accumulated 280 GB of consensus state in approximately one year since the Cobalt upgrade, and 32 GB of consensus state in approximately one month since the Damask upgrade. Another example would be an Emerald client node on the mainnet, which additionally accumulated 260 GB of paratime state in approximately five months since Emerald's launch, and 25 GB of paratime state in approximately one month since the Damask upgrade.&lt;/li&gt;
&lt;li&gt;Dump and restore upgrades, such as the Damask and Cobalt upgrades, include state wipes that free up node storage. If you need to access historical state, you can run a separate archive node. Also note, the latest is Eden &lt;/li&gt;
&lt;li&gt;It is recommended not to keep a complete state from the genesis onward unless you are running a node to preserve historical state. This will also reduce storage requirements for both consensus and paratime states, as well as improve the overall latency of the storage-related operations. To enable storage reduction, you should check out &lt;a href="https://docs.oasis.io/node/run-your-node/advanced/pruning#consensus-pruning" rel="noopener noreferrer"&gt;consensus pruning&lt;/a&gt; and &lt;a href="https://docs.oasis.io/node/run-your-node/advanced/pruning#paratime-pruning" rel="noopener noreferrer"&gt;paratime pruning&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Network&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consensus validator node and all paratime compute nodes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum&lt;/strong&gt;: 200 Mbps internet connection with low latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: 1 Gbps internet connection with low latency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regular workloads use relatively little traffic. The higher bandwidth is recommended for bursts of transactions, when a node with too little bandwidth can time out.   &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cloud Providers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you plan to run a Sapphire or Cipher compute node, a crucial step is verifying processor compatibility and checking the status of Intel SGX support (refer to &lt;strong&gt;Note #4 in the CPUs section&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You will come across several bare-metal or dedicated server providers using Intel processors that support SGX. However, you should also be aware of potential limitations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BIOS configuration&lt;/strong&gt;: Some providers restrict users from accessing or modifying BIOS settings, which might be essential to correctly configure Intel SGX.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outdated firmware&lt;/strong&gt;: SGX requires the latest firmware to function correctly. If the system provider is behind on updates, this is a problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of SGX-specific offerings&lt;/strong&gt;: Some providers do not advertise or specifically offer SGX-enabled servers. Users need to know specifically that their server is SGX-enabled, as this feature is non-negotiable for running some Oasis nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited support&lt;/strong&gt;: Sometimes even when an SGX-enabled server is available, the provider's support team might lack the expertise to handle SGX-specific issues or configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardware provisioning&lt;/strong&gt;: Use of keys, such as SGX sealing keys, involves them being bound to hardware to encrypt the data of an instance within an Intel SGX enclave. If the host of the instance is changed, the encrypted data cannot be decrypted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Known providers&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.alibabacloud.com/" rel="noopener noreferrer"&gt;Alibaba Cloud&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://www.alibabacloud.com/en/product/ebm" rel="noopener noreferrer"&gt;(ECS) Bare Metal Instances&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://www.alibabacloud.com/help/en/ecs/user-guide/build-an-sgx-encrypted-computing-environment" rel="noopener noreferrer"&gt;Build an SGX confidential computing environment&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://azure.microsoft.com/" rel="noopener noreferrer"&gt;Azure&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://learn.microsoft.com/en-us/azure/virtual-machines/dedicated-host-general-purpose-skus" rel="noopener noreferrer"&gt;Some Dedicated Host SKUs&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://learn.microsoft.com/en-us/azure/confidential-computing/virtual-machine-solutions-sgx" rel="noopener noreferrer"&gt;Solutions on Azure for Intel SGX&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://gcore.com/" rel="noopener noreferrer"&gt;Gcore&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://gcore.com/cloud/bare-metal-servers" rel="noopener noreferrer"&gt;Bare Metal&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://gcore.com/cloud/intel-sgx" rel="noopener noreferrer"&gt;Computing with Intel SGX&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://cloud.ibm.com/" rel="noopener noreferrer"&gt;IBM Cloud&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://www.ibm.com/cloud/vpc" rel="noopener noreferrer"&gt;Virtual Private Cloud (VPC)&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://cloud.ibm.com/docs/vpc?topic=vpc-about-sgx-vpc" rel="noopener noreferrer"&gt;Confidential computing with SGX for VPC&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.ovhcloud.com/" rel="noopener noreferrer"&gt;OVH&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://www.ovhcloud.com/en/bare-metal/prices/?use_cases=confidential-computing" rel="noopener noreferrer"&gt;Bare Metal servers&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://www.ovhcloud.com/en/bare-metal/intel-software-guard-extensions/" rel="noopener noreferrer"&gt;SGX for Confidential Computing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://phoenixnap.com/" rel="noopener noreferrer"&gt;PhoenixNAP&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://phoenixnap.com/bare-metal-cloud" rel="noopener noreferrer"&gt;Bare Metal Cloud&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://phoenixnap.com/kb/intel-sgx" rel="noopener noreferrer"&gt;What is Intel SGX and What are the Benefits?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.vultr.com/" rel="noopener noreferrer"&gt;Vultr&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Product&lt;/strong&gt;: &lt;a href="https://www.vultr.com/products/bare-metal/" rel="noopener noreferrer"&gt;Bare Metal&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://zenlot.medium.com/intel-sgx-development-on-vultr-30cdfd5c9754" rel="noopener noreferrer"&gt;Intel SGX development on Vultr&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Provider offerings change, so the list above may not reflect each provider's current SGX support. So, it is recommended to check out the provider's own documentation and confirm Intel SGX availability with them directly.&lt;br&gt;
If any cloud or dedicated server providers that actively support Intel SGX or Intel TDX are not in this list, or if you come across updated information about the providers listed above, you can let the Oasis team know by &lt;a href="https://github.com/oasisprotocol/docs/issues/new" rel="noopener noreferrer"&gt;creating an issue on GitHub&lt;/a&gt; with the additional details.&lt;/p&gt;

&lt;p&gt;This concludes part 1 of the prerequisites series. In the &lt;a href="https://dev.to/dc600/your-guide-to-the-prerequisites-for-running-nodes-on-oasis-part-2-stake-requirements-and-node-3nk6"&gt;next part&lt;/a&gt;, I will discuss stake requirements and how to install the Oasis node.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For technical specs, APIs, architecture, and integration guides, the &lt;strong&gt;&lt;a href="https://docs.oasis.io/" rel="noopener noreferrer"&gt;Oasis documentation&lt;/a&gt;&lt;/strong&gt; is your starting point.&lt;/li&gt;
&lt;li&gt;For direct support on specific issues, the Oasis engineering team and other node operators are available in the &lt;strong&gt;&lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;node-operators channel&lt;/a&gt;&lt;/strong&gt; on the official Discord.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>nodes</category>
      <category>devex</category>
    </item>
    <item>
      <title>Introducing Privana: A Deep Dive into Underlying Technology</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Tue, 27 Oct 2026 12:36:43 +0000</pubDate>
      <link>https://dev.to/dc600/introducing-privana-a-deep-dive-into-underlying-technology-33ia</link>
      <guid>https://dev.to/dc600/introducing-privana-a-deep-dive-into-underlying-technology-33ia</guid>
      <description>&lt;p&gt;In the world of privacy-first decentralized finance (DeFi), the upcoming Privana, built by and on Oasis, proposes a unique solution that deserves a deep dive. In the &lt;a href="https://dev.to/dc600/introducing-privana-a-deep-dive-into-core-concepts-4aib"&gt;first part&lt;/a&gt; of this exploratory series, I detailed the core concepts of this private DeFi application. In this part, we will go deeper and look into the underlying technology that makes Privana tick.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Oasis Sapphire and ROFL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the core concepts, &lt;a href="https://docs.oasis.io/build/sapphire/" rel="noopener noreferrer"&gt;Sapphire&lt;/a&gt; was mentioned several times, but why is this such an integral part of the technology that drives Privana? How does the Runtime Off-chain Logic (ROFL) framework fit in? The scope of Privana's functionality depends on both on-chain and off-chain components running in attested Trusted Execution Environments (TEEs). &lt;/p&gt;

&lt;p&gt;As the confidential EVM runtime, Sapphire utilizes Intel SGX enclaves to ensure smart contract logic and its state are confidential by default. As a result, transactions and contract storage are encrypted, while validators and node operators, even though they are crucial to running the network, cannot access or alter them.&lt;/p&gt;

&lt;p&gt;Running Privana's on-chain functionalities with Sapphire has advantages that underpin the application's privacy and security. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EVM Compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sapphire is EVM-compatible, so the smart contracts are written in Solidity. There is no need for prior or specialized TEE knowledge, and the confidential smart contracts can be independently audited, as the &lt;a href="https://github.com/oasisprotocol/privana" rel="noopener noreferrer"&gt;code is public&lt;/a&gt;. Anyone can thus verify whether the on-chain logic functions as claimed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confidential State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a critical property of Sapphire, as the encrypted contract storage stays on-chain and in memory. It guarantees that the state is accessible only to the executing TEE. This means that user balances, policies, and trade history are and remain private. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuspy8f42075vpz74s81q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuspy8f42075vpz74s81q.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;br&gt;
The diagram shows how each contract is encrypted with its own key, held by an isolated Key Manager. However, as it states, node operators are still able to view the access patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-chain signing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The core concepts highlight Privana as a multi-chain application. The architecture of Sapphire can help us understand how an EVM blockchain manages this.&lt;/p&gt;

&lt;p&gt;A Sapphire contract holds the private key inside the enclave and signs cross-chain transactions on Oasis itself. The key thus never leaves the enclave, and the contract logic that decides what to sign remains confidential. So, the destination chain can only see the finished transaction, a regularly signed transaction made from the application's pooled vault address. As a result, there is no way to link the transaction back to the users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ROFL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The chain-agnostic nature of Privana's vaults and the off-chain execution of application logic come from &lt;a href="https://docs.oasis.io/build/rofl/" rel="noopener noreferrer"&gt;ROFL&lt;/a&gt; TEEs, attested on-chain by Oasis Sapphire. The application's functionalities that run inside a ROFL container are executed in an off-chain, attested, TEE-secured setting. In the subsequent stage, Sapphire verifies whether the EVM transactions originate from that specific ROFL instance.&lt;/p&gt;

&lt;p&gt;In short, Sapphire holds the keys and handles accounting and signing, while the Privana service, running in ROFL, handles deposit verification, swaps, yield, and broadcasting.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Privana's Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While discussing the core concepts of Privana, we briefly touched on the architecture. Let's look at it now in more detail. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnsaavv2mftb0i9mtck9t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnsaavv2mftb0i9mtck9t.png" alt=" " width="800" height="461"&gt;&lt;/a&gt;&lt;br&gt;
There are five components. Integrators build with the Privana SDK, which then calls the service via the REST API. This service sits at the center of everything: it reads and writes the Oasis Sapphire contracts, which hold the keys and sign transactions confidentially, and it verifies and settles transactions on external chains, where deposits and pooled vaults sit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accounting block&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Accounting here is the confidential ledger. The contract stays on Sapphire and holds a mapping of deposit addresses to asset balances. This is entirely encrypted. The Privana service maintains this system with various functions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;processing deposits on each source chain&lt;/li&gt;
&lt;li&gt;ensuring balance change management works smoothly&lt;/li&gt;
&lt;li&gt;implementing the Know Your Transaction (KYT) routine by screening transactions&lt;/li&gt;
&lt;li&gt;validating balances before any trades can take place&lt;/li&gt;
&lt;li&gt;ensuring finality reconciliation once execution has gone through&lt;/li&gt;
&lt;li&gt;handling withdrawals taking place in all the supported chains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Microservices block&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Microservices implement the execution logic for DeFi operations. Privana has two microservices: swaps and yield. These will be covered in detail later. Moreover, there is room to add new ones going forward if Privana decides to diversify its services in perpetuals or lending. This is possible because the core accounting logic stays the same for all microservices as they settle against the same wallet balance, using the same signature path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remote attestation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TEEs being the privacy-preserving core of both Sapphire (SGX) and ROFL (TDX), understanding how remote attestations work in Privana is important. The attestation reports are signed by Intel's hardware root of trust. As a result, anyone can remotely verify that the enclave is running exactly the code it claims to run.   &lt;/p&gt;

&lt;p&gt;The beauty of this verification engine is that it is all-encompassing, providing robust, in-depth auditability that regular audits could have missed. It covers the on-chain contracts, the off-chain Privana service, as well as the microservices running in attested ROFL containers. This means it is also possible to verify the swap and yield logic being executed by the application. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not limited to DeFi&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the core architectural strengths of Privana is that its SDK is composable. So, while Privana acts as the face of private DeFi, the applicability goes beyond it. As a result, any dApp that involves private balances or scoped, time-bounded access can use the underlying architecture of the vaults. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Fallback &amp;amp; Recovery&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For the end users, there is a nagging question about any services, especially web3-related ones such as DeFi, given the crypto space has yet to achieve significant mass adoption. So, what happens if the enclave goes offline permanently, or if Privana stops its application and service? &lt;/p&gt;

&lt;p&gt;A USP of Privana's architecture is that it has built-in fallback and recovery safeguards. This is not a run-of-the-mill service-level promise; it is embedded in the system and guaranteed by Oasis Sapphire. &lt;/p&gt;

&lt;p&gt;As mentioned, Sapphire runs and executes the &lt;code&gt;Accounting&lt;/code&gt; contract, which means it is not dependent on Privana's off-chain service. Since the contract state is on-chain, even if Privana's application and service go offline, the exit option remains open. Let's see how this works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-chain withdrawal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Accounting&lt;/code&gt; contract allows two withdrawal paths independent of the downtime of the off-chain service in the ROFL container. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User balance&lt;/strong&gt;: The user can submit a withdrawal request signed by their wallet. The contract will return a signed transaction after a short time lapse on-chain. This results in the transaction paying out the user to their own address on the source chain. Anyone can broadcast it for the user, which also minimizes the risk of the funds being lost or stolen.     &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Funds in user deposit address&lt;/strong&gt;: This method is initiated if a deposit was never swept into the vault. The user can then call the contract directly to recover it. Following a short time lapse on-chain, the contract will return a signed transaction, the same as the first method. The difference here is that, in this case, the user can specify the destination in that call and will accordingly receive the payout.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important aspect of both these methods is that the payout address is specified before the transaction is signed. So, it is fixed permanently, and even if there is an untrusted broadcaster, the funds will only route to the designated address. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beyond service outage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A service outage is the easier case, since Sapphire stays live and the withdrawal paths above still work. A more serious scenario, like a permanently lost enclave, is where Privana's recovery model, informed by the sentinel-wallet design, comes into play. &lt;/p&gt;

&lt;p&gt;Liquefaction, whose role in Privana is described later, outlines operator-independent recovery so that asset owners can reclaim control of their funds without needing to trust any single party. This is reassuring: user assets are not designed to be permanently lockable. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Trust Model&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We glanced over this while discussing Privana's core concepts. Let's explore more here. &lt;/p&gt;

&lt;p&gt;No system is or can ever be absolutely trustless. Privana is built using technology that minimizes trust requirements as much as possible, but some assumptions still remain. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyr8i7tqv09whxz6pzfjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyr8i7tqv09whxz6pzfjr.png" alt=" " width="800" height="529"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt; from the table screenshot: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Research Basis: next section&lt;/li&gt;
&lt;li&gt;Sapphire &lt;a href="https://docs.oasis.io/build/sapphire/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two risks cannot be eliminated for Privana, even with the best of preparedness.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vulnerabilities in the TEE hardware itself, whether Intel SGX or TDX. This is inherent for all TEE platforms, although Sapphire, using SGX technology, has various mitigation steps added in the form of defense-in-depth design. Sapphire's SGX TEE resilience was demonstrated by its &lt;a href="https://oasis.net/blog/oasis-tee-vulnerabilities" rel="noopener noreferrer"&gt;withstanding TEE attacks&lt;/a&gt; by Battering RAM and Wiretap.&lt;/li&gt;
&lt;li&gt;Smart contract bugs in the external yield protocols that the user might choose to interact with. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Privana approaches this by mitigating potential fallout through conservative platform selection, audits, and protocol vetting. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete Knowledge proofs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://oasis.net/blog/privana-liquefaction-implementation" rel="noopener noreferrer"&gt;Liquefaction&lt;/a&gt; is one of the crucial technologies on which Privana stands, as it introduces key encumbrance. The Liquefaction framework also discusses &lt;strong&gt;Complete Knowledge (CK) proofs&lt;/strong&gt;, which are cryptographic proofs that a user has unencumbered access to a private key. They could become a valuable complement to Privana, for example, by letting centralized exchanges verify that a depositor's keys are not encumbered.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Research Basis&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The groundwork behind Privana's architecture and technology is laid down by cryptographic research from Cornell Tech. Recommended reading starts with the &lt;a href="https://arxiv.org/abs/2412.02634" rel="noopener noreferrer"&gt;Liquefaction paper&lt;/a&gt; as the primary research basis. &lt;/p&gt;

&lt;p&gt;This paper introduces key encumbrance as the core primitive, demonstrating that TEE-based key encumbrance can break the Single-Entity Address-Ownership (SEAO) assumption. Let's now look at the four cornerstones of the research that help to understand how the Liquefaction framework is implemented by Oasis in Privana. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Key Encumbrance&lt;/strong&gt;: Generating a private key and securely holding it inside a TEE, governed by programmable access-control policies, enabling automation without custody transfer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SEAO Assumption&lt;/strong&gt;: Challenging the assumption that one blockchain address can only be controlled by a single entity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Asset-Time Segmentation&lt;/strong&gt;: Implementing exclusive asset control by one sub-policy at any given time, thereby ensuring multiple policies don't end up competing amongst themselves, which could result in deadlock and double-spend.    &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Overlay Smart Contracts&lt;/strong&gt;: Applying smart-contract-like logic to chains, such as Bitcoin, Litecoin, Dogecoin, etc., that don't support native smart contracts as an extension of the encumbered keys being managed off-chain in TEEs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For interested readers, there are several references available in addition to the Liquefaction paper, if they want to do their own research on the security model. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kelkar et al. on Complete Knowledge proofs (&lt;a href="https://eprint.iacr.org/2023/044" rel="noopener noreferrer"&gt;ACM CCS, 2024&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Jean-Louis et al. on privacy flaws in TEE-based platforms (&lt;a href="https://eprint.iacr.org/2023/378" rel="noopener noreferrer"&gt;ePrint 2023/378&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Van Schaik et al. on SGX security (&lt;a href="https://par.nsf.gov//servlets/purl/10502842" rel="noopener noreferrer"&gt;IEEE S&amp;amp;P, 2024&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integrations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The components of Privana are assembled from public, auditable infrastructure, chosen because of their popular adoption and independent operation. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvc59qusl1rpkh8hj9nj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvc59qusl1rpkh8hj9nj9.png" alt=" " width="799" height="429"&gt;&lt;/a&gt;&lt;br&gt;
These are the live integrations as of now. If any services become unavailable, they can be replaced by similar services with the same interface.&lt;/p&gt;

&lt;p&gt;This concludes the deep dive into Privana’s underlying technology. Next time, I will discuss Privana’s features in detail. In the meantime, let’s continue the discussion in the comments section about what you think of these technological components that are the basis of Privana’s build.&lt;/p&gt;

&lt;p&gt;Resources &amp;amp; references:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://privana.finance/" rel="noopener noreferrer"&gt;Privana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oasis.net/" rel="noopener noreferrer"&gt;Oasis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For specific questions or feedback, connect on the &lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;Privana channel&lt;/a&gt;** on the official Discord.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web3</category>
      <category>decentralizedfinance</category>
      <category>privacy</category>
      <category>privana</category>
    </item>
    <item>
      <title>Your Guide to the Nodes You Can Run on Oasis</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Thu, 24 Sep 2026 07:22:24 +0000</pubDate>
      <link>https://dev.to/dc600/your-guide-to-the-nodes-you-can-run-on-oasis-135n</link>
      <guid>https://dev.to/dc600/your-guide-to-the-nodes-you-can-run-on-oasis-135n</guid>
      <description>&lt;p&gt;Tech-savvy users can get more involved in a blockchain protocol than the general community usually does - by running nodes that boost the network's security, robustness, diversity, and decentralization. In this guide, I will introduce the various types of nodes you can run on Oasis, with an overview of the distinctive roles they play in the protocol. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Validator Node&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Oasis is a proof-of-stake (PoS) protocol, which makes the &lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/validator-node" rel="noopener noreferrer"&gt;validator node&lt;/a&gt;&lt;/strong&gt; the single most critical component of the network. If you are running such a node, your responsibilities will range from verifying transactions to proposing new blocks to be added to the blockchain.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwk26wxfun2q531ffy79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwk26wxfun2q531ffy79.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Since Oasis has a modular architecture separating the consensus and the execution layers, where this node operates is an important indicator of its role in the network. Operating from the consensus layer, the validator node functions by staking the network's native token, &lt;a href="https://docs.oasis.io/general/manage-tokens/" rel="noopener noreferrer"&gt;ROSE&lt;/a&gt;. When you run this node, you participate in the consensus process by validating transactions, signing blocks, and ensuring the integrity of the blockchain. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Compute Nodes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As mentioned, the execution layer is separate in Oasis's architecture, and there are multiple parallel runtime instances possible, known as paratimes. So, &lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/paratime-node" rel="noopener noreferrer"&gt;compute nodes&lt;/a&gt;&lt;/strong&gt; are those that participate in executing smart contracts and processing related transactions in the network.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhghm57lw57s3a60m9wu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhghm57lw57s3a60m9wu.png" alt=" " width="800" height="527"&gt;&lt;/a&gt;&lt;br&gt;
If you are running such a node, your responsibilities will include handling computations, running decentralized applications (dApps), data processing, and executing privacy-preserving smart contracts.   &lt;/p&gt;

&lt;p&gt;Currently, there are three types of compute nodes on Oasis, based on operational paratimes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sapphire Compute Node&lt;/strong&gt; - If you are running this node, you are helping execute privacy-preserving smart contracts and process transactions on Oasis's confidential EVM runtime, Sapphire. This type of node is crucial to mainta&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;ining the confidentiality of sensitive data that is run through trusted execution environments (&lt;a href="https://docs.oasis.io/node/run-your-node/prerequisites/set-up-tee" rel="noopener noreferrer"&gt;TEEs&lt;/a&gt;). As a result, data remains encrypted and confidential while being processed, and enhanced security is enabled throughout.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cipher Compute Node&lt;/strong&gt; - Its role and functionality are the same as Sapphire, with only one exception: it is run on Oasis's WASM runtime, Cipher. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Emerald Compute Node&lt;/strong&gt; - This pertains to Oasis's original, non-confidential EVM runtime, Emerald. The function of this node is limited to executing smart contracts, validating transactions, and other operations within the paratime. There is no privacy-preserving component here.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Client Nodes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The role of a &lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/paratime-client-node" rel="noopener noreferrer"&gt;client node&lt;/a&gt;&lt;/strong&gt; is to enable an interface for users or other applications to interact with the network.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3p53wxgyxstbw8kw8lm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3p53wxgyxstbw8kw8lm.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
It is functionally different from compute nodes. If you are running such a node, your responsibilities will include performing blockchain queries, submitting transactions, and retrieving other data from the network.&lt;/p&gt;

&lt;p&gt;There are half a dozen different types of client nodes on Oasis that you can run at the moment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/non-validator-node" rel="noopener noreferrer"&gt;Non-Validator Node&lt;/a&gt;&lt;/strong&gt; - This type of client node supports network operations and decentralization instead of taking part in the consensus process of validating and proposing new blocks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sapphire Client Node&lt;/strong&gt; - This type of client node interacts specifically with the Sapphire runtime and its EVM-compatible privacy functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cipher Client Node&lt;/strong&gt; - This type of client node interacts specifically with the Cipher runtime and its WASM-compatible privacy functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/rofl-node" rel="noopener noreferrer"&gt;ROFL Node&lt;/a&gt;&lt;/strong&gt; - It is a specialized &lt;strong&gt;Sapphire client node&lt;/strong&gt; that supports TEEs and can host &lt;a href="https://docs.oasis.io/build/rofl/" rel="noopener noreferrer"&gt;ROFL apps&lt;/a&gt; integrating the runtime off-chain logic (ROFL) framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/paratime-observer-node" rel="noopener noreferrer"&gt;Observer Node&lt;/a&gt;&lt;/strong&gt; - It is a specialized client node for confidential paratimes like Sapphire and Cipher. So, if you run this node, you help with confidential smart contract queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/paratime-client-node#stateless-client-node-optional" rel="noopener noreferrer"&gt;Stateless Node&lt;/a&gt;&lt;/strong&gt; - It is a specialized client node that can operate without maintaining state, enabling instant bootstrapping, which makes it valuable for ROFL development.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Archive Node &amp;amp; Seed Node&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;These are a couple of specialized nodes on Oasis. The &lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/archive-node" rel="noopener noreferrer"&gt;archive node&lt;/a&gt;&lt;/strong&gt; stores the entire blockchain history. This is a critical function for in-depth analysis and development of the protocol, where you help ensure that all the past iterations of the network state remain accessible.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/seed-node" rel="noopener noreferrer"&gt;seed node&lt;/a&gt;&lt;/strong&gt; is like an address book for the network. By running this node, you ensure crucial support for other nodes so that they can discover peers and join the network. Like the non-validator node, it has no part to play in the consensus process. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Manager Node&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Decentralized key management is an essential primitive on Oasis. This makes the &lt;strong&gt;&lt;a href="https://docs.oasis.io/node/run-your-node/keymanager-node/" rel="noopener noreferrer"&gt;Key Manager Node&lt;/a&gt;&lt;/strong&gt; a highly specialized node on the network. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4un1l5bmhzm7fpzp1mjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4un1l5bmhzm7fpzp1mjg.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
If you are running such a node, your responsibilities center around securely managing cryptographic keys used in confidential computing. As a result, the node becomes vital for the network's secure, decentralized, and privacy-focused operations. It helps maintain the myriad privacy-preserving features as well as ensure secure encryption and decryption of data processed within the TEEs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Services&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes the nodes you run come with optional add-on services or interface layers sitting on top of the nodes. Let's look at the services that you can bundle with your nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rosetta Gateway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/oasisprotocol/oasis-rosetta-gateway" rel="noopener noreferrer"&gt;Rosetta Gateway&lt;/a&gt; is a specialized service that connects to a non-validator node. It implements the Rosetta API and provides a simplified, standardized interface to interact with the blockchain. If you opt for this service, it will ease the integration between Oasis and various external platforms, including exchanges, wallets, custodians, and blockchain-based applications. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public gRPC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a specialized service, this is a helpful management tool for developers that is not scoped to any single node type. The Oasis gRPC protocol provides an efficient, real-time, and cross-platform communication channel between the Oasis node and the network. As each node opens a gRPC socket, the public endpoints run a proxy exposing a small, safe subset of that API publicly. It thus acts as a filtering layer standing guard on what the node's raw gRPC socket would otherwise expose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web3 Gateway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Web3 Gateway is a specialized service that connects to a compute or a client node with EVM compatibility. It interacts with Oasis via the standard Web3 protocol, thereby opening a bridge to external Web3-based applications. It enables developers to access and leverage the tools, libraries, and practices in line with Ethereum development while also benefiting from Oasis's features and functionalities of privacy and confidential computation. &lt;/p&gt;

&lt;p&gt;This concludes the overview of the nodes you can run on Oasis. It is by no means comprehensive, as the prerequisites and the steps to run the nodes are too detailed to include here. So, I will follow this up with subsequent guides that cover them in the detail they warrant. Stay tuned.&lt;/p&gt;

&lt;p&gt;For technical specs, APIs, architecture, and integration guides, the &lt;strong&gt;&lt;a href="https://docs.oasis.io/" rel="noopener noreferrer"&gt;Oasis documentation&lt;/a&gt;&lt;/strong&gt; is your starting point.&lt;br&gt;
For direct support on specific issues, the Oasis engineering team and other node operators are available in the &lt;strong&gt;&lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;node-operators channel&lt;/a&gt;&lt;/strong&gt; on the official Discord.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>nodes</category>
      <category>devex</category>
    </item>
    <item>
      <title>Introducing Privana: A Deep Dive into Core Concepts</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Mon, 21 Sep 2026 08:55:40 +0000</pubDate>
      <link>https://dev.to/dc600/introducing-privana-a-deep-dive-into-core-concepts-4aib</link>
      <guid>https://dev.to/dc600/introducing-privana-a-deep-dive-into-core-concepts-4aib</guid>
      <description>&lt;p&gt;Privacy in blockchain and web3 is not a default setting. Because privacy must be designed in, decentralized applications (dApps), including decentralized finance (DeFi) solutions, often lack it. As a private, non-custodial DeFi interface, Privana aims to answer this need.&lt;/p&gt;

&lt;p&gt;Built by the Oasis team, Privana runs on Sapphire’s confidential EVM runtime inside hardware-secured enclaves, better known as Trusted Execution Environments (TEEs). This setup enables the features of privacy, automation, and self-custody to coexist without trade-offs. &lt;/p&gt;

&lt;p&gt;Before understanding in detail the core concepts behind Privana, it is useful to examine the privacy problem and how it is intended to be solved.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Finding the missing piece of the privacy puzzle&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;What &lt;a href="https://dev.to/dc600/privana-is-coming-private-defi-no-catch-4lcd"&gt;users can do with Privana&lt;/a&gt; underscores this application's privacy-first commitment: swap tokens, earn yield on stablecoins, and automate trading strategies. At the same time, users have self-custody, and none of their activities are revealed on-chain. This is in contrast to any standard decentralized exchange (DEX), where trades are always public; transactions are visible to anyone, including bots, who can also intervene with sandwich attacks and front-running; and full transparency dictates that user wallet history is always accessible. Privana is designed to solve these problems.&lt;/p&gt;

&lt;p&gt;Privana and Oasis combine to deliver the application’s multi-chain feature while maintaining the privacy setup. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu8h3803nqto12ma72fm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu8h3803nqto12ma72fm7.png" alt=" " width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each layer has to play only its own part. Oasis takes on the responsibility for privacy and security with Sapphire's confidential smart contracts and encrypted contract storage. The external chains just enjoy the benefits, and they only see what they need to – signed transactions in final state. Privana’s contribution is the user interface: wallet connection, asset deposit, execution of swaps, rule setup for automation, and portfolio management. &lt;/p&gt;

&lt;p&gt;It is crucial that privacy and security guarantees come from Oasis rather than from Privana because the assurances are backed by core hardware and blockchain levels instead of merely the application level.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;An overview of Privana’s core functionality&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Privana's core functionality can be stated in a single sentence. It operates pooled, policy-governed vaults that hold assets inside hardware enclaves and execute DeFi actions privately. Let’s see how this tracks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pooled vault model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When users deposit tokens in Privana, the funds are kept in a vault, a smart contract on Oasis Sapphire inside an Intel SGX enclave (more on this, rather than in individual wallets as usual. This model moves away from the system of individual wallet users holding their private keys and instead uses a single vault per chain to hold assets for multiple users. The obvious next question is how individual token holdings are then managed. The answer lies in a &lt;strong&gt;confidential accounting layer&lt;/strong&gt; tracking the user balances. This layer is a set of encrypted smart contracts that privately map and maintain individual token holdings. &lt;/p&gt;

&lt;p&gt;This design choice is deliberate and comes with several benefits.&lt;br&gt;
• &lt;strong&gt;Privacy amplification&lt;/strong&gt; – Every transaction originating from Privana has the same address – that of its pooled vault. Since any user’s personal wallet activity is not broadcast, no specific trade can be attributed to a specific person.&lt;br&gt;
• &lt;strong&gt;Liquidity efficiency&lt;/strong&gt; – The Privana vaults hold an inventory of commonly traded assets. As a result, internal liquidity can settle user trades instantly within the vault, eliminating the need for external transactions. This also augments privacy while being fast and cheap.&lt;br&gt;
• &lt;strong&gt;Lower costs&lt;/strong&gt; – Being a pooled model, there is no need for individual smart contracts for the users. This results in low complexity of the application, lower gas fees, and higher cost-efficiency.&lt;/p&gt;

&lt;p&gt;The confidential accounting layer in Privana’s pooled vault model is unique to DeFi solutions but follows the same logic as traditional institutions where, for example, users keeping their gold would all be stored in a single secure vault while the ledger records will maintain individual holdings. Privana’s use of this accounting layer thus serves 4 purposes.&lt;/p&gt;

&lt;p&gt;• When users deposit their tokens, this system verifies the deposit on the source chain and registers it to the balance in the user's name in the confidential ledger.&lt;/p&gt;

&lt;p&gt;• When users initiate a trade or yield activity, the system does a quick balance check for fund sufficiency before processing any transactions.&lt;/p&gt;

&lt;p&gt;• For every incoming deposit, the system runs Know Your Transaction (KYT) checks to verify that funds don’t originate from sanctioned sources. This filter is a compliance mechanism adding another layer of security to the vault without compromising its privacy mandate.&lt;/p&gt;

&lt;p&gt;• After every successful trade execution, there is immediate balance reconciliation so that the latest state of the user's holdings remains updated in vault records.&lt;/p&gt;

&lt;p&gt;A great advantage of Privana’s vaults is that they are chain-agnostic. The keys stay and run inside TEEs, while from the target blockchain's perspective, all logic is enforced off-chain. So, even a network like Bitcoin, without native smart contract support, can benefit from the model. &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The three pillars of Privana’s core concepts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;TEEs, key encumbrance, and the non-custodial model encapsulate the core concepts behind Privana’s build, so it is important to delve a little deeper into each of them. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TEEs&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzgmm2wjxfrpe9ea7u7ae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzgmm2wjxfrpe9ea7u7ae.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TEEs sit at the center of Privana's privacy and security architecture. It is hardware running code inside, like a locked room enforcing rules so that no one can view, access, or modify what’s inside. It keeps everybody out, even the operating system and the server operator. As mentioned before, for Privana, this locked room is an Intel SGX enclave on Oasis Sapphire.&lt;/p&gt;

&lt;p&gt;The TEE protects vault keys, user balances, policy rules, and transaction history. Everything stays encrypted within the TEE, only gets decrypted during the duration of processing, and is re-encrypted when processing is complete.&lt;/p&gt;

&lt;p&gt;There is never any exposure to external systems. So, the TEE prevents access to or reading of private keys or any attempts to bypass user policies. Moreover, no unauthorized transactions can get through or get signed. Not even an engineer with full server access can extract or alter what is inside the enclave.&lt;/p&gt;

&lt;p&gt;Most users will be satisfied with guarantees, but anyone who is tech-savvy and wants to verify for themselves can use remote attestation to check that the code running inside the enclave is the one that was promised and whether it is really untampered. &lt;/p&gt;

&lt;p&gt;From an applicability point of view, enterprise custody platforms often utilize TEEs for institutional users. Privana aims to provide the same security model for DeFi users. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key encumbrance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a standard wallet, users must manually approve every transaction by signing with their private keys, which increases the risk of exposure or compromise. With key encumbrance, users can pre-define rules and let automation take care of the rest. This is the practical application of the concept laid down in the &lt;a href="https://arxiv.org/abs/2412.02634" rel="noopener noreferrer"&gt;Liquefaction research paper&lt;/a&gt; by Austgen et al. at Cornell Tech. &lt;/p&gt;

&lt;p&gt;Key encumbrance thus lets the enclave execute on the user's behalf, bound or encumbered by user-defined policy that can be updated or revoked at any time at the user’s discretion.&lt;/p&gt;

&lt;p&gt;Take this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example policy: delegate yield routing, keep direct swap control&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USDC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;spend_limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="nx"&gt;USDC&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// max automated spend&lt;/span&gt;
  &lt;span class="nx"&gt;destination_lock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aave-v3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// only this protocol&lt;/span&gt;
  &lt;span class="nx"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;          &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// time-bound — auto-expires&lt;/span&gt;
  &lt;span class="nx"&gt;revocable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="kc"&gt;true&lt;/span&gt;              &lt;span class="c1"&gt;// you can always cancel&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// The enclave enforces these limits in hardware.&lt;/span&gt;
&lt;span class="c1"&gt;// No one — including Privana — can execute outside these rules.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Privana takes key encumbrance utility forward by introducing the principle of &lt;strong&gt;asset-time segmentation&lt;/strong&gt;. It means that at any given time, only a single entity can exclusively control any specific asset position, and this entity can either be the user themselves or the user’s delegate. As a result, two policies cannot simultaneously claim the same asset, thereby preventing conflicts and ensuring user exit as and when they want. &lt;/p&gt;

&lt;p&gt;The benefit of key encumbrance is best understood from how it counteracts the SEAO assumption model. Single-Entity Address-Ownership, or SEAO, dictates that one address must mean one corresponding user controlling it absolutely. In contrast, key encumbrance espouses programmable access-control policies that can function with complex rules, multiple delegations, time bounds, and asset limits. Everything is enforceable inside hardware without custody transference. This is the essence of automated, private DeFi without having to give up control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-custodial model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The term “custody” is used often but not always clearly understood in DeFi. Let’s compare Privana with other prevalent custody models regarding their attributes to understand the difference.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4asbk8cwzs3uc957djc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4asbk8cwzs3uc957djc3.png" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This redefines the concept of non-custodial. Before, in standard wallets, users had to either manually sign every transaction for safety or give up control to bots for automation, leading to potential security risks. Now, with Privana, automation and self-custody are simultaneous, with privacy ensured throughout the whole experience.&lt;/p&gt;

&lt;p&gt;This does not mean that there are no trust assumptions in Privana; it only means that the trust requirements are as minimal as possible. As long as Intel SGX hardware works as designed and Sapphire’s confidential smart contracts function as built and deployed, no one from Privana or Oasis’s side can access or tamper with the vault's private key or override the user’s policy rules. It may be useful to check out the &lt;a href="https://docs.privana.finance/architecture/trust-model" rel="noopener noreferrer"&gt;Trust Model&lt;/a&gt; page in Privana’s docs for details on every assumption and its mitigation.&lt;/p&gt;

&lt;p&gt;This concludes the deep dive into Privana’s core concepts. &lt;a href="https://dev.to/dc600/introducing-privana-a-deep-dive-into-underlying-technology-33ia"&gt;Next time&lt;/a&gt;, I will discuss Privana’s underlying technology in detail. In the meantime, let’s continue the discussion in the comments section about what you think of these concepts that are the pillars of Privana’s build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources &amp;amp; references:&lt;/strong&gt;&lt;br&gt;
• &lt;a href="https://privana.finance/" rel="noopener noreferrer"&gt;Privana&lt;/a&gt;&lt;br&gt;
• &lt;a href="https://oasis.net/" rel="noopener noreferrer"&gt;Oasis&lt;/a&gt;&lt;br&gt;
• For specific questions or feedback, connect on the &lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;Privana channel&lt;/a&gt;** on the official Discord.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>decentralizedfinance</category>
      <category>privacy</category>
      <category>privana</category>
    </item>
    <item>
      <title>Zero-Trust Networking to Control-Plane Privacy: How Diode Scales on Oasis</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Tue, 25 Aug 2026 07:27:03 +0000</pubDate>
      <link>https://dev.to/dc600/zero-trust-networking-to-control-plane-privacy-how-diode-scales-on-oasis-29jj</link>
      <guid>https://dev.to/dc600/zero-trust-networking-to-control-plane-privacy-how-diode-scales-on-oasis-29jj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpl6swpvez3o6d1w44lmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpl6swpvez3o6d1w44lmd.png" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enterprise integration of on-chain techniques is steadily growing, but is still far below blockchain's scope and potential. The main reason is that most crypto projects are built for users willing to jump through the hoops of complex interfaces and less-than-seamless experiences. &lt;/p&gt;

&lt;p&gt;So, it is refreshing to see a project like Diode that aims to reach users who don't need to know or learn about underlying technologies to avail the benefits of some product or service. Along the way, Diode has fully embraced the privacy-first philosophy. This encompasses team communication, zero-trust networking, and AI, with &lt;a href="https://oasis.net/" rel="noopener noreferrer"&gt;Oasis&lt;/a&gt; doing the heavy lifting behind the scenes by bringing private data, verifiable execution, and programmable policies to the table. &lt;/p&gt;

&lt;p&gt;This is especially beneficial for enterprise users who need to adhere to stringent regulations concerning data liability, and where high compliance levels mean zero tolerance for external access to their information.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Three Acts of Diode&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;What &lt;a href="https://diode.io/" rel="noopener noreferrer"&gt;Diode&lt;/a&gt; is doing is best understood by looking at their three-layered approach.&lt;/p&gt;

&lt;p&gt;In the first layer, they have introduced zero-trust networking (ZTN), which deserves a more thorough discussion later. Suffice here to say that Diode's WireGuard-native network is unique in its offering of blockchain-based identities, and is more cost-efficient than the alternatives, Tailscale or Zscaler. This is achieved by operating on bandwidth fees instead of traditional per-device charges.&lt;/p&gt;

&lt;p&gt;In the second layer, Diode has improved upon team communication by creating a blockchain-defined communication perimeter. As a result, it works virtually like a private Slack where each user holds an identity contract. This is a multi-sig wallet linking their devices to a single verifiable identity, resulting in a secure "zone" of communication. Such zones then control who can read messages, share files, and access tunneled browsing or encrypted dashboards.    &lt;/p&gt;

&lt;p&gt;In the third layer, there is private AI, coordinated by a B2B system. It enables organizations to query their own data via an LLM interface. With no sensitive information ever going out to any public platforms, access control is the main focus here. Oasis-anchored access control lists (ACLs) set predefined parameters, governing which tools each team can connect, which LLMs are available for data query, and what filters can determine the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;More on ZTNA&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk8s9p9yxh1cue9ed0tkt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk8s9p9yxh1cue9ed0tkt.png" alt=" " width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before going any further, let's take a closer look at Diode's privacy-focused zero-trust network access (ZTNA) model, marking their first collaboration with Oasis. ZTN is an alternative to VPN and can replace it altogether as the future method for secure communication. This is an excellent example of a Decentralized Physical Infrastructure Network (DePIN) use case providing SaaS solutions.&lt;/p&gt;

&lt;p&gt;Diode made the on-chain logic used in device onboarding and access permissions in the ZTNA model confidential and secure with Sapphire’s smart privacy infrastructure. This resulted in beefing up the encryption capabilities for decentralized messaging, p2p tunnels, and on-chain proxy services. Users can also avail benefits like connecting to servers, IoT devices, and remote workers to private network assets, all with zero data exposure risk.&lt;/p&gt;

&lt;p&gt;The significance of this privacy-first ZTNA model as the fundamental layer of Diode's system is that both the other layers - team communication and private AI - are built on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Oasis Tech Integration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The role of Oasis in Diode's development has grown in scope and impact as the tech integration is crucial across all these different layers. Typical blockchain transparency means familiarity with contract structure can potentially let anyone identify which wallets are in a given zone or which device keys belong to an identity. Oasis prevents this with control plane privacy, hardcoded with data confidentiality and end-to-end encryption.&lt;/p&gt;

&lt;p&gt;So now, to get even access to read the participating public keys in a Diode zone, a user needs to be a member of that zone contract. And the metadata always stays private by default. Moreover, for secure and seamless networking, WireGuard configurations, SSH keys, and device information are stored in Oasis perimeter contracts. The critical importance of going privacy-first is also demonstrated at the private AI layer, involving the Oasis-anchored ACLs. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Proof of Concept: On-chain Energy RWA With Trust Layer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fapivbibxh8smi7zsqr42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fapivbibxh8smi7zsqr42.png" alt=" " width="800" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a &lt;a href="https://diode.io/blog/diode-cleanconectai-oasis-verfiable-rwa" rel="noopener noreferrer"&gt;proof of concept&lt;/a&gt;, applying the Oasis-Diode collaborative infrastructure scope to the real-world assets (RWA) space in a dynamic 3-way partnership that includes CleanConnect for oil and gas certification data.&lt;/p&gt;

&lt;p&gt;Here, the AI-driven framework needs verifiable trust, which Oasis facilitates by bringing together Diode Nexus and CleanConnect's ProveZero multi-certification pathways. The partnership showcases the incorporation of adequate safeguards for regulated industrial data while delivering authenticated production proofs and ensuring the validity of on-chain RWA.&lt;/p&gt;

&lt;p&gt;CleanConnect's ProveZero AI-powered camera systems monitor for physical breaches, detect liquid leaks using machine learning, flag hard hat violations, and image methane in the infrared spectrum. As an application of this monitoring system, Chevron qualified for a multi-billion-dollar drilling lease.&lt;/p&gt;

&lt;p&gt;When verifiability at source is added to the mix, it becomes a crucial factor. With the cameras paired with blockchain-tied device identity, the generated data is routed via Sapphire smart contract-enabled ZTNA. &lt;/p&gt;

&lt;p&gt;All this together carries significant regulatory weight, as auditors can review and confirm the footage and sensor outputs in an unbroken provenance trail. It also enables producers, traders, and buyers to access cryptographic proof that the attributes encoded in the certification data, including ISO 14067, ISCC, EO100, MiQ, OGMP, EUMR, etc, are real and verified. This also authenticates a secure, single, auditable chain of custody across major global standards simultaneously.&lt;/p&gt;

&lt;p&gt;This is a scalable model for Oasis trust layer integration, assuring confidentiality, compliance, and control in private, automated, and cross-vendor AI systems. It also addresses the trust gap in current certification systems. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final Words&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Diode and Oasis coming together provides a working example for next-gen enterprise-grade privacy infrastructure. Diode is already working on making team communication and private AI products available for a wider user base. With &lt;a href="https://oasis.net/" rel="noopener noreferrer"&gt;Oasis&lt;/a&gt;'s tech stack taking care of confidentiality, data is no longer entrusted blindly but is verifiably secure.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
      <category>ai</category>
      <category>privacy</category>
    </item>
    <item>
      <title>ROFLize an App: Bonus Guide to Features &amp; Troubleshooting (Part 2)</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Fri, 14 Aug 2026 06:12:11 +0000</pubDate>
      <link>https://dev.to/dc600/roflize-an-app-bonus-guide-to-features-troubleshooting-part-2-2j2c</link>
      <guid>https://dev.to/dc600/roflize-an-app-bonus-guide-to-features-troubleshooting-part-2-2j2c</guid>
      <description>&lt;p&gt;In this 2-part bonus guide on the features and troubleshooting once you ROFLize an app, the &lt;a href="https://dev.to/dc600/roflize-an-app-bonus-guide-to-features-troubleshooting-part-1-324d"&gt;first part&lt;/a&gt; covered in detail the marketplace, secrets, and persistent storage. Let's continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Public Variables&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You will remember that we learned about secrets for confidential values. But an app may also consist of containers that need to access non-sensitive values and configurations. API endpoints, contract addresses, feature flags, etc are some examples of information that do not have or need any confidential attributes. This is when we use &lt;strong&gt;public variables&lt;/strong&gt;. They are basically arbitrary key-value pairs that are exposed to containers as environment variables.&lt;/p&gt;

&lt;p&gt;You can manage these public variables using the &lt;a href="https://docs.oasis.io/build/tools/cli/rofl#public-var" rel="noopener noreferrer"&gt;Oasis CLI&lt;/a&gt;. Take this example where we create a public variable called &lt;code&gt;API_URL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"https://api.example.com"&lt;/span&gt; | oasis rofl public-var &lt;span class="nb"&gt;set &lt;/span&gt;API_URL -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice that this command only updates the local app manifest file. The public variable, however, is not yet propagated to the app. As a result, you will be able to easily configure as many public variables as you want without having to constantly update the on-chain app configuration.&lt;/p&gt;

&lt;p&gt;Once the required public variables are created, you can update all of them in the on-chain configuration using the usual command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oasis rofl update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Oasis CLI documentation is useful if you need to consult comprehensive public variable management commands, including importing from &lt;code&gt;.env&lt;/code&gt; files, removing public variables, and other advanced features.&lt;/p&gt;

&lt;p&gt;Now, inside the containers, the public variables can be passed via environment variables. This is possible because each public variable is automatically exposed in the Compose environment and can be used in the Compose file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.io/library/alpine:3.21.2@sha256:f3240395711384fc3c07daa46cbc8d73aa5ba25ad1deb97424992760f8cb2b94&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "API URL is $API_URL"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;API_URL=${API_URL}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;rofl.yaml Manifest File&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before proceeding in this section, let's familiarize ourselves with the &lt;strong&gt;metadata&lt;/strong&gt; in the yaml root, consisting of these valid fields. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: A short name for your app that is readable by humans. e.g. &lt;code&gt;my-app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;version&lt;/code&gt;: The ROFL version you are using. e.g. &lt;code&gt;0.1.1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;repository&lt;/code&gt;: A path to the git repository. e.g. &lt;code&gt;https://github.com/user/my-app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author&lt;/code&gt;: The author name and the e-mail address. e.g., if you are John Doe, then it will show &lt;code&gt;John Doe &amp;lt;john@doe.com&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;license&lt;/code&gt;: The ROFL license in &lt;a href="https://spdx.org/licenses/" rel="noopener noreferrer"&gt;SPDX&lt;/a&gt; format. e.g. &lt;code&gt;Apache-2.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tee&lt;/code&gt;: The Trusted Execution Environment type that is being used. &lt;code&gt;tdx&lt;/code&gt; is the default option, while &lt;code&gt;sgx&lt;/code&gt; is also valid.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kind&lt;/code&gt;: As outlined in the initialization process of the &lt;a href="https://dev.to/dc600/roflize-an-app-part-1-rofl-workflow-to-initialization-4m78"&gt;workflow&lt;/a&gt;. Valid options for TDX TEE are &lt;code&gt;containers&lt;/code&gt;, which is the default, or &lt;code&gt;raw&lt;/code&gt;. If you use SGX TEE, then only &lt;code&gt;raw&lt;/code&gt; is the valid option.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;App Resources (&lt;code&gt;resources&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each containerized app running in ROFL needs pre-defined resources such as the number of assigned vCPUs, amount of memory, storage requirements, GPUs, etc, for its execution. In the app manifest file, these will be headed under &lt;code&gt;resources&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;512&lt;/span&gt;
  &lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;disk-persistent&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;512&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you decide to change the requested resources, it will result in the creation of a different enclave identity for the app. Then you will have to update the policy accordingly. &lt;/p&gt;

&lt;p&gt;Let's now see what these resources signify.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Memory (&lt;code&gt;memory&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
The amount of memory is specified in megabytes. It is initialized to &lt;code&gt;512&lt;/code&gt; by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;vCPU Count (&lt;code&gt;cpus&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
The number of vCPUs allocated to the VM. It is initialized to &lt;code&gt;1&lt;/code&gt; by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Storage (&lt;code&gt;storage&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
You can choose different storage options for your ROFL app based on its utility. Currently, it can be one of four options.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;disk-persistent&lt;/code&gt;: When the disk of the given size is persistent, it is encrypted and authenticated using a key derived by the decentralized on-chain key management system after successful attestation. This is what our example shows.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disk-ephemeral&lt;/code&gt;: When the disk of the given size is ephemeral, it is encrypted and authenticated using an ephemeral key randomly generated on each boot. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ram&lt;/code&gt;: Here, an ephemeral filesystem is entirely contained in encrypted memory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;none&lt;/code&gt;: Here, no storage provision has been made. This option is not valid for containerized apps, so you have to choose one of the previous three.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;size&lt;/code&gt; field defines the amount of storage to provision in megabytes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifacts (&lt;code&gt;artifacts&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This configures locations of artifacts used during the ROFL build process with &lt;code&gt;builder&lt;/code&gt;, &lt;code&gt;firmware&lt;/code&gt;, &lt;code&gt;kernel&lt;/code&gt;, &lt;code&gt;stage2&lt;/code&gt;, &lt;code&gt;container.runtime&lt;/code&gt;, and &lt;code&gt;container.compose&lt;/code&gt; as supported fields. If any fields are left unspecified, they will use the default artifacts from the CLI. For containerized apps, &lt;code&gt;container.compose&lt;/code&gt; points to the Compose file included in the ROFL bundle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;compose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;compose.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deployments (&lt;code&gt;deployments&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This contains ROFL deployments on specific networks.&lt;/p&gt;

&lt;p&gt;The deployment you have defined will show as &lt;code&gt;deployment_name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Deployment artifacts are optional and merged field by field on top of global &lt;code&gt;artifacts&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deployments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;testnet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;testnet&lt;/span&gt;
    &lt;span class="na"&gt;paratime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sapphire&lt;/span&gt;
    &lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;compose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;compose.testnet.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are four components to &lt;code&gt;policy&lt;/code&gt; under which your app will spin up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;quotes&lt;/code&gt;: Include TEE-specific policy requirements such as the TCB validity period and the minimum TCB-R number. This helps to indicate what security updates must be applied to the given platform. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enclaves&lt;/code&gt;: Include permissioned enclave IDs for running your app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;endorsements&lt;/code&gt;: Include a list of conditions defining who can run the app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;any: {}&lt;/code&gt; indicates any node can run the app. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;node: &amp;lt;node_id&amp;gt;&lt;/code&gt; indicates only a specified node ID can run the app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provider: &amp;lt;address&amp;gt;&lt;/code&gt; indicates nodes belonging to the specified ROFL provider can run the app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provider_instance_admin: &amp;lt;address&amp;gt;&lt;/code&gt; indicates machines having the specified admin can run the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can choose one or multiple conditions in a nested format by using &lt;code&gt;and&lt;/code&gt; and &lt;code&gt;or&lt;/code&gt; operators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;policy.yaml&lt;/span&gt;

&lt;span class="na"&gt;endorsements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;and&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;or&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider_instance_admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;provider_instance_admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oasis1qqcd0qyda6gtwdrfcqawv3s8cr2kupzw9v967au6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example indicates that the app can be run only on the specified provider, and on machines owned by either of the two admin addresses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fees: &amp;lt;fee_policy&amp;gt;&lt;/code&gt; specifies who pays for the registration and other fees. It can be either &lt;code&gt;endorsing_node&lt;/code&gt; when the node running the app pays, or &lt;code&gt;instance&lt;/code&gt; when the app instance pays.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final piece of this section is &lt;code&gt;machines&lt;/code&gt;, where the specific app deployment takes place. If you remember the &lt;strong&gt;&lt;a href="https://dev.to/dc600/roflize-an-app-part-2-create-build-deploy-test-2hmk"&gt;oasis rofl deploy&lt;/a&gt;&lt;/strong&gt; tutorial, it creates a new &lt;code&gt;default&lt;/code&gt; machine if there is no existing machine. If there is one, then the app is redeployed here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;machine_name&amp;gt;&lt;/code&gt; is the name you choose for the machine.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provider: &amp;lt;provider_address&amp;gt;&lt;/code&gt; is the Oasis native address of the ROFL provider hosting the machine.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;offer: &amp;lt;offer_name&amp;gt;&lt;/code&gt; specifies what offer you have chosen.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;id: &amp;lt;machine_id&amp;gt;&lt;/code&gt; is the ID of the machine per provider.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;permissions&lt;/code&gt; are optional, and when present, indicate ROFL scheduler-specific permissions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;log.view&lt;/code&gt; will list all the Oasis native addresses that can access machine logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;code&gt;appd&lt;/code&gt; REST API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Each containerized app running in ROFL runs a special daemon called &lt;code&gt;rofl-appd&lt;/code&gt;. It exposes additional functions via a simple HTTP REST API. To enable easier access isolation, the API is exposed via a UNIX socket located at &lt;code&gt;/run/rofl-appd.sock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's consider this example where we have used the &lt;a href="https://docs.docker.com/reference/compose-file/services/#short-syntax-5" rel="noopener noreferrer"&gt;short syntax for Compose volumes&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mycontainer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# ... other details omitted ...&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/run/rofl-appd.sock:/run/rofl-appd.sock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ROFL clients&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For your ROFL app, it is strongly recommended that you follow the steps to bind the UNIX socket by accessing the ROFL REST API through one of the ROFL clients. You can choose any one of the following languages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;oasis-rofl-client&lt;/code&gt; for &lt;a href="https://pypi.org/project/oasis-rofl-client/" rel="noopener noreferrer"&gt;Python&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@oasisprotocol/rofl-client&lt;/code&gt; for &lt;a href="https://www.npmjs.com/package/@oasisprotocol/rofl-client" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;oasis-rofl-client&lt;/code&gt; for &lt;a href="https://github.com/oasisprotocol/oasis-sdk/tree/main/rofl-client/rs" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: Although the communication with &lt;code&gt;rofl-appd&lt;/code&gt; is through UNIX sockets, the REST service still uses the HTTP protocol. In our examples, we will be using the &lt;code&gt;http://localhost/&amp;lt;endpoint_path&amp;gt;&lt;/code&gt; format throughout. You are free to provide any name instead of a hostname.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Endpoints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Identifier&lt;/strong&gt; is where the endpoint is used to retrieve the app ID.&lt;br&gt;
Endpoint: &lt;code&gt;/rofl/v1/app/id&lt;/code&gt; (&lt;code&gt;GET&lt;/code&gt;)&lt;br&gt;
Example response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rofl1qqn9xndja7e2pnxhttktmecvwzz0yqwxsquqyxdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, each registered app automatically gets access to a decentralized on-chain key management system. Now, the keys can only be generated inside properly attested app instances. They remain unchanged even if the app is deployed elsewhere, or even if its state is erased.&lt;br&gt;
Endpoint: &lt;code&gt;/rofl/v1/keys/generate&lt;/code&gt; (&lt;code&gt;POST&lt;/code&gt;)&lt;br&gt;
Example request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"key_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"demo key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"secp256k1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key_id&lt;/code&gt; is used for domain separation of different keys. It is a unique identifier, with every key ID corresponding to a different key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kind&lt;/code&gt; defines what kind of key should be generated. Options include:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;raw-256&lt;/code&gt; to generate 256 bits of entropy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;raw-386&lt;/code&gt; to generate 384 bits of entropy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ed25519&lt;/code&gt; to generate an Ed25519 private key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secp256k1&lt;/code&gt; to generate a Secp256k1 private key, as used in our example&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The generated &lt;code&gt;key&lt;/code&gt; is returned as a hexadecimal string.&lt;br&gt;
Example response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a54027bff15a8726b6d9f65383bff20db51c6f3ac5497143a8412a7f16dfdda9"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Authenticated Transaction Submission&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is important if your app is registered with a different chain instead of Oasis. It enables your ROFL app to submit authenticated transactions to that chain. As these transactions are signed by an &lt;strong&gt;endorsed ephemeral key&lt;/strong&gt;, they get automatically authenticated.&lt;/p&gt;

&lt;p&gt;This also helps to easily authenticate the transaction origin in smart contracts by simply invoking an &lt;a href="https://api.docs.oasis.io/sol/sapphire-contracts/contracts/Subcall.sol/library.Subcall.html#roflensureauthorizedorigin" rel="noopener noreferrer"&gt;appropriate subcall&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Subcall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;roflEnsureAuthorizedOrigin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;roflAppID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Endpoint: &lt;code&gt;/rofl/v1/tx/sign-submit&lt;/code&gt; (&lt;code&gt;POST&lt;/code&gt;)&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"encrypt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"gas_limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234845aaB7b6CD88c7fAd9E9E1cf07638805b20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dae1ee1f00000000000000000000000000000000000000000000000000002695a9e649b2"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's decipher the fields before proceeding further.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tx&lt;/code&gt; describes the transaction content. Different transaction kinds are supported as defined by the &lt;code&gt;kind&lt;/code&gt; field. &lt;/p&gt;

&lt;p&gt;Ethereum-compatible calls (&lt;code&gt;eth&lt;/code&gt;) use standard fields such as &lt;code&gt;gas_limit&lt;/code&gt;, &lt;code&gt;to&lt;/code&gt;, &lt;code&gt;value&lt;/code&gt;, and &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;gas_limit&lt;/code&gt;, you can input a JSON number (as used in the example), a decimal string, or a &lt;code&gt;0x&lt;/code&gt;-prefixed hex string. There should not be any whitespace, and irrespective of the input, it will be interpreted as a non-negative 64-bit integer.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;value&lt;/code&gt;, you can input a JSON number up to &lt;code&gt;2^64 - 1&lt;/code&gt;, a decimal string, or a 0x-prefixed hex string. There should not be any whitespace in the string forms, and the value must represent a non-negative integer up to 256 bits.&lt;/p&gt;

&lt;p&gt;For hex-encoded fields such as &lt;code&gt;to&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt;, you can input strings with or without a leading &lt;code&gt;0x&lt;/code&gt; prefix, but there should not be any whitespace or prefix-only input. Empty strings are accepted for contract creation or empty calldata, e.g. &lt;code&gt;to: ""&lt;/code&gt; or &lt;code&gt;data: ""&lt;/code&gt;. If you are providing input for the &lt;code&gt;to&lt;/code&gt; field, it must decode to exactly 20 bytes representing an Ethereum address.&lt;/p&gt;

&lt;p&gt;Alternately, Oasis SDK calls (&lt;code&gt;std&lt;/code&gt;) support CBOR-serialized hex-encoded &lt;code&gt;Transactions&lt;/code&gt; to be specified.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;encrypt&lt;/code&gt; is a boolean flag specifying whether the transaction should be encrypted. This field is &lt;code&gt;true&lt;/code&gt; by default. When an ephemeral key is being used, the encryption is handled transparently for the caller, and any response is first decrypted before being passed on.&lt;/p&gt;

&lt;p&gt;Now, as the outcome of the example request, the example response inside &lt;code&gt;data&lt;/code&gt; is generated as a JSON response containing a CBOR-serialized hex-encoded &lt;a href="https://api.docs.oasis.io/rust/oasis_runtime_sdk/types/transaction/enum.CallResult.html" rel="noopener noreferrer"&gt;call result&lt;/a&gt; that you will need to deserialize.&lt;/p&gt;

&lt;p&gt;If the call result is successful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1626f6b40"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It deserializes as &lt;code&gt;{"ok": ''}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If it is unsuccessful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1646661696ca364636f646508666d6f64756c656365766d676d6573736167657272657665727465643a20614a416f4c773d3d"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It deserializes as &lt;code&gt;{"fail": {"code": 8, "module": "evm", "message": "reverted: aJAoLw=="}}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replica Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This allows apps to publish arbitrary key-value pairs included in the on-chain ROFL replica registration and automatically namespaced with &lt;code&gt;net.oasis.app&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Get Metadata&lt;/strong&gt;: With this, you can retrieve all user-set metadata key-value pairs.
Endpoint: &lt;code&gt;/rofl/v1/metadata&lt;/code&gt; (&lt;code&gt;GET&lt;/code&gt;)
Example response:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"key_fingerprint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a54027bff15a8726"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set Metadata&lt;/strong&gt;: With this, you can set metadata key-value pairs to replace all existing app-provided metadata. 
Endpoint: &lt;code&gt;/rofl/v1/metadata&lt;/code&gt; (&lt;code&gt;POST&lt;/code&gt;)
Example request:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"key_fingerprint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a54027bff15a8726"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters for metadata validation are the number of pairs, key size, and value size.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upsert Metadata&lt;/strong&gt;: With this, you can input or update metadata key-value pairs. However, if you did not specify it in your request but there is existing app metadata, that will not be affected.
Endpoint: &lt;code&gt;/rofl/v1/metadata&lt;/code&gt; (&lt;code&gt;PUT&lt;/code&gt;)
Example request:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delete Metadata&lt;/strong&gt;: With this, you can delete given metadata keys, while keys that no longer exist will be skipped.
Endpoint: &lt;code&gt;/rofl/v1/metadata&lt;/code&gt; (&lt;code&gt;DELETE&lt;/code&gt;)
Example request:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"key_fingerprint"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever you use Set, Upsert, or Delete Metadata, any change in the metadata triggers a registration refresh.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This runs arbitrary query methods defined in the &lt;a href="https://github.com/oasisprotocol/oasis-sdk/tree/main/runtime-sdk" rel="noopener noreferrer"&gt;Oasis Runtime SDK&lt;/a&gt; module and returns the result.&lt;/p&gt;

&lt;p&gt;Endpoint: &lt;code&gt;/rofl/v1/query&lt;/code&gt; (&lt;code&gt;POST&lt;/code&gt;)&lt;br&gt;
Example request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rofl.App"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a16269645500694cb01f85408d624ea267f657bf285787a61db3"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;method&lt;/code&gt; refers to the internal name of query methods; in our example, it is &lt;a href="https://github.com/oasisprotocol/oasis-sdk/blob/394da333625a189abd8b752a9f2dc46bb883a781/runtime-sdk/src/modules/rofl/mod.rs#L647" rel="noopener noreferrer"&gt;rofl.App&lt;/a&gt;. You will recognize query methods by the &lt;code&gt;#[handler(query = "...")]&lt;/code&gt; annotation in the Oasis Runtime SDK source.&lt;br&gt;
&lt;code&gt;args&lt;/code&gt; represent query parameters for the method serialized as CBOR and hex-encoded.&lt;/p&gt;

&lt;p&gt;Example response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"a76269645500ffe981cceff2d759d19fa926faebb7d90c0a59a56373656b582056c6d4841fa5ad24ad761088cb7053ad312ef13f3c2f405640fdba2bde4c14386561646d696e55007814f3d954f41b6459eb9e4bc8fbc6767ece5aa9657374616b658249056bc75e2d631000004066706f6c696379a56466656573026671756f746573a263696173f663706373a363746478a173616c6c6f7765645f7464785f6d6f64756c657380737463625f76616c69646974795f706572696f64181e781e6d696e5f7463625f6576616c756174696f6e5f646174615f6e756d6265721268656e636c6176657382a2696d725f7369676e6572582000000000000000000000000000000000000000000000000000000000000000006a6d725f656e636c6176655820bd4844a79a12ba365e890ddeaebbc4e4292797c7d956b42c2e25e4aefce3b124a2696d725f7369676e6572582000000000000000000000000000000000000000000000000000000000000000006a6d725f656e636c6176655820412c94a9baa0949f718dbba41ab89c38ea5c320345bba36b07e2ef857ffe2fb96c656e646f7273656d656e747381a163616e79a06e6d61785f65787069726174696f6e036773656372657473a26a50494e4154415f4a5754590327a462706b58207f88546291174f854a8ce2eb4bbfc8e62e40d60cdae2d600920a766d3006bf6c646e616d65581aad0460d0f742ad697b6d7c8462cc2b153deeb051a791553ef52b656e6f6e63654f8cbbe6631910d9a702e49bd30ee8f46576616c75655902c1352d823e54f75c846579066e2c1a750387f0630e3f29dba5524984712883bb33371ff017e507ae432b135312af64bfb85f3b17def05b2ac2744256f5accf1a26b29cd8cd412f08bfc9204f9bfa670b2d65972cfc4a8d4e2074402f21c18dfe554b1f0a8a731c077699f741807b3a4047ef4dc570958b8b46111a445259e93c9b92a5f72a23d32cbbef875efe586a8ddda38f1fa286d19b369a2022c3eae1cdbf6f6de4dc055bbab36a2c4830f8e2c64437f5f878f419e21f3a4c0f13c47b63697668b34722eaa61bdffa12e82be6d0266a41590254c9d70e9237475f6115c2867065c49afa8032acdfe0bc5dc671ef48ebc58d893937659243479e2eaa38815cd8665541e4c7e40349524cda15f2d410cba100ee27f0a59dc63534f7cff2444b57c7b74060cf8c3e21e1590b597384a89a463d6bb4a52fc52a4592889448a8f8e0c02fef1689c1efea58ddc08783f6d22d7a908cdf2a45bc46a79a3b73ff5f13bbbf7219973a7382eee84b3b4d48036b5e87fb24223e6387a3e37f9c1ac9722534adfef0201ec13db2e70fe9cd0336f020e50b59d7d32951378f568a4ef3a8117386ff0f1ba4b7d33dcf913daa696a6a7d64d20220b0e5eec994ea56aa9c01f56f5e12bf7d555b3f4a218ddbd8ae1586d5cb1e76802c90e26472b233686e8449284829378163acd77d1b65d4953a76cc497584580c1a5ac4fe6d97fd818fa53c2eb43c6f1b7a79211ef57f24036b1f8ed37f4c3d36873bbbd876769a5fde17add6926317afc96c9707e10b150735c63877ffd6475b1a27b6dd108940f0097375e422b1d308c6c8a0a83847368f5760778c54f2a70b44f9365c55c4b5d69341cad62d6fdb11aa25a9e26b4977adebd65718042bda1cbbf988298d293547107c2f5899352188179bc4d22febc66e8e351885498e707dee583d052c0b7c13f930e4529b59c36c20ee3ee6d29d1a3e2bb65bd489b7206cd45d2ae046f1e147d6407c166e494e465552415f4150495f4b45595899a462706b582074be2e227be81a5e35943ac1b79e238395b9bc367f7a0d1eed740c259ae23a37646e616d65581ee5190cda87688753f6f221890bfed8fe0e27b3ced4a9bc54537da1f4cd90656e6f6e63654fcf5411193abf4f4711f17179ea4b6f6576616c756558304675a29c8398bc94b5057063b4badeb9937a6e019ef7f8095d6b5a035106d4e8e7d710af9b6883848886481c1d180cbc686d65746164617461a7736e65742e6f617369732e726f666c2e6e616d656f76616c696461746f722d6167656e74756e65742e6f617369732e726f666c2e617574686f72782a4d61746576c5be204a656b6f766563203c6d617465767a406f6173697370726f746f636f6c2e6f72673e766e65742e6f617369732e726f666c2e6c6963656e73656a4170616368652d322e30766e65742e6f617369732e726f666c2e76657273696f6e65302e312e30776e65742e6f617369732e726f666c2e686f6d6570616765784f68747470733a2f2f6769746875622e636f6d2f6f6173697370726f746f636f6c2f6572632d383030342f626c6f622f6d61737465722f524541444d452e6d642376616c696461746f722d6167656e7478196e65742e6f617369732e726f666c2e7265706f7369746f7279782968747470733a2f2f6769746875622e636f6d2f6f6173697370726f746f636f6c2f6572632d38303034781a6e65742e6f617369732e726f666c2e6465736372697074696f6e787f4c697374656e7320746f2056616c69646174696f6e52657175657374206576656e7473206f6620746865204552432d383030342076616c69646174696f6e20726567697374727920616e642076616c696461746573207768657468657220746865206167656e7420697320706f776572656420627920524f464c205445452e"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;data&lt;/code&gt;, the JSON response contains the CBOR-serialized method's return value in hex format.&lt;/p&gt;

&lt;p&gt;If you want to try other examples, you can check out the &lt;a href="https://github.com/oasisprotocol/demo-rofl/blob/ab7e60aeb5f10aaec0a5f401086b2ba259a30107/docker/app.sh#L9-L18" rel="noopener noreferrer"&gt;relevant section&lt;/a&gt; of the ROFL demo repository for querying with curl directly.&lt;br&gt;
There is also a production-ready Python example at hand - in the  &lt;a href="https://github.com/oasisprotocol/erc-8004/blob/18f8630f7397ec889ea55b008391664f3b736128/rofl-8004/rofl_metadata.py#L47" rel="noopener noreferrer"&gt;ROFL-8004 implementation&lt;/a&gt; where the query endpoint is used to fetch various app on-chain metadata for registration in the &lt;a href="https://eips.ethereum.org/EIPS/eip-8004#identity-registry" rel="noopener noreferrer"&gt;ERC-8004 identity registry&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Port Proxy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When you publish a port in your &lt;code&gt;compose.yaml&lt;/code&gt; file, the ROFL proxy automatically makes your services accessible via public URLs. It also ensures the routed traffic is done correctly.&lt;/p&gt;

&lt;p&gt;This uses TLS, which is terminated inside your ROFL enclave, maintaining confidentiality and integrity protection. As a result, even the provider cannot see or modify the traffic. Moreover, the default &lt;code&gt;terminate-tls&lt;/code&gt; mode generates and configures a Let's Encrypt certificate in ROFL to authenticate your services.&lt;/p&gt;

&lt;p&gt;To enable the proxy and expose a port from your container, you need to publish it in your &lt;code&gt;compose.yaml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;compose.yaml&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.io/hashicorp/http-echo:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5678:5678"&lt;/span&gt; &lt;span class="c1"&gt;# Expose container port 5678 on host port 5678&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After deploying your app, you can find the generated URL by running the usual command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oasis rofl machine show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output generated in this way will show a &lt;code&gt;Proxy&lt;/code&gt; section with the public URL for each published port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;m602.test-proxy-b.rofl.app&lt;/span&gt;
  &lt;span class="na"&gt;Ports from compose file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;5678 (frontend)&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://p5678.m602.test-proxy-b.rofl.app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use the &lt;a href="https://docs.docker.com/reference/compose-file/services/#annotations" rel="noopener noreferrer"&gt;annotations&lt;/a&gt; in your &lt;code&gt;compose.yaml&lt;/code&gt; file to configure the proxy behavior.&lt;/p&gt;

&lt;p&gt;The general format of an annotation is &lt;code&gt;net.oasis.proxy.ports.&amp;lt;published_port&amp;gt;.&amp;lt;setting&amp;gt;: &amp;lt;value&amp;gt;&lt;/code&gt;.&lt;br&gt;
Here, &lt;code&gt;&amp;lt;published_port&amp;gt;&lt;/code&gt; is the external port exposed in your compose.yaml, and &lt;code&gt;&amp;lt;setting&amp;gt;&lt;/code&gt; indicates the specific proxy configuration like &lt;code&gt;mode&lt;/code&gt; or &lt;code&gt;custom_domain&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Here I will configure port 80 to use the default &lt;code&gt;terminate-tls&lt;/code&gt; mode with a custom domain and port 8080 to use TCP &lt;code&gt;passthrough&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;compose.yaml&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;myservice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.io/my/service:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;net.oasis.proxy.ports.80.custom_domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mydomain.com&lt;/span&gt;
      &lt;span class="na"&gt;net.oasis.proxy.ports.8080.mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;passthrough&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The application container exposes ports 80 and 8080.&lt;/li&gt;
&lt;li&gt;On port 80, the proxy terminates TLS for mydomain.com and forwards traffic to the application container.&lt;/li&gt;
&lt;li&gt;On port 8080, the proxy forwards the raw TCP connection to your application container (&lt;code&gt;mode: passthrough&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Annotation Reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;net.oasis.proxy.ports.&amp;lt;published_port&amp;gt;.mode&lt;/code&gt; defines how the proxy should handle connections for the specified port.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5or3r6as0y9qy9nl8o1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5or3r6as0y9qy9nl8o1i.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;net.oasis.proxy.ports.&amp;lt;published_port&amp;gt;.custom_domain&lt;/code&gt; assigns a custom domain name to the published port.&lt;/p&gt;

&lt;p&gt;Here, when using the default &lt;code&gt;terminate-tls&lt;/code&gt; mode, you need to use special configuration for your custom domain to route through the proxy. Once the app is deployed, you can use Oasis CLI for instructions to configure &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;TXT&lt;/code&gt; records in your DNS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oasis rofl machine show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;m897.opf-testnet-rofl-25.rofl.app&lt;/span&gt;
  &lt;span class="na"&gt;Ports from compose file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;5678 (frontend)&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://demo.rofl.build&lt;/span&gt;
      &lt;span class="s"&gt;* Point the A record of your domain to&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;131.153.241.25&lt;/span&gt;
      &lt;span class="s"&gt;* Add a TXT record to your domain&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="s"&gt;oasis-rofl-verification=4SKHCn4E2SNDB5tXayQeHZsvH/+kJSNGuQaTAPepYJc=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you choose to go with &lt;code&gt;passthrough&lt;/code&gt; mode, the proxy will not terminate TLS and your app will then need to handle it directly. Also, here the &lt;code&gt;custom_domain&lt;/code&gt; setting is not needed, so you can configure the domain directly to the ROFL instance's address.&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;ignore&lt;/code&gt; mode, the port isn't published, so the &lt;code&gt;custom_domain&lt;/code&gt; setting has no effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Troubleshooting&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here I will cover some common errors and the troubleshooting process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compilation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes you will see an error message if the &lt;code&gt;aes&lt;/code&gt; and &lt;code&gt;ssse3&lt;/code&gt; compiler flags are not enabled during compilation of your SGX and TDX-raw ROFL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;error: The following target_feature flags must be set: +aes,+ssse3.
&lt;/span&gt;&lt;span class="gp"&gt;--&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/deoxysii-0.2.4/src/lib.rs:26:1
&lt;span class="go"&gt;|
&lt;/span&gt;&lt;span class="gp"&gt;26 | compile_error!("The following target_feature flags must be set: +aes,+ssse3.");&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="go"&gt;| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workaround is to add default flags to your &lt;code&gt;.cargo/config.toml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build]&lt;/span&gt;
&lt;span class="py"&gt;rustflags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"target-feature&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;+aes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;+ssse&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;rustdocflags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"target-feature&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;+aes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;+ssse&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;rustflags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"target-feature&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;+aes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;+ssse&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;rustdocflags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"-C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"target-feature&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;+aes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;+ssse&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Compose file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A couple of errors are possible here due to an upstream &lt;a href="https://github.com/containers/podman-compose/issues/264" rel="noopener noreferrer"&gt;&lt;code&gt;podman compose&lt;/code&gt; bug&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first is when environment variables defined are not considered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;oracle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CONTRACT_ADDRESS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0x5FbDB2315678afecb367f032d93F642f64180aa3&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bin/sh -c 'python main.py $${CONTRACT_ADDRESS}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this type of error, the &lt;code&gt;CONTRACT_ADDRESS&lt;/code&gt; field will return as empty in ROFL. You need to inject the variable value directly inside &lt;code&gt;entrypoint&lt;/code&gt; as a workaround.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;oracle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bin/sh -c 'python main.py 0x5FbDB2315678afecb367f032d93F642f64180aa3'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other type of error that may occur is when &lt;code&gt;depends_on&lt;/code&gt; is ignored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contracts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ghcr.io/foundry-rs/foundry:latest"&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./contracts:/contracts&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bin/sh -c 'cd contracts &amp;amp;&amp;amp; forge create'&lt;/span&gt;

  &lt;span class="na"&gt;oracle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bin/sh -c 'python main.py'&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;on-failure&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contracts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_completed_successfully&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this type of error, instead of &lt;code&gt;oracle&lt;/code&gt; spinning up once the &lt;code&gt;contracts&lt;/code&gt; service successfully deploys the contracts and finishes, they start in parallel by ignoring the &lt;code&gt;depends_on&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;There is no immediate workaround as of now. You can try to implement customized logic in your &lt;code&gt;oracle&lt;/code&gt; service to crash it, and then trigger the restart mechanism and try again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;appd&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you encounter the &lt;code&gt;422 Unprocessable Entity&lt;/code&gt; error, when the provided request couldn't be decoded, you need to ensure all the required fields are present and correctly formatted in accordance with the &lt;strong&gt;&lt;code&gt;appd&lt;/code&gt; REST API&lt;/strong&gt; section described above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ROFL Proxy URL is not working&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes the app might be using outdated artifacts, which will result in the proxy URL returned by &lt;code&gt;oasis rofl machine show&lt;/code&gt; being inaccessible. This is easily fixed by updating to the latest Oasis CLI version. The next step is to run &lt;code&gt;oasis rofl upgrade&lt;/code&gt; in your project directory to update the artifacts in your &lt;code&gt;rofl.yaml&lt;/code&gt; file, and finally, rebuild and redeploy your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oasis rofl build
oasis rofl update
oasis rofl deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This concludes our 2-part bonus guide describing the various features for your ROFL app, and some common troubleshooting hacks. Looking forward to your feedback in the comments section. &lt;/p&gt;

&lt;p&gt;For technical specs, APIs, architecture, and integration guides, the &lt;strong&gt;&lt;a href="https://docs.oasis.io/" rel="noopener noreferrer"&gt;Oasis documentation&lt;/a&gt;&lt;/strong&gt; is your starting point.&lt;br&gt;
For direct support on specific issues, the Oasis engineering team is available in the &lt;strong&gt;&lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;dev-central channel&lt;/a&gt;&lt;/strong&gt; on the official Discord.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>tee</category>
      <category>devex</category>
    </item>
    <item>
      <title>Blockchain Interoperability, Decoded. And What Lies Ahead.</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Thu, 23 Jul 2026 10:23:00 +0000</pubDate>
      <link>https://dev.to/dc600/blockchain-interoperability-decoded-and-what-lies-ahead-3ek</link>
      <guid>https://dev.to/dc600/blockchain-interoperability-decoded-and-what-lies-ahead-3ek</guid>
      <description>&lt;p&gt;Demystifying the intricacy of blockchain technology has been going on for decades now, and you would think we have come far enough to simplify the basic mechanics. Mostly true, but when a fundamental question like connectivity comes up, we are still trying to hone a universal hack for interoperability. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Problem Of Chains In Silo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The blockchain space is teeming with networks, and most of them are built to be self-sufficient, deterministic, and siloed. This isolation in the distributed ledger technology is a deliberate design to insulate the networks from total damage should one of them break down.   &lt;/p&gt;

&lt;p&gt;This system assures safety, but comes with the inherent flaw of fragmentation, which hugely limits the scope of the technology. If Ethereum does not know what is going on over at Solana, it not only creates a bottleneck in data movement but also leaves liquidity stuck. The value of any asset will depreciate if it can only move inside the home chain. You need to be able to transfer your tokens across networks. Hence, we need protocol interoperability. &lt;/p&gt;

&lt;p&gt;Moving away from monolithic to modular blockchain architecture was one of the first steps. The advent of layer-2 networks, optimistic rollups, and sidechains could only address scalability but they hardly solved the data and value transfer proposition.  &lt;/p&gt;

&lt;p&gt;The cost of communication to enable this was one of the biggest pain points of the last decade - transactional overheads in the form of gas fees piling up, sometimes making fund transfers too expensive to be viable. Many of us have experienced this firsthand. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Building Bridges For Seamless Connection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Over the years, we have seen breakthroughs in the interoperability situation- from cross-chain bridge iterations to, most recently, chain abstraction. Bridging your assets can either take the lock and mint route or the more fine-tuned atomic swap method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lock and mint&lt;/strong&gt; process, or its variation of &lt;strong&gt;burn and mint&lt;/strong&gt; process, works like this. Assets are locked (or burned) on the source chain, and identical value assets are created or minted on the destination chain.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8kbg7fctof9vh6b79u2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8kbg7fctof9vh6b79u2d.png" alt=" " width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;atomic swap&lt;/strong&gt; process, trustless cross-chain bridges, governed by smart contracts, are used. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgohlwg8eflckx532a6ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgohlwg8eflckx532a6ij.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bridging, whether you go with a human-dependent model (multisig) or a trust-logic model (on-chain light client), has its own set of challenges. These bridges simply need to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;trustless (existence of any external federated group of administrators could mean lost decentralization and exposure to hacking risks)&lt;/li&gt;
&lt;li&gt;extensible (adaptability of one protocol to another network’s domain)&lt;/li&gt;
&lt;li&gt;generalizable (capability to access and process all cross-domain datasets)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bottom line is there is always a trade-off. &lt;/p&gt;

&lt;p&gt;Bridges that are safe to use extract the cost of security as gas fees, and those that are cheap have high vulnerabilities leading to potential loss of your funds. &lt;/p&gt;

&lt;p&gt;As our DeFi footprint increases, hackers exploiting bridges have been a regular risk, with several hundred million user funds falling prey (&lt;a href="https://www.youtube.com/watch?v=G1SHHt5-Cms&amp;amp;t=320s" rel="noopener noreferrer"&gt;The Fragility Report&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=hlNNzUdPeCg&amp;amp;t=26s" rel="noopener noreferrer"&gt;The Mass Extinction Event&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;The time has come to talk about privacy now, and we will take a look at &lt;strong&gt;Oasis Privacy Layer (OPL)&lt;/strong&gt; and &lt;strong&gt;runtime off-chain logic (ROFL)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpsay4lp4spayu80mgrox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpsay4lp4spayu80mgrox.png" alt=" " width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Privacy As A Solution&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The gap left by the Bridging Trilemma - safe or cheap, rarely both - is where &lt;a href="https://oasis.net/" rel="noopener noreferrer"&gt;Oasis&lt;/a&gt; comes into the discussion. &lt;/p&gt;

&lt;p&gt;As a layer-1, PoS protocol with confidential computing and verifiable privacy as foundational premises, Oasis designed OPL, powered by the network's confidential EVM runtime, Sapphire, as an on-chain, plug-and-play interoperability tool. &lt;/p&gt;

&lt;p&gt;OPL is curated to ease developer activity, enabling cross-chain communication without migration. It bridges confidentiality to dApps living entirely on other chains through message-passing bridges. The dApp's main logic stays exactly where it is, gas token and all. Only the privacy-sensitive parts of execution get routed to Sapphire.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmbrkkuenzs1o3fl0lx3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmbrkkuenzs1o3fl0lx3h.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you get as a user out of this arrangement is confidential cross-chain transactions. No background tech distracting your experience, nor your financial privacy being accessible publicly in the name of full transparency. &lt;/p&gt;

&lt;p&gt;Compared to Polkadot's parachains or Cosmos's IBC at the network level, or even bridge protocols such as LayerZero and Axelar, this has a distinct point of difference. While the others solve the interoperability challenge with composability and stop at data (and value) movement, Oasis asks and answers the next logical question: whether this data should be visible once it does, and adds a privacy-preserving layer as a solution. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Off-chain Alternative&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After multisig, light client, and OPL, we now have a new approach- the Trustless AWS model. It involves secure and verifiable computation while moving the heavy lifting of verification off-chain. Oasis ROFL framework is a step in this direction. &lt;/p&gt;

&lt;p&gt;ROFL retains the black-box or secure enclave approach of OPL, using Trusted Execution Environments (TEEs) like Intel SGX or TDX. The architecture and the workflow promise optimal performance for running tamper-proof code and private, secure data processing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4px8vn92lf6z39o5mm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4px8vn92lf6z39o5mm1.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp794qedy6nkmvsca9zti.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp794qedy6nkmvsca9zti.jpeg" alt=" " width="680" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Moreover, Oasis can provide Privacy-as-a-Service to other chains by aligning ROFL with OPL. This means we can enjoy confidential bridging that combines multisig-grade trust with light-client-grade security, especially with cost efficiency that zero-knowledge proofs (ZKPs) lack. As cross-chain architectures, both ZKPs and even optimistic verification models also come up short in terms of built-in privacy capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl9mmytsa9xhygjfxq3r7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl9mmytsa9xhygjfxq3r7.png" alt=" " width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, what sets ROFL apart from everything else that came before is that it opens a door that bridges were never designed for: confidential, cross-chain intents. This is the basis for private swaps. Here, you can specify the condition that must be met before a swap executes. With enclave-held keys and the swap order sitting in the enclave memory until the moment of execution, it is structurally resistant to manipulation or front-running of the transaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Road Ahead&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The thread of our discussion inevitably leads to a conundrum. As interoperability options evolve, bridges can be faster, cheaper, safer, on-chain or off-chain, and still have a ceiling to what they can achieve. A single wallet achieved through chain abstraction might be the way to go.&lt;/p&gt;

&lt;p&gt;Consider this: a ROFL enclave holding a private key for any chain. It would mean signing a single transaction on Oasis while the matching action executes on Bitcoin or Ethereum or Solana or any protocol of your choice, without ever touching any of those networks directly. Here, you get smooth UI and UX, and the complexity is not your concern.&lt;/p&gt;

&lt;p&gt;Does this mean we have solved interoperability? No. But we have redefined the problem we started with. Moving data and assets across chains is doable and done. Now, we examine the mechanics of moving trust itself, verifiably and cheaply, without giving up confidentiality. That's where I think the road goes next. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://oasisrose.garden/lessons/blockchain-interoperability/" rel="noopener noreferrer"&gt;Blockchain Interoperability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oasisrose.garden/lessons/the-future-of-interoperability/" rel="noopener noreferrer"&gt;The Future of Interoperability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blockchain</category>
      <category>interoperability</category>
      <category>bridges</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Verifiable DeFi Is Catching On. Case Studies: Robin Markets, Tradable.</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Tue, 21 Jul 2026 09:54:51 +0000</pubDate>
      <link>https://dev.to/dc600/verifiable-defi-is-catching-on-case-studies-robin-markets-tradable-2cc1</link>
      <guid>https://dev.to/dc600/verifiable-defi-is-catching-on-case-studies-robin-markets-tradable-2cc1</guid>
      <description>&lt;p&gt;Confidential decentralized finance (DeFi) has always been one of the best use cases for Oasis's privacy stack. The industry's first and only production-ready confidential EVM, &lt;a href="https://oasis.net/blog/the-oasis-privacy-layer-powered-by-sapphire" rel="noopener noreferrer"&gt;Sapphire&lt;/a&gt;, was, however, only half the solution for trustless applications to ensure user data is sovereign and secured by default. &lt;/p&gt;

&lt;p&gt;On-chain runtime can only take you so far, especially when processing huge datasets or sensitive information is concerned. Oasis has crossed that hurdle now with runtime off-chain logic &lt;a href="https://oasis.net/blog/rofl-mainnet-launch" rel="noopener noreferrer"&gt;ROFL&lt;/a&gt; in production. This framework runs off-chain compute inside a Trusted Execution Environment (TEE) before handing over the result to Sapphire for on-chain storage and finalization. &lt;/p&gt;

&lt;p&gt;As Sapphire and ROFL enable verifiable privacy at scale, thereby counteracting the trust bottleneck, several projects have aligned themselves with Oasis to integrate this privacy layer for their products. Here, I will outline two examples that offer a glimpse into the future where confidential DeFi unfolds as verifiable private DeFi of tomorrow, uplifting user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Robin Markets &amp;amp; verifiable yield with trustless oracle&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Prediction markets are an interesting spin-off of the DeFi space, and Polymarket is undeniably one of the biggest players. Here, users can bet on real-world scenarios and outcomes, from elections to sports to just anything that involves Yes/No decisions. They can buy YES or NO tokens that are essentially tokenised positions in the market. The potentially lucrative returns attract not only crypto-native but also mainstream users, and at any given time, hundreds of millions in positions are open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Funds locked with idle positions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The prediction market sounds fun and simple to engage with but has an inherent problem. When a user buys those YES or NO tokens, the time taken to resolve the position may range from a few hours to a few days to a few months. And until resolution, the funds are locked in the position, sitting idle, and with zero benefit to the asset owner. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://robin.markets/" rel="noopener noreferrer"&gt;Robin Markets&lt;/a&gt; proposes to solve this inefficient situation. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftsq1w8t8lf6sgmzjs5bv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftsq1w8t8lf6sgmzjs5bv.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Users can trade and stake the YES or NO tokens, and earn passive income. It works like this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Robin Markets pairs the YES and NO tokens&lt;/li&gt;
&lt;li&gt;Then finds a YES staker and a NO staker on the same market&lt;/li&gt;
&lt;li&gt;Next pulls the underlying USDC collateral from Polymarket&lt;/li&gt;
&lt;li&gt;Finally routes it into viable DeFi yield strategies
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhdg0b82xht4u1uauep27.png" alt=" " width="800" height="398"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this scenario, both the YES and NO stakers stay in the market with their open positions untouched, while the collateral helps earn them APY.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yield distribution mechanism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Users earning from idle positions is good news, but the yield distribution scenario is challenging. At the resolution point, one position wins, and the other loses. But the yield accumulated during the lifecycle of the positions is not equivalent for the opposing parties, representing variable risks. &lt;/p&gt;

&lt;p&gt;It is improbable that the YES and NO stakers split the risk and the position 50:50, so the yield payout also cannot be an even distribution. Splitting the yield at the final resolved price is also inaccurate, as it will nullify the changing positions during the lifecycle of the staking period. &lt;/p&gt;

&lt;p&gt;Time-weighted average, or TWAP, is used to solve this dilemma. This mechanism tracks the average price of both the YES and NO positions during the lifecycle of the staking period before calculating yield distribution. Robin Markets has a trustless oracle server to access the price history from Polymarket. It then uses TWAP to process the yield calculation, and signs the results on-chain. Any update on the yield in the staking vault only applies when a valid signature is verified from the oracle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oasis role&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The trustless oracle runs on ROFL, executing the whole process of price fetching, TWAP computation, and result sign-off inside a secure enclave. No part of the process is visible, accessible, or modifiable by Robin Markets or any third parties. Also, since on-chain verification of signature must accompany any update, it ensures the oracle data remains in sync with the current chain state.&lt;/p&gt;

&lt;p&gt;The verifiable-by-design computation and tamper-proof oracle reports ensure there are no trust gaps in the mechanism, letting users avail a first for yield on locked prediction-market positions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Tradable &amp;amp; verifiable market intelligence&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DeFi is the go-to web3 use case for many, but the market reality of retail traders versus institutions and professional traders shows a huge and unfair gap. While institutions benefit from reading and interpreting on-chain flows, liquidity conditions, and real-time market sentiments, professional traders have access to high-grade tools, automations, and data analysis and insights. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://tradable.app/" rel="noopener noreferrer"&gt;Tradable platform&lt;/a&gt; and its SenseAI tool help plug this imbalance. With automated trading enabled and a personalised AI portfolio assistant to help, users other than traditional heavy hitters can also make the most of the market opportunities.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrz0agktcqhqfjkycs5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrz0agktcqhqfjkycs5j.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an autonomous agent, SenseAI reads the market 24x7, bringing institutional feeds and insights to retail. It involves simultaneous access to three layers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Macro structures like dominance trends and ETF flows&lt;/li&gt;
&lt;li&gt;Network health like wallet data and capital inflows/ outflows&lt;/li&gt;
&lt;li&gt;Market sentiment like fear/ greed cycles, narrative buildup, and trajectory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With institutional-grade intelligence on their fingertips, average users can use the opportunity to translate market trends and signals into potentially high-return crypto portfolios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mechanics of SenseAI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SenseAI, as a market intelligence tool, differs from most similar solutions that produce information overload by dumping too much raw data, with users unable to decide how to interpret the signals or what to do next. Instead, it runs a process that combines reasoned output from strategy, research, and analysis.&lt;/p&gt;

&lt;p&gt;As a result, SenseAI is involved in context building to decide what matters and when, data access and processing, and using all this to analyse signals and infer the best foot forward. Two key components of the process are &lt;strong&gt;divergence&lt;/strong&gt; and &lt;strong&gt;confluence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Divergence&lt;/strong&gt; is where the tool can flag the fragility of a network even when the price pumps and no apparent weakness is visible or predicted by price action. &lt;strong&gt;Confluence&lt;/strong&gt; is where the tool can read signal over narrative so that liquidity and on-chain activity expansion is validated as real strength rather than mere hype.&lt;/p&gt;

&lt;p&gt;Every insight is encrypted, verified and paid on-chain, yet the whole process feels like a normal web request.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0tn0y5iecllhmf5yz7ox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0tn0y5iecllhmf5yz7ox.png" alt=" " width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oasis role&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Market analysis, especially using autonomous agents, needs integrity, and that trust must be earned. The mechanism should be tamper-proof, and there should also be no bias for or against any crypto assets. Running inside ROFL, SenseAI ensures confidential compute on the Tradable virtual chain on Aurora. With &lt;a href="https://oasis.net/blog/tees-remote-attestation-process" rel="noopener noreferrer"&gt;remote attestation&lt;/a&gt; securing the tool's mechanism, it is safe from any manipulation by the operator, and the user prompts also stay confidential. &lt;/p&gt;

&lt;p&gt;Like any other AI tool, memory is the eternal pain point. As user interactions grow, memory also grows, branches, and needs constant access for context. The storage problem is solved by putting the entire memory, comprising messages and context, in an encrypted file on Autonomys Auto Drive. So, the confidential on-chain smart contract gatekeeps and proves any conversation that happens; Auto Drive stores the conversation content, and only the user, holding the keys, can access and read it.&lt;/p&gt;

&lt;p&gt;Currently, SenseAI is in testnet mode, where usage by the community provides the information layer for the tool. After mainnet rollout on Aurora and enabling of live token payments, it will be integrated into the Tradable platform as the verifiable market intelligence for individual traders.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final words&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Robin Markets and Tradable's SenseAI showcase how next-gen confidential DeFi evolves alongside AI agents. Integrating Oasis's tech stack like ROFL underlines the value of off-chain compute and verifiable privacy.&lt;/p&gt;

&lt;p&gt;What is your take on these projects? Let's hit the comments section.&lt;br&gt;
Also, explore Oasis's in-house &lt;a href="https://oasis.net/solutions-defi" rel="noopener noreferrer"&gt;private DeFi&lt;/a&gt; solution, Privana, or how the protocol can help build and deploy &lt;a href="https://oasis.net/ai-agents" rel="noopener noreferrer"&gt;verifiable agents&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>decentralizedfinance</category>
      <category>privacy</category>
      <category>verifiability</category>
    </item>
    <item>
      <title>ROFLize an App: Bonus Guide to Features &amp; Troubleshooting (Part 1)</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Fri, 17 Jul 2026 08:11:12 +0000</pubDate>
      <link>https://dev.to/dc600/roflize-an-app-bonus-guide-to-features-troubleshooting-part-1-324d</link>
      <guid>https://dev.to/dc600/roflize-an-app-bonus-guide-to-features-troubleshooting-part-1-324d</guid>
      <description>&lt;p&gt;Earlier, I described the entire workflow of how to ROFLize an app, from &lt;a href="https://dev.to/dc600/roflize-an-app-part-1-rofl-workflow-to-initialization-4m78"&gt;setting up prerequisites&lt;/a&gt; to &lt;a href="https://dev.to/dc600/roflize-an-app-part-2-create-build-deploy-test-2hmk"&gt;testing&lt;/a&gt; it. In a 2-part addendum, I will take you through the various features of ROFL that enhance the apps using it, and also how to troubleshoot issues. The first part covers the first three features.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;ROFL Marketplace&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While outlining the deployment process of the workflow, I first mentioned the ROFL marketplace. So, what is it? The ROFL marketplace is an on-chain protocol designed for app developers and ROFL node providers. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6oqhgj6sujlj68mnqhlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6oqhgj6sujlj68mnqhlz.png" alt=" " width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the diagram shows, the ROFL marketplace has three entities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App developers&lt;/strong&gt;: They build an app, register it on-chain, and rent a machine from the ROFL provider to deploy their apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ROFL providers&lt;/strong&gt;: They are the on-chain entity that bills and assigns machines to the developers, with a hosting plan called the offer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ROFL nodes&lt;/strong&gt;: These are servers running on the Oasis node that instantiate machines for hosting an app.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are an app developer, refer to the 2-part workflow series, and the deployment process in Part 2 will be relevant for you. Or, if you approach this as an ROFL provider, start by learning about the &lt;a href="https://docs.oasis.io/node/run-your-node/rofl-node/" rel="noopener noreferrer"&gt;ROFL node&lt;/a&gt; and setting it up to execute runtime off-chain logic inside a TEE.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Secrets&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes we encounter situations where containers need to access data, but exposing it would be disastrous. API keys for accessing certain services fall into this category, and blockchain transparency cannot prevent them from becoming public. Containers running in ROFL can safely pass this type of data using the &lt;strong&gt;secrets&lt;/strong&gt; feature.&lt;/p&gt;

&lt;p&gt;Secrets are arbitrary key-value pairs powered by end-to-end encryption, which can only be decrypted inside an app with the right attestation. You can manage this feature using the Oasis CLI, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"my very secret value"&lt;/span&gt; | oasis rofl secret &lt;span class="nb"&gt;set &lt;/span&gt;mysecret -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a detailed understanding of secret management commands, including importing from &lt;strong&gt;.env&lt;/strong&gt; files, removing secrets, and other advanced features, check out the &lt;a href="https://docs.oasis.io/build/tools/cli/" rel="noopener noreferrer"&gt;CLI documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the above example, the &lt;strong&gt;mysecret&lt;/strong&gt; we created is only encrypted and updated in the local app manifest file, and not yet reflected in the full app version. This enables you to configure multiple secrets without constantly updating the on-chain app configuration. Once you have created all the secrets you need, you can update them all at once with the usual command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;oasis rofl update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The local app manifest doesn't need to be private while storing the secrets. The secret values inside the manifest are end-to-end encrypted. In effect, they are completely inaccessible, even to the administrator who set them up. The reason why only the app can decrypt the secret is that every time a new secret is created, it is encrypted with a corresponding new ephemeral key. As soon as encryption is done, the ephemeral key is discarded and irretrievable. &lt;/p&gt;

&lt;p&gt;Now, the secrets pass inside the ROFL containers in two ways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Environment Variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each secret is automatically exposed in the Compose environment and can be trivially used in the Compose file. When this happens, the secret name convention changes, using capitalization and underscores. For example, the earlier known &lt;strong&gt;mysecret&lt;/strong&gt; will now become &lt;strong&gt;MYSECRET&lt;/strong&gt;. However, if you use any space in the name, e.g., &lt;strong&gt;my secret&lt;/strong&gt;, it will become &lt;strong&gt;MY_SECRET&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.io/library/alpine:3.21.2@sha256:f3240395711384fc3c07daa46cbc8d73aa5ba25ad1deb97424992760f8cb2b94&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello $MYSECRET!"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSECRET=${MYSECRET}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container Secrets&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each secret is also defined and can be passed as a container secret as per &lt;a href="https://docs.docker.com/compose/how-tos/use-secrets/" rel="noopener noreferrer"&gt;Docker documentation&lt;/a&gt;. You will also need to define this as an external secret since it is created by the app during boot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.io/library/alpine:3.21.2@sha256:f3240395711384fc3c07daa46cbc8d73aa5ba25ad1deb97424992760f8cb2b94&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello $(cat /run/secrets/mysecret)!"&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mysecret&lt;/span&gt;

&lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mysecret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Persistent Storage&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.oasis.io/build/sapphire/" rel="noopener noreferrer"&gt;Sapphire's&lt;/a&gt; confidential EVM runtime enables ROFL developers to use smart contracts for secure and consistent storage. But this is not workable for apps with intensive read/write functions. That's why ROFL has built-in support for local persistent storage. This feature comes with these characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local per-machine storage, not synchronized across other ROFL replicas&lt;/li&gt;
&lt;li&gt;Fully encrypted on the host machine&lt;/li&gt;
&lt;li&gt;Preserved during ROFL upgrades and node restarts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the key benefits of this feature is its utility for caching. Whenever the &lt;strong&gt;compose.yaml&lt;/strong&gt; file defines Docker images, persistent storage becomes the default storage destination. They are fetched only the first time an app is deployed, and afterwards, a cached version is used.&lt;/p&gt;

&lt;p&gt;Another aspect of the feature is that all non-external container volumes will automatically reside in persistent storage. Let me illustrate this with an example. Here, I have defined a new volume, as referenced in &lt;a href="https://docs.docker.com/reference/compose-file/volumes/" rel="noopener noreferrer"&gt;Docker documentation&lt;/a&gt;. I have named it &lt;strong&gt;my-volume&lt;/strong&gt; and made &lt;strong&gt;.ollama&lt;/strong&gt; in the home folder persistent. As a result, every time a machine hosting the app restarts, I will not need to download ollama models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;compose.yaml&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ollama&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docker.io/ollama/ollama"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;11434:11434"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-volume:/root/.ollama&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/bash"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/bin/ollama&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;serve&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sleep&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;5;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pull&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deepseek-r1:1.5b;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;wait"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;my-volume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;a href="https://dev.to/dc600/roflize-an-app-bonus-guide-to-features-troubleshooting-part-2-2j2c"&gt;concluding part&lt;/a&gt; of this addendum guide, I will discuss the remaining features and troubleshooting process.&lt;/p&gt;

&lt;p&gt;For technical specs, APIs, architecture, and integration guides, the &lt;strong&gt;&lt;a href="https://docs.oasis.io/" rel="noopener noreferrer"&gt;Oasis documentation&lt;/a&gt;&lt;/strong&gt; is your starting point. &lt;br&gt;
For direct support on specific issues, the Oasis engineering team is available in the &lt;strong&gt;&lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;dev-central channel&lt;/a&gt;&lt;/strong&gt; on the official Discord. &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>tee</category>
      <category>devex</category>
    </item>
    <item>
      <title>ROFLize an App? Part 2: Create, Build, Deploy, Test</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Wed, 15 Jul 2026 07:48:55 +0000</pubDate>
      <link>https://dev.to/dc600/roflize-an-app-part-2-create-build-deploy-test-2hmk</link>
      <guid>https://dev.to/dc600/roflize-an-app-part-2-create-build-deploy-test-2hmk</guid>
      <description>&lt;p&gt;Continuing with the 2-part series that is designed to guide developers as they attempt to ROFLize an app, we have &lt;a href="https://dev.to/dc600/roflize-an-app-part-1-rofl-workflow-to-initialization-4m78"&gt;so far covered&lt;/a&gt; the workflow, the prerequisites needed to proceed, how to containerize the app, and initialize. &lt;br&gt;
In this concluding part of the series, I will show you how to create, build, deploy, and test the app.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Create&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The first step for building an app is to create on-chain and assign a unique identifier or app ID. This ID is for use by on-chain smart contracts and has two functions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;helps interact with the right app&lt;/li&gt;
&lt;li&gt;gives the app access to a decentralized key management system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To create an app, you will need enough funds. Currently, the threshold for creating a ROFL app is 100 tokens. &lt;br&gt;
If you are doing this on mainnet, you will need to procure 100 ROSE from a centralized exchange. &lt;br&gt;
For this tutorial, we are assuming a testnet setup, so you can get your 100 TEST free from the &lt;a href="https://faucet.testnet.oasis.io/?paratime=sapphire" rel="noopener noreferrer"&gt;official faucet&lt;/a&gt;. &lt;br&gt;
It is also advisable that you &lt;a href="https://docs.oasis.io/build/tools/cli/wallet" rel="noopener noreferrer"&gt;create or import a &lt;strong&gt;secp256k1-bip44&lt;/strong&gt; account&lt;/a&gt; to use with the Ethereum-compatible tooling like Hardhat.&lt;/p&gt;

&lt;p&gt;The next step is to select the network - &lt;strong&gt;mainnet&lt;/strong&gt; or &lt;strong&gt;testnet&lt;/strong&gt;, and also the initial administrator account of the app, say &lt;strong&gt;myaccount&lt;/strong&gt;. The CLI will automatically update the manifest file with the assigned app identifier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl create --network testnet --account myaccount
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once done, the CLI will also output the new identifier. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Created ROFL application: rofl1qqn9xndja7e2pnxhttktmecvwzz0yqwxsquqyxdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the app deployer account the default initial admin for any update to the app's configuration. You can always change the admin address at any point.&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: The CLI implements a simple governance mechanism. Here, the app's admin is a single account, and even a smart contract can be the admin. It is also possible to implement advanced agent governance mechanisms like using multi-sigs or DAOs with veto powers to control the upgrade process.&lt;/p&gt;

&lt;p&gt;Now, a final note about the App ID. It is derived using one of the two schemes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creator address + creator account nonce: This is the default. It helps run tests, e.g. in &lt;a href="https://docs.oasis.io/build/tools/localnet" rel="noopener noreferrer"&gt;sapphire-localnet&lt;/a&gt;, where you want a deterministic app ID.&lt;/li&gt;
&lt;li&gt;Creator address + block round number + index of the &lt;strong&gt;rofl.Create&lt;/strong&gt; transaction in the block: This is when you want a non-deterministic approach. It is the preferred mode in production environments. It deters potential attackers from determining the app ID in advance, even if they knew the creator address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To select which app ID derivation scheme you want, you can simply pass the &lt;strong&gt;&lt;a href="https://docs.oasis.io/build/tools/cli/rofl#create" rel="noopener noreferrer"&gt;--scheme parameter&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Build&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This operation brings together &lt;strong&gt;compose.yaml&lt;/strong&gt;, specific operating system components, and the hash of a trusted block on the Sapphire chain. As a result, you can safely execute the app inside a TEE.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff44d8ldmb2a1xkagzg75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff44d8ldmb2a1xkagzg75.png" alt=" " width="432" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whenever any part of the app changes, this step is necessary before deploying. The build process takes the compose file together with other ROFL artifacts and deterministically generates a bundle that you can deploy later.&lt;br&gt;
Another function of the build process is to compute the enclave identity of the bundle. This is needed during remote attestation to authenticate the app instances before they can be allowed to access the key management system and other features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl build
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this step generates a ROFL bundle to be used later for deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROFL app built and bundle written to 'myapp.default.orc'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update On-chain App Config&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any changes to the &lt;a href="https://docs.oasis.io/build/rofl/features/manifest#policy" rel="noopener noreferrer"&gt;app's policy&lt;/a&gt; defined in the manifest also require updating the on-chain app config, so that the changes can take effect.&lt;br&gt;
The designated admin account can issue an update transaction by running the CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl update
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can automate the build and verify steps using the &lt;a href="https://github.com/oasisprotocol/build-deploy-rofl-action" rel="noopener noreferrer"&gt;build-deploy-rofl-action&lt;/a&gt; GitHub Action. More on this later.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Deploy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is one of the most detailed sections of the workflow. &lt;/p&gt;

&lt;p&gt;A ROFL app can be deployed to Sapphire or Cipher paratimes where the ROFL module has been installed. For our purposes, we will proceed with &lt;a href="https://docs.oasis.io/build/sapphire/network" rel="noopener noreferrer"&gt;Sapphire&lt;/a&gt;, as it implements all ROFL functionalities.&lt;/p&gt;

&lt;p&gt;You can deploy your app in several ways to a &lt;a href="https://docs.oasis.io/node/run-your-node/rofl-node" rel="noopener noreferrer"&gt;ROFL node&lt;/a&gt;, defined as a light Oasis Node with support for TEE and configured Sapphire runtime. I will discuss in detail on using the ROFL marketplace and GitHub Actions options. &lt;/p&gt;

&lt;p&gt;Alternatively, you can copy over the ROFL bundle to your ROFL node manually and configure it. As the ROFL node is a separate and elaborate topic, not in the scope of this tutorial, we will not go into details here, so check out the &lt;a href="https://docs.oasis.io/node/run-your-node/rofl-node#hosting-the-rofl-app-bundle-directly" rel="noopener noreferrer"&gt;quick guide&lt;/a&gt; for hosting the ROFL bundle directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy on ROFL Marketplace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Oasis CLI has built-in support for renting a machine on the ROFL marketplace and deploying an app. You can get a list of the default Oasis-managed ROFL providers with this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl deploy --show-offers
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Using provider: oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz (oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz)

Offers available from the selected provider:
- playground_short [0000000000000001]
  TEE: tdx | Memory: 4096 MiB | vCPUs: 2 | Storage: 19.53 GiB
  Price: 5.0 TEST/hour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to select a different provider and offer, you can do so by using the &lt;strong&gt;--provider&lt;/strong&gt; and &lt;strong&gt;--offer&lt;/strong&gt; &lt;a href="https://docs.oasis.io/build/tools/cli/rofl#deploy" rel="noopener noreferrer"&gt;parameters&lt;/a&gt;, respectively.&lt;/p&gt;

&lt;p&gt;For this tutorial, let us proceed with the default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl deploy
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Using provider: oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz (oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz)
Pushing ROFL app to OCI repository 'rofl.sh/0ba0712d-114c-4e39-ac8e-b28edffcada8:1747909776'...
No pre-existing machine configured, creating a new one...
Taking offer: playground_short [0000000000000001]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of this command is threefold.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It copies over the ROFL bundle .orc to an Oasis-managed OCI repository &lt;strong&gt;rofl.sh&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It pays offer &lt;strong&gt;playground_short&lt;/strong&gt; with ID &lt;strong&gt;0000000000000001&lt;/strong&gt; to provider &lt;strong&gt;oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It returns the machine ID and stores it in the manifest file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can check the status of your active ROFL machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl machine show
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;Provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz&lt;/span&gt;
&lt;span class="na"&gt;ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;         &lt;span class="s"&gt;00000000000000a2&lt;/span&gt;
&lt;span class="na"&gt;Offer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="m"&gt;0000000000000001&lt;/span&gt;
&lt;span class="na"&gt;Status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;accepted&lt;/span&gt;
&lt;span class="na"&gt;Creator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;oasis1qpupfu7e2n6pkezeaw0yhj8mcem8anj64ytrayne&lt;/span&gt;
&lt;span class="na"&gt;Admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;oasis1qpupfu7e2n6pkezeaw0yhj8mcem8anj64ytrayne&lt;/span&gt;
&lt;span class="na"&gt;Node ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;bOlqho9R3JHP64kJk+SfMxZt5fNkYWf6gdhErWlY60E=&lt;/span&gt;
&lt;span class="na"&gt;Created at&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2025-05-22 15:01:47 +0000 UTC&lt;/span&gt;
&lt;span class="na"&gt;Updated at&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2025-05-22 15:01:59 +0000 UTC&lt;/span&gt;
&lt;span class="na"&gt;Paid until&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2025-05-22 16:01:47 +0000 UTC&lt;/span&gt;
&lt;span class="na"&gt;Proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Domain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;m162.test-proxy-a.rofl.app&lt;/span&gt;
  &lt;span class="na"&gt;Ports from compose file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;5678 (frontend)&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://p5678.m162.test-proxy-a.rofl.app&lt;/span&gt;
&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;TEE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;Intel TDX&lt;/span&gt;
  &lt;span class="na"&gt;Memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;4096 MiB&lt;/span&gt;
  &lt;span class="na"&gt;vCPUs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;Storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;20000 MiB&lt;/span&gt;
&lt;span class="na"&gt;Deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;App ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rofl1qpjsc3qplf2szw7w3rpzrpq5rqvzv4q5x5j23msu&lt;/span&gt;
  &lt;span class="na"&gt;Metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;net.oasis.deployment.orc.ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rofl.sh/0ba0712d-114c-4e39-ac8e-b28edffcada8:1747909776@sha256:77ff0dc76adf957a4a089cf7cb584aa7788fef027c7180ceb73a662ede87a217&lt;/span&gt;
&lt;span class="na"&gt;Commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;&amp;lt;no queued commands&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The details of the machine will show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Machine status and expiration date&lt;/li&gt;
&lt;li&gt;Provider information&lt;/li&gt;
&lt;li&gt;Proxy URLs for any published ports&lt;/li&gt;
&lt;li&gt;Resource allocation (TEE type, memory, CPUs, storage)&lt;/li&gt;
&lt;li&gt;Deployment details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To view the logs of the app, you need to use this command and sign the request with the app's admin account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl machine logs
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although only the app admin can access the logs, the data here is stored unencrypted on the ROFL node. So, during the production stage, you should never print any confidential data to the standard or error outputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We briefly touched on this during the build process. This is applicable for ROFL apps from CI/CD pipelines. Recap of the &lt;a href="https://github.com/oasisprotocol/build-deploy-rofl-action" rel="noopener noreferrer"&gt;build-deploy-rofl-action&lt;/a&gt; automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can identify configuration errors on every push and pull request with this command, and you don't need to run a full build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oasisprotocol/build-deploy-rofl-action@master&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;testnet&lt;/span&gt;
    &lt;span class="na"&gt;only_validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build and Verify&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can verify that your build is reproducible and that enclave IDs match the on-chain state. Any mismatch will fail the build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oasisprotocol/build-deploy-rofl-action@master&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mainnet&lt;/span&gt;
    &lt;span class="na"&gt;skip_update&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;skip_deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Full Deployment&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oasisprotocol/build-deploy-rofl-action@master&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mainnet&lt;/span&gt;
    &lt;span class="na"&gt;wallet_account&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deployer&lt;/span&gt;
    &lt;span class="na"&gt;wallet_import&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;wallet_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.WALLET_SECRET }}&lt;/span&gt;
    &lt;span class="na"&gt;wallet_algorithm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secp256k1-raw&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it is time to check that the app is running. It does not matter which deployment path you take; the command is the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl show
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;App&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID:&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;rofl&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;qqn&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="err"&gt;xndja&lt;/span&gt;&lt;span class="mi"&gt;7e2&lt;/span&gt;&lt;span class="err"&gt;pnxhttktmecvwzz&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;yqwxsquqyxdf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Admin:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="err"&gt;oasis&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;qrydpazemvuwtnp&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;efm&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;vmfvg&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;tde&lt;/span&gt;&lt;span class="mi"&gt;044&lt;/span&gt;&lt;span class="err"&gt;qg&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;cxwzx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Staked&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;amount:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10000.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Policy:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"quotes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pcs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"tcb_validity_period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"min_tcb_evaluation_data_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"tdx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enclaves"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"z+StFagJfBOdGlUGDMH7RlcNUm1uqYDUZDG+g3z2ik8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"6KfY4DqD1Vi+H7aUn5FwwLobEzERHoOit7xsrPNz3eUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"endorsements"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"any"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fees"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Instances&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;===&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;RAK:&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;AQhV&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;X&lt;/span&gt;&lt;span class="mi"&gt;660&lt;/span&gt;&lt;span class="err"&gt;/+bR&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;REaWYkZNR&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;eAysFShylhe+&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;Ph&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;PM=&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;Node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;DbeoxcRwDO&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="err"&gt;Wh&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;bwq&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;rAR&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;wzhiB+LeYn+y&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;lFSGAZ&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;I=&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;Expiration:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows that there is a single instance of the app running on the given node. It also displays its public runtime attestation key (RAK) and the epoch at which its registration will expire if not refreshed. So, if you want to continue working with the app, you will need to periodically refresh the registration.&lt;/p&gt;

&lt;p&gt;You can also check out the status of your app on the Oasis Explorer → Sapphire → ROFL.&lt;br&gt;
&lt;a href="https://explorer.oasis.io/mainnet/sapphire/rofl/app" rel="noopener noreferrer"&gt;Mainnet&lt;/a&gt;&lt;br&gt;
&lt;a href="https://explorer.oasis.io/testnet/sapphire/rofl/app" rel="noopener noreferrer"&gt;Testnet&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Test&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While discussing the initialization phase, I outlined &lt;a href="https://docs.oasis.io/build/rofl/workflow/init#rofl-flavors" rel="noopener noreferrer"&gt;several ways&lt;/a&gt; to do so. So, the testing process will vary based on which option you took.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TDX ROFL containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No appd and Localnet Required&lt;/strong&gt;&lt;br&gt;
If your app doesn't rely on appd, you can export any secrets required by &lt;strong&gt;compose.yaml&lt;/strong&gt; and execute &lt;strong&gt;podman compose up&lt;/strong&gt; with a simple command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;export SECRET=some_secret
podman compose up --build
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Testing with appd and Localnet&lt;/strong&gt;&lt;br&gt;
If your app is connected to a functional appd, you will need to spin up the &lt;strong&gt;&lt;a href="https://docs.oasis.io/build/tools/localnet" rel="noopener noreferrer"&gt;sapphire-localnet&lt;/a&gt;&lt;/strong&gt; Docker image and bind-mount the folder that contains your &lt;strong&gt;rofl.yaml&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;docker run -it -p8544-8549:8544-8549 -v .:/rofls ghcr.io/oasisprotocol/sapphire-localnet
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will run for a few moments and give an output like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* TDX ROFL detected. Localnet appd service will be accessible via UNIX socket and TCP port
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;UNIX socket (Linux)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Shell

curl --unix-socket ./rofl-appd.sock http://localhost/rofl/v1/app/id
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;TCP port (macOS, Linux)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Shell

curl http://localhost:8549/rofl/v1/app/id
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.oasis.io/build/rofl/features/appd#rofl-clients" rel="noopener noreferrer"&gt;ROFL clients&lt;/a&gt; can connect to the TCP port using one of three ways.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Python&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;oasis_rofl_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RoflClient&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RoflClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8549&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;TypeScript&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RoflClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@oasisprotocol/rofl-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RoflClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8549&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;oasis_rofl_client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RoflClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RoflClient&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:8549"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once all this is done, you can now spin up your services and run tests. Usually we use the same &lt;strong&gt;compose.yaml&lt;/strong&gt; for production and testing. So, the following command is useful to point a service to an alternate Localnet's &lt;strong&gt;rofl-appd.sock&lt;/strong&gt; location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;compose.yaml&lt;/span&gt;

    &lt;span class="s"&gt;volumes&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${ROFL_APPD_SOCKET:-/run/rofl-appd.sock}:/run/rofl-appd.sock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you execute &lt;strong&gt;podman compose&lt;/strong&gt;, it brings up your services in the Localnet environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;export SECRET=some_secret
export ROFL_APPD_SOCKET=./rofl-appd.sock
podman compose up --build
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the final step, you are now ready to try out the app or execute your end-to-end integration tests as you see fit. Another option would be to use &lt;strong&gt;sapphire-localnet&lt;/strong&gt; in the form of a GitHub action inside your &lt;a href="https://docs.oasis.io/build/tools/localnet#github-actions" rel="noopener noreferrer"&gt;CI service&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TDX ROFL raw&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Local testing for this is currently not supported. So, if you have initialized with this option, you will need to deploy them on Sapphire Testnet and try them out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SGX ROFL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To test this, the first step is to compile your SGX ROFL with &lt;strong&gt;debug&lt;/strong&gt; option enabled. Invoke this command to create a separate &lt;strong&gt;localnet&lt;/strong&gt; deployment in your ROFL manifest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;rofl.yaml&lt;/span&gt;

&lt;span class="na"&gt;deployments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;localnet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rofl1qqn9xndja7e2pnxhttktmecvwzz0yqwxsquqyxdf&lt;/span&gt;
    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;testnet&lt;/span&gt;
    &lt;span class="na"&gt;paratime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sapphire&lt;/span&gt;
    &lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test:bob&lt;/span&gt;
    &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;oasis rofl build --deployment localnet --offline
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this command produces a bundle named &lt;strong&gt;your-app-name.localnet.orc&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, when you execute the &lt;strong&gt;sapphire-localnet&lt;/strong&gt; Docker image and bind-mount the folder that contains the ROFL manifest, the image will automatically register the ROFL on Localnet and execute it inside the Localnet ROFL node.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;docker run -it -p8544-8548:8544-8548 -v .:/rofls ghcr.io/oasisprotocol/sapphire-localnet
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify that the Localnet .orc bundle was loaded and you can test, look out for this output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; * Detected SGX ROFL bundle: /rofls/rofl-appd-localnet.localnet.orc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This concludes the detailed workflow of how to ROFLize an app. However, other aspects of this process also deserve a tutorial. For example, you may wonder what features a ROFL app has or how to troubleshoot, should you need to. I will write up a bonus guide for these topics next time.&lt;/p&gt;

&lt;p&gt;For a quick chat with the Oasis engineering team for help with specific issues, you can drop your comments in the &lt;strong&gt;dev-central channel&lt;/strong&gt; in the official &lt;a href="https://discord.com/invite/BQCxwhT5wS" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>blockchain</category>
      <category>tee</category>
      <category>devex</category>
    </item>
    <item>
      <title>Better AI Context Management With Privacy. Case Studies: Plurality, Ekai.</title>
      <dc:creator>DC</dc:creator>
      <pubDate>Wed, 24 Jun 2026 07:15:54 +0000</pubDate>
      <link>https://dev.to/dc600/better-ai-context-management-with-privacy-case-studies-plurality-ekai-53jg</link>
      <guid>https://dev.to/dc600/better-ai-context-management-with-privacy-case-studies-plurality-ekai-53jg</guid>
      <description>&lt;p&gt;Earlier this year, I had &lt;a href="https://dev.to/dc600/ai-has-a-memory-problem-decentralization-and-privacy-might-have-a-solution-part-3-2288"&gt;discussed&lt;/a&gt; at length about AI memory challenges and potential solutions. I mentioned a couple of names there who had been working on AI context management, as I firmly believe that is how we solve the memory constraints. &lt;/p&gt;

&lt;p&gt;Here, I will further explore two projects that have progressed in this aspect and offer a glimpse of the AI future that could take our experiences to the next level.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Plurality &amp;amp; portable AI context&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Consider this: what if you did not have to start over constantly, or to reiterate and summarize previous conversations whenever you switch models or start a new session? &lt;/p&gt;

&lt;p&gt;Plurality started by trying to answer this. Their aim: to develop an Open Context Layer. As a result, you could autonomously store your data and chats in specific memory buckets. This would not only help with better context management, but also enable sharing the context as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI Context Flow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Billed as a fix for the problem of portable AI memory, Plurality built &lt;strong&gt;&lt;a href="https://plurality.network/ai-context-flow/" rel="noopener noreferrer"&gt;AI Context Flow&lt;/a&gt;&lt;/strong&gt;. The tool works with ChatGPT, Claude, Gemini, Grok, and Perplexity. &lt;/p&gt;

&lt;p&gt;One of the USPs of AI Context Flow is the ingrained privacy control. It thus differs from most other solutions, where cloud storage and data mining are part of the deal, mostly without the knowledge or consent of the users. Plurality teamed up with Oasis for a TEE-based, privacy-first context management, where you can decide what AI can see, you can revoke access at your discretion, and have complete data ownership.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ooabpuz3rwruk08h2n0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ooabpuz3rwruk08h2n0.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's now see how Plurality and Oasis address the privacy question. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI Context Flow solves one problem but opens up a new challenge - the infrastructure issue. Helping portable context flow through other servers is tricky and poses inherent trust gaps.&lt;/p&gt;

&lt;p&gt;The easiest answer that springs to mind is adopting the Model Context Protocol (MCP). It enables agents to access tools, data, memory, and APIs. The infrastructure is powerful and growing as more and more AI products get built on top of it. But the privacy pain point lingers.&lt;/p&gt;

&lt;p&gt;Most people, when they talk about AI privacy, are thinking about the model. But the underlying infrastructure is where most privacy is exposed. When a tool uses MCP, the MCP operator can see everything running through the server. So, you get the portable context but without privacy guardrails. Plurality faced this issue while building AI Context Flow, where user intent, history, and sensitive information were vulnerable to third-party access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oasis solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oasis comes into the picture by offering its Runtime Off-chain Logic (&lt;a href="https://docs.oasis.io/build/rofl/" rel="noopener noreferrer"&gt;ROFL&lt;/a&gt;) for confidential computation to fix the infrastructure exposure dilemma.  Now, the context can flow through the MCP server running inside a Trusted Execution Environment (TEE). This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The operator cannot read context in memory&lt;/li&gt;
&lt;li&gt;The host OS cannot tamper with execution&lt;/li&gt;
&lt;li&gt;Code running is provable with remote attestation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, when Plurality runs its MCP server on ROFL, the confidentiality of the infrastructure layer is not rooted in mere trust assumptions but actually verifiable. Context is stored and processed within the secure enclave away from prying eyes, and visible and accessible only to the model as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plurality next&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Privacy-focused context management opens up new opportunities. In the next phase, Plurality is focusing on building a context marketplace on top of this foundation.&lt;/p&gt;

&lt;p&gt;Simply stated, the context marketplace aggregates the information and knowledge that usually stays fragmented and in silos to be available in packages that anyone can opt to inject into any AI tool. Here, too, the privacy constraint is the potential deal-breaker. And Oasis, with its privacy layer, enables sharing and monetization of context without accessibility to the parties facilitating the transaction in the marketplace. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Ekai &amp;amp; AI context layer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The trade-off of using AI extensively is our dependency on the context that we have built meticulously over time, fine-tuning prompts and accumulating layers of responses. &lt;/p&gt;

&lt;p&gt;Ekai has built a developer-focused solution that can seamlessly and cost-efficiently switch among various AI models via smart model routing without losing precious context. Oasis provides the trustless and verifiable privacy engine that such a context engine needs to function. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffz1nqv9xwusjqhduqdti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffz1nqv9xwusjqhduqdti.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It addresses two major pain points in AI today.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access control&lt;/strong&gt;: Access sharing is a common practice among users. They let friends and colleagues share access to AI models for ease of use. This is most prevalent while collaborating on projects. Divulging your actual credentials is a high-risk proposition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agent context&lt;/strong&gt;: Sharing access is easy; sharing context is the real challenge. Say, you are working with an agent for an hour, and it has accumulated patterns, decisions, contents, outputs, and the logic connecting everything. This context lives in plaintext and is shareable. But whenever there is a new session, the context is gone, or it is a nightmare to locate and reference it. Sometimes, even within a single session, the context degrades as the session timing progresses, leading to hallucinations. Summarization works with limitations, as compressed details tend to get lost in the AI's memory architecture.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ekai is trying to solve this by becoming the context engine for AI agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contexto&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Designed as the context layer for AI agents, &lt;strong&gt;&lt;a href="https://www.getcontexto.com/" rel="noopener noreferrer"&gt;Contexto&lt;/a&gt;&lt;/strong&gt; currently works with OpenAI, Anthropic, Google, xAI, OpenRouter, and Groq, while the gateway runs on ROFL. Since it is built as an OpenClaw plugin, migration is not necessary.&lt;/p&gt;

&lt;p&gt;From an architectural point of view, Contexto works by keeping the main thread clean by storing and indexing older work. So, when the agent calls for it, the tool retrieves the relevant context automatically. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjs3s9rfuc68mdvwzpfgt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjs3s9rfuc68mdvwzpfgt.png" alt=" " width="799" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All tasks and subtasks run in isolation and are handled by scoped sub-agents who will return contextualized outputs and assembled context in short and simple results. However, nothing gets thrown out, and if you need to trace the full details, they are recoverable on demand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Oasis adds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ekai's Control Plane enables storing encrypted API keys on-chain via Oasis &lt;a href="https://docs.oasis.io/build/sapphire/" rel="noopener noreferrer"&gt;Sapphire&lt;/a&gt;, so that you can delegate access with granular controls such as model restrictions, spending limits, and instant revocation. As decryption takes place only within the secure enclave or the TEE, it allows access sharing without credential sharing.&lt;/p&gt;

&lt;p&gt;Now, context. As our session windows with AI models grow, the more we have to lose if trust fails, since the context plaintext is recorded for anyone with access to see or manipulate. This context confidentiality issue is solved with ROFL running the context layer inside a TEE. Result: context is stored, indexed, and retrieved within the secure enclave without ever exposing the plaintext.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ekai next&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As of now, both the Control Plane and the context layer as an OpenClaw plugin are live on mainnet. The next phase involves making persistent context private by default as they design the bringing of the context store into the ROFL enclave. &lt;/p&gt;

&lt;p&gt;This would set the stage for agent-to-agent context routing. When this becomes possible, your agent will be able to collaborate with agents belonging to anyone. These disparate agents can then share relevant context with baked-in rules and privacy policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final words&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I am reminded of Oasis AI head, Marko Stokić's discussion about AI memory in his &lt;a href="https://www.forbes.com/sites/digital-assets/2025/12/12/why-crypto-needs-portable-ai-memory/" rel="noopener noreferrer"&gt;Forbes article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We need confidentially computed, and verifiable portable AI context where the user can decide if and when they want to move across AI models, and the interoperable memory layer is subject to the user's data sovereignty and privacy. Both Plurality and Ekai, adopting a privacy-first approach with Oasis's tech stack, demonstrate their commitment to that future.&lt;/p&gt;

&lt;p&gt;What is your take on these projects working to solve AI's persistent memory problem? Let's hit the comments section.&lt;br&gt;
And if you would want to explore more about how Oasis can help you deploy verifiable agents, the journey starts &lt;a href="https://oasis.net/ai-agents" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>context</category>
      <category>web3</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
