Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isomorphic message utils #555

Draft
wants to merge 2 commits into
base: epic/embedded-wallet
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions shim.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ declare module "@arconnect/webext-bridge" {
*/
chunk: ProtocolWithReturn<ApiCall<Chunk>, ApiResponse<number>>;

// AUTH POPUP:

/**
* `createAuthPopup()` in `auth.utils.ts` sends `auth_request` messages from the background to the auth popup, which
* are received in `auth.provider.ts`.
Expand Down Expand Up @@ -58,11 +60,22 @@ declare module "@arconnect/webext-bridge" {
*/
auth_app_disconnected: number;

// EMBEDDED:

embedded_open: null;
embedded_close: null;
embedded_resize: null;
embedded_auth: null;
embedded_balance: null;
embedded_info: null;

// OTHER:

switch_wallet_event: string | null;
copy_address: string;
event: Event;

// TODO: This doesn't seem to be doing anything. Get rid of `replaceArProtocolLinks`
ar_protocol: ProtocolWithReturn<{ url: string }, { url: sting }>;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/api/background/background-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
handleTabUpdate
} from "~api/background/handlers/browser/tabs/tabs.handler";
import { log, LOG_GROUP } from "~utils/log/log.utils";
import { isomorphicOnMessage } from "~utils/messaging/messaging.utils";

