feat: examples dapps update (#72)

* feat: updates example dapp with ethers to use `universal-provider`

* feat: updates example dapp with web3 to use `universal-provider`

* fix: sets `paramsString` and `address` to lower case when searching for match

* chore: yarn lock

* refactor: rm `outdated` warning

* refactor: standardize event logging

* refactor: rm logs

* refactor: adds `next` to `ethers` dapp

* chore: rm old files

* refactor: adds next to web3 example

* chore: test deploy vercel

* chore: remove console log

* chore: to trigger deployment

* Revert "chore: to trigger deployment"

This reverts commit bc7712780a101f0152c20ce4eca4d8d117d8eaa7.

* feat: updates readmes

Co-authored-by: crypblizz <45455218+crypblizz8@users.noreply.github.com>
This commit is contained in:
Gancho Radkov 2022-11-08 10:32:07 +02:00 committed by GitHub
parent 7721842601
commit 49920d0453
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 6970 additions and 6239 deletions

View File

@ -1,4 +1,3 @@
REACT_APP_PROJECT_ID=39bc93c...
REACT_APP_INFURA_ID=5dc0df...
REACT_APP_RELAY_URL=wss://relay.walletconnect.com
NEXT_PUBLIC_PROJECT_ID=39bc93c...
NEXT_PUBLIC_RELAY_URL=wss://relay.walletconnect.com

View File

@ -1,9 +1,4 @@
# React dApp (with v2 EthereumProvider + Ethers.js)
> **⚠️ This provider-based example is currently reliant on the deprecated `2.0.0-beta.26` SDK. ⚠️**
>
> This example will be updated to be compatible with the latest v2 SDK (`2.0.0-beta.100+`) in due time.
> In the meantime, please use the up-to-date [standalone client example](../react-dapp-v2/).
# React dApp (with v2 UniversalProvider + Ethers.js)
🔗 Live dapp demo - https://react-dapp-v2-with-ethers.vercel.app <br />
🔗 Live wallet demo - https://react-wallet.walletconnect.com/ <br />
@ -11,7 +6,7 @@
## Overview
This is an example implementation of a React dApp (generated via `create-react-app`) using the v2 [`EthereumProvider`](https://docs.walletconnect.com/2.0/quick-start/dapps/ethereum-provider) together with [`Ethers.js`](https://docs.ethers.io/v5/) to:
This is an example implementation of a React dApp (generated via `create-react-app`) using the v2 [`UniversalProvider`](https://github.com/WalletConnect/walletconnect-monorepo/tree/v2.0/providers/universal-provider) together with [`Ethers.js`](https://docs.ethers.io/v5/) to:
- handle pairings
- manage sessions
@ -33,9 +28,8 @@ cp .env.local.example .env.local
Your `.env.local` now contains the following environment variables:
- `REACT_APP_PROJECT_ID` (placeholder) - You can generate your own ProjectId at https://cloud.walletconnect.com
- `REACT_APP_INFURA_ID` (placeholder) - You can generate your own Infura ID via https://infura.io/
- `REACT_APP_RELAY_URL` (already set)
- `NEXT_PUBLIC_PROJECT_ID` (placeholder) - You can generate your own ProjectId at https://cloud.walletconnect.com
- `NEXT_PUBLIC_RELAY_URL` (already set)
## Develop

View File

@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@ -0,0 +1,16 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
distDir: "build",
webpack(config) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
};
return config;
},
};
module.exports = nextConfig;

View File

@ -11,10 +11,10 @@
"author": "WalletConnect, Inc. <walletconnect.com>",
"license": "MIT",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prettier": "prettier --check '**/*.{js,ts,jsx,tsx}'"
},
"repository": {
@ -29,11 +29,11 @@
},
"dependencies": {
"@ethereumjs/tx": "^3.5.0",
"@walletconnect/client": "2.0.0-beta.26",
"@walletconnect/ethereum-provider": "2.0.0-beta.26",
"@walletconnect/encoding": "^1.0.1",
"@walletconnect/qrcode-modal": "^1.7.1",
"@walletconnect/types": "2.0.0-beta.26",
"@walletconnect/utils": "2.0.0-beta.26",
"@walletconnect/types": "^2.1.1",
"@walletconnect/universal-provider": "^2.1.1",
"@walletconnect/utils": "^2.1.1",
"axios": "^0.21.1",
"blockies-ts": "^1.0.0",
"caip-api": "^2.0.0-beta.1",
@ -43,6 +43,7 @@
"ethers": "^5.3.0",
"prop-types": "^15.7.2",
"qr-image": "^3.2.0",
"next": "12.2.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "^4.0.3",
@ -51,6 +52,7 @@
"web-vitals": "^0.2.4"
},
"devDependencies": {
"@babel/preset-env": "^7.19.4",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
@ -61,8 +63,8 @@
"@types/pino": "^7.0.5",
"@types/prop-types": "^15.7.4",
"@types/qr-image": "^3.2.5",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react": "18.0.15",
"@types/react-dom": "18.0.6",
"@types/styled-components": "^5.1.21",
"prettier": "^2.5.1"
},
@ -72,16 +74,9 @@
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
"browserslist": [
">0.2%",
"not dead",
"not op_mini all"
]
}

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,6 +1,5 @@
import * as React from "react";
import styled from "styled-components";
import logo from "../assets/walletconnect.png";
const SBannerWrapper = styled.div`
display: flex;
@ -11,7 +10,7 @@ const SBannerWrapper = styled.div`
const SBanner = styled.div`
width: 275px;
height: 45px;
background: url(${logo}) no-repeat;
background: url(/assets/walletconnect.png) no-repeat;
background-size: cover;
background-position: center;
`;

View File

