Jeremy Rubin's Blog

Here you'll find an assorted mix of content from yours truly. I post about a lot of things, but primarily Bitcoin.

categories: Bitcoin, Shenzhen Journey.

7 Theses on a next step for BIP-119

Martin Luther had 99, I'm going to give you 7

Warning: this post assumes a great deal of context on CTV is already understood by the reader. If you are not familiar, you may wish to start with, the advent calendar, and the BIP-119 text and reference implementation, as those may provide much needed context about what CTV is and why a next step is being discussed. If you only have a little time, minimally I would advise these two from the advent calendar as the minimum required context: Contracting Primitives and Upgrades to Bitcoin and RoadMap or Load o’ Crap?.

This post starts with a conclusion:

Within a week from today, you’ll find software builds for a CTV Bitcoin Client for all platforms linked here:

  • Mac OSX TODO:
  • Windows TODO:
  • Linux TODO:

These will be built using GUIX, which are reproducible for verification. The intended code to be built will be which is based on Bitcoin Core v23.0 release candidate 5, with commit hash dd9a4e0ea8a109d1607ca1ec16119b1bc952d8b0. You can begin testing this immediately, and even producing your own GUIX builds as well.

Signatures for the builds will be available below:

  • TODO: … .asc

The source tarball:

  • TODO: … .tar.gz

The client has a Speedy Trial release similar to Taproots with parameters proposed to be:

  • Signal Start MTP: 1651708800 (May 5th, 2022, 00:00 UTC)
  • Signal Timeout MTP: 1660262400 (August 12th, 2022, 00:00 UTC)
  • Activation Height: 762048 (Approximately Nov 9th)

See the appendix to verify these parameters.

This ensures 6 signalling periods to activate CTV. The Start and Timeout are targeting mid-period (if hashrate stays steady) times to ensure that it is unlikely we would have more or fewer periods.

The week delay between this post and builds is to provide time for review on the selection of parameters as well as ability to rebase onto a final v23.0 release, should it become ready within the week. Backports are in the works for v22.0, but release builds may not be made available as Bitcoin’s release build processes have changed since v22.0 to use GUIX. The branch for backports is available here: with current commit hash 4d2c39314834a28cd46da943a12300cca8ffcb10, if you would like to help with testing.

Why this, why now?

I’ve just returned from the Bitcoin Miami “Bacchanal”. Personally, I had a couple different goals for being there1. One of my primary focuses was on talking to as many people as possible about BIP-119 and the future road to take.

While consensus has to happen among a much broader set of people than can fit in a conference in Miami, the reality is that there were more than 20,000 Bitcoiners at this event and a good representation across industry, developers, journalists, podcasters, plebs, whales, pool operators, miners, venture capitalists, and more. To say it was a representative sample wouldn’t be fair, but it certainly was not a homogeneous crowd. And I spoke to as many people as I could.

There were a couple common threads across the feedback I received:

  1. Agree or disagree with CTV in particular, folks generally liked how/that I was driving a conversation forward, and respected the hustle required to do so.
  2. A lot of people felt that CTV would help them in a tangible way, and more than a few times, individuals approached me with a concrete use case they needed but had not fully written it up yet.
  3. A lot of people wanted to know what the next step was and what I was planning to do to get it activated and when.

Some people had some suggestions on what I should do as a next step:

  1. Some folks said I should just do a UASF and rally the users.
  2. Some said I needed to organize a summit for developers to explore covenants2.
  3. Some said I didn’t need to do a UASF, nor advocate for it, but I did need to decide on exact release parameters and distribute a reproducible binary so that it was clear what should be run and when so that end-to-end activation testing could proceed.

It’s (un?)remarkably difficult to integrate all feedback on a complex topic like a Bitcoin upgrade coherently. But, having thought it through, I decided that the approach above was the correct next step. Below, you’ll find some reasoning on why I believe this to be proper and not out-of-line with how soft-fork development should go.

However, if I’m wrong in your view, consider me a mere messenger and please don’t shoot the messenger. You just need to communicate clearly to the community why they should not run and signal for CTV and I’m confident that the wisdom of the consensus set will decide in it’s best interests.

So why ship a binary and release parameters?

1) CTV passes a basic pre-flight checklist.

This discussion has to start anchored in a “pre-flight checklist” for CTV. These are fundamental questions that we should be able to tick boxes for for any proposed upgrade… Sadly, the community at large doesn’t have a codified checklist3, but personally I tick off the following boxes:

  1. No material changes to the BIP/Spec/Ref Impl necessary for ~2 years (beyond rebases).
  2. A reasonably well reviewed and tested PR-implementation exists.
  3. ~5 Months of a 5.5 BTC Bounty for bugs in CTV
  4. I socialized a similar roadmap 5 months ago, which received a reasonably warm response so there are ‘few surprises’ here against previously communicated intent.
  5. A community of supporters: breakdown, 16 supporting orgs, 109 individuals, 3 mining pools (totalling about 15-18% depending on when you look).
  6. Only 3 individual NACKs + 1 org (owned by one of the individuals). You should read them yourself, but I think the NACKs are summarizable as “it’s too soon” and “there should be a different process” rather than “I have identified a flaw in the proposal”. See section 4 for more on this. The NACKs are linked below:
  7. Ample time to have produced a nack with a technical basis.
  8. 7 regular meetings over ~16 weeks to discuss the upgrade.
  9. There exists software from multiple different parties for using CTV to accomplish various tasks. None of these users have uncovered issue or difficulty with CTV.
  10. Many in the community are arguing for more functionality than what CTV offers, rather than that the functionality of CTV might be unsafe. CTV ends up being close to a subset of functionality offered by these upgrades.
  11. CTV does not impose a substantial validation burden and is designed carefully to not introduce any Denial of Service vectors.
  12. There exists a Signet with CTV active where people have been able to experiment.
  13. Backports for current release and prior release (will be) available.

2) Unforced errors

In tennis, an unforced error is a type of lost point where a player loses because of their own mistake. For example, suppose your opponent shoots a shot that’s a lob high in the air and slow. But it looks like it’s going out, so you do a little victory dance only to uncover that… the ball lands in. You had enough time to get to the ball, but you chose not to because you didn’t think it would go in. Contrast this to a forced error – your opponent hits a shot so hard and fast across the court no human could reach it let alone return it4.

What’s this got to do with Bitcoin?

Community consensus is the ball, and we don’t know if by August it will be in or out.

Getting to where the ball might land is preparing a software artifact that can activate.

If an artifact isn’t prepared that does this, even if community consensus is ready by then, it’s an unforced error that it wasn’t ready which precludes us from being live in August.

When should you avoid an unforced error like this? When the cost of getting to the ball is sufficiently small.

I’m already maintaining a backportable to Bitcoin Core 23 and 22 patchset for CTV. It’s not much work to set parameters and do a release.

Which brings us to…

