- Background Info
- Git Repositories
- A note on the meaning of “Ciphertext”
- Development Environment
- Local Development
- Arbitrum Goerli Development
- Relevant Contract Addresses
- Relevant EOA Addresses
- Getting Arbitrum Goerli Gas
- Building an Application
- Building an Application Smart Contract
- Building an Application Frontend
- wagmi Library
- Modifying the medusa-app demo
Background Info
Git Repositories
medusa-network/medusa - Code that implements the threshold network/protocol; medusa nodes run this. Currently Private
medusa-network/medusa-contracts - Code that implements a protocol to interact with Medusa via EVM chains
medusa-network/medusa-sdk - A Typescript/Javascript SDK to interact with Medusa contracts from a frontend application
medusa-network/medusa-app - A demo application built with Medusa
A note on the meaning of “Ciphertext”
We use “ciphertext” interchangeably to refer to a few different encrypted things depending on the context. This can get a bit confusing. Here’s an explanation:
There are three distinct things that can be a ciphertext:
- Encrypted Content - this is what your users care about and usually what you care about when building an application. This is usually a file or some sort of long-form content. Medusa does not operate on this, care about this, or even know about this. A user’s content is encrypted symmetrically on their own machine and uploaded to an external storage, such as Filecoin.
- Encrypted key (encrypted with Medusa’s public key) - this is what Medusa refers to as “Ciphertext”. After a user encrypts and uploads their content, they will have a symmetric encryption key. This key is then encrypted with Medusa’s public key to form a “ciphertext”. The resulting ciphertext should be 32 bytes and will be sent when submitting ciphertext to the Medusa oracle contract. The Medusa nodes will operate on (reencrypt) this ciphertext.
- Reencrypted key (encrypted with the user’s public key) - the Medusa contracts and nodes also refer to this as “Ciphertext”. A reencrypted key is the result of a successful request/response to Medusa. Your application receives this key in a callback from Medusa and your user retrieves this key through your frontend by listening for events emitted by your application smart contract. A user can decrypt this key with their private key and then use it to ultimately decrypt the Encrypted Content that they care about.
Development Environment
Local Development
Developing locally with Medusa is not fully supported at the moment.
We have a readme to run a Medusa cluster locally, but there is still a small bit of work needed to expose the blockchain RPC from the private kubernetes network to the local network of your computer. This is needed to connect to the RPC from your browser
TODO:
Arbitrum Goerli Development
We have a cluster of Medusa nodes running on AWS that listens to a set of contracts deployed on the Arbitrum Goerli network. You can deploy your client smart contracts to arbitrum-goerli and integrate with Medusa that way.
We still need to verify the contracts on Arbitrum Goerli in order to easily inspect transactions coming from Medusa nodes/contracts. We can do this now that the medusa-contracts repo is open-source.
You can find the currently deployed contracts at this commit
TODO:
Relevant Contract Addresses
OracleFactory: 0x3A7E09AC73Df8e07ce47C7868715BAb4467bd841
DKGFactory: 0xc84983B3D1338DfB08c9c539bEc01ebcaeD7e5D6
DKG: 0x2382F8D16faDBE4bb593EAAca0a783Ca5232BF9e
BN254EncryptionOracle: 0xf1d5A4481F44fe0818b6E7Ef4A60c0c9b29E3118
Relevant EOA Addresses
Admin Account + Faucet: 0x82ad00373ffdf70fd32a3d41eedd70766e48e992
First Medusa Node (Relayer Node): 0xa79F1c8a025B4E1Bc545B0757e265827482abCe0
Second Medusa Node: 0xf5a3bE98B96AB036E949866996976879c73F4d06
Third Medusa Node: 0x17B4c0CbEB0A79A83e0Fec69fDBFc0c10484A63a
Getting Arbitrum Goerli Gas
The easiest way to get gas money is to use the Faucet on the Medusa demo site. Connect your wallet and then click “Faucet” in the top right of the screen. It will send you 0.01 ETH, which should be enough for ~100 transactions. You’re welcome to click it a few times if you need more, but please don’t abuse it.
If you need more, the best way I have found is to use the Goerli PoW faucet. Once you have “mined” some (You can get ~1 ETH/hour), you can bridge it to Arbitrum Goerli
Building an Application
To build an application, you need two things:
- An application smart contract
- A frontend for users to interact with your application
Building an Application Smart Contract
You can write a smart contract that implements an access control policy.
It will interact with Medusa through 3 primary functions:
- Submitting ciphertext
- Submitting reencryption requests
- Receiving callbacks with reencryption results
You can find an example application smart contract here
Building an Application Frontend
Your frontend should enable 3 primary functions:
- Submitting ciphertext
- Uploading encrypted content to storage
- Registering the key to unlock the encrypted content with Medusa as a “Ciphertext”
- Requesting to view/unlock ciphertext
- Viewing/browsing/finding submitted ciphertext
- Viewing ciphertext once it has been unlocked
wagmi Library
It’s worthwhile to get familiar with the wagmi library that we use to read/write to EVM blockchains. It’s really nice to work with, but not straightforward to read as it makes heavy use of React hooks/effects thus is very declarative.
Modifying the medusa-app demo
You can start by forking medusa-network/medusa-app
You can see the deployed demo here
Then, you may want to inspect/modify a few areas of code.
First, you should change the constants that refer to your application smart contract:
If you change or add to the structure of the events emitted by your contract:
- Modify the interfaces in src/stores/globalStore.ts
- Modify how event data is fetched and stored in src/pages/index.ts
If you want to change how events are rendered:
If you want to see how we use the medusa-sdk to encrypt/submit/decrypt content