Back to Chapters Chapter 08

Stableyard Today (Final destination)

From One Product to a Programmable Payment Network

For most of this year, Stableyard and DopePay were the same conversation. One team, one codebase, one thing to say when someone asked what I was building. Somewhere in the last few months that stopped being true, and I didn't fully notice until I caught myself explaining the company to an investor and kept saying "the platform" when I meant DopePay, and "DopePay" when I meant the platform. That's usually the sign a thing has quietly split into two things.

DopePay was the whole bet: stablecoins should be spendable anywhere existing payment rails already work, without anyone needing to think about chains, gas, or bridging. We built it as a consumer app first because that's the fastest way to find out if a bet like that is even true. It turned out to be true, and it turned out the hard parts weren't DopePay problems at all. Account identity, deposit routing, non-custodial vaults, settlement across chains and rails. That's infrastructure, and infrastructure doesn't belong to one app.

So it split. Stableyard is the platform now. DopePay is the first thing built on it, not the whole company. A strategic investment made that real instead of just true on a whiteboard. It's paying for the part that never shows up in a demo: more engineers on the platform itself, more chains, more products that get to run on the same rails DopePay already proved out.

A platform doesn't get to just say it's reliable. It has to keep proving it to itself, every time, or the word doesn't mean anything.

That belief is the actual subject of this chapter more than any number is. But I'll give you the numbers first, because I'd rather you hear them from me than notice their absence.

88% of all-time volume happened in the last 30 days
70% of that happened in the last 7 days alone

The absolute numbers behind that are still small, and I'm not going to dress them up. What I'll point to instead is the shape: this isn't a plateau, it's a curve that only recently started bending, and it's bending across more than one place at once. A separate routing layer has already moved value through Relay, Near Intents, and a handful of other liquidity providers across 11 chains, including a few most payment products never bother with. Local-currency QR payments are live today in Vietnam and the Philippines, with early activity starting in Kenya. Most of the people who've ever used those rails did it in just the last month. 1,349 non-custodial vaults have been created. None of that is a claim you have to take on faith.


The Part I'm Actually Proud Of

Everything above is running on what we'd now call v1, the system that proved the idea works. It's not the system I want to be running a real business on forever, and this year we didn't patch it, we rebuilt the core payments engine from scratch. Not a refactor. A different answer to the question of what a "payment" even is inside our system, and a much higher bar for what has to be true before we trust it.

The short version: v1 had separate systems for money coming in and money going out, which meant two data models, two sets of edge cases, and two chances for the same bug to exist twice. v2 collapses all of that into one canonical payment: receiving, sending, routing, vault funding, all the same object with a different intent, instead of several code paths pretending to be one API. That part is architecture. The parts I actually want to talk about are the problems underneath it that sound simple until you have to solve them for real money.

How do you know a payment actually happened?

The lazy answer is a webhook. A provider sends you a notification, you believe it, you update a balance. It's fast, and it's also nothing more than someone else's word for what happened. Not proof. So every deposit into Stableyard gets checked against the source chain itself, independently, before it's ever treated as real.

That's still not the hard part. The hard part is that a blockchain can rewrite its own recent history. A transaction gets confirmed, sits there looking settled for a while, and then a reorg can quietly replace the block it was in. The common fix is "wait for a bunch of confirmations and call it done." But confirmations only tell you a block existed at some point, not that it still does by the time you act on it. So after the wait, we go back and check that the exact block which confirmed your transaction is still the block the chain agrees on. If it isn't, the payment is treated as failed, not as "technically succeeded in a version of history that no longer exists," which is a much worse bug to ship than an honest failure.

And a transaction can be completely final on-chain and still not be the payment you were expecting: wrong token, wrong amount, wrong recipient, while the transaction itself reports total success. So we don't stop at "did something happen." We decode exactly what happened and check it against exactly what should have, before any of it is allowed to touch a balance.

None of that is one clever trick. It's five separate chain families (EVM chains, Solana, Movement, Tron, Bitcoin all have different finality models) all held to the same standard, which is most of why it took as long as it did.

Refunds That Refuse To Guess

A refund system that lets the caller specify a destination is one bad request away from sending someone else's money to a stranger. Ours doesn't ask. It derives the destination from the payment's own verified receipt history, wherever the money actually arrived from, and refuses the refund outright if that history is ambiguous instead of picking an answer.

Two Requests, One Outcome

Networks retry. People double-tap "send." A payment API has to assume the same request might arrive twice and treat that as normal, not as an attack. Every payment carries an idempotency key tied to exactly what was requested. Replay it and you get the original result back, not a second payment. Reuse the key with a different request and the system refuses outright rather than quietly picking a winner.

Vaults That Read the Chain, Not a Cache

A database is fast and can be wrong. The chain is slower and can't lie. Ask a vault how much it can still spend and it answers from the chain itself, cross-checked against our own records. If the two ever disagree, it throws an error instead of showing a number it can't stand behind. Revoking a spend authorization goes through the same signed approval flow as granting one.

An Audit Log We Can't Quietly Edit

The riskiest actor in most "trust us" systems isn't an outside attacker, it's someone on the inside fixing "just one record." Every administrative action writes to a table the database itself refuses to let anyone update, delete, or truncate. Not a policy that says we won't. A constraint that means we can't. Including on us.

None of it is in production yet, and that's on purpose. This is the layer everything else depends on, and it doesn't ship until it's actually ready to be depended on. The rest of this series is what that rebuild looks like up close, one piece at a time.

Chapter 7 was proof the idea worked.

This is proof it has to keep working, on purpose, every single time, and the foundation for whatever it becomes next.