3) Product Management is not “my Job” – it’s yours.

Devs don’t swing the racquet, we get to the ball. It’s the community’s job to decide to swing or not. One might rebutt this point – the community isn’t well informed to make that call, but fortunately devs and other tuned in individuals can serve as “coaches” to the public and advise on if the swing should happen.

Producing the code, the tools, the reviews, the builds, the dates, these are all getting to the ball activities.

It’s possible that as a developer, one could say that we should not get to the ball unless we know the community wants to swing.

But that’s false. What if the community wants to take a swing at it but developers haven’t gotten to the ball? What if developers refuse to get to the ball because they don’t want the community to take that shot? Well, tennis can be a game of doubles (I’m really sticking with this metaphor), and maybe your teammate – the community itself – strives to go for it and sprints cross court to make up and take a shot. Maybe that shot looks like a UASF, maybe it looks like a hard fork, maybe it’s lower quality since there was less time to make the right shot placement (worse code if usual devs don’t review). But ultimately, the economic majority is what backstops this, the devs just have the opportunity to help it along, perhaps, a little smoother.

Largely, the formal critiques of CTV (the 3 NACKs) are based on topics of whether or not to swing the racquet, not if we should be at the ball. There are other critiques as well, about the generality of the upgrade, but we’ll discuss those later in this post.

I’ll excerpt some quotes from the NACKs below:

Michael writes,

I also think attempting regular soft forks with single features is a disturbing pattern to get into having just activated Taproot. As I say in the linked post it means less and less community scrutiny of consensus changes, it becomes a full time job to monitor the regular soft forks being activated (or attempting to be activated) and only a tiny minority of the community can dedicate the time to do that.

So this seems to be a point largely about product management – we should only take a shot when we can line up more than once, due to the cost of swinging the racquet. Not really my job, it’s the communities.

Hence I’d like to register a “No” soft signal as I fundamentally disagree that a CTV soft fork should be attempted in the near future and my concerns over premature activation outweigh my enthusiasm for digging into the speculated real world use cases of CTV.

If you disagree that it should be attempted, that’s fine. Your time to voice your concerns is in making the swing.

John writes,

Generally, I do not think Bitcoin is ready for any new soft forked features at all in the short term. Taproot just arrived and there is already so much work to be done to adopt and utilize it.

This is a product management point. “Work on feature X should block all work on other features”. It’s not a point on if CTV is a feature of independent merit.

Further, it’s a layer violation. Wallet progress is wholly independent of consensus upgrades, and generally, we don’t operate on a waterfall development model.

Any improvements CTV-eltoo may bring to LN are not significant enough to claim they are urgent for adoption or R&D for LN progress and adoption.

Again, a product management point. How do we measure what is important to the Lightning Community? Oh, on, there are multiple Lightning Network companies and individuals (Lightning Labs, Muun Wallet, Roasbeef, ZmnSCPxj, LN Markets, Breez, fiatjaf, and more). So if that represents the community, then it seems like a greenlight.

Since I am not qualified, nor are 99% of Bitcoiners, to evaluate this deeply, I feel much more time and scrutiny is required to accept CTV and the related projects Jeremy has prepared with it.

If you’re not qualified, remind me why we’re listening?

Sorry, I couldn’t help the snark. Graciously, let’s accept the framing for a second – who are the stakeholders who need to sign off? What is this process like, concretely?

Is this a process that happens before or after we ‘get to the ball’?

It can definitely be after we get to the ball, and the decision to swing or not is a bit too product-management-y for how a dev should engage.

Also, related projects are a bit like the mix-ins at Cold Stone Creamery™. You are free, of course, to just get ice cream! That there are a myriad of uses doesn’t mean you need to accept all of them, it’s sufficient to just consider the one or two you care about.

I am currently happy with what we have in Bitcoin, and would prefer Core development prioritize optimizations and cleanup work over more and more features that have no urgent need or chance of adoption anytime soon.

This belies a basic misunderstanding of FLOSS:

  1. People work on what they want to
  2. CTV is already ‘finished’

A non-dev’s preference to spend time on cleanup or optimization doesn’t make any dev write that code or shift focus. Most core devs don’t have a boss, and if they do, it’s probably not you! It’s structurally impossible to direct the attention of developers.

And it so happens that I am not happy with what we have in Bitcoin, so I did something about it. With respect to adoption, people will likely be using CTV pretty soon after it’s available, since it is a big step up for a number of critical uses like vaults. These applications are already being built. They can be used on signet which can be deployed to mainnet immediately5. The implementation details for basic custody contracts are pretty simple and don’t require the level of coordination for support that other contracts like lightning or DLCs, so adoption can be at the individual level.

The path around prioritization remains a product management question, and not something devs can be compelled to follow.

4) There are other things to work on.

I can get to the ball for this shot, but then I’d like to work on getting in position for the next shot on time.

There are other important technologies to work on, keeping covenants in limbo ties up a lot of human capital in trying to solve for getting something, vs. having something and being able to work on building solutions using it plus designing new technologies that make Bitcoin even better in different or complimentary ways.

What’s the right amount of rumination (chewing) to swallowing? Eventually, the mouthful you have is stopping you from taking the next bite.

5) Consensus is memoryless

A memoryless process is something that “never makes progress”. For example, consider a board game, where you need to roll a 6 to win. You expect to need 6 rolls to win. You roll a 5. How many more rolls do you need? It’s not 5. It’s 6 – the process is memoryless.

Clearly consensus isn’t entirely memoryless. Something that is a concept only obviously has to be turned into a hard artifact.

CTV has been a ‘hard artifact’ for 2 years. 2 years ago I took a poll of 40 or so developers who attended my workshop in Feb 2020. An average sentiment was that maybe we try to do CTV in a year or so, and that we could definitely do it maybe in 2 years.

I hear the same today from people who advocate a slower process. Maybe a year from now, we could definitely do it in maybe 2 years.

In 2 years, if we wait, won’t we hear the same?

Here’s a few reason why we might hear the same complaints in the future:

In 2 years, suppose Bitcoin is ~2x the price.

Shouldn’t we acknowledge twice as much at risk and do twice as much work to security audit things going into it? What if it’s not just El Salvador with Bitcoin as a national currency, but now Guatamala too?

Suppose we want to get to a point where 50% of the community has reviewed a change. In 2 years, what if the community is 2x the size? Then even if we hit 50% of today’s community, we only have 25% of the community read up.

Hopefully we keep innovating. And if we do keep innovating, we’ll come up with new things. If we come up with a new thing that’s 2x as good as CTV in 2 years, but it takes another 2 years to implement it concretely, should we wait till we finish that? But what happens when we come up with something 2x better than that? Wait another 2 years? Now we’re 4 years out from when the swing to get CTV over the net was doable, and we’d have 0 in hand solutions for the problems CTV tries to solve.

