The Story of Hermetica
I spent my early career building an eyeglasses company in the developing world, primarily in West-Africa. As the company continued to grow, it was clear that we needed to move away from cash payments for payroll. When I proposed paying the team via bank wire, I was met with confused looks and empty stares. As it turns out, none of the people on my team (and nobody they knew!) had a bank account.
This experience fundamentally changed my understanding of our current financial infrastructure. It burst my Western bubble and made me realize that the majority of people, especially in the developing world, are completely excluded from the traditional financial system.
So when I discovered Bitcoin a couple years later, it clicked very quickly. My experiences in Africa allowed me to see Bitcoin as the inclusive freedom technology that it is. I realized that a financial system based on Bitcoin is naturally financially inclusive and as a result would unlock vast amounts of untapped human potential.
I was hooked.
So I dropped everything I was doing and dedicated myself to understanding and building on Bitcoin.
A financial system based on Bitcoin is naturally inclusive.
Fast forward to 2021 and Bitcoin had come a long way from where it was when I first discovered it. There were efficient spot exchanges, liquid derivatives markets and accessible lending infrastructures. The only problem was that it was all happening through centralized means. In order to do something with your Bitcoin, you had to give up custody and trust a centralized institution that could deny you access or, God forbid, misappropriate your funds.
How was this any different from the old system that we were aiming to change?
I’m of the belief that for a Bitcoin native financial system to succeed we don’t just need to offer the full range of financial services, but we need them to be on-chain. We need them in the form of permissionless, non-custodial applications.
When I discovered Stacks in early 2021, the final piece of the puzzle clicked: We finally had the necessary technology stack (no pun intended) to actually build out Bitcoin DeFi. The security-first smart contract infrastructure coupled with Bitcoin finality is the perfect combination to make Bitcoin-based financial services a reality.
Hermetica brings institutional-grade trading strategies and infrastructure to Bitcoin DeFi. Our first product line is a set of tokens that combine market-tested derivatives strategies with best-in-class risk management to allow users to generate yield. Our goal is to make trading strategies that are typically reserved for high net-worth individuals and institutions available to every Bitcoiner in a permissionless and non-custodial way.
Learn more about Hermetica and my experience building Bitcoin DeFi in my conversation with Hiro:
How Hermetica Works
The Hermetica app is quite simple. You log in with your Stacks-enabled Bitcoin wallet (Leather or Xverse are excellent choices) and then proceed to select the strategy you feel attracted to.
Hermetica brings institutional-grade trading strategies and infrastructure to Bitcoin DeFi.
Our Stacks Earn strategy, for example, aims to make a return in all market regimes - the six year backtest shows an average historical APY of 16.2% on STX. Our Bitcoin Bull strategy, on the other hand, gives you high returns in bull markets - the strategy generated returns of 69% in 2017/18 and 44% in 2020/21.
Once you’ve made up your mind, you choose the amount you would like to deposit and sign a transaction. That’s it. That’s all you need to do to deposit your Bitcoin and mint a Hermetica liquid yield token. The rest is automated and taken care of by the smart contracts.
Our smart contracts use a small portion of your deposit (i.e. 2% for the Earn token) to buy an exotic option strategy from a market maker. At the end of every weekly Epoch, the contracts calculate the profit and loss and settle the option. All of this happens automatically and in the background. As a user, you can track all of it on-chain and in our app (everything is 100% transparent) - but you don’t need to worry about the details of the trade execution or security.
Tracking Deposits With Chainhook
When you make a deposit, we use Chainhook to track your deposit transaction. We need to know how much you’ve deposited, and into which strategy, so we can update our database and display the right information to you on our frontend. Without access to Hiro’s Chainhook and API, we would need to run our own node and index the relevant on-chain events ourselves.
The benefit of running our own node and indexing infrastructure is that we would have full control over the codebase and deployment and would be able to fix any issues on our own time. However, the downsides are more significant. We would have to manage a second codebase, which is really unrelated to the core functionality of our app, and we would have to ensure high uptimes for our node, which in itself is a challenge.
Chainhook lets us focus our dev resources on building out the core functionality of our app.
That’s why we ultimately decided to go with using Chainhook. Hiro streams the relevant data packets for all contract calls made to our smart contracts to our servers. This allows us to just manage a minimal Chainhook integration and focus the rest of our dev resources on building out the core functionality of our app.
Constructing a Chainhook Predicate
In order to tell Hiro’s Chainhook infrastructure what data we are interested in, we need to define if-this-then-that logic in so-called <code-rich-text>predicates<code-rich-text>.
Below we have the chainhook predicate for a deposit transaction. The <code-rich-text>if_this<code-rich-text> section defines that we are interested in contract calls to the <code-rich-text>queue-deposit<code-rich-text> method on our Earn vault contract.
The <code-rich-text>then_that<code-rich-text> section specifies the URL we want to receive a POST request to once the <code-rich-text>if_this<code-rich-text> conditions are met.
The <code-rich-text>then_that<code-rich-text> section also allows us to set additional metadata like an <code-rich-text>authorization_header<code-rich-text>, which is used by our servers to identify legitimate POST requests, a <code-rich-text>start_block<code-rich-text>, specifying the first block height we want the Chainhook to send data to our servers, and the <code-rich-text>expire_after_occurrence<code-rich-text> field where we can define if we want the chainhook to stop the subscription after a certain amount of contract calls.
Processing the POST Request
The below code snippet describes an API endpoint handler function to process the data received by the POST request sent by the chainhook defined by the above predicate.
After checking that we are indeed handling a POST request (no other types are allowed), the code begins extracting the data:
We first need to access all the transactions that belong to the block which holds the deposit transaction. We want to access the <code-rich-text>timestamp<code-rich-text>, block metadata such as <code-rich-text>block_identifier<code-rich-text> and <code-rich-text>block_height<code-rich-text>, the chainhook method which in this case is <code-rich-text>queue-deposit<code-rich-text>, the <code-rich-text>contract_identifier<code-rich-text> which is composed of the <code-rich-text>deployerAddress<code-rich-text> and <code-rich-text>vaultContractName<code-rich-text>, and the <code-rich-text>transaction_identifier<code-rich-text> (tx id).
Once we get all this data we perform a number of checks.
We check if the current chainhook structure is not a rollback, if the <code-rich-text>bitcoin_block_identifier<code-rich-text> has a value (indicating that the block containing the transaction has been mined) and that the chainhook method is in-fact <code-rich-text>queue-deposit<code-rich-text>.
Next, we iterate through the transactions array, and for each transaction we extract the needed metadata from the chainhook structure. This includes the <code-rich-text>success<code-rich-text> status, the <code-rich-text>sender<code-rich-text>’s STX wallet address, method, arguments used to call this function, and the <code-rich-text>transaction_identifier<code-rich-text>.
Now that we have collected all the necessary data, we write the <code-rich-text>queue-deposit<code-rich-text> transaction and all its metadata into our database. The goal is to have our database reflect the same state as the smart contract to which the deposit was made. We use this database to display user data in our frontend, so it’s important to have it accurately reflect on-chain state.
Lastly, we send a 201 status response indicating that the instances were successfully written to the database. This 201 status tells the chainhook that the request has been processed. If we send an error response to the chainhook instead, the chainhook will stop processing new events.
Join Hermetica's Ongoing Journey
That’s a glimpse into how we’ve built the Hermetica app with Chainhooks. If you would like to learn more about our stablecoin, USDh, and try out our liquid yield tokens, visit our website at hermetica.fi, subscribe to our email newsletter, and follow us on X.
I’ll see you on-chain!