<?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: Fabian Bormann</title>
    <description>The latest articles on DEV Community by Fabian Bormann (@fabianbormann).</description>
    <link>https://dev.to/fabianbormann</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3909580%2F1bce41dc-19c3-499f-bacc-ca44d0e51095.jpeg</url>
      <title>DEV Community: Fabian Bormann</title>
      <link>https://dev.to/fabianbormann</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fabianbormann"/>
    <language>en</language>
    <item>
      <title>What a Playground: Building a Blockchain Sandbox with Yano and Yaci Store</title>
      <dc:creator>Fabian Bormann</dc:creator>
      <pubDate>Mon, 04 May 2026 21:02:05 +0000</pubDate>
      <link>https://dev.to/uverify/what-a-playground-building-a-blockchain-sandbox-with-yano-and-yaci-store-16lo</link>
      <guid>https://dev.to/uverify/what-a-playground-building-a-blockchain-sandbox-with-yano-and-yaci-store-16lo</guid>
      <description>&lt;h2&gt;
  
  
  The Problem with Local Blockchain Development
&lt;/h2&gt;

&lt;p&gt;Developing against a live blockchain network is slow by default. Transactions confirm in seconds at best. Reproducing a precise on-chain state for testing requires replaying a sequence of transactions in the right order, signed by the right keys.&lt;/p&gt;

&lt;p&gt;The alternatives are mocking the chain or stubbing the indexer. Both trade one problem for another. You end up testing against a model of the blockchain rather than the blockchain itself. That gap has a way of hiding bugs until the worst possible moment.&lt;/p&gt;

&lt;p&gt;For UVerify, we needed something better. The UVerify sandbox built with &lt;a href="https://github.com/bloxbean/yano" rel="noopener noreferrer"&gt;Yano&lt;/a&gt; and &lt;a href="https://github.com/bloxbean/yaci-store" rel="noopener noreferrer"&gt;Yaci Store&lt;/a&gt; is the result.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;The UVerify sandbox runs six Docker services. Three of them are the interesting ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yano&lt;/strong&gt; is a &lt;a href="https://github.com/bloxbean/yano/tree/main/node-app" rel="noopener noreferrer"&gt;local running Java Cardano node&lt;/a&gt;. It produces blocks, exposes a Cardano node-to-node (N2N) port for downstream indexers, and provides a Blockfrost-compatible REST API. It also ships with a snapshot API that lets you take a named checkpoint of the full RocksDB chain state and restore it later. That snapshot mechanism is the foundation everything else is built on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yaci Store&lt;/strong&gt; is a full Cardano chain indexer, also from bloxbean. It connects to Yano's N2N port, syncs the chain from genesis, and exposes a rich REST API covering UTxOs, transactions, assets, epochs, staking pools, and governance data. The sandbox runs Yaci Store as a standalone Docker container on port 8080 with its own PostgreSQL schema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yaci Viewer&lt;/strong&gt; is a block explorer built on top of Yaci Store. It runs at port 3001 and gives you a visual browser for every block, transaction, and UTxO the local devnet has produced. When you submit a test transaction and want to inspect its inputs and outputs, Yaci Viewer is where you look.&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.amazonaws.com%2Fuploads%2Farticles%2Fct13p7nrwphrfbcultj7.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.amazonaws.com%2Fuploads%2Farticles%2Fct13p7nrwphrfbcultj7.png" alt="Yaci Viewer showing a transaction on the local devnet" width="800" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yaci Store exposes a rich REST API documented via Swagger UI at &lt;code&gt;http://localhost:8080/swagger-ui/index.html&lt;/code&gt;. The API surface covers UTxOs, transactions, assets, epochs, staking pools, governance, and more.&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.amazonaws.com%2Fuploads%2Farticles%2Fg3d6mb5n6qmwjz0aylpl.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.amazonaws.com%2Fuploads%2Farticles%2Fg3d6mb5n6qmwjz0aylpl.png" alt="Yaci Store Swagger UI showing the available API endpoints" width="800" height="606"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UVerify UI             http://localhost:3000
UVerify Backend        http://localhost:9090
UVerify API (Swagger)  http://localhost:9090/swagger-ui/index.html
Yaci Viewer            http://localhost:3001
Yaci Store API         http://localhost:8080
Yaci Store (Swagger)   http://localhost:8080/swagger-ui/index.html
Yano devnet API        http://localhost:7070/q/swagger-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Snapshot: No Private Keys, No Transaction Replay
&lt;/h2&gt;

&lt;p&gt;The most important property of the sandbox is what you do not have to do when you start it.&lt;/p&gt;