All this points to the nature of the memorylessness of trying to get consensus in an open network.

The best I can do is to get to the ball and let the community decide to take the shot.

Concretely – what is the cost to having CTV in bitcoin during this time while the “better” alternative is being worked on, if we do decide to activate knowing we might one day obsolete CTV? What are the benefits to having 3-5 years of basic covenants in the meantime? On the balance it seems, to me, net positive. It also seems to be a decision that the community at large can judge if the costs are worth the benefits.

6) You can fight against it.

A criticism of the soft fork process is it’s not safe with Speedy Trial (ST) and ST is bad so we shouldn’t do it. This is not a strong criticism: with Taproot, our most important upgrade in years, went smoothly even though there was sharp disagreement over the safety of the mechanism at the time.

Here’s a breakdown of why Speedy Trial is OK from the perspective of different participants:

You want CTV and won’t take no for an answer.

Start with a ST. After 3 months, it either goes or it doesn’t. At least we were at the ball. Now, let’s do a UASF with a LOT=true setting. Because ST is a fail fast, it’s in theory using time where otherwise we’d have to spend coordinating for the harsher realities of a LOT=true effort, so it’s a happy-path optimization.

If you’re a miner, you should signal during the period.

You’d like CTV and might take no.

ST is for you. Can always follow up with another ST if the first fails, or another option if your opinion changes.

If you’re a miner, you should signal during the period.

You do not want CTV, but if others do want it, whatever.

ST is for you – it only goes through if others signal for it.

If you’re a miner, you can signal no during the period, and you can write a blogpost on why you don’t.

You do not want CTV, and will not take yes for an answer.

I’ve written forkd software in 40 lines of python which guarantees you to be on a non-activating chain. Resist my evil6 fork!

If you’re a miner, you signal no during this period. You may want to optimize the forkd code for never building on the chain you don’t like.

7) Bitcoin Core is not Bitcoin

Bitcoin Core is a ‘reference client’ for the Bitcoin network, but it is not the job of any of the maintainers of Bitcoin Core to decide what happens with respect to consensus upgrades.

When I’ve previously asked maintainers for clarity on what ‘merge rubric’ they might apply to the CTV pull request, I’ve been effectively stonewalled with no criterion (even for things that were historically merged) and claims that soft-fork discussion is outside the purview of maintainership. To be clear, I’m not asking maintainers to merge, merely when they do make the decision to, what they are evaluating. The reticence to make clear guidelines around this was surprising to me, at first.

But then I understood: it isn’t the maintainer’s fault that they cannot give me any guidance, it’s how it must be.

The idea that Bitcoin Core might serve as the deciding body for consensus upgrades puts developers of Bitcoin Core into a dangerous position in the future, whereby various agents might wrongfully attempt to compel Core developers (e.g., using the legal system) to release a soft-fork client for whatever nefarious goal. Making it clear that soft-forks are released by independent efforts and adopted by the community at large is the only process we can take that keeps Bitcoin Core apolitical and unexposed.

We’ve seen in other communities what it looks like when lead devs exert too much influence over the protocol and reference clients directly. Not good. We do not want to have a similar precedent for Bitcoin.

While previous soft-forks have generally been released by Core, I have no qualms with leading by example for how future soft-fork development should be. And if Core wants to merge CTV and do a release with compatible parameters, they are welcome to, without such a release being driven by the project maintainers directly, but rather to maintain compatibility with the will of the community.

Thus, Alea Iacta Est.

Bonus: What do I do now?

I believe the community’s next steps are:

  1. Evaluate the software proposed above and find any bugs (claim 5.5 BTC Bounties?)
  2. Discuss vociferously through the next few months if BIP-119 should be activated or not (that means you should e.g. post publicly if you/your org endorses this particular path, cover it in your news org, etc).
  3. Before the end of July, Miners should signal if the speedy trial should succeed
  4. Before November, if Speedy Trial passes, then all users should ensure they upgrade to validate CTV
  5. If Speedy Trial fails, at least we were at the ball, and we can either try again next year, meaning CTV would be availble for use in at minimum 1.5 years, or we can re-evaluate the design of CTV against alternatives that would take more time to prepare engineering wise (e.g., more general covenants, small tweaks to CTV).

What is Jeremy Rubin going to do?

Well, at this point I am unemotional about any outcome. Judica, my startup, is focused on Bitcoin infrastructure that can be used to great impact with or without CTV, so I’ve explicitly positioned myself to be personally indifferent to outcome. I personally think that CTV is ready to go, and will deliver immense benefits to the network, so I’ll advocate for signalling for it.

However, in my advocacy, I’ll be careful to note that it’s not a must. All actors must decide if it’s in their own rational self-interest to have the soft-fork proceed.

But what about UASF?

Regrettably, no one has produced the ST compatible UASF code since last year, for various reasons. I understand the motives and tradeoffs of a UASF out the gate, but I still personally believe a UASF is best done as a follow-up to a ST, as I detailed in my mailing list post on the subject here.

Appendix: Parameter Check!

$ gdate -d@1651708800 -u
Thu May  5 00:00:00 UTC 2022
$ gdate -d@1660262400 -u
Fri Aug 12 00:00:00 UTC 2022

The below script simulates the passage of time and confirms that we are beginning at an expected mid-period time, and we are also ending near a mid-period time, given the assumed number of SIGNAL_PERIODS. This technique should guarantee with high certainty at least SIGNAL_PERIODS - 1, and repeating the simulation with up-to-date numbers as the signalling window progresses will produce more accurate forecasts.

import datetime
current_time = 1650301349
height_now = 732450
minutes_till_may_5th = 23457
height = int(height_now + minutes_till_may_5th/10.0)
print("Expected Height", height)
start_height = height + (2016 - (height % 2016))
print("Expected Start Height", start_height)
print("Start is mid period: ", (start_height-height)/2016.0)
minutes_from_now = 10*(start_height - height_now)
print("In This many Minutes", minutes_from_now)
print("In This many days", minutes_from_now/60.0/24.0)
stop_height = start_height + 2016*SIGNAL_PERIODS
print("Stopping at height", stop_height)
total_blocks = stop_height - height_now
end_time = (total_blocks - 2016/2)*10*60 + current_time
print("End of signalling at expected time", datetime.datetime.fromtimestamp(end_time))

active_height = 762048
secs_till_active = (active_height - height_now)*10*60
print("Active at", datetime.datetime.fromtimestamp(current_time + secs_till_active))
Expected Height 734795
Expected Start Height 735840
Start is mid period:  0.5183531746031746
In This many Minutes 33900
In This many days 23.541666666666668
Stopping at height 749952
End of signalling at expected time 2022-08-10 23:02:29
Active at 2022-11-09 23:02:29
  1. including roller skating along the beach of course… 

  2. in theory, was intended to be part of this… 

  3. I think defining such a process more formally would be great, but it’d be controversial. 

  4. technically, if you don’t touch it, this is a winner. A forced error, as Mike West notes, is where you still got your racquet to the ball. However, winners and forced errors are pretty similar in contrast to unforced errors. 

  5. probably following a thorough security review 

  6. sigh, if you really think I’m not working in good faith it’s a lost cause… 

