Composooor Snap: A composability enabler for hybrid onchain and offchain apps

An ETHDenver Hackathon winner

by MetaMaskJune 26, 2023
Snaps Spotlights Feature Images

MetaMask Snaps is the roadmap to making MetaMask the most extensible wallet in the world. As a developer, you can bring your features and APIs to MetaMask in totally new ways. Web3 developers are the core of this growth and this series aims to showcase the novel MetaMask Snaps being built today.

Composooor Snap


Snap Repo: https://github.com/kairos-loan/composooor/tree/main/packages/snap

Why did you build it?

During our experience of developing smart-contract based financial protocols and other blockchain apps we noticed a recurrent pattern. More and more apps are using offchain resources (such as computation or data storage) verified in the contract logic due to blockchains technical limitations. Examples include order books, merkle trees of airdrops, sorted lists, token attributes etc.

In each case valuable information is stored/computed off chain but can be used and has big effects on onchain interactions. To make this possible, contracts use different cryptographic techniques such as hashes or signatures to check validity. Dapps then require frontends/apis with specific logic that can come up with the relevant information for the contract. Sadly this pattern breaks composability, e.g a DeFi app relying on a proprietary order book served on AWS can’t be easily integrated by another smart contract.

Fed up by those limitations we decided to come up with a standard and infrastructure to enable all apps to be easily integrated into anything. We strongly believe that making integrations easier again are opening many opportunities to the space.

Can you walk us through the technical implementation?

Intro

The Composooor metamask snap is used to standardize and handle communication between a web client, one or multiple offchain arbitrary ressources, and an arbitrary number of smart-contracts implementing the composooor standard. All standard ressources are easily accessible on an npm package that makes using composooor’s superpowers a one liner in most cases.

Step by step

  • When preparing a transaction, our metamask snap wallet will request an estimate gas call on the desired on chain contract.
  • If the contract needs some data or computation made off chain to function, it will revert with a standardized error containing specs on how to find this missing data. The standardized error looks like this
error MissingOffchainDataError(
    address registryAddress,
    string url,
    bytes abiArgs
);

this error is exposed by the ComposooorRegister that contracts must extend to access offchain ressouces.

  • The Metamask snap wallet can then decode this error and finds the missing data either by fetching it on a decentralized protocol, or on an API, or by executing some code it fetched from this sources to produce it. For the ETHDenver hackathon, we implemented the simplest option which is the API call.
const responseData = await fetch(error.url + `?args=${error.abiArgs}`);
  • The wallet will then estimate gas again, this time adding an instruction to store the fetched data in the standardized registry of the corresponding contract before calling the desired method.
const callToRegisterData: Call = {
    callee: error.registryAddress,
    functionSelector: utils.id('recordParameter(bytes)').slice(0, 10) as PrefixedBy0x,
    data: defaultAbiCoder.encode(['bytes'], [data]) as PrefixedBy0x,
};
  • During the transaction execution, the same or another contract may need another off chain ressource to function. If it’s the case, the wallet loops on the transaction preparation steps until no offchain ressource is needed anymore. This enables endless composability between protocols accessing rich offchain ressources.
  • When the gas estimation is successful, the user is prompted with the signature of the prepared transaction, to execute successfully with all necessary ressources included.

What integrating a composooor-enabled app / making your own looks like.

At ETHDenver we showed how composooor reduces code complexity of the usual hybrid app pattern by at least 80-90%.

Smart contract side

Import with import "@composooor/ComposooorRegister.sol";. Example usage :

contract Example is ComposooorRegister {
    function action() public {
        bytes memory data = consumeParameter("http://api.api/number", abi.encode(arguments));
        (uint256 offchainNumber) = abi.decode(data, (uint256));
        (...)
    }
}

ComposooorRegister is made with solidity.

Front end side

The composooor snap yields the most returns on the front-end side: it reduces typically 200+ lines integrations to… 0 ! The snap logic handles everything.

Demo

We made a fully integrated demo in the form of a react-wagmi dapp. This dapp makes it possible to buy an NFT paying only a small fraction of the price upfront and taking a loan to repay later to finance the rest. Onchain, it is no less than 8 contracts which are involved in the transaction. In the middle of it, the NFT marketplace requires an offchain signature of the NFT seller. The composooor snap is able to pick up the error, decode it and provide the information onchain (after being fetched in an api) despite the complexity of the transaction. Composooor made this app way simpler to implement.

Screenshot 2023-06-26 at 9.49.45 PM

What are the next steps if you would implement this?

Part of such an innovation making developers gain considerable time and enabling new blockchain usecases is adoption. We would implement and deploy multiple user-facing apps using Composooor snap behind the scenes and working with the corresponding snap. If those apps gain traction, we would make some partnerships to compose them with other apps starting a flywheel of adoption fueled by the simplified dev experience. Along the way the snap and the standard would evolve into a more general and standardized product fitting the original vision: connecting blockchains synchronously to arbitrary resources, in an agnostic way regarding decentralization and usecases.

Can you tell us a little bit about yourself and your team?

We’re a team building a lending protocol to use NFTs as collateral with a more capital efficient approach. We decided to go with an architecture using off-chain components like an order book. This choice allows to improve capital efficiency and user experience but may limit interoperability with other protocols. This is why we developed the Composooor snap allowing easy integration with other protocols. We hope that this library will be used by other teams, opening new possibilities and making their work easier.

What opportunities do you see with MetaMask Snaps and the possibilities it unlocks for the Web3 space?

Wallets are one of the main unavoidable pillars/building blocks of web3 and MetaMask is the defacto default wallet for most users. Enabling developers to leverage this for arbitrary new use cases seems crucial to me. The main point is that we can’t imagine or prepare for all innovations wallets will need to be a part of so giving some access to them is like the transition from bitcoin to ethereum: enable arbitrary use cases on top of your tech has unforeseen exponentially compounding upside. So its hard to answer this question but what I’m most excited about is apps making the wallet do more than just signing messages and optimizes the interactions is a context-rich way for the user.

Any advice you would like to share with developers keen to try MetaMask Snaps?

Make use of the template provided and be careful to correctly ask for every user approval needed and use as few as possible.

Building with MetaMask Snaps


To get started with MetaMask Snaps:

  1. Checkout the developer docs
  2. Install MetaMask Flask
  3. Check out a MetaMask Snaps guide
  4. Stay connected with us on Twitter, GitHub discussions, and Discord

Keep an eye out for our team at the next hackathon in an area near you! Happy BUIDLing ⚒️

Disclaimer: MetaMask Snaps are generally developed by third parties other the ConsenSys Software. Use of third-party-developed MetaMask Snaps is done at your own discretion and risk and with agreement that you will solely be responsible for any loss or damage that results from such activities. ConsenSys makes no express or implied warranty, whether oral or written, regarding any third-party-developed MetaMask Snaps and disclaims all liability for third-party developed Snaps. Use of blockchain-related software carries risks, and you assume them in full when using MetaMask Snaps.

Receive our Newsletter