&lt;p&gt;You do not need the private keys that were used to deploy the smart contracts. You do not need to replay the bootstrap sequence that funded the service wallet, initialized the proxy contract, or registered the bootstrap datum on-chain. All of that state is already present in the snapshot. Starting the sandbox restores it instantly.&lt;/p&gt;

&lt;p&gt;The snapshot is a RocksDB checkpoint taken with Yano's snapshot API after a &lt;code&gt;bootstrap.sh&lt;/code&gt; script ran through the full initialization sequence on a fresh chain. The resulting directory is bundled into the Yano Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="s2"&gt;"bloxbean-yano:/app/snapshots/uverify-base-state"&lt;/span&gt; ./yano/snapshots/
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; uverify/sandbox-node:latest ./yano/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;sandbox.sh start&lt;/code&gt; runs and finds no existing chainstate volume, it seeds the Docker volume from that bundled snapshot before starting any services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CHAINSTATE_VOLUME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:/chainstate"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  uverify/sandbox-node:latest &lt;span class="se"&gt;\&lt;/span&gt;
  sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cp -a /app/snapshots/uverify-base-state/checkpoint/. /chainstate/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From that point forward, Yano starts from a chain that already has every contract deployed and every funding transaction confirmed. The UVerify backend connects, Yaci Store syncs from slot 0, and the whole environment is ready without you having to own, manage, or even know about the service wallet mnemonic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wall-Clock Catch-Up
&lt;/h2&gt;

&lt;p&gt;There is one subtlety with restoring a snapshot: the chain stopped at a specific slot in the past. Cardano's KES (Key Evolving Signature) protocol has time-based validity windows. If the devnet node tries to produce blocks as if no time had passed, it will eventually fail key evolution checks.&lt;/p&gt;

&lt;p&gt;Yano solves this with a single API call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:7070/api/v1/devnet/epochs/catch-up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This advances the local chain forward through all the intermediate epochs to reach the current wall-clock time. It runs in seconds regardless of how long ago the snapshot was taken. The &lt;code&gt;sandbox.sh&lt;/code&gt; script calls it automatically after the node comes up, so by the time the rest of the services are healthy, the devnet is producing blocks at the correct epoch and slot.&lt;/p&gt;

&lt;p&gt;This is the piece that makes the sandbox work correctly whether you started it an hour after the last snapshot was built or six months later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Yaci Store as an Embedded Library
&lt;/h2&gt;

&lt;p&gt;The standalone Yaci Store container handles the block explorer use case. But the UVerify backend has a different requirement: it needs to react to specific UTxOs arriving on-chain in real time, not poll a REST API.&lt;/p&gt;

&lt;p&gt;The bloxbean ecosystem provides a &lt;code&gt;yaci-store-spring-boot-starter&lt;/code&gt; library that embeds the Yaci Store indexing pipeline directly into a Spring Boot application. The UVerify backend uses this to run its own internal indexer alongside the application code.&lt;/p&gt;

&lt;p&gt;The backend pulls in four Yaci Store starters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;yaci-store-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;yaci-store-utxo-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;yaci-store-transaction-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;yaci-store-script-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To hook into the indexing pipeline, the backend provides a custom &lt;code&gt;UVerifyStorage&lt;/code&gt; that extends &lt;code&gt;UtxoStorageImpl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="nd"&gt;@Profile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"!disable-indexer"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UVerifyStorage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;UtxoStorageImpl&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;saveUnspent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddressUtxo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;addressUtxoList&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddressUtxo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processedByUVerifyCore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;cardanoBlockchainService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processAddressUtxos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addressUtxoList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddressUtxo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processedByExtensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;extensionManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processAddressUtxos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addressUtxoList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddressUtxo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processedByUVerifyProxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;hasBeenProcessedByUVerifyProxy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addressUtxoList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddressUtxo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allProcessed&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;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;allProcessed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processedByUVerifyCore&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;allProcessed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processedByExtensions&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;allProcessed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processedByUVerifyProxy&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;allProcessed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saveUnspent&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;allProcessed&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;deleteUnspentBySlotGreaterThan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;cardanoBlockchainService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleRollbackToSlot&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;extensionManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleRollbackToSlot&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time a new block arrives, Yaci Store calls &lt;code&gt;saveUnspent&lt;/code&gt; with the list of new UTxOs. &lt;code&gt;UVerifyStorage&lt;/code&gt; routes each UTxO through the core processing pipeline, the extension manager, and the proxy contract filter. Only UTxOs relevant to UVerify contracts are persisted. Rollbacks are handled the same way.&lt;/p&gt;