Sapio Studio Tutorial for CTV Meeting

On Your Mark Get Set GOOOOOO

Other people have followed this tutorial with some success:

Common sticking points include:

  1. Not building latest sapio binary before starting
  2. Not building latest sapio-studio project before starting
  3. Not having the correct clang version (>=12)
  4. brew installing clang somewhere else (try /opt/homebrew, but also /usr/local/Cellar)

  1. Set up a signet node.

Build this branch

You’ll likely want settings like this in your bitcoin.conf too:

server = 1
  1. You’ll need to create a new wallet, if you’ve not done it before
./bitcoin-cli -signet createwallet sapio-studio-tutorial # If you've done this before fine
./bitcoin-cli -signet getnewaddress
  1. Get coins to your address / DM me for more

  2. Follow the install instructions on You can skip the the sapio-studio part / pod part and just do the Local Quickstart up until “Instantiate a contract from the plugin”.
  3. run cargo build –release from the root directory to build the sapio-cli.

Start Up Sapio Studio

  1. Get Yarn
  2. Install Sapio Studio
    git clone --depth 1 && cd sapio-studio
    yarn install
  3. Start react server
    yarn start-react

    Leave that running in tab

  4. Start electron server
    yarn start-electron

Once it launches this is what you should see: Go ahead and click on settings to configure the sapio cli for the first time. First, let’s configure our sapio-cli. Go head and do “Configured Here” and leave everything blank. Click on the select file and point sapio studio to your (freshly done) release build of sapio-cli.

Click Save Settings.

Now, you should see the following confirmation.

Next let’s configure your node. Clikc select file and point it to your .cookie file and then configure the node as Signet & set the RPC port to whatever you used. Save it.

Click test connection – it should tell you… something.

Navigate back to wallet. You should see some balance or something (assuming you did the faucet).