export function setupBackgroundService() {
log(
Expand All @@ -36,8 +37,8 @@ export function setupBackgroundService() {

// MESSAGES:
// Watch for API call and chunk messages:
onMessage("api_call", handleApiCallMessage);
onMessage("chunk", handleChunkMessage);
isomorphicOnMessage("api_call", handleApiCallMessage);
isomorphicOnMessage("chunk", handleChunkMessage);

// LIFECYCLE:

Expand Down
4 changes: 2 additions & 2 deletions src/api/background/handlers/browser/tabs/tabs.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export async function handleTabUpdate(

if (popupTabID !== -1 && changeInfo?.status === "loading") {
isomorphicSendMessage({
destination: `popup@${popupTabID}`,
messageId: "auth_tab_reloaded",
tabId: popupTabID,
data: tabID
});
}
Expand Down Expand Up @@ -82,8 +82,8 @@ export async function handleTabClosed(closedTabID: number) {

// If some other tab was closed and there's a popup, notify the popup in case it has AuthRequest from the closed tab:
isomorphicSendMessage({
destination: `popup@${popupTabID}`,
messageId: "auth_tab_closed",
tabId: popupTabID,
data: closedTabID
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,31 @@ export async function handleActiveAddressChange({
if (permissionCheck.has.length === 0) return;

// trigger emitter
await sendMessage(
"event",
{
await isomorphicSendMessage({
destination: `content-script@${tab.id}`,
messageId: "event",
data: {
name: "activeAddress",
value: permissionCheck.result ? newAddress : null
},
`content-script@${tab.id}`
);
}
});

const popupTabID = getCachedAuthPopupWindowTabID();

if (popupTabID) {
isomorphicSendMessage({
destination: `popup@${popupTabID}`,
messageId: "auth_active_wallet_change",
tabId: popupTabID,
// tabId: popupTabID,
data: tab.id
});
}

// trigger event via message
await sendMessage(
"switch_wallet_event",
permissionCheck ? newAddress : null,
`content-script@${tab.id}`
);
await isomorphicSendMessage({
destination: `content-script@${tab.id}`,
messageId: "switch_wallet_event",
data: permissionCheck ? newAddress : null
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { forEachTab } from "~applications/tab";
import { compareGateways } from "~gateways/utils";
import type { InitAppParams } from "~applications/application";
import Application, { PREFIX } from "~applications/application";
import { isomorphicSendMessage } from "~utils/messaging/messaging.utils";

export async function handleAppConfigChange(
changes: Record<string, StorageChange<InitAppParams>>,
Expand Down Expand Up @@ -98,10 +99,16 @@ export async function handleAppConfigChange(
const eventsForTab = events
.filter(({ appURL }) => getAppURL(tab.url) === appURL)
.map((e) => e.event);

// send the events
for (const event of eventsForTab) {
// trigger emiter
await sendMessage("event", event, `content-script@${tab.id}`);
// TODO: Remove this await here
await isomorphicSendMessage({
destination: `content-script@${tab.id}`,
messageId: "event",
data: event
});
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ export async function handleAppsChange({
}: StorageChange<string[]>) {
// message to send the event
const triggerEvent = (tabID: number, type: "connect" | "disconnect") =>
sendMessage(
"event",
{
isomorphicSendMessage({
destination: `content-script@${tabID}`,
messageId: "event",
data: {
name: type,
value: null
},
`content-script@${tabID}`
);
}
});

// trigger events
forEachTab(async (tab) => {
Expand All @@ -45,8 +45,8 @@ export async function handleAppsChange({

if (popupTabID) {
isomorphicSendMessage({
destination: `popup@${popupTabID}`,
messageId: "auth_app_disconnected",
tabId: popupTabID,
data: tab.id
});
}
Expand All @@ -73,8 +73,8 @@ export async function handleAppsChange({

if (popupTabID) {
isomorphicSendMessage({
destination: `popup@${popupTabID}`,
messageId: "auth_app_disconnected",
tabId: popupTabID,
data: tab.id
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Application from "~applications/application";
import { forEachTab } from "~applications/tab";
import { getAppURL } from "~utils/format";
import browser from "webextension-polyfill";
import { isomorphicSendMessage } from "~utils/messaging/messaging.utils";

/**
* Added wallets change listener.
Expand Down Expand Up @@ -32,14 +33,14 @@ export async function handleWalletsChange({
if (permissionCheck.has.length === 0) return;

// trigger emiter
await sendMessage(
"event",
{
await isomorphicSendMessage({
destination: `content-script@${tab.id}`,
messageId: "event",
data: {
name: "addresses",
value: permissionCheck.result ? addresses : null
},
`content-script@${tab.id}`
);
}
});
});

// add or remove ANS label change listener
Expand Down
12 changes: 6 additions & 6 deletions src/api/foreground/foreground-setup-ar-protocol-links.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { sendMessage } from "@arconnect/webext-bridge";
import { isString } from "typed-assert";
import { isomorphicSendMessage } from "~utils/messaging/messaging.utils";

// TODO: This is not enough for client-rendered pages (e.g. React apps):

Expand All @@ -21,12 +22,11 @@ export async function replaceArProtocolLinks() {
for (const el of elements) {
// ask the background script to return the correct ar:// url
try {
// TODO: Replace with postMessage for the embedded wallet:
const res = await sendMessage(
"ar_protocol",
{ url: el[fields[el.tagName]] },
"background"
);
const res = await isomorphicSendMessage({
destination: "background",
messageId: "ar_protocol",
data: { url: el[fields[el.tagName]] }
});

// check result
isString(res?.url);
Expand Down
10 changes: 6 additions & 4 deletions src/api/foreground/foreground-setup-events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { onMessage } from "@arconnect/webext-bridge";
import { isomorphicOnMessage } from "~utils/messaging/messaging.utils";

// Some backend handlers (`src/api/background/handlers/*`) will use `sendMessage(...)` to communicate with the
// `event.ts` content script, which in turn calls `postMessage()`, dispatches events or performs certain actions in the
Expand All @@ -10,9 +11,9 @@ import { onMessage } from "@arconnect/webext-bridge";
//
// See https://stackoverflow.com/questions/16266474/javascript-listen-for-postmessage-events-from-specific-iframe

export function setupEventListeners(iframe?: HTMLIFrameElement) {
export function setupEventListeners() {
// event emitter events
onMessage("event", ({ data, sender }) => {
isomorphicOnMessage("event", ({ data, sender }) => {
if (sender.context !== "background") return;

// send to mitt instance
Expand All @@ -24,7 +25,7 @@ export function setupEventListeners(iframe?: HTMLIFrameElement) {

// listen for wallet switches
/** @deprecated */
onMessage("switch_wallet_event", ({ data, sender }) => {
isomorphicOnMessage("switch_wallet_event", ({ data, sender }) => {
if (sender.context !== "background") return;

// dispatch custom event
Expand All @@ -35,9 +36,10 @@ export function setupEventListeners(iframe?: HTMLIFrameElement) {
);
});

// TODO: This will never be used for the embedded wallet, so there's no need to change it to `isomorphicSendMessage()`:
// copy address in the content script
// (not possible in the background)
onMessage("copy_address", async ({ sender, data: addr }) => {
isomorphicOnMessage("copy_address", async ({ sender, data: addr }) => {
if (sender.context !== "background") return;

const input = document.createElement("input");
Expand Down
8 changes: 4 additions & 4 deletions src/api/modules/sign/sign_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ export function signAuth(

for (const chunk of dataChunks.concat(tagChunks)) {
await isomorphicSendMessage({
destination: `popup@${popupWindowTabID}`,
messageId: "auth_chunk",
tabId: popupWindowTabID,
data: chunk
});
}
Expand All @@ -95,8 +95,8 @@ export function signAuth(
};

await isomorphicSendMessage({
destination: `popup@${popupWindowTabID}`,
messageId: "auth_chunk",
tabId: popupWindowTabID,
data: endChunk
});

Expand Down Expand Up @@ -164,8 +164,8 @@ export function signAuthKeystone(

for (const chunk of dataChunks) {
await isomorphicSendMessage({
destination: `popup@${popupWindowTabID}`,
messageId: "auth_chunk",
tabId: popupWindowTabID,
data: chunk
});
}
Expand All @@ -185,8 +185,8 @@ export function signAuthKeystone(
};

await isomorphicSendMessage({
tabId: `popup@${popupWindowTabID}`,
messageId: "auth_chunk",
tabId: popupWindowTabID,
data: endChunk
});

Expand Down
2 changes: 2 additions & 0 deletions src/applications/tab.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import browser from "webextension-polyfill";

// TODO: Mock all these for the embedded wallet...

/**
* Get a browser tab by id
*
Expand Down
14 changes: 9 additions & 5 deletions src/contents/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { PlasmoCSConfig } from "plasmo";
import type { ApiCall } from "shim";
import injectedScript from "url:./injected/setup-wallet-sdk.injected-script.ts";
import { log, LOG_GROUP } from "~utils/log/log.utils";
import { isomorphicSendMessage } from "~utils/messaging/messaging.utils";

log(LOG_GROUP.SETUP, "api.content-script.ts");

Expand Down Expand Up @@ -34,6 +35,9 @@ container.removeChild(script);
//
// iframeElement.contentWindow.postMessage(...);

// TODO: The embedded wallet probably needs a listener equivalent to this one, or replace the postMessage in
// `foreground-setup-wallet.ts`.

window.addEventListener(
"message",
async ({ data }: MessageEvent<ApiCall & { ext: "arconnect" }>) => {
Expand All @@ -50,11 +54,11 @@ window.addEventListener(
log(LOG_GROUP.API, `${data.type} (${data.callID})...`);

// send call to the background
const res = await sendMessage(
data.type === "chunk" ? "chunk" : "api_call",
data,
"background"
);
const res = await isomorphicSendMessage({
destination: "background",
messageId: data.type === "chunk" ? "chunk" : "api_call",
data
});

log(LOG_GROUP.API, `${data.type} (${data.callID}) =`, res);

Expand Down
Loading