Inspiration
Simplicity is an amazing idea, really. However, as Seth talked at the end of the last day of the Liquid & Simplicity Bootcamp on Thursday, there's not really a way yet to make the general public know that a contract (that is directed to the general public, of course if it is a problem between people who happen to know each other there is no such problem) exists and that they can fund, enter or try to spend this contract if they fulfill the requirements.
So thinking about this problem of reach, we thought about using Nostr as a decentralized solution to propagate the info necessary about a Simplicity contract in order for it to be available to spend (or try) for the general public, in a public square of the internet, and also in a way that multiple Nostr clients can create implementations using it. So basically our idea is the proof-of-concept of a sub-protocol, or pseudo-protocol that exists within Nostr to propagate the Simplicity contract and the important info. Many implementations like MareNostrum can surge, we are just one implementation.
What it does
MareNostrum is a proof-of-concept of a decentralized layer to propagate, discover, and interact with Simplicity contracts intuitively through Nostr. It can generate Simplicity contracts dynamically with the user's inputs, generate the hex of the contract using the SimplicityHL compiler and then generate the contract address using hal-simplicity cli and even fund the address using an api route to fetch the liquid faucet. From then it can sign in to Nostr using the NIP07 browser extension, create a "subprotocol" for the propagation of the contract to the Nostr network (a json struct), this json struct has all the info necessary to spend the tx (including the necessary witness format).
The contract is propagated to Nostr using a kind1 event (not ideal, but fast and efficient) and then any client can verify, interact, and even create the spending tx with the info propagated. MareNostrum has its own implementation of a table of contracts propagated to the Nostr network.
How we built it
We used SvelteKit for the frontend with typescript and tailwindcss for the css styles (just the regular webslop). The main reason behind choosing to write the frontend in a javascript framework is that it's easy and fast to use with NDK (Nostr Dev Kit) for signing using the NIP07 and the browser extension every time an event is published.
The back-end was written in Go with Fiber as the library for the api routes (it's more intuitive). There are two api routes, the /generate-contract that calls two shell scripts, one to use simplicityHL compiler to generate the hex of the contract, and the other to call hal-simplicity cli to get the address of the contract, and the /fund-address, which makes a get request to the Liquid faucet with the contract address to get some coins to it.
The propagation to the Nostr network does not happen in the Go backend but in the svelte frontend because it was just easier to just use NDK, that just works so well with javascript webslop.
We only used only one Simplicity contract sample in order to make this PoC project doable in the time period allocated. However, as many contract samples as needed can be added to MareNostrum, and even contracts propagated by other implementations could be added by default to MareNostrum's menu of contracts.
The contract sample/template we used has a hardcoded oracle_pk, that is only for test use, in a real world contract we would need an oracle public key from a real oracle server running (we started writing something like that, but had no time to finish it).
Challenges we ran into
- The biggest challenge was to understand how the witness was able to satisfy the Simplicity contract, or at least the lifecycle of a contract, how to create one, how the witness needs to be formatted, and how the owner_sig or the oracle_sig would work (if the contract needs it, I think in the contract sample we used only the oracle_sig was needed but we kinda hardcoded it).
- Of course, the SimplicityHL was and still is a big challenge for us, but fortunately we were able to at least overcome our sample contract.
- Creating the tx for spending the contract is also a challenge, due to the time limit we were not able to implement an api route that could use the info propagated about the contract to create the spendable tx.
Accomplishments that we're proud of
Being able to understand, generate and fund a contract was a satisfying feeling. Also, even though we were not able to create the spending tx, understanding the information needed to create it and how we could implement it taught us a lot about how SimplicityHL works. Propagating things to Nostr is also cool. We get the feeling of freedom and coolness of just putting stuff in a decentralized network, really cool and fun, anything with Nostr is fun.
What we learned
The lifecycle of a Simplicity contract, how to spend a Simplicity contract, how the Liquid Sidechain works and connects to Bitcoin, also learning a little bit of SimplicityHL has taught us about how Bitcoin script itself works.
What's next for MareNostrum
- Implementation of a menu of sample contracts available;
- Expand the dynamic input of the user in the contracts to make them more reactive and "playable", so the user can tinker with contracts in a more fun, easy and dynamic way.
- The "claim" function in our table of contracts. It is going to call the function to create the spendable tx and propagate it in the liquid testnet.
- The default way of adding other contract templates/samples by just inspecting the propagated info of contracts created by other implementations like MareNostrum.
- Some UI/UX fixes.
- Working on our "sub-protocol" inside Nostr, making the fields more efficient, organized and concise.
- The kind1 Nostr event is not the ideal way to propagate this kind of things, so we think about understanding more about the multitude of event kinds in Nostr and switch to one that better fits our needs. If we do not find any, propose a new Nostr event only for our SCPN (Simplicity Contract Propagation on Nostr) through a new NIP.
- Maybe in the future even to make possible for users to fund contracts using Nostr zaps with lightning and spend this contracts also with Nostr zaps and lightning.
Built With
- daisyui
- fiber
- go
- liquid
- ndk
- nostr
- shell
- simplicity
- svelte
- tailwindcss
- typescript
Log in or sign up for Devpost to join the conversation.