Next, click “Load WASM Plugin” and find your plugin-example/target/wasm32-unknown-unknown/debug/*.wasm files. Go ahead and pick the jamesob vault one.

Next, click Create new contract.

You’ll see a little applet for the JameVault. Look at that handsome guy!

Next, we need to create some Taproot keys for this – gonna need some command line action:

./bitcoin-cli -signet getaddressinfo $(./bitcoin-cli -signet getnewaddress "vault_project" "bech32m")

and then copy the witness program. do this twice – one for cold one for hot.

Now click on your applet and start filling it out. You can get new addresses by clicking on Bitcoin Node (just not keys yet) n.b. sometimes things are in btc, sometimes in sats. c’est la vie. finish up and click submit If all is right, you should see a contract get created! To actually create it, click on the parent txn and then sign it… and then broadcast it (with real money you’ll want to verify before doing this) it’ll now pop up in the mempool.

n.b. BUG ALERT: the viewer on the right hand side is a little glitchy. before playing with the psbts/txn signing logic, always close it and re-open by clicking on the txn you want. Now you can click on the begin redeem txn and broadcast and sign that one so it’s in the mempool Click on the updatable output, and you’ll see some options. click on spend hot, and fill out the form. Hit submit, and then hit recompile.

Be sure to pick an amount that is amount in input - fee (todo: make this smarter!). if all is well, you’ll see a hot spend.

if you picked a relative timelock > 1 block, try playing with the simulate tab :D.

If you navigate back to the CONTRACTS tab you can pull up contracts you previously made / recompilations with effects, even across sessions.

London Advancing Bitcoin Tutorial

Content for Following Along!

Other people have followed this tutorial with some success:

If you’re having a problem, see above log where people have had issues. Common problems include:

  1. Not building latest sapio binary
  2. Not having the correct clang version (>=12)
  3. brew installing clang somewhere else (try /opt/homebrew, but also /usr/local/Cellar)
  4. xargs not liking something (working to debug it, you can open the JSONs with vi and do by hand some of the steps).

  1. Install JQ (json manipulating tool) if you don’t have it / other things needed to run a bitcoin node.
  2. Set up a signet node.

Build this branch

You’ll likely want settings like this in your bitcoin.conf too:

# generate this yourself                                                                                                                    rpcauth=generateme:fromtherpcauth.pyfile     

Get coins / DM me

  1. Follow the install instructions on You can skip the the sapio-studio part / pod part and just do the Local Quickstart up until “Instantiate a contract from the plugin”. You’ll also want to run cargo build –release from the root directory to build the sapio-cli.

  2. Open up the site
  3. Run sapio-cli contract api –file plugin-example/target/wasm32-unknown-unknown/debug/sapio_wasm_plugin_example.wasm
  4. Copy the resulting JSON into the RJSF site
  5. Fill out the form as you wish. You should see a JSON like
      "context": {
     "amount": 3,
     "network": "Signet",
     "effects": {
       "effects": {}
      "arguments": {
     "TreePay": {
       "fee_sats_per_tx": 1000,
       "participants": [
           "address": "tb1pwqchwp3zur2ewuqsvg0mcl34pmcyxzqn9x8vn0p5a4hzckmujqpqp2dlma",
           "amount": 1
           "address": "tb1pwqchwp3zur2ewuqsvg0mcl34pmcyxzqn9x8vn0p5a4hzckmujqpqp2dlma",
           "amount": 1
       "radix": 2

    You may have to delete some extra fields (that site is a little buggy).

Optionally, just modify the JSON above directly.

  1. Copy the JSON and paste it into a file ARGS.json
  2. Find your sapio-cli config file (mine is at ~/.config/sapio-cli/config.json). Modify it to look like (enter your rpcauth credentials):
      "main": null,
      "testnet": null,
      "signet": {
     "active": true,
     "api_node": {
       "url": "",
       "auth": {
         "UserPass": [
           "YOUR RPC NAME",
     "emulator_nodes": {
       "enabled": false,
       "emulators": [],
       "threshold": 1
     "plugin_map": {}
      "regtest": null
  3. Create a contract template:
    cat ARGS.json| ./target/release/sapio-cli contract create  --file plugin-example/target/wasm32-unknown-unknown/debug/sapio_wasm_plugin_example.wasm  | jq > UNBOUND.json
  4. Get a proposed funding & binding of the template to that utxo:
cat UNBOUND.json| ./target/release/sapio-cli contract bind | jq > BOUND.json
  1. Finalize the funding tx:
cat BOUND.json | jq ".program[\"funding\"].txs[0].linked_psbt.psbt" | xargs echo | xargs -I% ./bitcoin-cli -signet utxoupdatepsbt % |  xargs -I% ./bitcoin-cli -signet walletprocesspsbt % | jq ".psbt" | xargs -I% ./bitcoin-cli -signet finalizepsbt % | jq ".hex"
  1. Review the hex transaction/make sure you want this contract… and then send to network:
    ./bitcoin-cli -signet sendrawtransaction 020000000001015e69106b2eb00d668d945101ed3c0102cf35aba738ee6520fc2603bd60a872ea0000000000feffffff02e8c5eb0b000000002200203d00d88fd664cbfaf8a1296d3f717625595d2980976bbf4feeb
  2. Send the other transactions:
cat BOUND.json| jq .program | jq ".[].txs[0].linked_psbt.psbt" | xargs -I% ./target/release/sapio-cli psbt finalize --psbt %  | xargs -I% ./bitcoin-cli -signet sendrawtransaction %

Now what?

  • Maybe load up the Sapio Studio and try it through the GUI?
  • Modify the congestion control tree code and recompile it?
  • How big of a tree can you make (I did about 6000 last night)?
  • Try out other contracts?

RoadMap or Load o' Crap?

Day 27: Rubin's Bitcoin Advent Calendar

Welcome to day 27 of my Bitcoin Advent Calendar. You can see an index of all the posts here or subscribe at to get new posts in your inbox

I know, I know.

God forbid, a roadmap. People hate roadmaps. As I’ve noted before:

Bitcoin Eschews Roadmaps and Agendas. I provide this maxim to make clear that this document is by no means an official roadmap, narrative, or prioritization. However, it is my own assessment of what the current most pragmatic approach to upgrading Bitcoin is, based on my understanding of the state of outstanding proposals and their interactions.

My priorities in producing this are to open a discussion on potential new features, risk minimization, and pragmatic design for Bitcoin.

If you didn’t click, I definitely recommend reading the quoted post in conjunction with this one. As well as, if you’re a first time visitor to the Advent Calendar, the preceding 26 posts.

In contrast to my prior post, this roadmap is going to be less about full justifications and unbiased weightings and tallyings of sentiments and more just me spitting out a timeline we could introduce changes on. It’s not a final answer, and in no way authoritative, but it’s a launch point for a discussion that has to happen in some way at some point in order to advance a soft-fork.

Consider this as being posted for the sake of public review. If you disagree with this, let me know why! But please no attacks just for the act of discussing the topic of soft-fork activation1.

So buckle up here’s how we could make Bitcoin kick ass in 2022 and beyond:

2022: The Year of the Covenant

BIP-119 Timeline

CheckTemplateVerify is getting close to ready to go. There are numerous supporters (listed on, few detractors, and a bumper crop of amazing use cases (did you read the calendar?) waiting for us on the other side of CTV activation. The major critiques are that we might want something that does ‘more’ than CTV itself, or to include it in a bundle of things.

My take: we’re not Gordon Gecko. Greed is Not Good. CTV represents a clean, well contained, unproblematic upgrade that’s going to deliver hella functionality in service of scaling, decentralization, self custody, and privacy. Let’s secure the bag for Bitcoin users everywhere and make it happen. We can always do more, later, informed by what extensions we need for rapidly maturing tools like Sapio. CTV is also technically specified and implemented sufficiently – a view I’ve confirmed with a couple other devs – that it is able to be considered for release.

What would have to happen to release CTV?

  1. More signalers would need to be on or other platforms to demonstrate interest and demand for CTV, ideally explaining which use cases are important to them and why. Every voice counts for consensus. There is no list long enough to capture what it would mean to have consensus, so there is not some threshold that implies a ‘go ahead’, but N+1 is clearly better than N.
  2. More “regular contributors” would need to spend time reviewing the code and BIP to assure themselves of correctness and safety. Nothing can move forward with out, no matter the count of casual contributors. Many regular contributors don’t want to ‘get political’ and look at forks. Fortunately, while all consensus changes are complex, CTV is a very tiny and easy to review change in comparison with SegWit or Taproot (more similar to CheckLockTimeVerify – a couple hundred lines of consensus code, a couple hundred lines of non consenus code, and a couple thousand lines of tests, no cryptographic primitives). NOTE: This is a big if! Every contributor has the right to review, and ACK or provide a reasoned NACK. Even if everyone else is excited about something doesn’t mean there isn’t space for new thought-through dissent. At the end of the article, I discuss some concrete next steps to ensure more developer review occurs.
  3. We would need to merge the implementation. This is simple, but enough ACKs have to come in and rebases on other subsequent changes to get it in. This can happen ahead of ‘full consensus’ since there are no deployment parameters, but aids in increasing the testing priority of CTV.
  4. We would need to get a majority of miners/pools primed to accept the upgrade.
  5. Major alternative implementation maintainers (e.g., BTCD, Knots) should show willingness to implement or accept patches for the new rules (although it’s a soft-fork, this is good to do).
  6. We would need to decide on release parameters for the implementation.
  7. We would need to merge and release a client with release parameters
  8. The client would needs to lock-in by a supermajority of miners signalling.
  9. Then, and only then, would CTV be fully available.

What’s the Maximally Aggressive/Optimistic Timeline?

  1. Soft Signals / Developer Review: 2-3 months required to get ACKs on the implementation, assuming no major changes required.
  2. Merge: Instant, just whenever there are ACKs against the implementation being safe and matching BIP. Usually, enough ACKs for a PR is 2 regular contributors, the comitter, and a maintainer, but for consensus changes there is no threshold at which Bitcoin considers a change sufficiently peer reviewed. A consensus change should see higher quality reviews, as well as external consensus that the change is desired.
  3. Getting miners primed to signal: ~20% of pools are on, more should be coming on board soon. Don’t expect this to take additional time if in conjunction with Developer review.
  4. Debating Timelines: ~1 month to agree on a release timeline
  5. Preparing a release: ~1 month to do release candidates and testing.
  6. Speedy Trial: 3 months of signalling, 3 months of waiting for lock-in to active.

Overall, it could look like this:

On March 15th developers reach agreement on merging BIP-119’s implementation. On April 15th, agreement is reached on release parameters for signalling from ~ June 1st to ~September 1st. The activation height would be November 10th. A client is prepared, and tested, and released. No issues are found. The miners signal at some point in the 3 month window above the threshold. CTV locks-in. Developers can prep wallet software for deeper integration. CTV activates before Thanksgiving, avoiding the “dire straits” of thanksgiving-hanukkah-christmas-chinese-new-year-valentines-day season.

but that’s basically identical to Taproot’s timeline?

Exactly. If we act on this timeline starting in early January 2022, it is possible to meet an almost identical timeline for CTV as Taproot.

Part of why it works is that the next major release is scheduled for 2022-04-01. Soft forks are usually released as a minor patch on top of a few recent major releases. So CTV could be:

  1. Code included in 23.0 for CTV, no activation parameters
  2. Activation parameters in 23.1, and backported to 22.x, 21.x, and (really this is up to maintainers how far to backport!).
  3. 23.1 released before June 1st, 2022.

What could go wrong?

  1. Concern: There could be a small tweak to CTV that makes it marginally better, and it’s worth adding some extra review time as a result.
    CTV is highly design specific, so it’s unlikely there could be a change needed, but not impossible. Changes would be unlikely to be large, though, e.g. perhaps comitting to the same fields in a different order. Taproot saw some small changes about a month before being merged.
  2. Concern: Release process has a delay due to an issue uncovered in non-CTV code.
    Soft fork releases are usually a minor patch onto an existing version, so it’s unlikely that there would be a new bug, but the release would still be planned and could resume as soon as patched. Speedy Trial’s ‘delayed activation’ also helps with providing more time for (non-consensus) bug fixes in the client between lock-in and activation.
  3. Concern: Release process has a delay due to an issue uncovered in CTV’s code.
    If the issue is a bug, it would merit more strict scrutiny on the code and tests (which are pretty comprehensive currently) as to how they could be passing with an issue like that. Once patched and reviewed, it’s still possible to merge and release. However, the issue could also be a conceptual bug (e.g., here’s how to do recursive covenants with CTV), which would certainly delay (and I’d be the first to say it!) continuing with CTV at the present time. The former issue is likely more likely than the latter, and that risk is defrayed by thorough code review and testing.
  4. Concern: There’s not enough developer consensus conceptually.
    There are many developers supporting on I’ve also made an effort to reach out to a variety of developers who are not on the site to seek out dissent, and I do not think there are any current safety concerns, which is positive for developers who might not Ack but don’t have a ‘this is a grave mistake’ Nack up their sleeves. Again, there’s no well defined threshold for what is “enough”.
  5. Concern: Miners don’t want CTV and don’t signal for it.
    _20% of the hash pools already say they do want it, and more should be joining that list soon™. Should that not happen, there could be a UASF effort to ensure the activation of BIP-119 if users want CTV strongly enough. _
  6. Concern: Disagreement on Activation mechanism.
    Taproot’s Speedy Trial (ST) worked very well. Big Success. No need to mess with the recipe. UASF-clienters know how to make the mods to the activation logic for whatever they want as a competing client. But perhaps that’s not a comfortable status quo, so this is certainly one to watch. I’ve made my own remarks on what order of operations I think ST/UASF/etc should go in here, but there’s not consensus on this topic. Notably, there is some dissent from reusing ST at all. While important, activation logic is a secondary (but still critical) concern to the decision to accept the current specification and implementation of CTV in the first place, and discussion on that can proceed in parallel to progress on consensus on the implementation.

And Then What?

After the release of CTV Soft Fork Client, what goes next?

  1. Jeremy takes a vacation for a month.
  2. Sapio continues to improve dramatically, as detailed in the last post.
  3. Work begins on new Opcodes.
  4. More fun applications get built on CTV/Sapio (for examples, review the entire series of the Advent Calendar, but a few of my favorites are Payment Pools, Vaults, and Bonded Oracles).
  5. Non-Interactive Lightning Channel BOLT drops.
  6. Payment Pool spec drops with LN integration.
  7. (Privacy + Scale)++

New Opcodes you say?

Yep, new opcodes. As soon as CTV is merged, there are some new features that could be tooled into BIPs without much controversy, given their simplicity:

  1. New Math Opcodes
  3. OP_CSFS

These are “universally agreed on” bits of functionality that have very little wiggle room in how they might be specified. Therefore their implementation, testing, and release is mostly mechanical. This makes them good bets for a concrete timeline because they’re a rote-development task with few research dependencies and easily agreed on design.

With hard work, these could be reviewed and tested in time for Speedy Trial signalling in June 2023 (+1 year), with realllllly hard work 6 months earlier (but there are conflicting priorities for developer’s time – e.g., building stuff with/for CTV and Taproot – that make that super unlikely).

What about Anyprevout

Anyprevout is 1000000% not ruled out here for advancing to the consensus stage in 2022. There are a couple things happening on Anyprevout that make me suspect it might be more primed towards early-mid 2024 best case.

  1. Taproot upgraded channels taking some steam away from Eltoo with AJ’s proposal to do state compaction via PTLCs.
  2. Disagreement over no justice transactions in the community for high value channels.
  3. Open research on specific Eltoo protocol implementation / need for other tools (like SIGHASH_BUNDLE).
  4. Lack of an open PR and test suite for it.
  5. CSFS + CTV permitting a version of Eltoo.

All of these reasons point to it being highly unlikely APO could be finished on the timeline presented for CTV, but also that given a desire to see a working LN client (ensuring the protocol is sound end-to-end without modifications) leads to additional engineering complexity.

I’ve heard on the rumour vine some excellent engineers might start working on an Eltoo implementation, I believe that work to be of tremendous value to gain consensus on deploying anyprevout.

Given that a couple years seems like the best case for a set of upgrades around APO to deliver Eltoo, if we have the ability to deliver CTV now, it is a good asymmetric bet for delivering utility to Bitcoin’s users.

Suppose I’m wrong, and Anyprevout really could get done in 2022. Shouldn’t it be ‘next’ and CTV can wait?

The notion that any soft-fork is “next” for consideration and blocks any other from being considered is somewhat contrary to the support for parallel soft-forks with distinct version bits used for signalling. The possibility of deploying soft forks on independent bits means things can be ultimately “proposed” whenever they’re mature enough to enter the “final stage” and the timing fits with Bitcoin’s general release schedule. The chief counterarguments to this are twofold: One, review resources are finite and we can’t even think about \(>1\) thing at a time; Two, it’s bad if the protocol is simultaneously deploying \(N\) upgrades and any of them might fail, leading to \(2^N\) potential protocol states. It’s actually the other way around: if things can proceed in parallel we can get more review, because developers won’t feel that reviewing others work has the potential to slow down their own, and we’ll be more certain that the upgrades we release are strongly desired by the community (i.e., will end in a UASF if not activated due to miner apathy).

What about TapLeafUpdateVerify

If I had to estimate, I’d say TLUV needs another year or so of people ‘stewing’ on the possibilities and design before it could move forward. It would then probably need at least a year of tinkering to get a well-accepted implementation, and then a year for release process. So let’s say best case it could be a 2024 thing, more likely 2025 given Anyprevout is seen as higher priority for the engineering work.

What about Inherited IDs (IIDs)?

They didn’t make the cut in the earlier piece since they’re a bit more abstract, but I’d posit that IIDs could also approach a 2024 timeline were the developer of the idea to spend a heckin’ big amount of time on advocacy for the concept in 2022, and present a clean implementation of the concept (& demonstration of overheads) by 2023. This is complicated by the issue that he would have to also solve issues with requiring a new index, such as helping assist assumeutxo compatibility, write reindexing logic from genesis (or somehow exclude old coins?), and also work on utreexo compatibility. Those all seem tractable, but very hard to do for someone who is not a full-time long-time contributor to the project, but I’m a believer that the job could be done given the quality of the insights in the IIDs paper.

Parallel Developments?

In parallel to the above, there are some things that I think are very cool that should remain under development, but don’t have a clear path to inclusion presently.

The first is Transaction Sponsorship, which could substantially simplify many protocols on top of Bitcoin, especially things like Eltoo and CTV stuff. We can’t predict that too well because it will depend on what developers end up running up against with current best practices around CPFP/RBF, but I suspect it might become popular if a small group of developers prioritizes such an approach as a unified front. Since it’s technically simple, it wouldn’t take much time to implement, but because there’s very little consensus for it right now it’s not fit for inclusion in a roadmap.

The next is Simplicity. Simplicity could completely change how Bitcoin scripting works and is super duper exciting. I guess it’s going out on Elements sometime soon? However, it’s stupidly complicated for most devs to fully understand (although it is called simplicity…), so it would take a fair amount of time (read: years) before the implementation could be sufficiently independently reviewed by the intersection of qualified Bitcoin and Programming Language theory reviewers. The interesting thing about Simplicity with respect to this roadmap is that because it’s so general, as soon as it seems like Simplicity would be on Bitcoin within ~1.5 years, it’s likely all other scripting soft fork developers would “stop” development2 and focus on deployment as Simplicity Jets.

Concrete Next Steps

Should this plan not seem feasible to the near unanimity of the community for us the deliver on (e.g., with +2-3 months of the suggested timeline), I don’t think there is another good opportunity to enact on an activation of CTV and the best course of action would be to delay +1 year. There could be a UASF for it, since there is strong user demand for CTV, but I wouldn’t personally lead the charge on that beyond ensuring that the BIP-119 code remains up-to-date and is implemented correctly.

Assuming someone doesn’t make a bold argument that gives me or the aggregate current supporters of CTV pause, I plan to begin holding a fortnightly CTV review session to iron out any details, additional testing, code review, and activation plans. I would also like to help a third party host a review club, although the focus of Review Club is more educational for the reviewers as opposed to for the purpose of formally reviewing the code for merge.

You’ve now reached the end of Rubin’s Bitcoin Advent Calendar, 2021! Congrats. wc -w $(ls | grep advent) tells me that means you read 50,773 words total of me rambling on about covenants. That’s PhD thesis length! I really hope you found something to enjoy.

A special thanks to all who helped review this post in particular and provided feedback in ensuring I’ve done an OK job capturing the complexity of gaining consensus. To the extent that I haven’t succeeded in representing your perspectives here, I take sole responsibility for the inadequacy. Your constructive feedback on how to improve is welcomed. A further special thanks to Ryan Gentry who encouraged me to produce the series in the first place, and to Sarah Satoshi for her support as I battled my way through this task.

As for me, I’m off to sip some Eggnog and eat some holiday cookies! I’ll take a little bit of a break, and be back in the New Year following up on next steps and dropping fresh content for y’all as always.

Merry Christmas and Happy New Years,


  1. You do you though. It’d really hurt my feelings if you called me a Smelly Weasel attacking Bitcoin. 

  2. Transaction Sponsorship cannot be done, as far as I understand, as a part of Simplicty. Things like that would progress independently. 

The History and Future of Sapio

Day 26: Rubin's Bitcoin Advent Calendar

Welcome to day 26 of my Bitcoin Advent Calendar. You can see an index of all the posts here or subscribe at to get new posts in your inbox

Sapio began as little more than a slide in presentations I would give on what BIP-119 could be with the support of a programming environment.

While my conceptions of what could be built with CTV were about on-par with where they are today, the tools available were very clunky. You can see one of the original diagrams from the C++ Code below (code here).

    *                   [      vault_to_vault n  ]
    *                     |a                   |b
    *                    (0)                  (1)
    *                    /\                   /\
    * wait + maturity   /  \                 /  \ wait + step_period    (attached)
    * [   hot_to_hot   ]   /  [vault_to_cold]    [vault_to_vault n - 1]
    *                     /                         |           |
    *        [hot_to_cold]                         (0)         (1)
    *                                               .           .
    *                                               .           .
    *                                                           .
    *                                                     wait + step_period * n   (attached)
    *                                                   [vault_to_vault 0]
    *                                                      |
    *                                                     (0)
    *                                                     */

