From 0a9303bfb9750265c57bc21ee75b49da2c40956e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Jul 2023 11:21:13 -0400 Subject: [PATCH 1/9] Add in support for geofence check in oeth --- dapp-oeth/pages/_app.js | 6 + dapp-oeth/src/components/GeoFenceCheck.js | 229 ++++++++++++++++++++++ dapp-oeth/src/hooks/useLocalStorage.js | 129 ++++++++++++ 3 files changed, 364 insertions(+) create mode 100644 dapp-oeth/src/components/GeoFenceCheck.js create mode 100644 dapp-oeth/src/hooks/useLocalStorage.js diff --git a/dapp-oeth/pages/_app.js b/dapp-oeth/pages/_app.js index 970ca5b8d6..820a7676c7 100644 --- a/dapp-oeth/pages/_app.js +++ b/dapp-oeth/pages/_app.js @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react' +import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import Head from 'next/head' import { useCookies } from 'react-cookie' @@ -79,6 +80,10 @@ const client = createClient({ connectors, }) +const GeoFenceCheck = dynamic(() => import('components/GeoFenceCheck'), { + ssr: false, +}) + function App({ Component, pageProps, err }) { const { address: account, isConnected: active } = useAccount() const [locale, setLocale] = useState('en_US') @@ -125,6 +130,7 @@ function App({ Component, pageProps, err }) { + diff --git a/dapp-oeth/src/components/GeoFenceCheck.js b/dapp-oeth/src/components/GeoFenceCheck.js new file mode 100644 index 0000000000..edee3942da --- /dev/null +++ b/dapp-oeth/src/components/GeoFenceCheck.js @@ -0,0 +1,229 @@ +import { useState } from 'react' +import { Modal } from 'react-bootstrap' +import useLocalStorage from 'hooks/useLocalStorage' + +const GeoFenceCheck = () => { + const { data: hasConfirmedGeoLocation, onSetItem } = useLocalStorage( + '@originprotocol/oeth-geo-check', + false + ) + + const [isChecked, setIsChecked] = useState(false) + + const onAckGeoFence = () => { + onSetItem(true) + } + + return ( + <> + +
+
+

Not supported in the United States

+
+
+

+ It appears that you are accessing the Origin Ether interface from + inside the united states. +

+

+ The OETH interface is not available to persons or entities who + reside in, are citizens of, are located in, are incorporated in, + or have a registered office in the United States of America. +

+
+
    +
  • + Only continue if you are not a person or company who is a + resident of, or is located, incorporated or has a registered + agent in the United States. +
  • +
  • + You are lawfully permitted to access this site and trade OETH + under the laws of the jurisdiction in which you reside and are + located. +
  • +
