diff --git a/dapps/react-dapp-v2/src/components/OriginSimulationDropdown.tsx b/dapps/react-dapp-v2/src/components/OriginSimulationDropdown.tsx
new file mode 100644
index 0000000..7fab261
--- /dev/null
+++ b/dapps/react-dapp-v2/src/components/OriginSimulationDropdown.tsx
@@ -0,0 +1,56 @@
+import * as React from "react";
+import { ORIGIN_OPTIONS } from "../constants/default";
+import styled from "styled-components";
+
+interface OriginSimulationProps {
+ origin: string;
+ show: boolean;
+}
+
+const SelectContainer = styled.select`
+ width: 150px;
+ background: transparent;
+ color: black;
+ height: 30px;
+ border-radius: 4px;
+ padding: 2px;
+ font-size: "1.25em";
+ bottom: 40px;
+ left: 50px;
+ direction: ltr;
+ unicode-bidi: embed;
+ margin: 5px;
+`;
+
+const SelectOption = styled.option`
+ font-size: "1.25em";
+`;
+
+const OriginSimulationDropdown = (props: OriginSimulationProps) => {
+ const { origin, show } = props;
+ const setOrigin = React.useCallback((origin: string) => {
+ localStorage.setItem("wallet_connect_dapp_origin", origin);
+ location.reload();
+ }, []);
+ return (
+
+ {show && (
+ setOrigin(e?.target?.value)}
+ >
+
+ {ORIGIN_OPTIONS.map((e, i) => {
+ return (
+
+ {e.label}
+
+ );
+ })}
+
+ )}
+
+ );
+};
+
+export default OriginSimulationDropdown;
diff --git a/dapps/react-dapp-v2/src/components/Dropdown.tsx b/dapps/react-dapp-v2/src/components/RelayRegionDropdown.tsx
similarity index 56%
rename from dapps/react-dapp-v2/src/components/Dropdown.tsx
rename to dapps/react-dapp-v2/src/components/RelayRegionDropdown.tsx
index 3d64767..67afc6c 100644
--- a/dapps/react-dapp-v2/src/components/Dropdown.tsx
+++ b/dapps/react-dapp-v2/src/components/RelayRegionDropdown.tsx
@@ -4,9 +4,10 @@ import styled from "styled-components";
import Icon from "./Icon";
import { useState } from "react";
-interface DropdownProps {
+interface RelayRegionDropdownProps {
relayerRegion: string;
setRelayerRegion?: (relayer: string) => void;
+ show: boolean;
}
const SelectContainer = styled.select`
@@ -17,47 +18,27 @@ const SelectContainer = styled.select`
border-radius: 4px;
padding: 2px;
font-size: "1.25em";
- position: absolute;
bottom: 40px;
left: 50px;
direction: ltr;
unicode-bidi: embed;
+ margin: 5px;
`;
const SelectOption = styled.option`
font-size: "1.25em";
`;
-const Dropdown = (props: DropdownProps) => {
- const { relayerRegion, setRelayerRegion } = props;
- const [openSelect, setOpenSelect] = useState(false);
- const selectRef = React.createRef();
-
- const openDropdown = () => {
- setOpenSelect(!openSelect);
- };
-
+const RelayRegionDropdown = (props: RelayRegionDropdownProps) => {
+ const { relayerRegion, setRelayerRegion, show } = props;
return (
-
-
- {openSelect && (
+
+ {show && (
setRelayerRegion?.(e?.target?.value)}
>
-
+
{REGIONALIZED_RELAYER_ENDPOINTS.map((e, i) => {
return (
@@ -71,4 +52,4 @@ const Dropdown = (props: DropdownProps) => {
);
};
-export default Dropdown;
+export default RelayRegionDropdown;
diff --git a/dapps/react-dapp-v2/src/components/app/index.tsx b/dapps/react-dapp-v2/src/components/app/index.tsx
index 119cfd5..eda24c0 100644
--- a/dapps/react-dapp-v2/src/components/app/index.tsx
+++ b/dapps/react-dapp-v2/src/components/app/index.tsx
@@ -53,6 +53,13 @@ export const SToggleContainer = styled.div`
}
`;
+export const SDropDownContainer = styled.div`
+ padding-top: 20px;
+ display: flex;
+ justify-content: center;
+ align-items: flex-end;
+`;
+
export const SFullWidthContainer = styled.div`
width: 100%;
display: flex;
diff --git a/dapps/react-dapp-v2/src/constants/default.ts b/dapps/react-dapp-v2/src/constants/default.ts
index 83528b6..6ac925a 100644
--- a/dapps/react-dapp-v2/src/constants/default.ts
+++ b/dapps/react-dapp-v2/src/constants/default.ts
@@ -1,3 +1,5 @@
+import { getAppMetadata } from "@walletconnect/utils";
+
if (!process.env.NEXT_PUBLIC_PROJECT_ID)
throw new Error("`NEXT_PUBLIC_PROJECT_ID` env variable is missing.");
@@ -48,6 +50,7 @@ export const DEFAULT_APP_METADATA = {
description: "React App for WalletConnect",
url: "https://walletconnect.com/",
icons: ["https://avatars.githubusercontent.com/u/37784886"],
+ verifyUrl: "https://verify.walletconnect.com",
};
/**
@@ -185,3 +188,18 @@ export const REGIONALIZED_RELAYER_ENDPOINTS: RelayerType[] = [
label: "Asia Pacific",
},
];
+
+export const ORIGIN_OPTIONS = [
+ {
+ value: getAppMetadata().url,
+ label: "VALID",
+ },
+ {
+ value: "https://invalid.origin",
+ label: "INVALID",
+ },
+ {
+ value: "unknown",
+ label: "UNKNOWN",
+ },
+];
diff --git a/dapps/react-dapp-v2/src/contexts/ClientContext.tsx b/dapps/react-dapp-v2/src/contexts/ClientContext.tsx
index 61b8025..fc56383 100644
--- a/dapps/react-dapp-v2/src/contexts/ClientContext.tsx
+++ b/dapps/react-dapp-v2/src/contexts/ClientContext.tsx
@@ -46,6 +46,7 @@ interface IContext {
isFetchingBalances: boolean;
setChains: any;
setRelayerRegion: any;
+ origin: string;
}
/**
@@ -86,7 +87,7 @@ export function ClientContextProvider({
const [relayerRegion, setRelayerRegion] = useState(
DEFAULT_RELAY_URL!
);
-
+ const [origin, setOrigin] = useState(getAppMetadata().url);
const reset = () => {
setSession(undefined);
setBalances({});
@@ -284,15 +285,24 @@ export function ClientContextProvider({
const createClient = useCallback(async () => {
try {
setIsInitializing(true);
-
+ const claimedOrigin =
+ localStorage.getItem("wallet_connect_dapp_origin") || origin;
const _client = await Client.init({
logger: DEFAULT_LOGGER,
relayUrl: relayerRegion,
projectId: DEFAULT_PROJECT_ID,
- metadata: getAppMetadata() || DEFAULT_APP_METADATA,
+ metadata: {
+ ...(getAppMetadata() || DEFAULT_APP_METADATA),
+ url: claimedOrigin,
+ verifyUrl:
+ claimedOrigin === "unknown"
+ ? "http://non-existent-url"
+ : DEFAULT_APP_METADATA.verifyUrl, // simulates `UNKNOWN` verify context
+ },
});
setClient(_client);
+ setOrigin(_client.metadata.url);
prevRelayerValue.current = relayerRegion;
await _subscribeToEvents(_client);
await _checkPersistedState(_client);
@@ -302,7 +312,13 @@ export function ClientContextProvider({
} finally {
setIsInitializing(false);
}
- }, [_checkPersistedState, _subscribeToEvents, _logClientId, relayerRegion]);
+ }, [
+ _checkPersistedState,
+ _subscribeToEvents,
+ _logClientId,
+ relayerRegion,
+ origin,
+ ]);
useEffect(() => {
if (!client) {
@@ -329,6 +345,7 @@ export function ClientContextProvider({
disconnect,
setChains,
setRelayerRegion,
+ origin,
}),
[
pairings,
@@ -345,6 +362,7 @@ export function ClientContextProvider({
disconnect,
setChains,
setRelayerRegion,
+ origin,
]
);
diff --git a/dapps/react-dapp-v2/src/pages/index.tsx b/dapps/react-dapp-v2/src/pages/index.tsx
index cbfe88d..baf6f0c 100644
--- a/dapps/react-dapp-v2/src/pages/index.tsx
+++ b/dapps/react-dapp-v2/src/pages/index.tsx
@@ -4,7 +4,7 @@ import React, { useEffect, useRef, useState } from "react";
import Banner from "../components/Banner";
import Blockchain from "../components/Blockchain";
import Column from "../components/Column";
-import Dropdown from "../components/Dropdown";
+import RelayRegionDropdown from "../components/RelayRegionDropdown";
import Header from "../components/Header";
import Modal from "../components/Modal";
import {
@@ -32,6 +32,7 @@ import {
SButtonContainer,
SConnectButton,
SContent,
+ SDropDownContainer,
SLanding,
SLayout,
SToggleContainer,
@@ -39,6 +40,8 @@ import {
import { useWalletConnectClient } from "../contexts/ClientContext";
import { useJsonRpc } from "../contexts/JsonRpcContext";
import { useChainData } from "../contexts/ChainDataContext";
+import Icon from "../components/Icon";
+import OriginSimulationDropdown from "../components/OriginSimulationDropdown";
// Normal import does not work here
const { version } = require("@walletconnect/sign-client/package.json");
@@ -66,6 +69,7 @@ const Home: NextPage = () => {
isInitializing,
setChains,
setRelayerRegion,
+ origin,
} = useWalletConnectClient();
// Use `JsonRpcContext` to provide us with relevant RPC methods and states.
@@ -444,6 +448,12 @@ const Home: NextPage = () => {
}
};
+ const [openSelect, setOpenSelect] = useState(false);
+
+ const openDropdown = () => {
+ setOpenSelect(!openSelect);
+ };
+
const renderContent = () => {
const chainOptions = isTestnet ? DEFAULT_TEST_CHAINS : DEFAULT_MAIN_CHAINS;
@@ -469,10 +479,17 @@ const Home: NextPage = () => {
Connect
-
+
+
+
+
+
) : (
diff --git a/wallets/react-wallet-v2/src/components/ProjectInfoCard.tsx b/wallets/react-wallet-v2/src/components/ProjectInfoCard.tsx
index c2f6b6f..47917b8 100644
--- a/wallets/react-wallet-v2/src/components/ProjectInfoCard.tsx
+++ b/wallets/react-wallet-v2/src/components/ProjectInfoCard.tsx
@@ -1,3 +1,8 @@
+import { useMemo } from 'react'
+import { useSnapshot } from 'valtio'
+
+import SettingsStore from '@/store/SettingsStore'
+import { getVerifyStatus } from '@/utils/HelperUtil'
import { Avatar, Col, Link, Row, Text } from '@nextui-org/react'
import { SignClientTypes } from '@walletconnect/types'
@@ -12,17 +17,26 @@ interface IProps {
* Components
*/
export default function ProjectInfoCard({ metadata }: IProps) {
+ const { currentRequestVerifyContext } = useSnapshot(SettingsStore.state)
const { icons, name, url } = metadata
-
+ const validation = useMemo(
+ () => getVerifyStatus(currentRequestVerifyContext),
+ [currentRequestVerifyContext]
+ )
return (
-
-
-
-
-
- {name}
- {url}
-
-
+ <>
+
+
+
+
+
+ {name}
+
+ {url}
+ {validation}
+
+
+
+ >
)
}
diff --git a/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts b/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts
index 2d6cf0f..9b190e6 100644
--- a/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts
+++ b/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts
@@ -5,6 +5,8 @@ import { POLKADOT_SIGNING_METHODS } from '@/data/PolkadotData'
import { MULTIVERSX_SIGNING_METHODS } from '@/data/MultiversxData'
import { TRON_SIGNING_METHODS } from '@/data/TronData'
import ModalStore from '@/store/ModalStore'
+import SettingsStore from '@/store/SettingsStore'
+import { useSnapshot } from 'valtio'
import { signClient } from '@/utils/WalletConnectUtil'
import { SignClientTypes } from '@walletconnect/types'
import { useCallback, useEffect } from 'react'
@@ -19,6 +21,8 @@ export default function useWalletConnectEventsManager(initialized: boolean) {
*****************************************************************************/
const onSessionProposal = useCallback(
(proposal: SignClientTypes.EventArguments['session_proposal']) => {
+ // set the verify context so it can be displayed in the projectInfoCard
+ SettingsStore.setCurrentRequestVerifyContext(proposal.verifyContext)
ModalStore.open('SessionProposalModal', { proposal })
},
[]
@@ -30,9 +34,11 @@ export default function useWalletConnectEventsManager(initialized: boolean) {
const onSessionRequest = useCallback(
async (requestEvent: SignClientTypes.EventArguments['session_request']) => {
console.log('session_request', requestEvent)
- const { topic, params } = requestEvent
+ const { topic, params, verifyContext } = requestEvent
const { request } = params
const requestSession = signClient.session.get(topic)
+ // set the verify context so it can be displayed in the projectInfoCard
+ SettingsStore.setCurrentRequestVerifyContext(verifyContext)
switch (request.method) {
case EIP155_SIGNING_METHODS.ETH_SIGN:
diff --git a/wallets/react-wallet-v2/src/store/SettingsStore.ts b/wallets/react-wallet-v2/src/store/SettingsStore.ts
index 628e2b5..5be3b35 100644
--- a/wallets/react-wallet-v2/src/store/SettingsStore.ts
+++ b/wallets/react-wallet-v2/src/store/SettingsStore.ts
@@ -1,3 +1,4 @@
+import { Verify } from '@walletconnect/types'
import { proxy } from 'valtio'
/**
@@ -17,6 +18,7 @@ interface State {
kadenaAddress: string
relayerRegionURL: string
activeChainId: string
+ currentRequestVerifyContext?: Verify.Context
}
/**
@@ -89,6 +91,10 @@ const SettingsStore = {
state.activeChainId = value
},
+ setCurrentRequestVerifyContext(context: Verify.Context) {
+ state.currentRequestVerifyContext = context
+ },
+
toggleTestNets() {
state.testNets = !state.testNets
if (state.testNets) {
diff --git a/wallets/react-wallet-v2/src/utils/HelperUtil.ts b/wallets/react-wallet-v2/src/utils/HelperUtil.ts
index b7a007f..8498be5 100644
--- a/wallets/react-wallet-v2/src/utils/HelperUtil.ts
+++ b/wallets/react-wallet-v2/src/utils/HelperUtil.ts
@@ -9,6 +9,7 @@ import { TRON_CHAINS, TTronChain } from '@/data/TronData'
import { KADENA_CHAINS, TKadenaChain } from '@/data/KadenaData'
import { utils } from 'ethers'
+import { Verify } from '@walletconnect/types'
/**
* Truncates string (in the middle) via given lenght value
@@ -160,3 +161,15 @@ export function formatChainName(chainId: string) {
chainId
)
}
+
+export function getVerifyStatus(context?: Verify.Context) {
+ if (!context) return ''
+ switch (context.verified.validation) {
+ case 'VALID':
+ return '✅ Verified'
+ case 'INVALID':
+ return '❌ Origin does not match'
+ case 'UNKNOWN':
+ return '❓ Unknown'
+ }
+}