Staff / Tech Lead Software Engineer — blockchain protocols & Web3 infrastructure, and production systems more broadly.
Where ideas become words (maybe). I write about blockchain protocols, Web3 infrastructure, and production systems more broadly — plus whatever else I run into building software day to day.
While researching vault standards to inform the design of a planned vault product on Rootstock, it became clear pretty quickly that “use ERC-4626” wasn’t the whole answer. The base standard covers a lot, but it also assumes a specific shape (one share token, one asset, everything settling synchronously) that doesn’t fit every vault a real product might need. I put together an internal walkthrough for the team, covering ERC-4626 and the standards that extend it, for exactly the cases where the base spec runs out. This post is that walkthrough.
At RootstockLabs, one of the products I owned the architecture for was the RootstockCollective dApp (frontend source) — a UI that needs to answer questions like “what’s this user’s balance,” “what has this contract emitted since block X,” and “show me the history of this account” on every page load. This is the story of how that UI went from asking the chain those questions directly, every time, to asking a decentralized indexing network instead — and why the process mattered as much as the destination.
A new user shows up with an address and no RBTC in it. Every transaction, including the very first one, needs gas, and gas on Rootstock is paid in RBTC. RIF Relay removes that requirement: a user pays with a token they already hold, or gets the transaction sponsored outright, while a separate account submits it and pays the actual gas.
At RootstockLabs, I led the team that extended and productionized RIF Relay, including the smart-contract changes required to support Boltz’s Rootstock integration, a non-custodial Bitcoin and Lightning swap service. This post covers how RIF Relay’s relay flow and smart-wallet architecture work, and what changed when a real integration stopped fitting the generic model.
This post aims to describe the basic mechanisms behind iterators and generators.
Iterator protocol # As in many programming languages, Python allows you to iterate over a collection. The iteration mechanism is often useful when we need to scan a sequence, an operation that is very common in programming. In Python, the iterator protocol involves two components: an iterable and an iterator.
In many cases we need to change the content of a component dynamically — for instance, to allow the user to change view, or to let the children render data retrieved and processed by its parent component. Below, we are going to show some techniques for creating a component without deciding in advance how the data will be shown. According to the application’s needs, each technique has its own strengths, but all of them encourage component reusability. We are going to describe: