We recently published videos from our Chrome Extension meetup. In the videos, we discuss the latest changes and adaptations when working with Manifest v3. There are new insights provided in the presentations that expand on the blog below. You can find the presentations from our meetup on Fordefi's YouTube channel.
The Chrome Extension Manifest is a JSON configuration file that instructs the Chrome browser how to behave when a user installs your extension. It includes information about your extension's permissions, content scripts, and background scripts, among other things. In June 2021, Google released Manifest v3, which made significant changes to how extensions behave and how they are managed by the browser, compared to Manifest v2.
Manifest v3 introduces new restrictions on the permissions that extensions can request. It also allows users to grant permissions to specific sites, rather than giving blanket access to all sites.
In Chrome Extension Manifest v3, the script, which was previously used to run extension code in the background, has been replaced by a service worker.
Background scripts are a crucial element in most extensions, as they enable the developer to carry out actions or run code without requiring user input or action. They are often used for tasks such as sending notifications, coordinating with content scripts, and much more. These scripts typically run continuously in the background.
Background service workers are only activated when needed, such as through the receipt of a message. To begin execution, service workers must first register listeners for specific events. Once these events are triggered, the background service worker will activate and execute the desired tasks. After a period of time which is determined by the browser, the background service worker will automatically shut down, until it is activated again.
Background service workers also have more limited permissions than background scripts in Manifest v2. Service workers can only access certain APIs and perform certain actions when they are active, and they must request permission to use any additional APIs they need. This means that service workers cannot perform certain actions that background scripts could in Manifest v2, such as modifying network requests or accessing the user's data without explicit permission.
In Manifest v2, it is easy to evaluate the performance of the background script as it is similar to evaluating any other web page. However, this common method of profiling is facing challenges when applied to the background service worker, resulting in errors.
A request for addressing this issue has been submitted.
These changes have had a significant impact on many existing extensions. The changes broke a lot of existing code and required developers to completely redesign their extensions in order to make them compatible with the new manifest.
There were numerous controversies following the changes in Manifest v3, including Brave's announcement to continue supporting Manifest version 2, Tor worrying about user privacy, and some bloggers considering migrating to Firefox.
During the process of adapting their extensions for Manifest v3, developers encountered a significant problem with the lack of documentation and guidance from Google. Due to the significant changes in Manifest v3 and the insufficient documentation, many developers have struggled to comprehend how to migrate their extensions to the new manifest.
A web3 transaction involves three key parties: the dApp websites, the blockchain, and the wallet. A user initiates a blockchain transaction through a dApp website. The dApp website creates the transaction based on the user’s action, and passes this transaction to the wallet. The wallet then presents the transaction to the user, asks for the user’s consent, signs the transaction, and passes it to the blockchain.
To facilitate this flow, the wallet needs several functionalities. First, in order to receive the transaction from the dApp website, the wallet needs to interact with the website and inject a piece of code into it. Second, to interact with the user and get the user’s consent, the wallet needs to open a popup. Finally, to send the transaction to the blockchain, the wallet needs to issue network requests. These three pieces need a reliable communication channel with each other in order to pass the transaction data from one step to the other.
On the face of it, the constraints imposed by Manifest v3 might seem to hinder some of the basic tasks the above flows requires:
In the rest of the article we will describe how we addressed those challenges.
All data that is transferred to or from the background service worker, as well as any information that is processed by the worker, must go through the extension's storage. To facilitate this, we developed a generic layer that can store the information efficiently and easily, and can also manage concurrent requests that need to modify the storage.
The extension must be able to handle multiple message requests concurrently from the dApp website.
To handle these messages, we may simultaneously access the same storage elements, such as adding a value to an array or reading a complex object from storage.
An example of how to read and write complex data to chrome storage:
Imagine the consequences if two separate requests were to update `FORDEFI_data` at the same time. Both read the data and update it – they could overwrite each other and cause data loss, as seen in the following example:
Link to code
To prevent this, we flattened any complex data structures and reconstructed them when they needed to be returned in full. Take note of how the `itemKey` is appended to `globalKey`, allowing for each item within the complex object to be stored individually and preventing any alteration made to one item from overwriting the others.
Now, even if multiple requests access the data simultaneously, they will not be able to overwrite each other.
Our extension maintains a long-term connection with the dApp website and any popups it generates. However, in Manifest v3, the extension background service worker is short-term and will shut down after 5 minutes.
It was recently announced that this behavior will change in Q1 of 2023! The service worker staleness will depend on its activity and will not be time based anymore. |
Due to this behavior, we needed to develop a communication layer that can re-establish the connection when it is lost.
Our solution has two components:
In order to establish a two-way handshake, the service worker and the service that wants to communicate with it follow the following protocol:
An example of the process in action:
Link to code
As the extension cannot directly modify or access the website, we had to develop a complementary mechanism that allows us to retrieve and set information that the background service worker needs.
To accomplish this, we created an `inpage` script that is injected into the website by the `content script` service, which has access to the website. The `inpage` script communicates with the `content script` using post messaging, and the `content script` communicates with the background service worker using `chrome.runtime.connect`. This establishes a bi-directional communication channel between the website and the browser service worker, allowing the service worker to interact with and access the website while adhering to the restrictions of Manifest v3.
An alternative method exists to address the present issue of profiling the background service worker, and is mentioned in the link I previously shared in this post.
Here’s a small demonstration of how it would work:
Manifest v3 has both advantages and challenges. While it offers improved security, privacy, and efficiency compared to v2, it requires developers to construct multiple frameworks to replicate the functionality of their previous solutions and completely redesign their infrastructure. As a company that values staying current with technology, FORDEFI made the decision to adopt Manifest v3 from the beginning, which allowed us to carefully plan our product with these limitations in mind and build a reliable and robust infrastructure.
At some point in the future, Google will no longer permit the publication of Manifest v2 extensions (although it is currently unknown when these extensions will be removed from the store). As a result, the demand for best practices, a knowledge base, and a supportive community is growing rapidly. We hope that the documentation for Manifest v3 will expand and developers will no longer have to navigate these challenges on their own. In the meantime, we hope that this post will be helpful to those who, like us, have struggled with the transition to Manifest v3.