Published on

Mercury Ecosystem V1 Is Here! Check Out The Release Announcement

Authors

Wait!? Can I use the native Rust SDK everywhere? Can I build customized network-data proxies for my protocols? This and more, all in Rust ❤️🦀.

~ Some Rust Dev


The journey of Mercury development is an ever-evolving one. We started off as a managed indexer that ingests conditionally depending on subscriptions, then developed a webassembly virtual machine to execute custom ingestion/indexing solutions, then hardwired Soroban to our VM, and finally built a serverless function execution backend to search the ledger and the Mercury database.

The release of the Mercury Ecosystem V1 is the signature that we are committed to the growth of Stellar and to onboarding first hundreds, then thousands of developers to the chain's ecosystem. The new features proposed in the ecosystem have the goal of allowing unprecedented network data access and programmability in a developer-friendly environment that is accessible and efficient.

This isn't only a game-changer for Soroban developers. We use a novel and innovative approach to network data services that is new in the industry: you build and deploy fully-featured Web3 APIs that run in a specialized virtual machine. No more manifests, handlers, mappings, and partial customization; it's your binary running with privileged access to on-chain data + RPC functionality.

Below are the biggest user-facing updates.

Open Access to Zephyr.

There have already been some experimental Zephyr programs (xycLoans, Soroban Governor) running on Mercury's cloud infrastructure, but now you can sign up and deploy your own!

Zephyr functions on the Cloud Environment.

Your Zephyr programs can now not only run real-time as Stellar ledgers close, but can also be called and executed through web requests with a custom-defined API, just like serverless functions.

Data Catchups - Backfilling with Historical Events.

If your program should be relying on Soroban events that have already been emitted before you deployed the Zephyr program to Mercury, we've got you covered.

You can initiate "near-instant" catchups and execute your programs against historical events. How does this work? We artificially build ledger transitions starting off the indexed events of the requested contracts.

Note: this is also much faster than doing the same thing with a stellar-core catchup.

RPC Functionality In Your Programs.

If you've been following the rumors on X (twitter), you heard correctly: programmable RPC functionality on our server is here and currently executing instructions in our VM!

You can say goodbye to having to rely on additional RPC services if you're already working with Mercury for the indexing.

You can embed the RPC functionality you require directly inside your Zephyr program: simulation, requiring ledgrs, and even packaging simulated transactions! And all can be customized according to your requirements while using the native Soroban SDK's typesystem.

Sending Web Requests.

Zephyr programs can now also send any web requests you want them to, enabling you to set up monitoring, and strategy workflows.

As a result of all the features that were added to Mercury, your programs can now:

  • ingest and index on-chain data real-time (you'll likely notice even lower latency than Horizon).
  • access ledger state, even iterate across subsets of it.
  • simulate contract calls + package the tx.
  • have your typesystem completely rely on the Soroban Rust SDK you write contracts with.

This effectively enables developers to never again have to deal with network data in an environment that isn’t the one you write the contracts themselves with.

This is an incredible advancement in terms of developer experience, especially for smart contract developers who aren't front-end developers: you can build your contracts, index data real-time, process it, retrieve it, simulate transactions and get ledger entries from within the same typesafe, well-known and dev-friendly workspace and environment. This makes zephyr the perfect middleware between the human-readable data that you can now easily use in your clients and the data that lives on the ledger or in tracked history.

This API, or proxy, has the possibility of building the invocation using the native rust types, and returning exactly the same result as the RPC simulation, enabling you to build better APIs than building everything client-side with less usable data helpers abstracting the need for encoding/decoding client-side.

For example, with the below code we take care of providing the frontend with the already-simulated and assembled transaction to be signed by the users depending on the action they wish to perform:

This code is taken from a dApp that will launch tomorrow, the first RPC-less Soroban app.

#[no_mangle]
pub extern "C" fn simulate() {
    let env = EnvClient::empty();
    let request: SimulationRequest = env.read_request_body();

    let response = match request {
        SimulationRequest::Send(SimulateSend { from, sequence, message }) => {
            let address = Address::from_string(&SString::from_str(&env.soroban(), &from));
            let message = Bytes::from_slice(&env.soroban(), message.as_bytes());
            env.simulate_contract_call_to_tx(
                from,
                sequence,
                CONTRACT_ADDRESS,
                Symbol::new(&env.soroban(), "send"),
                vec![
                    &env.soroban(),
                    address.into_val(env.soroban()),
                    message.into_val(env.soroban()),
                ],
            )
            
        },
        SimulationRequest::Vote(SimulateVote { from, sequence, hash, upvote }) => {
            let address = Address::from_string(&SString::from_str(&env.soroban(), &from));
            let hash = BytesN::<32>::from_array(&env.soroban(), &to_array::<u8, 32>(hex::decode(hash).unwrap()));
            let action = if upvote {
                "upvote"
            } else {
                "downvote"
            };

            env.simulate_contract_call_to_tx(
                from,
                sequence,
                CONTRACT_ADDRESS,
                Symbol::new(&env.soroban(), action),
                vec![
                    &env.soroban(),
                    address.into_val(env.soroban()),
                    hash.into_val(env.soroban())
                ],
            )
        }
    }
    .unwrap();

    env.conclude(response)
}

This accepts the request specified by the user SimulationRequest (defined in the code), and returns a transaction ready to be signed and sent to the network.

The above code exists in a workspace along with:

  • data processing and indexing.
  • data retrieval.

New Dashboard Interface and Website.

Check out the updated dashboards at:

The new landing page is https://mercurydata.app/.


Soroban is already one of the best smart contract development experiences in the whole industry, and we believe that tooling and infra advancements such as the one we just shipped further improves the overall full-stack experience, and hopefully enabling onboarding more developers and innovation.

If you’re building educational material on Soroban, we’d love to help you get started with Zephyr’s full-stack experience and help in any contents you’re interested in creating.


Last but not least, the V1 release is not perfect. Any feedback, feature requests, and suggestions are welcome!