Skip to content

nexisdev/zodiac-pilot

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zodiac Pilot

Build Status Contributor Covenant

Chrome extension to simulate Dapp interactions and record transactions. Available on the Chrome Webstore

Contribute

Run in development

Build a development bundle of the extension in watch mode:

yarn dev

The build output is written to public/build.

To enable the extension in Chrome, follow these steps:

  1. Open the Extension Management page by navigating to chrome://extensions.
  2. Enable Developer Mode by clicking the toggle switch at the top right of the page.
  3. Click the Load unpacked button and select the zodiac-pilot/public directory.

Package for production

yarn build

How it works

The extension consists of three different interacting pieces:

The different scripts communicate exclusively via message passing. Extension page and background script use chrome.runtime.sendMessage while extension page and injected script talk via window.postMessage.

Zodiac Pilot host

Originally, we started out building the Pilot as an extension page, which are hosted under chrome-extension://<EXTENSION_ID>. However extension pages are subject to some restrictions that make implementing certain integrations difficult, most notably:

  • All extensions are sandboxed from each other, meaning that the MetaMask injected provider would not be available to an extension page.
  • Extension pages have no access to Indexed DB, which is a dependency of Ganache.

That's why the extension is now running under an external host, https://pilot.gnosisguild.org.

Open Dapps in iframe

For allowing arbitrary pages to be loaded in our iframe we drop X-Frame-Options and Content-Security-Policy HTTP response headers for any requests originating from tabs showing our extension.

As we don't want to generally lift cross origin restrictions, we dynamically adjust the condition under which the declarativeNetRequest rule applies. In our background script, we track tabs running our extension and will apply the header removal only for requests originating from any of these tabs.

Syncing iframe location

The problem: When the user navigates the Dapp, the address bar of the Zodiac Pilot should update accordingly. The browser back button should function as usual and when reloading the extension page the iframe should continue showing the original page. Since browsers block access to foreign origin iframes we need to leverage Chrome extension super powers to detect navigation events in the iframe.

The solution: We listen to chrome.tabs.onUpdated in the background script and notify the content script about it via a message, which relays the message to the extension app. This relaying is necessary because a background script can not directly talk to an externally hosted app. For retrieving the new iframe location, we then post a message to the injected script in the iframe window, which will send us the response in another message.

Inject EIP-1193 provider

When the simulator iframe opens any page, we inject the build/inject.js script as a node into the DOM of the Dapp.

The injected script then runs in the context of the Dapp and injects an EIP-1193 compatible API at window.ethereum. The injected provider forwards all request calls to the parent extension page via window.postMessage where they are handled with on of our providers. We currently offer two kinds of providers, the WrappingProvider for synchronously dispatching the transaction as a meta transaction of a Zodiac module function call, and ForkProvider for simulating the transaction in a local fork of the connected network and recording it for later batch transmission.

Simulating transaction in a fork

When the provider we inject into the Dapp iframe receives a transaction request, we record it and simulate the transaction in a fork of the target network, impersonating the Avatar account. That way the app can continue communicating with the fork network, so that a whole session of multiple transactions can be recorded before anything is signed and submitted to the real chain.

There are two options available for simulating transactions in a fork, Tenderly and a Ganache EVM running locally in the browser.

Tenderly

Tenderly provides rich debugging capabilities, which help in understanding the exact effects of each recorded transaction before actually signing anything. Fresh forks are created via Tenderly's Simulation API and each fork will have its own JSON RPC URL.

Local fork with Ganache (under development)

We use Ganache to run a local EVM with a fork of the network the user is connected to.

TODO: The following is still true, but we should adjust the implementation now that the extension is running under an external host.

Ganache depends on Indexed DB, which is not available to extension pages. For this reason we run it via an injected script on an externally hosted page in an iframe. Again we communicate via window.postMessage. That way we connect Ganache to the WalletConnect provider in the extension page so it can fork the active network. At the same time, we connect the Dapp injected provider to ForkProvider in the host page, which forwards requests to the Ganache provider running in the ganache iframe.

Wrapping of transactions

A batch of recorded transaction can finally be submitted as a multi-send transaction. Zodiac Pilot is currently geared to submitting transactions via a Roles mod, which means that the multi-send call needs to wrapped in a Roles mod's execTransactionWithRole call. This is implemented in the WrappingProvider.

In the future, we plan to make Zodiac Pilot more generally useful, meaning that users will be able to customize the exact way of transaction wrapping.

Overview of providers

Diagram giving an overview of providers

About

Chrome extension to simulate Dapp interactions and record transactions

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 90.4%
  • CSS 8.2%
  • Other 1.4%