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

bundle and inject code for bring #3624

Closed
wants to merge 19 commits into from
Closed
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
4 changes: 2 additions & 2 deletions packages/yoroi-extension/app/api/thunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ export async function getWallets(walletId?: number): Promise<Array<WalletState>>
return resp;
}

export async function subscribe(activeWalletId: ?number): Promise<void> {
await callBackground({ type: 'subscribe', request: { activeWalletId } });
export async function subscribe(activeWalletId: ?number, changed?: boolean): Promise<void> {
await callBackground({ type: 'subscribe', request: { activeWalletId, changed: changed === true } });
}

export const createWallet: GetEntryFuncType<typeof CreateWallet> = async (request) => {
Expand Down
8 changes: 6 additions & 2 deletions packages/yoroi-extension/app/stores/toplevel/WalletStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ export default class WalletStore extends Store<StoresMap, ActionsMap> {

runInAction(() => {
this.wallets.push(newWallet);
this.initialSyncingWalletIds.add(newWallet.publicDeriverId);
this._setActiveWallet({
publicDeriverId: newWallet.publicDeriverId,
});
this.actions.dialogs.closeActiveDialog.trigger();
this.initialSyncingWalletIds.add(newWallet.publicDeriverId);
this.actions.router.goToRoute.trigger({ route: ROUTES.WALLETS.ROOT });
});
};
Expand Down Expand Up @@ -286,11 +286,15 @@ export default class WalletStore extends Store<StoresMap, ActionsMap> {
this.actions.profile.setSelectedNetwork.trigger(
getNetworkById(this.wallets[walletIndex].networkId)
);
const changed = (this.selectedIndex != null) && (this.selectedIndex !== walletIndex)
// This flag is used to determine whether to send the active-wallet-open event to Bring's content script.
// Don't send it here when we are creating a new wallet because the wallet hasn't been synced.
&& !this.isInitialSyncing(publicDeriverId);
this.selectedIndex = walletIndex;
this.selectedWalletName = this.wallets[walletIndex].name;
// Cache select wallet
this.api.localStorage.setSelectedWalletId(publicDeriverId);
subscribe(publicDeriverId);
subscribe(publicDeriverId, changed);
};

getLastSelectedWallet: void => ?WalletState = () => {
Expand Down
180 changes: 180 additions & 0 deletions packages/yoroi-extension/chrome/content-scripts/bringInject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// @flow

import { bringInitContentScript } from "@bringweb3/chrome-extension-kit";

(async () => {
await bringInitContentScript({
iframeEndpoint: process.env.IFRAME_ENDPOINT,
getWalletAddress: async () => await new Promise(resolve => setTimeout(() => resolve('<USER_WALLET_ADDRESS>'), 200)),// Async function that returns the current user's wallet address
promptLogin: () => { return window.prompt('login'); }, // Function that prompts a UI element asking the user to login
walletAddressListeners: ["customEvent:addressChanged"], // A list of custom events that dispatched when the user's wallet address had changed
customTheme: {
// font
fontUrl: 'https://fonts.googleapis.com/css2?family=Matemasie&display=swap',
fontFamily: "'Matemasie', system-ui",
// Popup
popupBg: "#192E34",
popupShadow: "",
// Primary button
primaryBtnBg: "linear-gradient(135deg, #5DEB5A 0%, #FDFC47 100%)",
primaryBtnFC: "#041417",
primaryBtnFW: "600",
primaryBtnFS: "14px",
primaryBtnBorderC: "transparent",
primaryBtnBorderW: "0",
primaryBtnRadius: "8px",
// Secondary button
secondaryBtnBg: "transparent",
secondaryBtnFS: "12px",
secondaryBtnFW: "500",
secondaryBtnFC: "white",
secondaryBtnBorderC: "rgba(149, 176, 178, 0.50)",
secondaryBtnBorderW: "2px",
secondaryBtnRadius: "8px",
// Markdown
markdownBg: "#07131766",
markdownFS: "12px",
markdownFC: "#DADCE5",
markdownBorderW: "0",
markdownRadius: "4px",
markdownBorderC: "black",
markdownScrollbarC: "#DADCE5",
// Wallet address
walletBg: "#33535B",
walletFS: "10px",
walletFW: "400",
walletFC: "white",
walletBorderC: "white",
walletBorderW: "0",
walletRadius: "4px",
// Details of offering
detailsBg: "#33535B",
detailsTitleFS: "15px",
detailsTitleFW: "600",
detailsTitleFC: "white",
detailsSubtitleFS: "14px",
detailsSubtitleFW: "500",
detailsSubtitleFC: "#A8ADBF",
detailsRadius: "8px",
detailsBorderW: "0",
detailsBorderC: "transparent",
detailsAmountFC: "#5DEB5A",
detailsAmountFW: "700",
// Overlay
overlayBg: "#192E34E6",
overlayFS: "13px",
overlayFW: "400",
overlayFC: "#DADCE5",
loaderBg: "#0A2EC0",
// Optout \ Turn off
optoutBg: "#192E34",
optoutFS: "14px",
optoutFW: "400",
optoutFC: "white",
optoutRadius: "56px",
// X Button and close buttons
closeFS: "9px",
closeFW: "300",
closeFC: "#B9BBBF",
// Token name
tokenBg: "transparent",
tokenFS: "13px",
tokenFW: "600",
tokenFC: "#DADCE5",
tokenBorderW: "2px",
tokenBorderC: "#DADCE5",
// Notification popup
notificationFS: "14px",
notificationFW: "500",
notificationFC: "white",
notificationBtnBg: "linear-gradient(135deg, #5DEB5A 0%, #FDFC47 100%)",
notificationBtnFS: "12px",
notificationBtnFW: "500",
notificationBtnFC: "#041417",
notificationBtnBorderW: "0",
notificationBtnBorderC: "transparent",
notificationBtnRadius: "8px",
activateTitleFS: "--activate-title-f-s",
activateTitleFW: "--activate-title-f-w",
activateTitleFC: "--activate-title-f-c",
activateTitleBoldFS: "--activate-title-bold-f-s",
activateTitleBoldFW: "--activate-title-bold-f-w",
activateTitleBoldFC: "--activate-title-bold-f-c",
}
});
})().catch(console.error);

function getFromBackground(functionName: string, params: andy): Promise<any> {
const uid = Math.random();
return new Promise((resolve, reject) => {
chrome.runtime.onMessage.addListener((msg, sender) => {
if (msg.type === 'connector_rpc_response' && msg.uid === uid) {
if (msg.return.ok) {
resolve(msg.return.ok);
} else {
reject(new Error(msg.return.err));
}
}
});

window.postMessage({
type: "connector_rpc_request",
url: location.hostname,
uid,
function: functionName,
params,
returnType: 'json',
});
});
}

async function getFirstAddress(): Promise<string> {
const usedAddresses = await getFromBackground('get_used_addresses', [undefined]);
if (usedAddresses.length > 0) {
return usedAddresses[0];
}
const unusedAddresses = await getFromBackground('get_unused_addresses', [undefined]);
return unusedAddresses[0];
}

function getTheme(): Promise<'light' | 'dark'> {
return getFromBackground('get-theme-mode', [undefined]);
}

function popUpWalletCreation(): void {
getFromBackground('pop-up-wallet-creation');
}

function listenForActiveWalletOpen(callback) {
// todo: verify sender extension id
chrome.runtime.onMessage.addListener((msg, sender) => {
if (msg.type === 'active-wallet-open') {
callback(msg.activeWalletId);
}
});
}

async function example() {
try {
const addr = await getFirstAddress();
console.log('address', addr);
} catch (error) {
if (error.message === 'no wallet') {
console.log('no wallet');
if (window.confirm('no wallet, click OK to create')) {
popUpWalletCreation();
}
} else {
throw error;
}
}

const theme = await getTheme();
console.log('theme:', theme);

listenForActiveWalletOpen((walletId: ?number) => {
console.log('active wallet ID is:', walletId);
});
}

example().catch(console.error);
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
} from './connect';
import type { CardanoTxRequest } from '../../../../../app/api/ada';
import type { NFTMetadata } from '../../../../../app/api/ada/lib/storage/database/primitives/tables';
import { getPublicDeriverById } from '../yoroi/utils';
import { getProtocolParameters } from '../yoroi/protocolParameters';
import { hexToBytes } from '../../../../../app/coreUtils';

Expand Down Expand Up @@ -641,6 +642,25 @@ const Handlers = Object.freeze({
);
}
}),