&lt;p&gt;In the sandbox, the backend is pointed at Yano's N2N port via &lt;code&gt;application-devnet.yml&lt;/code&gt;. The same code runs unchanged against preprod and mainnet by simply changing the target node host, port, and protocol magic. No conditional logic, no environment-specific branches.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building and Destroying
&lt;/h2&gt;

&lt;p&gt;Starting the sandbox is a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./sandbox.sh start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the chainstate volume already exists from a previous run, it resumes from where it left off. If you want to wipe everything and start from a clean snapshot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./sandbox.sh start &lt;span class="nt"&gt;--clean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This stops all services, deletes the chainstate volume and the PostgreSQL data, and re-seeds from the bundled snapshot. The whole reset takes about a minute. When it finishes, every service is running and all URLs are printed to the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Service                     URL
  ─────────────────────────   ──────────────────────────────────────────
  UVerify UI                  http://localhost:3000
  UVerify Backend             http://localhost:9090
  API docs (Swagger)          http://localhost:9090/swagger-ui/index.html
  Chain viewer                http://localhost:3001
  Yaci Store API              http://localhost:8080
  Yaci Store (Swagger)        http://localhost:8080/swagger-ui/index.html
  Yano devnet API             http://localhost:7070/q/swagger-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get back a pristine environment with all contracts deployed, all wallets funded, and the chain caught up to wall time. The snapshot is deterministic, so the starting state is always identical no matter how many times you reset.&lt;/p&gt;




&lt;h2&gt;
  
  
  Faucet Mechanics
&lt;/h2&gt;

&lt;p&gt;The sandbox includes a faucet wallet funded during the bootstrap sequence. When running examples, you request funds through the UVerify backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;UVerifyClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;baseUrl&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:9090&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signTx&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fundWallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend faucet uses a &lt;code&gt;FAUCET_MNEMONIC&lt;/code&gt; wallet to build and submit a real Cardano transaction. The transaction is confirmed on-chain, indexed by the embedded Yaci Store, and the UTxO is visible in Yaci Viewer.&lt;/p&gt;

&lt;p&gt;Yano also exposes a direct fund endpoint at &lt;code&gt;POST /api/v1/devnet/fund&lt;/code&gt; that injects UTxOs into the ledger state directly, without creating a transaction. This is useful during the bootstrap process when you need to seed wallets before any application logic is running. For normal example usage, the backend faucet is the right choice: it produces real confirmed transactions with real tx hashes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running the Examples
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/UVerify-io/uverify-examples" rel="noopener noreferrer"&gt;uverify-examples&lt;/a&gt; repository contains nine examples across TypeScript, Python, and Java. Every example is self-contained: no shared utilities, no build system setup. Each one targets the sandbox by default.&lt;/p&gt;

&lt;p&gt;TypeScript examples run with &lt;a href="https://deno.com/" rel="noopener noreferrer"&gt;Deno&lt;/a&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;cd &lt;/span&gt;uverify-examples/typescript/diploma
deno run &lt;span class="nt"&gt;-A&lt;/span&gt; index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python examples use &lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer"&gt;uv&lt;/a&gt; with inline PEP 723 dependency declarations:&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;cd &lt;/span&gt;uverify-examples/python/diploma
uv run main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Java examples use &lt;a href="https://www.jbang.dev/" rel="noopener noreferrer"&gt;JBang&lt;/a&gt; with &lt;code&gt;//DEPS&lt;/code&gt; headers:&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;cd &lt;/span&gt;uverify-examples/java/diploma
jbang Diploma.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each example creates a wallet, requests funds from the faucet, issues a certificate, and prints the transaction hash and a verification URL. The wallet mnemonic is persisted to a local file so subsequent runs reuse the same address. You can watch each transaction arrive in Yaci Viewer at &lt;code&gt;http://localhost:3001&lt;/code&gt; while the example is running.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The sandbox requires Docker. Everything else is handled automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/UVerify-io/uverify-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;uverify-examples
./sandbox.sh start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the complete setup. All six services start from the snapshot, the chain advances to wall time, and the URLs are printed to the terminal.&lt;/p&gt;

&lt;p&gt;If you run into an issue or want to discuss the tooling, join the &lt;a href="https://discord.gg/Dvqkynn6xc" rel="noopener noreferrer"&gt;Discord community&lt;/a&gt; or open an issue on &lt;a href="https://github.com/UVerify-io/uverify-examples" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The full SDK and API documentation is at &lt;a href="https://docs.uverify.io" rel="noopener noreferrer"&gt;docs.uverify.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>cardano</category>
      <category>sandbox</category>
      <category>java</category>
    </item>
  </channel>
</rss>