@ -50,7 +50,7 @@ const SActiveSession = styled(SActiveAccount as any)`
interface HeaderProps {
ping: () => Promise<void>;
disconnect: () => Promise<void>;
session: SessionTypes.Created | undefined;
session: SessionTypes.Struct | undefined;
}
const Header = (props: HeaderProps) => {

View File

@ -6,7 +6,7 @@ import { PairingTypes } from "@walletconnect/types";
import Peer from "./Peer";
interface PairingProps {
pairing: PairingTypes.Settled;
pairing: PairingTypes.Struct;
onClick?: any;
}
@ -16,14 +16,12 @@ const SPairingContainer = styled.div`
`;
const Pairing = (props: PairingProps) => {
const {
state: { metadata },
} = props.pairing;
const { peerMetadata } = props.pairing;
return (
<SPairingContainer onClick={props.onClick}>
<div>
{typeof metadata !== "undefined" ? (
<Peer oneLiner metadata={metadata} />
{typeof peerMetadata !== "undefined" ? (
<Peer oneLiner metadata={peerMetadata} />
) : (
<div>{`Unknown`}</div>
)}

View File

@ -1,6 +1,6 @@
import { CoreTypes } from "@walletconnect/types";
import * as React from "react";
import styled from "styled-components";
import { AppMetadata } from "@walletconnect/types";
import { colors, fonts } from "../styles";
const SPeerOneLiner = styled.div`
@ -53,7 +53,7 @@ const SName = styled(SCenter as any)`
interface PeerProps {
oneLiner?: boolean;
metadata: AppMetadata;
metadata: CoreTypes.Metadata;
}
const Peer = (props: PeerProps) =>

View File

@ -19,14 +19,17 @@ export const DEFAULT_TEST_CHAINS = [
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
export const DEFAULT_PROJECT_ID = process.env.REACT_APP_PROJECT_ID;
export const DEFAULT_PROJECT_ID = process.env.NEXT_PUBLIC_PROJECT_ID;
export const DEFAULT_INFURA_ID = process.env.REACT_APP_INFURA_ID;
export const DEFAULT_RELAY_URL = process.env.REACT_APP_RELAY_URL;
export const DEFAULT_RELAY_URL = process.env.NEXT_PUBLIC_RELAY_URL;
export const DEFAULT_EIP155_METHODS = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"];
export enum DEFAULT_EIP_155_EVENTS {
ETH_CHAIN_CHANGED = "chainChanged",
ETH_ACCOUNTS_CHANGED = "accountsChanged",
}
export const DEFAULT_LOGGER = "debug";
export const DEFAULT_APP_METADATA = {

View File

@ -1,7 +1,3 @@
import Client, { CLIENT_EVENTS } from "@walletconnect/client";
import EthereumProvider from "@walletconnect/ethereum-provider";
import { PairingTypes, SessionTypes } from "@walletconnect/types";
import QRCodeModal from "@walletconnect/qrcode-modal";
import {
createContext,
ReactNode,
@ -11,31 +7,31 @@ import {
useMemo,
useState,
} from "react";
import {
DEFAULT_INFURA_ID,
DEFAULT_LOGGER,
DEFAULT_PROJECT_ID,
DEFAULT_RELAY_URL,
} from "../constants";
import QRCodeModal from "@walletconnect/qrcode-modal";
import { apiGetChainNamespace, ChainsMap } from "caip-api";
import UniversalProvider from "@walletconnect/universal-provider";
import { PairingTypes, SessionTypes } from "@walletconnect/types";
import Client from "@walletconnect/sign-client";
import { DEFAULT_LOGGER, DEFAULT_PROJECT_ID, DEFAULT_RELAY_URL } from "../constants";
import { providers, utils } from "ethers";
import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../helpers";
import { apiGetChainNamespace, ChainsMap } from "caip-api";
/**
* Types
*/
interface IContext {
client: Client | undefined;
session: SessionTypes.Created | undefined;
session: SessionTypes.Struct | undefined;
connect: (caipChainId: string, pairing?: { topic: string }) => Promise<void>;
disconnect: () => Promise<void>;
isInitializing: boolean;
chain: string;
pairings: string[];
pairings: PairingTypes.Struct[];
accounts: string[];
balances: AccountBalances;
isFetchingBalances: boolean;
chainData: ChainNamespaces;
onEnable: (chainId: string) => Promise<void>;
web3Provider?: providers.Web3Provider;
}
@ -44,15 +40,18 @@ interface IContext {
*/
export const ClientContext = createContext<IContext>({} as IContext);
/**
* Provider
*/
/**
* Provider
*/
export function ClientContextProvider({ children }: { children: ReactNode | ReactNode[] }) {
const [client, setClient] = useState<Client>();
const [pairings, setPairings] = useState<string[]>([]);
const [session, setSession] = useState<SessionTypes.Created>();
const [pairings, setPairings] = useState<PairingTypes.Struct[]>([]);
const [session, setSession] = useState<SessionTypes.Struct>();
const [ethereumProvider, setEthereumProvider] = useState<EthereumProvider>();
const [ethereumProvider, setEthereumProvider] = useState<UniversalProvider>();
const [web3Provider, setWeb3Provider] = useState<providers.Web3Provider>();
const [isFetchingBalances, setIsFetchingBalances] = useState(false);
@ -96,33 +95,46 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
throw new Error("ethereumProvider is not initialized");
}
await ethereumProvider.disconnect();
resetApp();
}, [ethereumProvider]);
const _subscribeToClientEvents = useCallback(async (_client: Client) => {
const _subscribeToProviderEvents = useCallback(async (_client: UniversalProvider) => {
if (typeof _client === "undefined") {
throw new Error("WalletConnect is not initialized");
}
_client.on(CLIENT_EVENTS.pairing.proposal, async (proposal: PairingTypes.Proposal) => {
const { uri } = proposal.signal.params;
_client.on("display_uri", async (uri: string) => {
console.log("EVENT", "QR Code Modal open");
QRCodeModal.open(uri, () => {
console.log("EVENT", "QR Code Modal closed");
});
});
_client.on(CLIENT_EVENTS.pairing.created, async () => {
setPairings(_client.pairing.topics);
// Subscribe to session ping
_client.on("session_ping", ({ id, topic }: { id: number; topic: string }) => {
console.log("EVENT", "session_ping");
console.log(id, topic);
});
_client.on(CLIENT_EVENTS.session.updated, (updatedSession: SessionTypes.Settled) => {
console.log("EVENT", "session_updated");
setAccounts(updatedSession.state.accounts);
setSession(updatedSession);
// Subscribe to session event
_client.on("session_event", ({ event, chainId }: { event: any; chainId: string }) => {
console.log("EVENT", "session_event");
console.log(event, chainId);
});
_client.on(CLIENT_EVENTS.session.deleted, () => {
// Subscribe to session update
_client.on(
"session_update",
({ topic, session }: { topic: string; session: SessionTypes.Struct }) => {
console.log("EVENT", "session_updated");
setSession(session);
},
);
// Subscribe to session delete
_client.on("session_delete", ({ id, topic }: { id: number; topic: string }) => {
console.log("EVENT", "session_deleted");
console.log(id, topic);
resetApp();
});
}, []);
@ -131,24 +143,30 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
try {
setIsInitializing(true);
const _client = await Client.init({
const provider = await UniversalProvider.init({
projectId: DEFAULT_PROJECT_ID,
logger: DEFAULT_LOGGER,
relayUrl: DEFAULT_RELAY_URL,
projectId: DEFAULT_PROJECT_ID,
});
setClient(_client);
await _subscribeToClientEvents(_client);
setEthereumProvider(provider);
setClient(provider.client);
await _subscribeToProviderEvents(provider);
} catch (err) {
throw err;
} finally {
setIsInitializing(false);
}
}, [_subscribeToClientEvents]);
}, [_subscribeToProviderEvents]);
const onEnable = useCallback(
async (caipChainId: string) => {
if (!client) {
const createWeb3Provider = useCallback((ethereumProvider: UniversalProvider) => {
const web3Provider = new providers.Web3Provider(ethereumProvider);
setWeb3Provider(web3Provider);
}, []);
const connect = useCallback(
async (caipChainId: string, pairing?: { topic: string }) => {
if (!ethereumProvider) {
throw new ReferenceError("WalletConnect Client is not initialized.");
}
@ -164,33 +182,97 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
{},
);
// Create WalletConnect Provider
const ethereumProvider = new EthereumProvider({
chainId: Number(chainId),
rpc: {
infuraId: DEFAULT_INFURA_ID,
custom: customRpcs,
const session = await ethereumProvider.connect({
namespaces: {
eip155: {
methods: [
"eth_sendTransaction",
"eth_signTransaction",
"eth_sign",
"personal_sign",
"eth_signTypedData",
],
chains: [`eip155:${chainId}`],
events: ["chainChanged", "accountsChanged"],
rpcMap: customRpcs,
},
},
client,
pairingTopic: pairing?.topic,
});
const web3Provider = new providers.Web3Provider(ethereumProvider);
console.log(ethereumProvider);
setEthereumProvider(ethereumProvider);
setWeb3Provider(web3Provider);
createWeb3Provider(ethereumProvider);
const _accounts = await ethereumProvider.enable();
const _session = await client.session.get(client.session.topics[0]);
console.log("_accounts", _accounts);
setAccounts(_accounts);
setSession(_session);
setSession(session);
setChain(caipChainId);
QRCodeModal.close();
},
[ethereumProvider, chainData.eip155, createWeb3Provider],
);
const onSessionConnected = useCallback(
async (_session: SessionTypes.Struct) => {
if (!ethereumProvider) {
throw new ReferenceError("EthereumProvider is not initialized.");
}
const allNamespaceAccounts = Object.values(_session.namespaces)
.map(namespace => namespace.accounts)
.flat();
const allNamespaceChains = Object.keys(_session.namespaces);
const chainData = allNamespaceAccounts[0].split(":");
const caipChainId = `${chainData[0]}:${chainData[1]}`;
console.log("restored caipChainId", caipChainId);
setChain(caipChainId);
setSession(_session);
setAccounts(allNamespaceAccounts.map(account => account.split(":")[2]));
console.log("RESTORED", allNamespaceChains, allNamespaceAccounts);
createWeb3Provider(ethereumProvider);
},
[ethereumProvider, createWeb3Provider],
);
const _checkForPersistedSession = useCallback(
async (provider: UniversalProvider) => {
if (typeof provider === "undefined") {
throw new Error("WalletConnect is not initialized");
}
const pairings = provider.client.pairing.getAll({ active: true });
// populates existing pairings to state
setPairings(pairings);
console.log("RESTORED PAIRINGS: ", pairings);
if (typeof session !== "undefined") return;
// populates (the last) existing session to state
if (ethereumProvider?.session) {
const _session = ethereumProvider?.session;
console.log("RESTORED SESSION:", _session);
await onSessionConnected(_session);
return _session;
}
},
[session, ethereumProvider, onSessionConnected],
);
useEffect(() => {
loadChainData();
}, []);
useEffect(() => {
if (!client) {
createClient();
}
}, [client, createClient]);
useEffect(() => {
const fetchBalances = async () => {
if (!web3Provider || !accounts) return;
try {
setIsFetchingBalances(true);
const _balances = await Promise.all(
_accounts.map(async account => {
accounts.map(async account => {
const balance = await web3Provider.getBalance(account);
return {
account,
@ -212,51 +294,22 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
} finally {
setIsFetchingBalances(false);
}
};
QRCodeModal.close();
},
[client, chainData.eip155],
);
const _checkForPersistedSession = useCallback(
async (_client: Client) => {
if (typeof _client === "undefined") {
throw new Error("WalletConnect is not initialized");
}
// populates existing pairings to state
setPairings(_client.pairing.topics);
if (typeof session !== "undefined") return;
// populates existing session to state (assume only the top one)
if (_client.session.topics.length) {
const _session = await _client.session.get(_client.session.topics[0]);
const [namespace, chainId] = _session.state.accounts[0].split(":");
const caipChainId = `${namespace}:${chainId}`;
onEnable(caipChainId);
}
},
[session, onEnable],
);
useEffect(() => {
loadChainData();
}, []);
useEffect(() => {
if (!client) {
createClient();
}
}, [client, createClient]);
fetchBalances();
}, [web3Provider, accounts]);
useEffect(() => {
const getPersistedSession = async () => {
if (client && !hasCheckedPersistedSession) {
await _checkForPersistedSession(client);
setHasCheckedPersistedSession(true);
}
if (!ethereumProvider) return;
await _checkForPersistedSession(ethereumProvider);
setHasCheckedPersistedSession(true);
};
getPersistedSession();
}, [client, _checkForPersistedSession, hasCheckedPersistedSession]);
if (ethereumProvider && chainData && !hasCheckedPersistedSession) {
getPersistedSession();
}
}, [ethereumProvider, chainData, _checkForPersistedSession, hasCheckedPersistedSession]);
const value = useMemo(
() => ({
@ -269,8 +322,8 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
client,
session,
disconnect,
connect,
chainData,
onEnable,
web3Provider,
}),
[
@ -283,8 +336,8 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
client,
session,
disconnect,
connect,
chainData,
onEnable,
web3Provider,
],
);

View File

@ -190,6 +190,7 @@ export function setLocaleStorageTestnetFlag(value: boolean): void {
}
export function getLocalStorageTestnetFlag(): boolean {
if (typeof window === "undefined") return false;
let value = INITIAL_STATE_TESTNET_DEFAULT;
const persisted = window.localStorage.getItem(LOCALSTORAGE_KEY_TESTNET);
if (!persisted) {

View File

@ -1,27 +0,0 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import { createGlobalStyle } from "styled-components";
import { ClientContextProvider } from "./contexts/ClientContext";
import App from "./App";
import { globalStyle } from "./styles";
const GlobalStyle = createGlobalStyle`
${globalStyle}
`;
declare global {
// tslint:disable-next-line
interface Window {
blockies: any;
}
}
ReactDOM.render(
<>
<GlobalStyle />
<ClientContextProvider>
<App />
</ClientContextProvider>
</>,
document.getElementById("root"),
);

View File

@ -9,7 +9,7 @@ import { STable } from "../components/shared";
import { SModalContainer, SModalTitle } from "./shared";
interface PairingModalProps {
pairings: PairingTypes.Settled[];
pairings: PairingTypes.Struct[];
connect: (pairing?: { topic: string }) => Promise<void>;
}

View File

@ -0,0 +1,3 @@
export default function FourOhFour() {
return <h1>404 Page Not Found</h1>;
}

View File

@ -0,0 +1,22 @@
import type { AppProps } from "next/app";
import { createGlobalStyle } from "styled-components";
import { ClientContextProvider } from "../contexts/ClientContext";
import { globalStyle } from "../styles";
const GlobalStyle = createGlobalStyle`
${globalStyle}
`;
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<GlobalStyle />
<ClientContextProvider>
<Component {...pageProps} />
</ClientContextProvider>
</>
);
}
export default MyApp;

View File

@ -0,0 +1,3 @@
export default function Error() {
return <div>An error as occured</div>;
}

View File

@ -1,26 +1,27 @@
import type { NextPage } from "next";
import React, { useState } from "react";
import { version } from "@walletconnect/client/package.json";
import { version } from "@walletconnect/universal-provider/package.json";
import * as encoding from "@walletconnect/encoding";
import { BigNumber, utils } from "ethers";
import { TypedDataField } from "@ethersproject/abstract-signer";
import { Transaction } from "@ethereumjs/tx";
import Banner from "./components/Banner";
import Blockchain from "./components/Blockchain";
import Column from "./components/Column";
import Header from "./components/Header";
import Modal from "./components/Modal";
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants";
import Banner from "./../components/Banner";
import Blockchain from "./../components/Blockchain";
import Column from "./../components/Column";
import Header from "./../components/Header";
import Modal from "./../components/Modal";
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./../constants";
import {
AccountAction,
eip712,
formatTestTransaction,
getLocalStorageTestnetFlag,
setLocaleStorageTestnetFlag,
} from "./helpers";
import Toggle from "./components/Toggle";
import RequestModal from "./modals/RequestModal";
import PingModal from "./modals/PingModal";
} from "./../helpers";
import Toggle from "./../components/Toggle";
import RequestModal from "./../modals/RequestModal";
import PingModal from "./../modals/PingModal";
import {
SAccounts,
SAccountsContainer,
@ -29,8 +30,8 @@ import {
SLanding,
SLayout,
SToggleContainer,
} from "./components/app";
import { useWalletConnectClient } from "./contexts/ClientContext";
} from "./../components/app";
import { useWalletConnectClient } from "./../contexts/ClientContext";
interface IFormattedRpcResponse {
method: string;
@ -39,7 +40,7 @@ interface IFormattedRpcResponse {
result: string;
}
export default function App() {
const Home: NextPage = () => {
const [isTestnet, setIsTestnet] = useState(getLocalStorageTestnetFlag());
const [isRpcRequestPending, setIsRpcRequestPending] = useState(false);
const [rpcResult, setRpcResult] = useState<IFormattedRpcResponse | null>();
@ -61,7 +62,7 @@ export default function App() {
chainData,
isFetchingBalances,
isInitializing,
onEnable,
connect,
web3Provider,
} = useWalletConnectClient();
@ -73,10 +74,13 @@ export default function App() {
throw new Error("WalletConnect Client is not initialized");
}
if (typeof session === "undefined") {
throw new Error("Session is not connected");
}
try {
setIsRpcRequestPending(true);
const _session = await client.session.get(client.session.topics[0]);
await client.session.ping(_session.topic);
await client.ping({ topic: session.topic });
setRpcResult({
address: "",
method: "ping",
@ -274,16 +278,6 @@ export default function App() {
<Banner />
<h6>
<span>{`Using v${version || "2.0.0-beta"}`}</span>
<sup>
(
<a
style={{ textDecoration: "underline" }}
href="https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2-with-ethers"
>
outdated
</a>{" "}
)
</sup>
</h6>
<SButtonContainer>
<h6>Select an Ethereum chain:</h6>
@ -292,7 +286,7 @@ export default function App() {
<Toggle active={isTestnet} onClick={toggleTestnets} />
</SToggleContainer>
{chainOptions.map(chainId => (
<Blockchain key={chainId} chainId={chainId} chainData={chainData} onClick={onEnable} />
<Blockchain key={chainId} chainId={chainId} chainData={chainData} onClick={connect} />
))}
</SButtonContainer>
</SLanding>
@ -330,4 +324,6 @@ export default function App() {
</Modal>
</SLayout>
);
}
};
export default Home;

View File

@ -1,26 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "preserve",
"incremental": true
},
"include": [
"src"
]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,3 @@
REACT_APP_PROJECT_ID=39bc93...
REACT_APP_INFURA_ID=5dc0df...
REACT_APP_RELAY_URL=wss://relay.dev.walletconnect.com
NEXT_PUBLIC_PROJECT_ID=39bc93c...
NEXT_PUBLIC_RELAY_URL=wss://relay.walletconnect.com

View File

@ -1,9 +1,4 @@
# React dApp (with v2 EthereumProvider + web3.js)
> **⚠️ This provider-based example is currently reliant on the deprecated `2.0.0-beta.26` SDK. ⚠️**
>
> This example will be updated to be compatible with the latest v2 SDK (`2.0.0-beta.100+`) in due time.
> In the meantime, please use the up-to-date [standalone client example](../react-dapp-v2/).
# React dApp (with v2 UniversalProvider + web3.js)
🔗 Live dapp demo - https://react-dapp-v2-with-web3js.vercel.app <br />
🔗 Live wallet demo - https://react-wallet.walletconnect.com/ <br />
@ -11,7 +6,7 @@
## Overview
This is an example implementation of a React dApp (generated via `create-react-app`) using the v2 [`EthereumProvider`](https://docs.walletconnect.com/2.0/quick-start/dapps/ethereum-provider) together with [`web3.js`](https://web3js.readthedocs.io/) to:
This is an example implementation of a React dApp (generated via `create-react-app`) using the v2 [`UniversalProvider`](https://github.com/WalletConnect/walletconnect-monorepo/tree/v2.0/providers/universal-provider) together with [`web3.js`](https://web3js.readthedocs.io/) to:
- handle pairings
- manage sessions
@ -33,9 +28,8 @@ cp .env.local.example .env.local
Your `.env.local` now contains the following environment variables:
- `REACT_APP_PROJECT_ID` (placeholder) - You can generate your own ProjectId at https://cloud.walletconnect.com
- `REACT_APP_INFURA_ID` (placeholder) - You can generate your own Infura ID via https://infura.io/
- `REACT_APP_RELAY_URL` (already set)
- `NEXT_PUBLIC_PROJECT_ID` (placeholder) - You can generate your own ProjectId at https://cloud.walletconnect.com
- `NEXT_PUBLIC_RELAY_URL` (already set)
## Develop

View File

@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@ -0,0 +1,16 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
distDir: "build",
webpack(config) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
};
return config;
},
};
module.exports = nextConfig;

View File

@ -11,10 +11,10 @@
"author": "WalletConnect, Inc. <walletconnect.com>",
"license": "MIT",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prettier": "prettier --check '**/*.{js,ts,jsx,tsx}'"
},
"repository": {
@ -29,11 +29,11 @@
},
"dependencies": {
"@ethereumjs/tx": "^3.5.0",
"@walletconnect/client": "2.0.0-beta.26",
"@walletconnect/ethereum-provider": "2.0.0-beta.26",
"@walletconnect/encoding": "^1.0.1",
"@walletconnect/universal-provider": "2.1.1",
"@walletconnect/qrcode-modal": "^1.7.1",
"@walletconnect/types": "2.0.0-beta.26",
"@walletconnect/utils": "2.0.0-beta.26",
"@walletconnect/types": "2.1.1",
"@walletconnect/utils": "2.1.1",
"axios": "^0.21.1",
"blockies-ts": "^1.0.0",
"caip-api": "^2.0.0-beta.1",
@ -43,6 +43,7 @@
"ethers": "^5.3.0",
"prop-types": "^15.7.2",
"qr-image": "^3.2.0",
"next": "12.2.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "^4.0.3",
@ -52,6 +53,7 @@
"web3": "^1.7.0"
},
"devDependencies": {
"@babel/preset-env": "^7.19.4",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
@ -62,8 +64,8 @@
"@types/pino": "^7.0.5",
"@types/prop-types": "^15.7.4",
"@types/qr-image": "^3.2.5",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react": "18.0.15",
"@types/react-dom": "18.0.6",
"@types/styled-components": "^5.1.21",
"prettier": "^2.5.1"
},
@ -73,16 +75,9 @@
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
"browserslist": [
">0.2%",
"not dead",
"not op_mini all"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,6 +1,5 @@
import * as React from "react";
import styled from "styled-components";
import logo from "../assets/walletconnect.png";
const SBannerWrapper = styled.div`
display: flex;
@ -11,7 +10,7 @@ const SBannerWrapper = styled.div`
const SBanner = styled.div`
width: 275px;
height: 45px;
background: url(${logo}) no-repeat;
background: url(/assets/walletconnect.png) no-repeat;
background-size: cover;
background-position: center;
`;

View File

@ -50,7 +50,7 @@ const SActiveSession = styled(SActiveAccount as any)`
interface HeaderProps {
ping: () => Promise<void>;
disconnect: () => Promise<void>;
session: SessionTypes.Created | undefined;
session: SessionTypes.Struct | undefined;
}
const Header = (props: HeaderProps) => {

View File

@ -6,7 +6,7 @@ import { PairingTypes } from "@walletconnect/types";
import Peer from "./Peer";
interface PairingProps {
pairing: PairingTypes.Settled;
pairing: PairingTypes.Struct;
onClick?: any;
}
@ -16,14 +16,12 @@ const SPairingContainer = styled.div`
`;
const Pairing = (props: PairingProps) => {
const {
state: { metadata },
} = props.pairing;
const { peerMetadata } = props.pairing;
return (
<SPairingContainer onClick={props.onClick}>
<div>
{typeof metadata !== "undefined" ? (
<Peer oneLiner metadata={metadata} />
{typeof peerMetadata !== "undefined" ? (
<Peer oneLiner metadata={peerMetadata} />
) : (
<div>{`Unknown`}</div>
)}

View File

@ -1,6 +1,6 @@
import * as React from "react";
import styled from "styled-components";
import { AppMetadata } from "@walletconnect/types";
import { CoreTypes } from "@walletconnect/types";
import { colors, fonts } from "../styles";
const SPeerOneLiner = styled.div`
@ -53,7 +53,7 @@ const SName = styled(SCenter as any)`
interface PeerProps {
oneLiner?: boolean;
metadata: AppMetadata;
metadata: CoreTypes.Metadata;
}
const Peer = (props: PeerProps) =>

View File

@ -19,11 +19,9 @@ export const DEFAULT_TEST_CHAINS = [
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
export const DEFAULT_PROJECT_ID = process.env.REACT_APP_PROJECT_ID;
export const DEFAULT_PROJECT_ID = process.env.NEXT_PUBLIC_PROJECT_ID;
export const DEFAULT_INFURA_ID = process.env.REACT_APP_INFURA_ID;
export const DEFAULT_RELAY_URL = process.env.REACT_APP_RELAY_URL;
export const DEFAULT_RELAY_URL = process.env.NEXT_PUBLIC_RELAY_URL;
export const DEFAULT_EIP155_METHODS = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"];

View File

@ -1,7 +1,3 @@
import Client, { CLIENT_EVENTS } from "@walletconnect/client";
import EthereumProvider from "@walletconnect/ethereum-provider";
import { PairingTypes, SessionTypes } from "@walletconnect/types";
import QRCodeModal from "@walletconnect/qrcode-modal";
import {
createContext,
ReactNode,
@ -11,33 +7,31 @@ import {
useMemo,
useState,
} from "react";
import Web3 from "web3";
import QRCodeModal from "@walletconnect/qrcode-modal";
import { apiGetChainNamespace, ChainsMap } from "caip-api";
import {
DEFAULT_INFURA_ID,
DEFAULT_LOGGER,
DEFAULT_PROJECT_ID,
DEFAULT_RELAY_URL,
} from "../constants";
import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../helpers";
import UniversalProvider from "@walletconnect/universal-provider";
import Client from "@walletconnect/sign-client";
import Web3 from "web3";
import { DEFAULT_LOGGER, DEFAULT_PROJECT_ID, DEFAULT_RELAY_URL } from "../constants";
import { utils } from "ethers";
import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../helpers";
import { PairingTypes, SessionTypes } from "@walletconnect/types";
/**
* Types
*/
interface IContext {
client: Client | undefined;
session: SessionTypes.Created | undefined;
session: SessionTypes.Struct | undefined;
connect: (caipChainId: string, pairing?: { topic: string }) => Promise<void>;
disconnect: () => Promise<void>;
isInitializing: boolean;
chain: string;
pairings: string[];
pairings: PairingTypes.Struct[];
accounts: string[];
balances: AccountBalances;
isFetchingBalances: boolean;
chainData: ChainNamespaces;
onEnable: (chainId: string) => Promise<void>;
web3Provider?: Web3;
}
@ -51,10 +45,10 @@ export const ClientContext = createContext<IContext>({} as IContext);
*/
export function ClientContextProvider({ children }: { children: ReactNode | ReactNode[] }) {
const [client, setClient] = useState<Client>();
const [pairings, setPairings] = useState<string[]>([]);
const [session, setSession] = useState<SessionTypes.Created>();
const [pairings, setPairings] = useState<PairingTypes.Struct[]>([]);
const [session, setSession] = useState<SessionTypes.Struct>();
const [ethereumProvider, setEthereumProvider] = useState<EthereumProvider>();
const [ethereumProvider, setEthereumProvider] = useState<UniversalProvider>();
const [web3Provider, setWeb3Provider] = useState<Web3>();
const [isFetchingBalances, setIsFetchingBalances] = useState(false);
@ -98,33 +92,46 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
throw new Error("ethereumProvider is not initialized");
}
await ethereumProvider.disconnect();
resetApp();
}, [ethereumProvider]);
const _subscribeToClientEvents = useCallback(async (_client: Client) => {
const _subscribeToProviderEvents = useCallback(async (_client: UniversalProvider) => {
if (typeof _client === "undefined") {
throw new Error("WalletConnect is not initialized");
}
_client.on(CLIENT_EVENTS.pairing.proposal, async (proposal: PairingTypes.Proposal) => {
const { uri } = proposal.signal.params;
_client.on("display_uri", async (uri: string) => {
console.log("EVENT", "QR Code Modal open");
QRCodeModal.open(uri, () => {
console.log("EVENT", "QR Code Modal closed");
});
});
_client.on(CLIENT_EVENTS.pairing.created, async () => {
setPairings(_client.pairing.topics);
// Subscribe to session ping
_client.on("session_ping", ({ id, topic }: { id: number; topic: string }) => {
console.log("EVENT", "session_ping");
console.log(id, topic);
});
_client.on(CLIENT_EVENTS.session.updated, (updatedSession: SessionTypes.Settled) => {
console.log("EVENT", "session_updated");
setAccounts(updatedSession.state.accounts);
setSession(updatedSession);
// Subscribe to session event
_client.on("session_event", ({ event, chainId }: { event: any; chainId: string }) => {
console.log("EVENT", "session_event");
console.log(event, chainId);
});
_client.on(CLIENT_EVENTS.session.deleted, () => {
// Subscribe to session update
_client.on(
"session_update",
({ topic, session }: { topic: string; session: SessionTypes.Struct }) => {
console.log("EVENT", "session_updated");
setSession(session);
},
);
// Subscribe to session delete
_client.on("session_delete", ({ id, topic }: { id: number; topic: string }) => {
console.log("EVENT", "session_deleted");
console.log(id, topic);
resetApp();
});
}, []);
@ -133,24 +140,30 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
try {
setIsInitializing(true);
const _client = await Client.init({
const provider = await UniversalProvider.init({
projectId: DEFAULT_PROJECT_ID,
logger: DEFAULT_LOGGER,
relayUrl: DEFAULT_RELAY_URL,
projectId: DEFAULT_PROJECT_ID,
});
setClient(_client);
await _subscribeToClientEvents(_client);
setEthereumProvider(provider);
setClient(provider.client);
await _subscribeToProviderEvents(provider);
} catch (err) {
throw err;
} finally {
setIsInitializing(false);
}
}, [_subscribeToClientEvents]);
}, [_subscribeToProviderEvents]);
const onEnable = useCallback(
async (caipChainId: string) => {
if (!client) {
const createWeb3Provider = useCallback((ethereumProvider: UniversalProvider) => {
const web3Provider = new Web3(ethereumProvider);
setWeb3Provider(web3Provider);
}, []);
const connect = useCallback(
async (caipChainId: string, pairing?: { topic: string }) => {
if (!ethereumProvider) {
throw new ReferenceError("WalletConnect Client is not initialized.");
}
@ -166,35 +179,97 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
{},
);
// Create WalletConnect Provider
const ethereumProvider = new EthereumProvider({
chainId: Number(chainId),
rpc: {
infuraId: DEFAULT_INFURA_ID,
custom: customRpcs,
const session = await ethereumProvider.connect({
namespaces: {
eip155: {
methods: [
"eth_sendTransaction",
"eth_signTransaction",
"eth_sign",
"personal_sign",
"eth_signTypedData",
],
chains: [`eip155:${chainId}`],
events: ["chainChanged", "accountsChanged"],
rpcMap: customRpcs,
},
},
client,
pairingTopic: pairing?.topic,
});
const web3Provider = new Web3(ethereumProvider);
console.log(ethereumProvider);
console.log(web3Provider);
setEthereumProvider(ethereumProvider);
setWeb3Provider(web3Provider);
createWeb3Provider(ethereumProvider);
const _accounts = await ethereumProvider.enable();
const _session = await client.session.get(client.session.topics[0]);
console.log("_accounts", _accounts);
setAccounts(_accounts);
setSession(_session);
setSession(session);
setChain(caipChainId);
QRCodeModal.close();
},
[ethereumProvider, chainData.eip155, createWeb3Provider],
);
const onSessionConnected = useCallback(
async (_session: SessionTypes.Struct) => {
if (!ethereumProvider) {
throw new ReferenceError("EthereumProvider is not initialized.");
}
const allNamespaceAccounts = Object.values(_session.namespaces)
.map(namespace => namespace.accounts)
.flat();
const allNamespaceChains = Object.keys(_session.namespaces);
const chainData = allNamespaceAccounts[0].split(":");
const caipChainId = `${chainData[0]}:${chainData[1]}`;
console.log("restored caipChainId", caipChainId);
setChain(caipChainId);
setSession(_session);
setAccounts(allNamespaceAccounts.map(account => account.split(":")[2]));
console.log("RESTORED", allNamespaceChains, allNamespaceAccounts);
createWeb3Provider(ethereumProvider);
},
[ethereumProvider, createWeb3Provider],
);
const _checkForPersistedSession = useCallback(
async (provider: UniversalProvider) => {
if (typeof provider === "undefined") {
throw new Error("WalletConnect is not initialized");
}
const pairings = provider.client.pairing.getAll({ active: true });
// populates existing pairings to state
setPairings(pairings);
console.log("RESTORED PAIRINGS: ", pairings);
if (typeof session !== "undefined") return;
// populates (the last) existing session to state
if (ethereumProvider?.session) {
const _session = ethereumProvider?.session;
console.log("RESTORED SESSION:", _session);
await onSessionConnected(_session);
return _session;
}
},
[session, ethereumProvider, onSessionConnected],
);
useEffect(() => {
loadChainData();
}, []);
useEffect(() => {
if (!client) {
createClient();
}
}, [client, createClient]);
useEffect(() => {
const fetchBalances = async () => {
if (!web3Provider || !accounts) return;
try {
setIsFetchingBalances(true);
const _balances = await Promise.all(
_accounts.map(async account => {
accounts.map(async account => {
const balance = await web3Provider.eth.getBalance(account);
return {
account,
@ -216,51 +291,22 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
} finally {
setIsFetchingBalances(false);
}
};
QRCodeModal.close();
},
[client, chainData.eip155],
);
const _checkForPersistedSession = useCallback(
async (_client: Client) => {
if (typeof _client === "undefined") {
throw new Error("WalletConnect is not initialized");
}
// populates existing pairings to state
setPairings(_client.pairing.topics);
if (typeof session !== "undefined") return;
// populates existing session to state (assume only the top one)
if (_client.session.topics.length) {
const _session = await _client.session.get(_client.session.topics[0]);
const [namespace, chainId] = _session.state.accounts[0].split(":");
const caipChainId = `${namespace}:${chainId}`;
onEnable(caipChainId);
}
},
[session, onEnable],
);
useEffect(() => {
loadChainData();
}, []);
useEffect(() => {
if (!client) {
createClient();
}
}, [client, createClient]);
fetchBalances();
}, [web3Provider, accounts]);
useEffect(() => {
const getPersistedSession = async () => {
if (client && !hasCheckedPersistedSession) {
await _checkForPersistedSession(client);
setHasCheckedPersistedSession(true);
}
if (!ethereumProvider) return;
await _checkForPersistedSession(ethereumProvider);
setHasCheckedPersistedSession(true);
};
getPersistedSession();
}, [client, _checkForPersistedSession, hasCheckedPersistedSession]);
if (ethereumProvider && chainData && !hasCheckedPersistedSession) {
getPersistedSession();
}
}, [ethereumProvider, chainData, _checkForPersistedSession, hasCheckedPersistedSession]);
const value = useMemo(
() => ({
@ -273,8 +319,8 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
client,
session,
disconnect,
connect,
chainData,
onEnable,
web3Provider,
}),
[
@ -287,8 +333,8 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
client,
session,
disconnect,
connect,
chainData,
onEnable,
web3Provider,
],
);

View File

@ -190,6 +190,7 @@ export function setLocaleStorageTestnetFlag(value: boolean): void {
}
export function getLocalStorageTestnetFlag(): boolean {
if (typeof window === "undefined") return false;
let value = INITIAL_STATE_TESTNET_DEFAULT;
const persisted = window.localStorage.getItem(LOCALSTORAGE_KEY_TESTNET);
if (!persisted) {

View File

@ -1,27 +0,0 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import { createGlobalStyle } from "styled-components";
import { ClientContextProvider } from "./contexts/ClientContext";
import App from "./App";
import { globalStyle } from "./styles";
const GlobalStyle = createGlobalStyle`
${globalStyle}
`;
declare global {
// tslint:disable-next-line
interface Window {
blockies: any;
}
}
ReactDOM.render(
<>
<GlobalStyle />
<ClientContextProvider>
<App />
</ClientContextProvider>
</>,
document.getElementById("root"),
);

View File

@ -9,7 +9,7 @@ import { STable } from "../components/shared";
import { SModalContainer, SModalTitle } from "./shared";
interface PairingModalProps {
pairings: PairingTypes.Settled[];
pairings: PairingTypes.Struct[];
connect: (pairing?: { topic: string }) => Promise<void>;
}

View File

@ -0,0 +1,3 @@
export default function FourOhFour() {
return <h1>404 Page Not Found</h1>;
}

View File

@ -0,0 +1,22 @@
import type { AppProps } from "next/app";
import { createGlobalStyle } from "styled-components";
import { ClientContextProvider } from "../contexts/ClientContext";
import { globalStyle } from "../styles";
const GlobalStyle = createGlobalStyle`
${globalStyle}
`;
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<GlobalStyle />
<ClientContextProvider>
<Component {...pageProps} />
</ClientContextProvider>
</>
);
}
export default MyApp;

View File

@ -0,0 +1,3 @@
export default function Error() {
return <div>An error as occured</div>;
}

View File

@ -1,25 +1,25 @@
import React, { useState } from "react";
import { version } from "@walletconnect/client/package.json";
import { version } from "@walletconnect/universal-provider/package.json";
import * as encoding from "@walletconnect/encoding";
import { utils } from "ethers";
import { TypedDataField } from "@ethersproject/abstract-signer";
import { Transaction } from "@ethereumjs/tx";
import Banner from "./components/Banner";
import Blockchain from "./components/Blockchain";
import Column from "./components/Column";
import Header from "./components/Header";
import Modal from "./components/Modal";
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants";
import Banner from "./../components/Banner";
import Blockchain from "./../components/Blockchain";
import Column from "./../components/Column";
import Header from "./../components/Header";
import Modal from "./../components/Modal";
import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./../constants";
import {
AccountAction,
eip712,
getLocalStorageTestnetFlag,
setLocaleStorageTestnetFlag,
} from "./helpers";
import Toggle from "./components/Toggle";
import RequestModal from "./modals/RequestModal";
import PingModal from "./modals/PingModal";
} from "./../helpers";
import Toggle from "./../components/Toggle";
import RequestModal from "./../modals/RequestModal";
import PingModal from "./../modals/PingModal";
import {
SAccounts,
SAccountsContainer,
@ -28,8 +28,8 @@ import {
SLanding,
SLayout,
SToggleContainer,
} from "./components/app";
import { useWalletConnectClient } from "./contexts/ClientContext";
} from "./../components/app";
import { useWalletConnectClient } from "./../contexts/ClientContext";
interface IFormattedRpcResponse {
method: string;
@ -60,7 +60,7 @@ export default function App() {
chainData,
isFetchingBalances,
isInitializing,
onEnable,
connect,
web3Provider,
} = useWalletConnectClient();
@ -72,10 +72,13 @@ export default function App() {
throw new Error("WalletConnect Client is not initialized");
}
if (typeof session === "undefined") {
throw new Error("Session is not connected");
}
try {
setIsRpcRequestPending(true);
const _session = await client.session.get(client.session.topics[0]);
await client.session.ping(_session.topic);
await client.ping({ topic: session.topic });
setRpcResult({
address: "",
method: "ping",
@ -124,7 +127,6 @@ export default function App() {
}
const [address] = await web3Provider.eth.getAccounts();
const tx = {
from: address,
to: address,
@ -283,16 +285,6 @@ export default function App() {
<Banner />
<h6>
<span>{`Using v${version || "2.0.0-beta"}`}</span>
<sup>
(
<a
style={{ textDecoration: "underline" }}
href="https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2-with-web3js"
>
outdated
</a>{" "}
)
</sup>
</h6>
<SButtonContainer>
<h6>Select an Ethereum chain:</h6>
@ -301,7 +293,7 @@ export default function App() {
<Toggle active={isTestnet} onClick={toggleTestnets} />
</SToggleContainer>
{chainOptions.map(chainId => (
<Blockchain key={chainId} chainId={chainId} chainData={chainData} onClick={onEnable} />
<Blockchain key={chainId} chainId={chainId} chainData={chainData} onClick={connect} />
))}
</SButtonContainer>
</SLanding>

View File

@ -1,26 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "preserve",
"incremental": true
},
"include": [
"src"
]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

File diff suppressed because it is too large Load Diff