0

I created an extension that append button on each tweet on twitter. Upon clicking that button I should perform a function window.phantom.solana.connect().

When I enter window.phantom.solana.connect() directly in my console it works, but the problem is when I try to trigger this function from content script it the window object has different context than the one I am using inside of my browser and it doesn't contain phantom.solana... properties

here is my manifest.json

{
"manifest_version": 3,
"name": "react-boilerplate",
"description": "react-boilerplate for chrome extension",
"version": "1.0.0",
"action": {
"default_title": "React Boilerplate"
},
"permissions": \["tabs", "bookmarks", "storage", "identity", "scripting"\],
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": \[
{
"matches": \["https://*.twitter.com/*"\],
"js": \["contentScript.js"\]
}
\],
"web_accessible_resources": \[
{
"resources": \["web_accessible_resources.js"\],
"matches": \["\<all_urls\>"\],
"extension_ids": \["bfnaelmomeimhlpmgjnjophhpkkoljpa"\]
}
\]
}

and my content script

import React from "react";
import { createRoot } from "react-dom/client";
import "../assets/tailwind.css";
import ContentScript from "./contentScript";

function init() {
const appContainer = document.createElement("div");
if (!appContainer) {
throw new Error("Cannot find app container");
}

const root = createRoot(appContainer);
const articleList = window.document.querySelectorAll("article");
root.render(\<ContentScript /\>);

for (const element of articleList) {
var btn = document.createElement("button");

    btn.appendChild(document.createTextNode("Bonk tweet"));
    btn.style.color = "white";
    btn.addEventListener("click", function () {
      // this function should catch the window object
      chrome.runtime.sendMessage(
        { greetings: "Bonk tweet" },
        function (response) {
          console.log(response.farewell);
          // don't have access to window.phantom.solana
          console.log(this);
          console.log(window);
        }
      );
    });
    
    element.appendChild(btn);

}
}
setTimeout(init, 4000);

I tried to access it on a various ways through events, web_accessible_resources... Still no luck. Does anyone knows how can I access the same window object inside my extension

1 Answers1

-1

Content scripts don't have access the host page's window object. But they do have access to the host page's DOM. So you can work around this limitation by adding a script tag to the host page's DOM so that it executes in the host page's context and has access to the host window object.

const scriptTag = document.createElement('script');
scriptTag.setAttribute('type','application/javascript');
scriptTag.innerText = `window.phantom.solana.connect()`;
document.head.appendChild(scriptTag);

Additionally, you could set up a message handler in the script tag above, and send a message from your content script to execute that handler.

This workaround will not work if the page has a content security policy though.

Hammad Akhwand
  • 779
  • 1
  • 7
  • 19