From dc56c094ea1c3c34161706040a555cf727e4d9ec Mon Sep 17 00:00:00 2001 From: Victor Kirov Date: Thu, 25 Jan 2024 12:48:47 +0200 Subject: [PATCH 1/5] Add new setting for prioritising Xverse --- package-lock.json | 2 +- src/app/hooks/useChromeLocalStorage.ts | 22 ++++++++++++++++++++++ src/app/screens/settings/index.tsx | 22 ++++++++++++++++++++-- src/app/utils/chromeLocalStorage.ts | 11 +++++++++++ src/content-scripts/content-script.ts | 14 +++++++++----- src/inpage/index.ts | 11 +++++++++-- src/locales/en.json | 4 +++- 7 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 src/app/hooks/useChromeLocalStorage.ts create mode 100644 src/app/utils/chromeLocalStorage.ts diff --git a/package-lock.json b/package-lock.json index d80e31636..8317eae94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16932,7 +16932,7 @@ "requires": { "@types/bn.js": "^5.1.0", "@types/node": "^18.0.4", - "buffer": "^6.0.3" + "buffer": "6.0.3" } }, "@stacks/network": { diff --git a/src/app/hooks/useChromeLocalStorage.ts b/src/app/hooks/useChromeLocalStorage.ts new file mode 100644 index 000000000..713229557 --- /dev/null +++ b/src/app/hooks/useChromeLocalStorage.ts @@ -0,0 +1,22 @@ +import { useEffect, useState } from 'react'; + +export const useChromeLocalStorage = (key: string, defaultValue?: T) => { + const [value, setValueState] = useState(undefined); + + useEffect(() => { + setValueState(undefined); + chrome.storage.local.get(key, (result) => { + const newValue = result[key] === undefined ? defaultValue : result[key]; + setValueState(newValue); + }); + }, [key]); + + const setValue = (newValue: T) => { + chrome.storage.local.set({ [key]: newValue }); + setValueState(newValue); + }; + + return [value, setValue] as const; +}; + +export default useChromeLocalStorage; diff --git a/src/app/screens/settings/index.tsx b/src/app/screens/settings/index.tsx index cdf5b42f8..0d0e02e39 100644 --- a/src/app/screens/settings/index.tsx +++ b/src/app/screens/settings/index.tsx @@ -3,6 +3,7 @@ import ArrowIcon from '@assets/img/settings/arrow.svg'; import XverseLogo from '@assets/img/settings/logo.svg'; import PasswordInput from '@components/passwordInput'; import BottomBar from '@components/tabBar'; +import useChromeLocalStorage from '@hooks/useChromeLocalStorage'; import useSeedVault from '@hooks/useSeedVault'; import useWalletReducer from '@hooks/useWalletReducer'; import useWalletSelector from '@hooks/useWalletSelector'; @@ -11,6 +12,7 @@ import { ChangeActivateRareSatsAction, ChangeActivateRBFAction, } from '@stores/wallet/actions/actionCreators'; +import { chromeLocalStorageKeys } from '@utils/chromeLocalStorage'; import { PRIVACY_POLICY_LINK, SUPPORT_LINK, TERMS_LINK } from '@utils/constants'; import { isInOptions, isLedgerAccount } from '@utils/helper'; import { useState } from 'react'; @@ -67,6 +69,10 @@ function Setting() { hasActivatedRBFKey, selectedAccount, } = useWalletSelector(); + const [isPriorityWallet, setIsPriorityWallet] = useChromeLocalStorage( + chromeLocalStorageKeys.isPriorityWallet, + true, + ); const navigate = useNavigate(); const dispatch = useDispatch(); const { resetWallet } = useWalletReducer(); @@ -100,6 +106,10 @@ function Setting() { navigate('/backup-wallet'); }; + const switchIsPriorityWallet = () => { + setIsPriorityWallet(!isPriorityWallet); + }; + const switchActivateOrdinalState = () => { dispatch(ChangeActivateOrdinalsAction(!hasActivatedOrdinalsKey)); // disable rare sats if ordinal is disabled @@ -202,6 +212,7 @@ function Setting() { onClick={openChangeNetworkScreen} textDetail={network.type} /> + + - - + { + return new Promise((resolve) => { + chrome.storage.local.get(chromeLocalStorageKeys.isPriorityWallet, (result) => { + resolve(result[chromeLocalStorageKeys.isPriorityWallet]); + }); + }); +} diff --git a/src/content-scripts/content-script.ts b/src/content-scripts/content-script.ts index 005fde8d3..69e5d5f52 100644 --- a/src/content-scripts/content-script.ts +++ b/src/content-scripts/content-script.ts @@ -22,6 +22,7 @@ import { } from '@common/types/message-types'; import getEventSourceWindow from '@common/utils/get-event-source-window'; import RequestsRoutes from '@common/utils/route-urls'; +import { getIsPriorityWallet } from '@utils/chromeLocalStorage'; // Legacy messaging to work with older versions of Connect window.addEventListener('message', (event) => { @@ -203,8 +204,11 @@ document.addEventListener(DomEventName.createRepeatInscriptionsRequest, (( }); }) as EventListener); -// Inject inpage script (Stacks Provider) -const inpage = document.createElement('script'); -inpage.src = chrome.runtime.getURL('inpage.js'); -inpage.id = 'xverse-wallet-provider'; -document.body.appendChild(inpage); +// Inject in-page script (Stacks and Bitcoin Providers) +getIsPriorityWallet().then((isPriorityWallet) => { + const inpage = document.createElement('script'); + inpage.src = chrome.runtime.getURL('inpage.js'); + inpage.id = 'xverse-wallet-provider'; + inpage.setAttribute('data-is-priority', isPriorityWallet ? 'true' : ''); + document.body.appendChild(inpage); +}); diff --git a/src/inpage/index.ts b/src/inpage/index.ts index e9b634585..04494a68d 100644 --- a/src/inpage/index.ts +++ b/src/inpage/index.ts @@ -14,8 +14,15 @@ declare global { } // we inject these in case implementors call the default providers -window.StacksProvider = StacksMethodsProvider as StacksProvider; -window.BitcoinProvider = SatsMethodsProvider as BitcoinProvider; +if (document.currentScript?.dataset.isPriority) { + Object.defineProperties(window, { + StacksProvider: { get: () => StacksMethodsProvider, set: () => {} }, + BitcoinProvider: { get: () => SatsMethodsProvider, set: () => {} }, + }); +} else { + window.StacksProvider = StacksMethodsProvider as StacksProvider; + window.BitcoinProvider = SatsMethodsProvider; +} // We also inject the providers in an Xverse object in order to have them exclusively available for Xverse wallet // and not clash with providers from other wallets diff --git a/src/locales/en.json b/src/locales/en.json index d7fe25d36..0ac5e2d31 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -757,7 +757,9 @@ "ENABLE_RARE_SATS_DETAIL": "Automatically scan and display rare sats in your Ordinals wallet.", "ENABLE_SPEED_UP_TRANSACTIONS": "Enable speed up transactions", "ENABLE_SPEED_UP_TRANSACTIONS_DETAIL": "Allows you to speed up unconfirmed transactions by paying a higher fee.", - "ADVANCED": "Advanced" + "ADVANCED": "Advanced", + "XVERSE_DEFAULT": "Use Xverse as default wallet", + "XVERSE_DEFAULT_DESCRIPTION": "Allow apps to prioritize Xverse when looking for a wallet with which to connect." }, "OPTIONS_DIALOG": { "SWITCH_ACCOUNT": "Switch Account", From 584aab11e984242c58e0e01651bc4aa715ed5b60 Mon Sep 17 00:00:00 2001 From: Victor Kirov Date: Thu, 25 Jan 2024 12:50:19 +0200 Subject: [PATCH 2/5] default to false priority on storage failure --- src/app/utils/chromeLocalStorage.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/app/utils/chromeLocalStorage.ts b/src/app/utils/chromeLocalStorage.ts index e88b06317..0568deb65 100644 --- a/src/app/utils/chromeLocalStorage.ts +++ b/src/app/utils/chromeLocalStorage.ts @@ -4,8 +4,12 @@ export const chromeLocalStorageKeys = { export function getIsPriorityWallet(): Promise { return new Promise((resolve) => { - chrome.storage.local.get(chromeLocalStorageKeys.isPriorityWallet, (result) => { - resolve(result[chromeLocalStorageKeys.isPriorityWallet]); - }); + try { + chrome.storage.local.get(chromeLocalStorageKeys.isPriorityWallet, (result) => { + resolve(result[chromeLocalStorageKeys.isPriorityWallet]); + }); + } catch (e) { + resolve(false); + } }); } From 62ed27241ae2e8dc30a28028f1f1e12824ac55bf Mon Sep 17 00:00:00 2001 From: Victor Kirov Date: Mon, 29 Jan 2024 13:48:31 +0200 Subject: [PATCH 3/5] Use chrome storage util --- src/app/hooks/useChromeLocalStorage.ts | 7 ++++--- src/app/utils/chromeLocalStorage.ts | 18 ++++++++---------- src/app/utils/chromeStorage.ts | 6 +++--- src/content-scripts/content-script.ts | 14 +++++++++++--- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/app/hooks/useChromeLocalStorage.ts b/src/app/hooks/useChromeLocalStorage.ts index 713229557..b507a0cba 100644 --- a/src/app/hooks/useChromeLocalStorage.ts +++ b/src/app/hooks/useChromeLocalStorage.ts @@ -1,3 +1,4 @@ +import { chromeLocalStorage } from '@utils/chromeStorage'; import { useEffect, useState } from 'react'; export const useChromeLocalStorage = (key: string, defaultValue?: T) => { @@ -5,14 +6,14 @@ export const useChromeLocalStorage = (key: string, defaultVal useEffect(() => { setValueState(undefined); - chrome.storage.local.get(key, (result) => { - const newValue = result[key] === undefined ? defaultValue : result[key]; + chromeLocalStorage.getItem(key).then((result) => { + const newValue = result === undefined ? defaultValue : result; setValueState(newValue); }); }, [key]); const setValue = (newValue: T) => { - chrome.storage.local.set({ [key]: newValue }); + chromeLocalStorage.setItem(key, newValue); setValueState(newValue); }; diff --git a/src/app/utils/chromeLocalStorage.ts b/src/app/utils/chromeLocalStorage.ts index 0568deb65..001c907c6 100644 --- a/src/app/utils/chromeLocalStorage.ts +++ b/src/app/utils/chromeLocalStorage.ts @@ -1,15 +1,13 @@ +import { chromeLocalStorage } from './chromeStorage'; + export const chromeLocalStorageKeys = { isPriorityWallet: 'isPriorityWallet', }; -export function getIsPriorityWallet(): Promise { - return new Promise((resolve) => { - try { - chrome.storage.local.get(chromeLocalStorageKeys.isPriorityWallet, (result) => { - resolve(result[chromeLocalStorageKeys.isPriorityWallet]); - }); - } catch (e) { - resolve(false); - } - }); +export async function getIsPriorityWallet(): Promise { + const isPriorityWallet = await chromeLocalStorage.getItem( + chromeLocalStorageKeys.isPriorityWallet, + ); + + return isPriorityWallet ?? true; } diff --git a/src/app/utils/chromeStorage.ts b/src/app/utils/chromeStorage.ts index 44d4527a0..451e7182f 100644 --- a/src/app/utils/chromeStorage.ts +++ b/src/app/utils/chromeStorage.ts @@ -19,7 +19,7 @@ class ChromeStorage { return runtimeMap.get(this).lastError; } - setItem(key: string, item: any): Promise { + setItem(key: string, item: any): Promise { return new Promise((resolve, reject) => { this.getDriver().set({ [key]: item }, () => { if (this.hasError()) { @@ -30,7 +30,7 @@ class ChromeStorage { }); } - getItem(key: string): Promise { + getItem(key: string): Promise { return new Promise((resolve, reject) => { this.getDriver().get(key, (response: any) => { if (this.hasError()) { @@ -41,7 +41,7 @@ class ChromeStorage { }); } - removeItem(key: string): Promise { + removeItem(key: string): Promise { return new Promise((resolve, reject) => { this.getDriver().remove(key, () => { if (this.hasError()) { diff --git a/src/content-scripts/content-script.ts b/src/content-scripts/content-script.ts index 69e5d5f52..50e3081eb 100644 --- a/src/content-scripts/content-script.ts +++ b/src/content-scripts/content-script.ts @@ -205,10 +205,18 @@ document.addEventListener(DomEventName.createRepeatInscriptionsRequest, (( }) as EventListener); // Inject in-page script (Stacks and Bitcoin Providers) -getIsPriorityWallet().then((isPriorityWallet) => { +const injectInPageScript = (isPriority) => { const inpage = document.createElement('script'); inpage.src = chrome.runtime.getURL('inpage.js'); inpage.id = 'xverse-wallet-provider'; - inpage.setAttribute('data-is-priority', isPriorityWallet ? 'true' : ''); + inpage.setAttribute('data-is-priority', isPriority ? 'true' : ''); document.body.appendChild(inpage); -}); +}; + +getIsPriorityWallet() + .then((isPriorityWallet) => { + injectInPageScript(isPriorityWallet); + }) + .catch(() => { + injectInPageScript(false); + }); From 34d0328e9cb43f4989c43957b993b3c7bf3c98fa Mon Sep 17 00:00:00 2001 From: Victor Kirov Date: Mon, 29 Jan 2024 13:59:58 +0200 Subject: [PATCH 4/5] Fix chrome storage types --- src/app/hooks/useSeedVault.ts | 4 ++-- src/app/utils/chromeStorage.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/hooks/useSeedVault.ts b/src/app/hooks/useSeedVault.ts index cdc58e8d3..299f1c5ba 100644 --- a/src/app/hooks/useSeedVault.ts +++ b/src/app/hooks/useSeedVault.ts @@ -20,13 +20,13 @@ const cryptoUtilsAdapter: CryptoUtilsAdapter = { }; const secureStorageAdapter: StorageAdapter = { - get: async (key: string) => chromeSessionStorage.getItem(key), + get: async (key: string) => chromeSessionStorage.getItem(key, null), set: async (key: string, value: string) => chromeSessionStorage.setItem(key, value), remove: async (key: string) => chromeSessionStorage.removeItem(key), }; const commonStorageAdapter: StorageAdapter = { - get: async (key: string) => chromeLocalStorage.getItem(key), + get: async (key: string) => chromeLocalStorage.getItem(key, null), set: async (key: string, value: string) => chromeLocalStorage.setItem(key, value), remove: async (key: string) => chromeLocalStorage.removeItem(key), }; diff --git a/src/app/utils/chromeStorage.ts b/src/app/utils/chromeStorage.ts index 451e7182f..943dd62e4 100644 --- a/src/app/utils/chromeStorage.ts +++ b/src/app/utils/chromeStorage.ts @@ -19,35 +19,35 @@ class ChromeStorage { return runtimeMap.get(this).lastError; } - setItem(key: string, item: any): Promise { + setItem(key: string, item: any): Promise { return new Promise((resolve, reject) => { this.getDriver().set({ [key]: item }, () => { if (this.hasError()) { return reject(this.getError()); } - return resolve(true); + return resolve(); }); }); } - getItem(key: string): Promise { + getItem(key: string, defaultValue?: D): Promise { return new Promise((resolve, reject) => { this.getDriver().get(key, (response: any) => { if (this.hasError()) { return reject(this.getError()); } - return resolve(response[key]); + return resolve(response[key] || defaultValue); }); }); } - removeItem(key: string): Promise { + removeItem(key: string): Promise { return new Promise((resolve, reject) => { this.getDriver().remove(key, () => { if (this.hasError()) { return reject(this.getError()); } - return resolve(true); + return resolve(); }); }); } From 9d28d0f6018826d6dfbd868414bab193257514bc Mon Sep 17 00:00:00 2001 From: Victor Kirov Date: Mon, 29 Jan 2024 14:05:20 +0200 Subject: [PATCH 5/5] fix storage default value --- src/app/utils/chromeStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/utils/chromeStorage.ts b/src/app/utils/chromeStorage.ts index 943dd62e4..9b1d8958a 100644 --- a/src/app/utils/chromeStorage.ts +++ b/src/app/utils/chromeStorage.ts @@ -36,7 +36,7 @@ class ChromeStorage { if (this.hasError()) { return reject(this.getError()); } - return resolve(response[key] || defaultValue); + return resolve(response[key] ?? defaultValue); }); }); }