+
+
+ +
+
+ +
+
+ + + ) +} + +export default GeoFenceCheck diff --git a/dapp-oeth/src/hooks/useLocalStorage.js b/dapp-oeth/src/hooks/useLocalStorage.js new file mode 100644 index 0000000000..548a18236e --- /dev/null +++ b/dapp-oeth/src/hooks/useLocalStorage.js @@ -0,0 +1,129 @@ +import { useCallback, useEffect, useState } from 'react' + +const LOCAL_STORAGE_CHANGE_EVENT_NAME = 'onLocalStorageChange' + +const isTypeOfLocalStorageChanged = (evt) => { + return !!evt && evt.type === LOCAL_STORAGE_CHANGE_EVENT_NAME +} + +const isBrowser = () => { + return typeof window !== 'undefined' && typeof window.document !== 'undefined' +} + +const writeStorage = (key, value) => { + if (!isBrowser()) { + return + } + + try { + window.localStorage.setItem( + key, + typeof value === 'object' ? JSON.stringify(value) : `${value}` + ) + window.dispatchEvent( + new CustomEvent(LOCAL_STORAGE_CHANGE_EVENT_NAME, { + detail: { key, value }, + }) + ) + } catch (err) { + if ( + err instanceof TypeError && + err.message.includes('circular structure') + ) { + throw new TypeError( + 'The object that was given to the writeStorage function has circular references.\n' + + 'For more information, check here: ' + + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value' + ) + } + throw err + } +} + +const deleteFromStorage = (key) => { + if (!isBrowser()) { + return + } + window.localStorage.removeItem(key) + window.dispatchEvent( + new CustomEvent(LOCAL_STORAGE_CHANGE_EVENT_NAME, { + detail: { key, value: null }, + }) + ) +} + +const tryParse = (value) => { + try { + return JSON.parse(value) + } catch { + return value + } +} + +const useLocalStorage = (key, defaultValue) => { + const [localState, updateLocalState] = useState( + window.localStorage.getItem(key) === null + ? defaultValue + : tryParse(window.localStorage.getItem(key)) + ) + + const onLocalStorageChange = useCallback( + (event) => { + if (isTypeOfLocalStorageChanged(event)) { + if (event.detail.key === key) { + updateLocalState(event.detail.value) + } + } else { + if (event.key === key) { + updateLocalState( + event.newValue === null ? null : tryParse(event.newValue) + ) + } + } + }, + [updateLocalState, key] + ) + + useEffect(() => { + if (!isBrowser()) { + return + } + + const listener = (e) => { + onLocalStorageChange(e) + } + + window.addEventListener(LOCAL_STORAGE_CHANGE_EVENT_NAME, listener) + + // The storage event only works in the context of other documents (eg. other browser tabs) + window.addEventListener('storage', listener) + + // Write default value to the local storage if there currently isn't any value there. + if (window.localStorage.getItem(key) === null && defaultValue !== null) { + writeStorage(key, defaultValue) + } + + return () => { + window.removeEventListener(LOCAL_STORAGE_CHANGE_EVENT_NAME, listener) + window.removeEventListener('storage', listener) + } + }, [key, defaultValue, onLocalStorageChange]) + + const writeState = useCallback( + (value) => + value instanceof Function + ? writeStorage(key, value(localState)) + : writeStorage(key, value), + [key] + ) + + const deleteState = useCallback(() => deleteFromStorage(key), [key]) + + return { + data: localState ?? defaultValue, + onSetItem: writeState, + onRemoveItem: deleteState, + } +} + +export default useLocalStorage From c55a7e5cf5b3a6dcd04adb5da7c33382e6802aec Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Jul 2023 11:27:27 -0400 Subject: [PATCH 2/9] Add ousd --- dapp/pages/_app.js | 5 + dapp/src/components/GeoFenceCheck.js | 229 +++++++++++++++++++++++++++ dapp/src/hooks/useLocalStorage.js | 129 +++++++++++++++ 3 files changed, 363 insertions(+) create mode 100644 dapp/src/components/GeoFenceCheck.js create mode 100644 dapp/src/hooks/useLocalStorage.js diff --git a/dapp/pages/_app.js b/dapp/pages/_app.js index 0bc51c94af..656b155bff 100644 --- a/dapp/pages/_app.js +++ b/dapp/pages/_app.js @@ -80,6 +80,10 @@ const client = createClient({ connectors, }) +const GeoFenceCheck = dynamic(() => import('components/GeoFenceCheck'), { + ssr: false, +}) + function App({ Component, pageProps, err }) { const [locale, setLocale] = useState('en_US') const { address: account, isConnected: active } = useAccount() @@ -133,6 +137,7 @@ function App({ Component, pageProps, err }) { + diff --git a/dapp/src/components/GeoFenceCheck.js b/dapp/src/components/GeoFenceCheck.js new file mode 100644 index 0000000000..6f6a60a507 --- /dev/null +++ b/dapp/src/components/GeoFenceCheck.js @@ -0,0 +1,229 @@ +import { useState } from 'react' +import { Modal } from 'react-bootstrap' +import useLocalStorage from 'hooks/useLocalStorage' + +const GeoFenceCheck = () => { + const { data: hasConfirmedGeoLocation, onSetItem } = useLocalStorage( + '@originprotocol/ousd-geo-check', + false + ) + + const [isChecked, setIsChecked] = useState(false) + + const onAckGeoFence = () => { + onSetItem(true) + } + + return ( + <> + +
+
+

Not supported in the United States

+
+
+

+ It appears that you are accessing the Origin Ether interface from + inside the united states. +

+

+ The OETH interface is not available to persons or entities who + reside in, are citizens of, are located in, are incorporated in, + or have a registered office in the United States of America. +

+
+
    +
  • + Only continue if you are not a person or company who is a + resident of, or is located, incorporated or has a registered + agent in the United States. +
  • +
  • + You are lawfully permitted to access this site and trade OETH + under the laws of the jurisdiction in which you reside and are + located. +
  • +
+
+
+ +
+
+ +
+
+ + + ) +} + +export default GeoFenceCheck diff --git a/dapp/src/hooks/useLocalStorage.js b/dapp/src/hooks/useLocalStorage.js new file mode 100644 index 0000000000..548a18236e --- /dev/null +++ b/dapp/src/hooks/useLocalStorage.js @@ -0,0 +1,129 @@ +import { useCallback, useEffect, useState } from 'react' + +const LOCAL_STORAGE_CHANGE_EVENT_NAME = 'onLocalStorageChange' + +const isTypeOfLocalStorageChanged = (evt) => { + return !!evt && evt.type === LOCAL_STORAGE_CHANGE_EVENT_NAME +} + +const isBrowser = () => { + return typeof window !== 'undefined' && typeof window.document !== 'undefined' +} + +const writeStorage = (key, value) => { + if (!isBrowser()) { + return + } + + try { + window.localStorage.setItem( + key, + typeof value === 'object' ? JSON.stringify(value) : `${value}` + ) + window.dispatchEvent( + new CustomEvent(LOCAL_STORAGE_CHANGE_EVENT_NAME, { + detail: { key, value }, + }) + ) + } catch (err) { + if ( + err instanceof TypeError && + err.message.includes('circular structure') + ) { + throw new TypeError( + 'The object that was given to the writeStorage function has circular references.\n' + + 'For more information, check here: ' + + 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value' + ) + } + throw err + } +} + +const deleteFromStorage = (key) => { + if (!isBrowser()) { + return + } + window.localStorage.removeItem(key) + window.dispatchEvent( + new CustomEvent(LOCAL_STORAGE_CHANGE_EVENT_NAME, { + detail: { key, value: null }, + }) + ) +} + +const tryParse = (value) => { + try { + return JSON.parse(value) + } catch { + return value + } +} + +const useLocalStorage = (key, defaultValue) => { + const [localState, updateLocalState] = useState( + window.localStorage.getItem(key) === null + ? defaultValue + : tryParse(window.localStorage.getItem(key)) + ) + + const onLocalStorageChange = useCallback( + (event) => { + if (isTypeOfLocalStorageChanged(event)) { + if (event.detail.key === key) { + updateLocalState(event.detail.value) + } + } else { + if (event.key === key) { + updateLocalState( + event.newValue === null ? null : tryParse(event.newValue) + ) + } + } + }, + [updateLocalState, key] + ) + + useEffect(() => { + if (!isBrowser()) { + return + } + + const listener = (e) => { + onLocalStorageChange(e) + } + + window.addEventListener(LOCAL_STORAGE_CHANGE_EVENT_NAME, listener) + + // The storage event only works in the context of other documents (eg. other browser tabs) + window.addEventListener('storage', listener) + + // Write default value to the local storage if there currently isn't any value there. + if (window.localStorage.getItem(key) === null && defaultValue !== null) { + writeStorage(key, defaultValue) + } + + return () => { + window.removeEventListener(LOCAL_STORAGE_CHANGE_EVENT_NAME, listener) + window.removeEventListener('storage', listener) + } + }, [key, defaultValue, onLocalStorageChange]) + + const writeState = useCallback( + (value) => + value instanceof Function + ? writeStorage(key, value(localState)) + : writeStorage(key, value), + [key] + ) + + const deleteState = useCallback(() => deleteFromStorage(key), [key]) + + return { + data: localState ?? defaultValue, + onSetItem: writeState, + onRemoveItem: deleteState, + } +} + +export default useLocalStorage From 50faa4e1b4eb298625f2e5bc0afe1085d08ee4b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Jul 2023 11:27:57 -0400 Subject: [PATCH 3/9] Navigate to ousd.com for ousd dapp --- dapp/src/components/GeoFenceCheck.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/GeoFenceCheck.js b/dapp/src/components/GeoFenceCheck.js index 6f6a60a507..4643f47b27 100644 --- a/dapp/src/components/GeoFenceCheck.js +++ b/dapp/src/components/GeoFenceCheck.js @@ -70,7 +70,7 @@ const GeoFenceCheck = () => {