ext.mjs raw

   1  // ext.mjs — Browser extension API (MV2 persistent background page).
   2  // Implements the jsbridge/ext package for the signer background script.
   3  
   4  // StorageGet retrieves a value from browser.storage.local.
   5  export function StorageGet(key, fn) {
   6    browser.storage.local.get(key).then((result) => {
   7      fn(result[key] || "");
   8    }).catch(() => {
   9      fn("");
  10    });
  11  }
  12  
  13  // StorageSet stores a key-value pair in browser.storage.local.
  14  export function StorageSet(key, value) {
  15    browser.storage.local.set({ [key]: value });
  16  }
  17  
  18  // StorageRemove removes a key from browser.storage.local.
  19  export function StorageRemove(key) {
  20    browser.storage.local.remove(key);
  21  }
  22  
  23  // OnMessage registers a handler for browser.runtime.onMessage.
  24  // fn receives (method, paramsJSON, senderTabID, respond).
  25  // respond is called with the response JSON string when ready.
  26  export function OnMessage(fn) {
  27    browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  28      const method = msg.method || "";
  29      const params = msg.params ? JSON.stringify(msg.params) : "{}";
  30      const tabID = (sender.tab && sender.tab.id) || 0;
  31      function respond(result) {
  32        try {
  33          const parsed = JSON.parse(result);
  34          if (parsed.error) {
  35            sendResponse({ error: parsed.error });
  36          } else {
  37            sendResponse(parsed.result !== undefined ? parsed.result : parsed);
  38          }
  39        } catch (e) {
  40          sendResponse(result);
  41        }
  42      }
  43      try {
  44        fn(method, params, tabID, respond);
  45      } catch (e) {
  46        console.error("smesh handler error:", e);
  47        sendResponse({ error: e.message || "handler error" });
  48      }
  49      return true; // keep sendResponse channel open for async
  50    });
  51  }
  52  
  53  // SendMessageToTab sends a message to a specific tab's content script.
  54  export function SendMessageToTab(tabID, msg) {
  55    try {
  56      const parsed = JSON.parse(msg);
  57      browser.tabs.sendMessage(tabID, parsed);
  58    } catch (e) {
  59      browser.tabs.sendMessage(tabID, { data: msg });
  60    }
  61  }
  62  
  63  // ConsoleLog logs to the browser console and forwards to active tab.
  64  export function ConsoleLog(msg) {
  65    console.log('[smesh-bg]', msg);
  66    // Also forward to active tab's content script for page console visibility.
  67    try {
  68      browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
  69        if (tabs.length > 0) {
  70          browser.tabs.sendMessage(tabs[0].id, { type: "LOG", text: msg }).catch(() => {});
  71        }
  72      }).catch(() => {});
  73    } catch(e) {}
  74  }
  75  
  76  // GetActiveTab gets the active tab's ID and URL.
  77  export function GetActiveTab(fn) {
  78    browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
  79      if (tabs.length > 0) {
  80        fn(tabs[0].id, tabs[0].url || "");
  81      } else {
  82        fn(0, "");
  83      }
  84    }).catch(() => {
  85      fn(0, "");
  86    });
  87  }
  88