Skip to content

Commit

Permalink
feat: use iframe for hosted wallet in prod (#199)
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanfarrer authored Aug 29, 2023
1 parent 308d207 commit a8b7dfa
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 77 deletions.
16 changes: 8 additions & 8 deletions examples/example-react-vite/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions examples/example-react-vite/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "example-react-vite",
"private": true,
"version": "3.5.0",
"version": "3.6.0",
"homepage": "/walletconnect-demo",
"type": "module",
"scripts": {
Expand All @@ -16,7 +16,7 @@
"dependencies": {
"@microlink/react-json-view": "1.22.2",
"@provenanceio/wallet-utils": "2.8.0",
"@provenanceio/walletconnect-js": "file:../provenanceio-walletconnect-js-3.5.0.tgz",
"@provenanceio/walletconnect-js": "file:../provenanceio-walletconnect-js-3.6.0.tgz",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "1.3.0",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@provenanceio/walletconnect-js",
"version": "3.5.0",
"version": "3.6.0",
"private": false,
"sideEffects": false,
"main": "esm/index.js",
Expand Down
25 changes: 7 additions & 18 deletions src/consts/walletList/hosted.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { HOSTED_IFRAME_EVENT_TYPE } from '../../consts';
import { Wallet, WalletEventValue } from '../../types';
import { FIGURE_HOSTED_WALLET_URL_PROD } from '../urls';
import { WALLET_APP_IDS } from '../walletAppIds';

const FIGURE_HOSTED_IGNORED_EVENTS: WalletEventValue[] = [
Expand All @@ -14,25 +13,15 @@ export const FIGURE_HOSTED = {
type: ['hosted', 'mobile'],
title: 'Figure Account',
icon: 'figure',
eventAction: ({ uri, address, event, redirectUrl }) => {
eventAction: (eventData) => {
const { event } = eventData;
// If we have an event, make sure it's not an "ignored" event
if (event && !FIGURE_HOSTED_IGNORED_EVENTS.includes(event)) {
// Build a full set of urlSearchParams to append to the url
const searchParams = new URLSearchParams();
if (uri) searchParams.append('wc', uri);
if (address) searchParams.append('address', address);
if (event) searchParams.append('event', event);
if (redirectUrl) searchParams.append('redirectUrl', redirectUrl);
const searchParamsString = searchParams.toString();
const url = `${FIGURE_HOSTED_WALLET_URL_PROD}${
searchParamsString ? `&${searchParamsString}` : ''
}`;
const width = 600;
const height = window.outerHeight < 750 ? window.outerHeight : 550;
const top = window.outerHeight / 2 + window.screenY - height / 2;
const left = window.outerWidth / 2 + window.screenX - width / 2;
const windowOptions = `popup=1 height=${height} width=${width} top=${top} left=${left} resizable=1, scrollbars=1, fullscreen=0, toolbar=0, menubar=0, status=1`;
window.open(url, 'figure-wallet-hosted', windowOptions);
window.document.dispatchEvent(
new CustomEvent(HOSTED_IFRAME_EVENT_TYPE, {
detail: { ...eventData, walletId: WALLET_APP_IDS.FIGURE_HOSTED },
})
);
}
},
} as Wallet;
Expand Down
92 changes: 46 additions & 46 deletions src/hooks/useHostedWalletIframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,13 @@ const IFRAME_NOTIFICATION_HEIGHT = 600;
const IFRAME_NOTIFICATION_WIDTH = 600;
const IFRAME_ID = 'figure-wallet-hosted';

// Create shared BroadcastChannel instance to prevent catching own
// events on same page from multiple iframe creations
const channel = new BroadcastChannel('figure-hosted-wallet');
channel.onmessage = handleChannelMessage;

export function useHostedWalletIframe() {
useEffect(() => {
document.addEventListener(HOSTED_IFRAME_EVENT_TYPE, (ev) => {
catchWCJSMessage(ev as any); // NOTE: types not picking up correctly?
});

return () => {
document.removeEventListener(HOSTED_IFRAME_EVENT_TYPE, (ev) => {
catchWCJSMessage(ev as any); // NOTE: types not picking up correctly?
});
};
}, []);

function handleIframeMessage(event: MessageEvent<any>) {
const acceptableOrigins = [
new URL(FIGURE_HOSTED_WALLET_URL_PROD).origin,
new URL(FIGURE_HOSTED_WALLET_URL_TEST).origin,
];
const overrideUrl = localStorage.getItem(
'FIGURE_HOSTED_WALLET_URL_TEST_OVERRIDE'
);
if (overrideUrl) {
acceptableOrigins.push(new URL(overrideUrl).origin);
}
// Only listen for events coming from the hosted wallet origin
if (!acceptableOrigins.includes(event.origin)) return;
if (event.data === 'window_close') {
removeIframe();
}
}

useEffect(() => {
window.addEventListener('message', handleIframeMessage);

return () => {
window.removeEventListener('message', handleIframeMessage);
};
}, []);
}

// Check if the iframe exists
const iframeExists = () => !!document.getElementById(IFRAME_ID);

// If the iframe element exists, remove it from the DOM
function removeIframe() {
const iframeElement = document.getElementById(IFRAME_ID);
if (!!iframeElement) {
if (iframeElement) {
iframeElement.remove();
}
}
Expand All @@ -83,6 +38,11 @@ function handleChannelMessage(event: MessageEvent<any>) {
}
}

// Create shared BroadcastChannel instance to prevent catching own
// events on same page from multiple iframe creations
const channel = new BroadcastChannel('figure-hosted-wallet');
channel.onmessage = handleChannelMessage;

// Add ability for dApp/website to send a message to this extension
const createIframe = (url: string) => {
// Remove any existing iframes on this window
Expand Down Expand Up @@ -186,3 +146,43 @@ const catchWCJSMessage = ({ detail }: CustomEvent<EventData>) => {
break;
}
};

export function useHostedWalletIframe() {
useEffect(() => {
document.addEventListener(HOSTED_IFRAME_EVENT_TYPE, (ev) => {
catchWCJSMessage(ev as any); // NOTE: types not picking up correctly?
});

return () => {
document.removeEventListener(HOSTED_IFRAME_EVENT_TYPE, (ev) => {
catchWCJSMessage(ev as any); // NOTE: types not picking up correctly?
});
};
}, []);

function handleIframeMessage(event: MessageEvent<any>) {
const acceptableOrigins = [
new URL(FIGURE_HOSTED_WALLET_URL_PROD).origin,
new URL(FIGURE_HOSTED_WALLET_URL_TEST).origin,
];
const overrideUrl = localStorage.getItem(
'FIGURE_HOSTED_WALLET_URL_TEST_OVERRIDE'
);
if (overrideUrl) {
acceptableOrigins.push(new URL(overrideUrl).origin);
}
// Only listen for events coming from the hosted wallet origin
if (!acceptableOrigins.includes(event.origin)) return;
if (event.data === 'window_close') {
removeIframe();
}
}

useEffect(() => {
window.addEventListener('message', handleIframeMessage);

return () => {
window.removeEventListener('message', handleIframeMessage);
};
}, []);
}

0 comments on commit a8b7dfa

Please sign in to comment.