When I presented it on February 1st, 2020 at the CTV workshop, one of the last Bitcoin events before the pandemic began1, I knew I had to present a more concrete vision on how smart contracts could be built, rather than spit-and-glue C++.

And so I included slide inspired by the hand rolled smart contracts I was making in C++ about how the technique could be generalized.

a slide at the feb. 2020 CTV workshop.

This is a research project I am interested in pursuing. We have a few scripting languages. We have Dan here who wrote Ivy. There’s also Balzac and Solidity. It’s poorly named, but it actually has some really interesting ideas that aren’t in other scripting languages for bitcoin. There’s some notion of participants with private state they are storing, and has some notion of interactivity. I also threw up there BlueSpec which is like a VHDL competitor that is pretty neat. If you think about it, there’s a software layer for controlling vaults but there’s also a hardware layer- so how can we describe transactional hardware? You wind up with similar controls as a BlueSpec-like language where you are creating plumbing and a description of how things are moving rather than something that has imperative state.

As an example, one of the properties with OP_CHECKTEMPLATEVERIFY that is cool is the narrow window of a standard OP_CHECKTEMPLATEVERIFY script is that you have this composability property where for a given model that goes to arbitrary address outputs, you can just throw another one inside it. As the outputs of that annuinity, you can put undo send as the outputs of that annunity, and you can tag on more and more programs into that if you want. On this slide is a templately description of a language, which helps if someone else given the same program description can verify that the hash is the same for the given inputs. Instead of sending you a million branches, you can generate them yourselves.

