Inspiration

Blockchains, at the moment, are siloed execution environment. For instance, to use the MNEE stablecoin, you have to deploy your application to Ethereum, or rely on bridges to teleport MNEE across chains. In real world, this is not always the case. While MNEE may live on Ethereum, the actions that justify spending those assets often happen elsewhere. This project aims to break this barrier: spending should not depend on where the tokens are held. Funds can remain locked where they live, and become spendable when predefined actions execute successfully, regardless of the chain the actions run on. This is when we can have truly programmable, trust-less spending across ecosystems.

What it does

The system consists of a TokenReceiver contract deployed on Ethereum, where MNEE is held. This contract receives and locks MNEE tokens and dispatches a cross-chain message describing a requested action. While the funds remain locked, no spending is possible.

On the destination chain, a Controller contract receives the message, decodes the requested action, and invokes a dedicated Actions contract to execute it. These actions are predefined and can represent arbitrary on-chain logic.

Only once an action completes successfully does the Actions contract emit a confirmation back through the Controller to the TokenReceiver. Upon receiving verified execution confirmation, the TokenReceiver releases the previously locked funds to the designated recipient.

In this model, tokens never need to move chains, spending is authorised by execution, not by location.

How we built it

The system is designed around a basic principle, where the tokens live should not determine how/where they can be spent. To achieve this, I created smart contracts on the Source chain and the Recipient chain.

1. Source chain

On Ethereum, where MNEE is deployed, we implemented a TokenReceiver contract responsible for custody of tokens.

  • It accepts MNEE deposits and locks the funds on-chain
  • Each deposit is associated with a structured & versioned action request
  • Locked funds can only be withdrawn when a cross chain message is received from the Recipient chain.

2. Cross-Chain Messaging Layer

The project uses a cross-chain messaging layer called ISMP for message passing. It doesn't need to transfer any tokens, only messages.

  • The messages are deterministic and replay-protected
  • Payloads are versioned

This approach eliminated the need for bridging or swap

3. Recipient Chain: Controller Contract

This contract is responsible for receiving the cross-chain message(s) dispatched, decodes the message bytes and calls the treasury contract with the appropriate parameters. Actions created in this way, by the Controller, are automatically identified as cross-chain Actions. It is important to note that this Controller does not hold any funds and its sole responsibility is to authorise and dispatch transactions to the Actions contract.

4. Recipient Chain: Actions Contract

Actions are implemented as predefined, modular contracts on the destination chain. Each action represents a specific, allowed execution path (e.g. PAYOUT, BATCH_PAYOUT, STREAM_PAYMENT, e.t.c). Execution is deterministic and verifiable on-chain. Once an Action is executed, the Controller is notified and it dispatches a message to Ethereum. The TokenReceiver accepts and unlocks the exact funds attached to the Action.

Challenges we ran into

Integrating with Hyperbridge SDK is not straight forward as available documentation(s) do not detail the process of making the cross-chain calls.

Also, figuring out the best way to transmit the encoded data for each Action is not easy also.

Accomplishments that we're proud of

I am proud to have been able to make and send the cross chain transactions and see everything work out properly.

What we learned

What's next for XChain Programmable Spending

Built With

Share this project:

Updates