'get-theme-mode': NewHandler.basic<
void,
'dark' | 'light'
>(async () => {
const localStorageApi = new LocalStorageApi();
let theme = await localStorageApi.getUserThemeMode();
if (theme !== 'light' && theme !== 'dark') {
theme = 'light';
}
return { ok: theme };
}),

'pop-up-wallet-creation': NewHandler.basic<
void,
void,
>(async () => {
chrome.tabs.create({ url: 'main_window.html' });
}),
});

function sendRpcResponse(response: Object, tabId: number, messageUid: number) {
Expand Down Expand Up @@ -688,7 +708,26 @@ export async function handleRpc(message: Object, sender: Object) {

let connectedWallet = undefined;
if (handler.needConnectedWallet) {
connectedWallet = await getConnectedWallet(tabId, handler.syncConnectedWallet);
try {
connectedWallet = await getConnectedWallet(tabId, handler.syncConnectedWallet);
} catch (error) {
// fixme: unsafe
const localStorageApi = new LocalStorageApi();
const publicDeriverId = await localStorageApi.getSelectedWalletId();
if (publicDeriverId != null) {
connectedWallet = await getPublicDeriverById(publicDeriverId);
}
if (connectedWallet == null) {
sendRpcResponse(
{
err: 'no wallet',
},
tabId,
message.uid,
);
return;
}
}
}

const result = await handler.handle({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,6 @@ export const RemoveWalletFromWhiteList: HandlerType<
const site = connectedSites[tabId];
if (site.url === request.url) {
sendToInjector(Number(tabId), { type: 'disconnect' });
break;
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
} from './connector';
import { GetProtocolParameters } from './protocolParameters';
import { subscribe } from '../../subscriptionManager';
import { notifyAllTabsActiveWalletOpen } from './utils';

const handlerMap = Object.freeze({
[GetHistoricalCoinPrices.typeTag]: GetHistoricalCoinPrices.handle,
Expand Down Expand Up @@ -98,6 +99,10 @@ export function getHandler(typeTag: string): ?Handler {
if (typeTag === 'subscribe') {
return async (request, sender, sendResponse) => {
subscribe(sender.tab.id, request.request.activeWalletId);
if (request.request.changed) {
// notify content scripts in all tabs
notifyAllTabsActiveWalletOpen(request.request.activeWalletId);
}
sendResponse(undefined);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,18 @@ export async function getPublicDeriverById(publicDeriverId: number): Promise<Pub
}
throw new Error(`missing public deriver ${publicDeriverId}`);
}

export function notifyAllTabsActiveWalletOpen(activeWalletId: number) {
declare var chrome;
chrome.tabs.query({}, (tabs) => {
for (const tab of tabs) {
chrome.tabs.sendMessage(
tab.id,
{
type: 'active-wallet-open',
activeWalletId,
}
);
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { getCardanoStateFetcher } from '../../utils';
import LocalStorageApi, {
loadSubmittedTransactions, persistSubmittedTransactions
} from '../../../../../app/api/localStorage';
import { getPublicDeriverById } from './utils';
import { getPublicDeriverById, notifyAllTabsActiveWalletOpen } from './utils';
import { removePublicDeriver } from '../../../../../app/api/ada/lib/storage/bridge/walletBuilder/remove';
import { loadWalletsFromStorage } from '../../../../../app/api/ada/lib/storage/models/load';
import {
Expand Down Expand Up @@ -57,15 +57,18 @@ export const CreateWallet: HandlerType<CreateWalletRequest, CreateWalletResponse
walletPassword: request.walletPassword,
accountIndex: request.accountIndex,
});
const publicDeriverId = publicDerivers[0].getPublicDeriverId();

emitUpdateToSubscriptions({
type: 'wallet-state-update',
params: {
eventType: 'new',
publicDeriverId: publicDerivers[0].getPublicDeriverId(),
publicDeriverId,
}
});
syncWallet(publicDerivers[0], 'new wallet', 1);
syncWallet(publicDerivers[0], 'new wallet', 1).then(() => {
notifyAllTabsActiveWalletOpen(publicDeriverId);
});
return await getPlaceHolderWalletState(publicDerivers[0]);
},
});
Expand Down Expand Up @@ -103,15 +106,18 @@ export const CreateHardwareWallet: HandlerType<
checkAddressesInUse: stateFetcher.checkAddressesInUse,
addressing: request.addressing,
});
const publicDeriverId = publicDeriver.getPublicDeriverId();

emitUpdateToSubscriptions({
type: 'wallet-state-update',
params: {
eventType: 'new',
publicDeriverId: publicDeriver.getPublicDeriverId(),
publicDeriverId,
}
});
syncWallet(publicDeriver, 'new wallet', 1);
syncWallet(publicDeriver, 'new wallet', 1).then(() => {
notifyAllTabsActiveWalletOpen(publicDeriverId);
});;

return await getPlaceHolderWalletState(publicDeriver);
},
Expand Down
Loading