Q: Is there code for your metascript thing?

A: No. It’s just an idea I’ve been toying with. I got relatively close to metascript just writing in C++ just writing with C++ templates. Then I got ready to kill myself doing that because writing templates.

I’d discussed similar slides at earlier events, usually included it as an example of something someone else could build while I kept pluggin’ away working on Bitcoin Core. Eventually I realized that me claiming that CTV could be used to do these things and CTV demonstrably doing these things was an obstacle… I needed to make the prototype.

So I set off hacking together a prototype… I spent an afternoon or two mucking around in C++ only to realize that wasn’t going to happen, and then I switched to python. Python was a great choice, and after quite a bit of time pluggin away, I had something that actually worked.

There was a moment of magic where I connected it to the Sapio Studio (which actually existed long before Sapio as just a visualizer for a set of transactions) to load a contract written in python and… it worked. Really well. It felt incredible. I began talking more about what Sapio could do, thinking through some of the problems and solutions. I even gave a talk in the metaverse with Udi where I dropped my virtual laser pointer on the ground for a minute and couldn’t pick it back up.

there were more people sitting further back I swear…

At a certain point I decided to start working on cleaning up Sapio by using Python’s gradual typing and trying to convert to using Miniscript instead of my custom-made Sapio script fragment builder. I was neck deep in type refactors and then I had a deep realization:


I was incredibly greatful for the rapid iterating that python allowed me, but I realized at this point that it was going to be nearly impossible to make Sapio actually good and not just a toy working in python. What had started as a proof of concept for someone to do “for real” had gotten good enough conceptually but was bursting at the seams and was not going to ever yield something production grade.

So I did a reset.

I started building Sapio in Rust, re-implementing (but much more cleanly) the paradigms that I had previously developed, relying on well tested and type rust-bitcoin libraries instead of janky test-framework python code from Bitcoin Core.

And one day – almost like Deja Vu – I plugged the Sapio Rust served in place of the Python one for the Sapio Studio and everything Just Worked™.

Since then, Sapio has only matured and gotten better and better with each passing month. I’ve added tons of new features, improved the underlying architecture, made the ABIs more well defined, built stronger intergrations with the GUI, and more. Today, Sapio is actually usable on mainnet (if you’re an expert at least), and I’ve used to do congestion control payments and art projects.

Sapio has helped me cut through the content for this Advent Calendar like a swiss army knife. It’s actually becoming a pretty decent tool!

What’s Next

Sapio needs to get to the next level. There are many major areas of work in the pipeline. You might think of this as “Sapio is so incomplete it’s not ready”. I think of it more as Sapio is just getting started:

Upgrade to Taproot

Support for Taproot in rust-bitcoin and rust-miniscript is coming! Once that lands, I need to rebase (and maybe upstream?) some Sapio features, and then update the compiler to always use Taproot outputs!

Improve Sapio CTV Emulators with Taproot (if ctv seems to be slow)

Once taproot lands, the multi-sig federated oracle designs can be set up to do a MuSig Schnorr signature instead of just a bare multi-sig, allowing wider federations.

This engineering work only really matters if CTV seems unlikely, but could be useful to have anyways for future purposes & extensions to Sapio.

Right now Sapio works for making little Applets, but there is no “end to end” software (e.g., vaults) made in Sapio.

This requires work on both the Sapio Studio front and potentially on a website for things like Sapio NFTs.

This will push the boundaries on integrating Sapio into real applications.

One particular feature that would be great is ‘auto-signing’ on valid state transitions proposed at a certain continuation point. For example, if we have an NFT we want to dutch auction, we should be able to have a sapio module running that is happy to spit out the relevant transactions with a nice API.

More advanced programming of transactions

Currently the Sapio transaction builder from within Sapio branches is a bit limited in what it can express.

Augmenting it with the ability to more fully describe partially signed bitcoin transactions (PSBTs), e.g., when used in the continuation context would advance the state of the art.

Key Management

Relatedly, it would be really useful if you could tell Sapio how to access a signing module and have sapio use that external key to generate the appropriate signatures for the state transitions.

Better sapio-cli / server that can keep WASM modules loaded in memory, aiding performance

Right now every time a module is used the entire thing has to reload which is super slow.

It should be possible to have a single server instances that manages a cache of all modules, greatly boosting performance, especially for recursive cross-module calling contracts.

Client Side Verification Caching Across Module Boundaries

For things like NFTs that we saw, we have to always re-compile the entire history of the NFT to do state transitions. However, many of these state transitions are just doing the exact same thing every time, re-verifying from genesis. We should be able to cache the compilations at well defined boundaries.

Better formal analysis tools / type system on top of Sapio

Currently Sapio has the ability to define various interfaces for composing Sapio contracts cleanly.

But we don’t have a great way of proving what we want a contract to do v.s. what it does.

This work will start as being able to express more properties about a module in it’s “manifest”, and will culminate in being able to check the validity of compositions of contracts based on them.

If anyones looking to do a PhD thesis on Sapio, this is prolly it.

More Module Types

Right now all WASM modules are for generating a ‘Compiled’ contract from a JSON.

I would love to add defined module types to cover all the standard components like:

  • Miniscript Fragments
  • Then Functions
  • Continuation Functions
  • Transaction Template Generators
  • Trait Verifiers

and more.

More Emulator Types

Sapio works today with CTV then functions because the functionality can be emulated by a federation of signers.

Figuring out how to cleanly extend the signing server paradigm to a number of different types of Covenant proposal (e.g. APO, TLUV, CAT) or other opcodes could add a lot of value for making Sapio the defacto platform and proving ground for upgrades to Bitcoin.

Unifying Then and Continuation

Then and Continuation really are the same thing conceptually, it would be

Standard Library of useful applications / Plugins

Title says it all. There should be more off the shelf things to use!

Wallet Stack for Sapio Contracts

The Sapio Studio is rapidly imporving as a system for engaging with Sapio contracts, but it’s lacking in the management and storage of all of a user’s contracts. We can, and will, do a better job with this.

This includes being able to make watchtower-like functionality for Sapio. It’s coming, but will likely require a lot of new features to the language spec to express if this then that monitoring conditions. And with features comes complexity.

You can see hints to this in the slide earlier, being able to react to e.g. confirmation or mempool events.

This also includes dramatic improvements needed to the GUI so that users can understand much more deeply what contracts are doing.

Binary Releases

Right now Sapio is just DIY to build and run it yourself, but we really ought to work towards stable binary releases to quickstart users.

Visual Programming for Building Sapio Contracts

When composing together Sapio modules, I would really like for it to be kind of labview like interface for adding data or other modules, where you can “typecheck” that the wires (module names) are composing into slots they work. If that sounded like gibberish, I just mean that I want to be able to plug in a module hash for a NFT Sale contract into my NFT contract and have the UX give me real time feedback if I should be able to do that.

Sapio Package Manager / Deterministic Builds / Signers

As more modules become commonly used (e.g., like NFTs) we want to ensure all users can build an exact copy themselves (Deterministic Builds) or that they can find a build signed by a number of respected code signers (Signers). While we can use Cargo / for the package management of our actual rust code, we need something to distribute the sapio wasm blobs nicely!


Writing tests for Sapio contracts is hard as heck. We need some bold ideas on what sorts of properties would be useful to test for. Fortunately, a lot of properties we care about (like not wasting money) can be checked by the sapio library to be safe, but we still want to be able to ensure we never lose a users funds out of Sapio.

#### Getting CTV Locked in


If I get even a tenth of this completed 2022 will be a good year for Sapio.

But I plan to get it all done.

Perhaps with your support – if you’re an engineer or funder interested in helping propel this, please reach out!

p.s. safe holiday travels!

  1. That honor I think goes to the MIT Bitcoin Expo. 

© 2011-2021 Jeremy Rubin. All rights reserved.