feat: cosmos example dapp (#102)
* feat: updates cosmos example dapp to latest "@walletconnect" * refactor: uses default methods from `constants` * chore: updates dependencies
This commit is contained in:
parent
a959f1e766
commit
0fd85d199a
5
dapps/react-dapp-v2-cosmos-provider/next-env.d.ts
vendored
Normal file
5
dapps/react-dapp-v2-cosmos-provider/next-env.d.ts
vendored
Normal 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.
|
16
dapps/react-dapp-v2-cosmos-provider/next.config.js
Normal file
16
dapps/react-dapp-v2-cosmos-provider/next.config.js
Normal 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;
|
@ -11,10 +11,10 @@
|
|||||||
"author": "WalletConnect, Inc. <walletconnect.com>",
|
"author": "WalletConnect, Inc. <walletconnect.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"dev": "next dev",
|
||||||
"build": "react-scripts build",
|
"build": "next build",
|
||||||
"test": "react-scripts test",
|
"start": "next start",
|
||||||
"eject": "react-scripts eject",
|
"lint": "next lint",
|
||||||
"prettier": "prettier --check '**/*.{js,ts,jsx,tsx}'"
|
"prettier": "prettier --check '**/*.{js,ts,jsx,tsx}'"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -28,11 +28,8 @@
|
|||||||
"react-error-overlay": "6.0.9"
|
"react-error-overlay": "6.0.9"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@walletconnect/client": "2.0.0-beta.26",
|
"@walletconnect/types": "2.3.0",
|
||||||
"@walletconnect/cosmos-provider": "2.0.0-beta.26",
|
"@walletconnect/utils": "2.3.0",
|
||||||
"@walletconnect/qrcode-modal": "^1.7.1",
|
|
||||||
"@walletconnect/types": "2.0.0-beta.26",
|
|
||||||
"@walletconnect/utils": "2.0.0-beta.26",
|
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"blockies-ts": "^1.0.0",
|
"blockies-ts": "^1.0.0",
|
||||||
"caip-api": "^2.0.0-beta.1",
|
"caip-api": "^2.0.0-beta.1",
|
||||||
@ -47,7 +44,12 @@
|
|||||||
"react-scripts": "^4.0.3",
|
"react-scripts": "^4.0.3",
|
||||||
"styled-components": "^5.2.0",
|
"styled-components": "^5.2.0",
|
||||||
"typescript": "^4.3.2",
|
"typescript": "^4.3.2",
|
||||||
"web-vitals": "^0.2.4"
|
"web-vitals": "^0.2.4",
|
||||||
|
"next": "12.2.4",
|
||||||
|
"@ethereumjs/tx": "^3.5.0",
|
||||||
|
"@walletconnect/encoding": "^1.0.1",
|
||||||
|
"@walletconnect/universal-provider": "2.3.0",
|
||||||
|
"@web3modal/standalone": "^2.0.0-beta.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@testing-library/jest-dom": "^5.16.1",
|
"@testing-library/jest-dom": "^5.16.1",
|
||||||
@ -60,10 +62,11 @@
|
|||||||
"@types/pino": "^7.0.5",
|
"@types/pino": "^7.0.5",
|
||||||
"@types/prop-types": "^15.7.4",
|
"@types/prop-types": "^15.7.4",
|
||||||
"@types/qr-image": "^3.2.5",
|
"@types/qr-image": "^3.2.5",
|
||||||
"@types/react": "^17.0.38",
|
"@types/react": "18.0.15",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "18.0.6",
|
||||||
"@types/styled-components": "^5.1.21",
|
"@types/styled-components": "^5.1.21",
|
||||||
"prettier": "^2.5.1"
|
"prettier": "^2.5.1",
|
||||||
|
"eslint-config-next": "12.2.4"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
@ -5,8 +5,6 @@ import Icon from "./Icon";
|
|||||||
|
|
||||||
import { AssetData } from "../helpers";
|
import { AssetData } from "../helpers";
|
||||||
|
|
||||||
import eth from "../assets/eth.svg";
|
|
||||||
import erc20 from "../assets/erc20.svg";
|
|
||||||
import { getChainMetadata } from "../chains";
|
import { getChainMetadata } from "../chains";
|
||||||
|
|
||||||
const xdai = getChainMetadata("eip155:100").logo;
|
const xdai = getChainMetadata("eip155:100").logo;
|
||||||
@ -39,17 +37,17 @@ const SAssetBalance = styled.div`
|
|||||||
function getAssetIcon(asset: AssetData): JSX.Element {
|
function getAssetIcon(asset: AssetData): JSX.Element {
|
||||||
if (!!asset.contractAddress) {
|
if (!!asset.contractAddress) {
|
||||||
const src = `https://raw.githubusercontent.com/TrustWallet/tokens/master/tokens/${asset.contractAddress.toLowerCase()}.png`;
|
const src = `https://raw.githubusercontent.com/TrustWallet/tokens/master/tokens/${asset.contractAddress.toLowerCase()}.png`;
|
||||||
return <Icon src={src} fallback={erc20} />;
|
return <Icon src={src} fallback={"/assets/erc20.svg"} />;
|
||||||
}
|
}
|
||||||
switch (asset.symbol.toLowerCase()) {
|
switch (asset.symbol.toLowerCase()) {
|
||||||
case "eth":
|
case "eth":
|
||||||
return <Icon src={eth} />;
|
return <Icon src={"assets/eth.svg"} />;
|
||||||
case "xdai":
|
case "xdai":
|
||||||
return <Icon src={xdai} />;
|
return <Icon src={xdai} />;
|
||||||
case "matic":
|
case "matic":
|
||||||
return <Icon src={matic} />;
|
return <Icon src={matic} />;
|
||||||
default:
|
default:
|
||||||
return <Icon src={erc20} />;
|
return <Icon src={"/assets/erc20.svg"} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import logo from "../assets/walletconnect.png";
|
|
||||||
|
|
||||||
const SBannerWrapper = styled.div`
|
const SBannerWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -11,7 +10,7 @@ const SBannerWrapper = styled.div`
|
|||||||
const SBanner = styled.div`
|
const SBanner = styled.div`
|
||||||
width: 275px;
|
width: 275px;
|
||||||
height: 45px;
|
height: 45px;
|
||||||
background: url(${logo}) no-repeat;
|
background: url(/assets/walletconnect.png) no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
`;
|
`;
|
||||||
|
@ -50,7 +50,7 @@ const SActiveSession = styled(SActiveAccount as any)`
|
|||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
ping: () => Promise<void>;
|
ping: () => Promise<void>;
|
||||||
disconnect: () => Promise<void>;
|
disconnect: () => Promise<void>;
|
||||||
session: SessionTypes.Created | undefined;
|
session: SessionTypes.Struct | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Header = (props: HeaderProps) => {
|
const Header = (props: HeaderProps) => {
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import Head from "next/head";
|
||||||
|
import * as React from "react";
|
||||||
|
import { DEFAULT_APP_METADATA } from "../constants";
|
||||||
|
|
||||||
|
const Metadata = () => (
|
||||||
|
<Head>
|
||||||
|
<title>{DEFAULT_APP_METADATA.name}</title>
|
||||||
|
<meta name="description" content={DEFAULT_APP_METADATA.description} />
|
||||||
|
<meta name="url" content={DEFAULT_APP_METADATA.url} />
|
||||||
|
|
||||||
|
{DEFAULT_APP_METADATA.icons.map((icon, index) => (
|
||||||
|
<link key={index} rel="icon" href={icon} />
|
||||||
|
))}
|
||||||
|
</Head>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Metadata;
|
@ -6,7 +6,7 @@ import { PairingTypes } from "@walletconnect/types";
|
|||||||
import Peer from "./Peer";
|
import Peer from "./Peer";
|
||||||
|
|
||||||
interface PairingProps {
|
interface PairingProps {
|
||||||
pairing: PairingTypes.Settled;
|
pairing: PairingTypes.Struct;
|
||||||
onClick?: any;
|
onClick?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,14 +16,12 @@ const SPairingContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Pairing = (props: PairingProps) => {
|
const Pairing = (props: PairingProps) => {
|
||||||
const {
|
const { peerMetadata } = props.pairing;
|
||||||
state: { metadata },
|
|
||||||
} = props.pairing;
|
|
||||||
return (
|
return (
|
||||||
<SPairingContainer onClick={props.onClick}>
|
<SPairingContainer onClick={props.onClick}>
|
||||||
<div>
|
<div>
|
||||||
{typeof metadata !== "undefined" ? (
|
{typeof peerMetadata !== "undefined" ? (
|
||||||
<Peer oneLiner metadata={metadata} />
|
<Peer oneLiner metadata={peerMetadata} />
|
||||||
) : (
|
) : (
|
||||||
<div>{`Unknown`}</div>
|
<div>{`Unknown`}</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { AppMetadata } from "@walletconnect/types";
|
|
||||||
import { colors, fonts } from "../styles";
|
import { colors, fonts } from "../styles";
|
||||||
|
import { Metadata } from "@walletconnect/universal-provider";
|
||||||
|
|
||||||
const SPeerOneLiner = styled.div`
|
const SPeerOneLiner = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -53,7 +53,7 @@ const SName = styled(SCenter as any)`
|
|||||||
|
|
||||||
interface PeerProps {
|
interface PeerProps {
|
||||||
oneLiner?: boolean;
|
oneLiner?: boolean;
|
||||||
metadata: AppMetadata;
|
metadata: Metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Peer = (props: PeerProps) =>
|
const Peer = (props: PeerProps) =>
|
||||||
|
@ -9,14 +9,16 @@ export const DEFAULT_TEST_CHAINS = [
|
|||||||
|
|
||||||
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...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_INFURA_ID = process.env.NEXT_PUBLIC_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 const DEFAULT_EIP155_METHODS = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"];
|
||||||
|
|
||||||
|
export const DEFAULT_COSMOS_METHODS = ["cosmos_signDirect", "cosmos_signAmino"];
|
||||||
|
|
||||||
export const DEFAULT_LOGGER = "debug";
|
export const DEFAULT_LOGGER = "debug";
|
||||||
|
|
||||||
export const DEFAULT_APP_METADATA = {
|
export const DEFAULT_APP_METADATA = {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Client, { CLIENT_EVENTS } from "@walletconnect/client";
|
import SignClient from "@walletconnect/sign-client";
|
||||||
import { PairingTypes, SessionTypes } from "@walletconnect/types";
|
import { ISignClient, PairingTypes, SessionTypes } from "@walletconnect/types";
|
||||||
import CosmosProvider from "@walletconnect/cosmos-provider";
|
import UniversalProvider, { IUniversalProvider } from "@walletconnect/universal-provider";
|
||||||
import QRCodeModal from "@walletconnect/qrcode-modal";
|
import { Web3Modal } from "@web3modal/standalone";
|
||||||
import {
|
import {
|
||||||
createContext,
|
createContext,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
@ -11,7 +11,12 @@ import {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { DEFAULT_LOGGER, DEFAULT_PROJECT_ID, DEFAULT_RELAY_URL } from "../constants";
|
import {
|
||||||
|
DEFAULT_COSMOS_METHODS,
|
||||||
|
DEFAULT_LOGGER,
|
||||||
|
DEFAULT_PROJECT_ID,
|
||||||
|
DEFAULT_RELAY_URL,
|
||||||
|
} from "../constants";
|
||||||
import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../helpers";
|
import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../helpers";
|
||||||
import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
||||||
|
|
||||||
@ -19,17 +24,17 @@ import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
|||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
interface IContext {
|
interface IContext {
|
||||||
client: Client | undefined;
|
client: ISignClient | undefined;
|
||||||
session: SessionTypes.Created | undefined;
|
session: SessionTypes.Struct | undefined;
|
||||||
disconnect: () => Promise<void>;
|
disconnect: () => Promise<void>;
|
||||||
isInitializing: boolean;
|
isInitializing: boolean;
|
||||||
chain: string;
|
chain: string;
|
||||||
pairings: string[];
|
pairings: PairingTypes.Struct[];
|
||||||
accounts: string[];
|
accounts: string[];
|
||||||
balances: AccountBalances;
|
balances: AccountBalances;
|
||||||
chainData: ChainNamespaces;
|
chainData: ChainNamespaces;
|
||||||
onEnable: (chainId: string) => Promise<void>;
|
onEnable: (chainId: string) => Promise<void>;
|
||||||
cosmosProvider?: CosmosProvider;
|
cosmosProvider?: IUniversalProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,11 +46,12 @@ export const ClientContext = createContext<IContext>({} as IContext);
|
|||||||
* Provider
|
* Provider
|
||||||
*/
|
*/
|
||||||
export function ClientContextProvider({ children }: { children: ReactNode | ReactNode[] }) {
|
export function ClientContextProvider({ children }: { children: ReactNode | ReactNode[] }) {
|
||||||
const [client, setClient] = useState<Client>();
|
const [client, setClient] = useState<ISignClient>();
|
||||||
const [pairings, setPairings] = useState<string[]>([]);
|
const [pairings, setPairings] = useState<PairingTypes.Struct[]>([]);
|
||||||
const [session, setSession] = useState<SessionTypes.Created>();
|
const [session, setSession] = useState<SessionTypes.Struct>();
|
||||||
|
const [web3Modal, setWeb3Modal] = useState<Web3Modal>();
|
||||||
|
|
||||||
const [cosmosProvider, setCosmosProvider] = useState<CosmosProvider>();
|
const [cosmosProvider, setCosmosProvider] = useState<UniversalProvider>();
|
||||||
|
|
||||||
const [isInitializing, setIsInitializing] = useState(false);
|
const [isInitializing, setIsInitializing] = useState(false);
|
||||||
const [hasCheckedPersistedSession, setHasCheckedPersistedSession] = useState(false);
|
const [hasCheckedPersistedSession, setHasCheckedPersistedSession] = useState(false);
|
||||||
@ -86,68 +92,57 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
|
|||||||
if (typeof cosmosProvider === "undefined") {
|
if (typeof cosmosProvider === "undefined") {
|
||||||
throw new Error("cosmosProvider is not initialized");
|
throw new Error("cosmosProvider is not initialized");
|
||||||
}
|
}
|
||||||
await cosmosProvider.disconnect();
|
cosmosProvider.disconnect();
|
||||||
|
resetApp();
|
||||||
}, [cosmosProvider]);
|
}, [cosmosProvider]);
|
||||||
|
|
||||||
const onSessionConnected = useCallback(async (_session: SessionTypes.Settled) => {
|
const onSessionConnected = useCallback(async (_session: SessionTypes.Struct) => {
|
||||||
setSession(_session);
|
setSession(_session);
|
||||||
setChain(_session.permissions.blockchain.chains[0]);
|
|
||||||
setAccounts(_session.state.accounts);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const _subscribeToClientEvents = useCallback(
|
const _subscribeToProviderEvents = useCallback(
|
||||||
async (_client: Client) => {
|
async (provider: UniversalProvider) => {
|
||||||
if (typeof _client === "undefined") {
|
provider.on("display_uri", async (uri: string) => {
|
||||||
throw new Error("WalletConnect is not initialized");
|
console.log("EVENT", "QR Code Modal open", uri);
|
||||||
}
|
web3Modal?.openModal({ uri });
|
||||||
|
|
||||||
_client.on(CLIENT_EVENTS.pairing.proposal, async (proposal: PairingTypes.Proposal) => {
|
|
||||||
const { uri } = proposal.signal.params;
|
|
||||||
console.log("EVENT", "QR Code Modal open");
|
|
||||||
QRCodeModal.open(uri, () => {
|
|
||||||
console.log("EVENT", "QR Code Modal closed");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_client.on(CLIENT_EVENTS.pairing.created, async () => {
|
provider.on("session_delete", () => {
|
||||||
setPairings(_client.pairing.topics);
|
|
||||||
});
|
|
||||||
|
|
||||||
_client.on(CLIENT_EVENTS.session.updated, (updatedSession: SessionTypes.Settled) => {
|
|
||||||
console.log("EVENT", "session_updated");
|
|
||||||
onSessionConnected(updatedSession);
|
|
||||||
});
|
|
||||||
|
|
||||||
_client.on(CLIENT_EVENTS.session.deleted, () => {
|
|
||||||
console.log("EVENT", "session_deleted");
|
console.log("EVENT", "session_deleted");
|
||||||
resetApp();
|
resetApp();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[onSessionConnected],
|
[web3Modal],
|
||||||
);
|
);
|
||||||
|
|
||||||
const createClient = useCallback(async () => {
|
const createClient = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
setIsInitializing(true);
|
setIsInitializing(true);
|
||||||
|
|
||||||
const _client = await Client.init({
|
const provider = await UniversalProvider.init({
|
||||||
|
projectId: DEFAULT_PROJECT_ID,
|
||||||
logger: DEFAULT_LOGGER,
|
logger: DEFAULT_LOGGER,
|
||||||
relayUrl: DEFAULT_RELAY_URL,
|
relayUrl: DEFAULT_RELAY_URL,
|
||||||
|
});
|
||||||
|
|
||||||
|
setCosmosProvider(provider);
|
||||||
|
setClient(provider.client);
|
||||||
|
|
||||||
|
const web3Modal = new Web3Modal({
|
||||||
projectId: DEFAULT_PROJECT_ID,
|
projectId: DEFAULT_PROJECT_ID,
|
||||||
});
|
});
|
||||||
|
|
||||||
setClient(_client);
|
setWeb3Modal(web3Modal);
|
||||||
await _subscribeToClientEvents(_client);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
} finally {
|
} finally {
|
||||||
setIsInitializing(false);
|
setIsInitializing(false);
|
||||||
}
|
}
|
||||||
}, [_subscribeToClientEvents]);
|
}, []);
|
||||||
|
|
||||||
const onEnable = useCallback(
|
const onEnable = useCallback(
|
||||||
async (caipChainId: string) => {
|
async (caipChainId: string) => {
|
||||||
if (!client) {
|
if (!cosmosProvider) {
|
||||||
throw new ReferenceError("WalletConnect Client is not initialized.");
|
throw new ReferenceError("WalletConnect Client is not initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,47 +155,50 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
|
|||||||
console.log("Enabling cosmosProvider for chainId: ", chainId);
|
console.log("Enabling cosmosProvider for chainId: ", chainId);
|
||||||
|
|
||||||
// Create WalletConnect Provider
|
// Create WalletConnect Provider
|
||||||
const cosmosProvider = new CosmosProvider({
|
const session = await cosmosProvider.connect({
|
||||||
chains: [chainId],
|
namespaces: {
|
||||||
client,
|
cosmos: {
|
||||||
|
methods: DEFAULT_COSMOS_METHODS,
|
||||||
|
chains: [caipChainId],
|
||||||
|
events: ["chainChanged", "accountsChanged"],
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(cosmosProvider);
|
const _accounts = await cosmosProvider.enable();
|
||||||
setCosmosProvider(cosmosProvider);
|
setAccounts(_accounts);
|
||||||
|
setSession(session);
|
||||||
|
onSessionConnected(session!);
|
||||||
|
setChain(caipChainId);
|
||||||
|
|
||||||
try {
|
web3Modal?.closeModal();
|
||||||
await cosmosProvider.connect();
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const _session = await client.session.get(client.session.topics[0]);
|
|
||||||
|
|
||||||
onSessionConnected(_session);
|
|
||||||
|
|
||||||
QRCodeModal.close();
|
|
||||||
},
|
},
|
||||||
[client, onSessionConnected],
|
[cosmosProvider, onSessionConnected, web3Modal],
|
||||||
);
|
);
|
||||||
|
|
||||||
const _checkForPersistedSession = useCallback(
|
const _checkForPersistedSession = useCallback(
|
||||||
async (_client: Client) => {
|
async (provider: IUniversalProvider) => {
|
||||||
if (typeof _client === "undefined") {
|
if (!provider) {
|
||||||
throw new Error("WalletConnect is not initialized");
|
throw new Error("Universal Provider is not initialized");
|
||||||
}
|
}
|
||||||
// populates existing pairings to state
|
// populates existing pairings to state
|
||||||
setPairings(_client.pairing.topics);
|
setPairings(provider.client!.pairing.getAll({ active: true }));
|
||||||
if (typeof session !== "undefined") return;
|
if (typeof session !== "undefined") return;
|
||||||
// populates existing session to state (assume only the top one)
|
// populates existing session to state (assume only the top one)
|
||||||
if (_client.session.topics.length) {
|
if (provider.session) {
|
||||||
const _session = await _client.session.get(_client.session.topics[0]);
|
console.log("provider.session", provider.session);
|
||||||
const [namespace, chainId] = _session.state.accounts[0].split(":");
|
const session = provider.session;
|
||||||
|
|
||||||
|
const accounts = session.namespaces[Object.keys(session.namespaces)[0]].accounts;
|
||||||
|
const [namespace, chainId] = accounts[0].split(":");
|
||||||
const caipChainId = `${namespace}:${chainId}`;
|
const caipChainId = `${namespace}:${chainId}`;
|
||||||
onEnable(caipChainId);
|
setAccounts(accounts);
|
||||||
|
setSession(session);
|
||||||
|
setChain(caipChainId);
|
||||||
|
onSessionConnected(session!);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[session, onEnable],
|
[session, onSessionConnected],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -213,16 +211,20 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
|
|||||||
}
|
}
|
||||||
}, [client, createClient]);
|
}, [client, createClient]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (cosmosProvider && web3Modal) _subscribeToProviderEvents(cosmosProvider);
|
||||||
|
}, [_subscribeToProviderEvents, cosmosProvider, web3Modal]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getPersistedSession = async () => {
|
const getPersistedSession = async () => {
|
||||||
if (client && !hasCheckedPersistedSession) {
|
if (cosmosProvider && !hasCheckedPersistedSession) {
|
||||||
await _checkForPersistedSession(client);
|
await _checkForPersistedSession(cosmosProvider);
|
||||||
setHasCheckedPersistedSession(true);
|
setHasCheckedPersistedSession(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getPersistedSession();
|
getPersistedSession();
|
||||||
}, [client, _checkForPersistedSession, hasCheckedPersistedSession]);
|
}, [cosmosProvider, _checkForPersistedSession, hasCheckedPersistedSession]);
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -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"),
|
|
||||||
);
|
|
@ -9,7 +9,7 @@ import { STable } from "../components/shared";
|
|||||||
import { SModalContainer, SModalTitle } from "./shared";
|
import { SModalContainer, SModalTitle } from "./shared";
|
||||||
|
|
||||||
interface PairingModalProps {
|
interface PairingModalProps {
|
||||||
pairings: PairingTypes.Settled[];
|
pairings: PairingTypes.Struct[];
|
||||||
connect: (pairing?: { topic: string }) => Promise<void>;
|
connect: (pairing?: { topic: string }) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
dapps/react-dapp-v2-cosmos-provider/src/pages/404.tsx
Normal file
3
dapps/react-dapp-v2-cosmos-provider/src/pages/404.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function FourOhFour() {
|
||||||
|
return <h1>404 Page Not Found</h1>;
|
||||||
|
}
|
24
dapps/react-dapp-v2-cosmos-provider/src/pages/_app.tsx
Normal file
24
dapps/react-dapp-v2-cosmos-provider/src/pages/_app.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import "../styles/globals.css";
|
||||||
|
import type { AppProps } from "next/app";
|
||||||
|
import { createGlobalStyle } from "styled-components";
|
||||||
|
import { ClientContextProvider } from "../contexts/ClientContext";
|
||||||
|
import Metadata from "../components/Metadata";
|
||||||
|
|
||||||
|
import { globalStyle } from "./../styles";
|
||||||
|
const GlobalStyle = createGlobalStyle`
|
||||||
|
${globalStyle}
|
||||||
|
`;
|
||||||
|
|
||||||
|
function MyApp({ Component, pageProps }: AppProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Metadata />
|
||||||
|
<GlobalStyle />
|
||||||
|
<ClientContextProvider>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</ClientContextProvider>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyApp;
|
3
dapps/react-dapp-v2-cosmos-provider/src/pages/_error.tsx
Normal file
3
dapps/react-dapp-v2-cosmos-provider/src/pages/_error.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function Error() {
|
||||||
|
return <div>An error as occured</div>;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { version } from "@walletconnect/client/package.json";
|
import { version } from "@walletconnect/sign-client/package.json";
|
||||||
import {
|
import {
|
||||||
formatDirectSignDoc,
|
formatDirectSignDoc,
|
||||||
stringifySignDocValues,
|
stringifySignDocValues,
|
||||||
@ -7,15 +7,15 @@ import {
|
|||||||
verifyDirectSignature,
|
verifyDirectSignature,
|
||||||
} from "cosmos-wallet";
|
} from "cosmos-wallet";
|
||||||
|
|
||||||
import Banner from "./components/Banner";
|
import Banner from "./../components/Banner";
|
||||||
import Blockchain from "./components/Blockchain";
|
import Blockchain from "./../components/Blockchain";
|
||||||
import Column from "./components/Column";
|
import Column from "./../components/Column";
|
||||||
import Header from "./components/Header";
|
import Header from "./../components/Header";
|
||||||
import Modal from "./components/Modal";
|
import Modal from "./../components/Modal";
|
||||||
import { DEFAULT_MAIN_CHAINS } from "./constants";
|
import { DEFAULT_MAIN_CHAINS } from "./../constants";
|
||||||
import { AccountAction } from "./helpers";
|
import { AccountAction } from "./../helpers";
|
||||||
import RequestModal from "./modals/RequestModal";
|
import RequestModal from "./../modals/RequestModal";
|
||||||
import PingModal from "./modals/PingModal";
|
import PingModal from "./../modals/PingModal";
|
||||||
import {
|
import {
|
||||||
SAccounts,
|
SAccounts,
|
||||||
SAccountsContainer,
|
SAccountsContainer,
|
||||||
@ -23,8 +23,8 @@ import {
|
|||||||
SContent,
|
SContent,
|
||||||
SLanding,
|
SLanding,
|
||||||
SLayout,
|
SLayout,
|
||||||
} from "./components/app";
|
} from "./../components/app";
|
||||||
import { useWalletConnectClient } from "./contexts/ClientContext";
|
import { useWalletConnectClient } from "./../contexts/ClientContext";
|
||||||
|
|
||||||
interface IFormattedRpcResponse {
|
interface IFormattedRpcResponse {
|
||||||
method?: string;
|
method?: string;
|
||||||
@ -72,8 +72,9 @@ export default function App() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
setIsRpcRequestPending(true);
|
setIsRpcRequestPending(true);
|
||||||
const _session = await client.session.get(client.session.topics[0]);
|
const session = cosmosProvider?.session;
|
||||||
await client.session.ping(_session.topic);
|
if (!session) return;
|
||||||
|
await cosmosProvider.client?.ping({ topic: session.topic! });
|
||||||
setRpcResult({
|
setRpcResult({
|
||||||
address: "",
|
address: "",
|
||||||
method: "ping",
|
method: "ping",
|
||||||
@ -198,7 +199,7 @@ export default function App() {
|
|||||||
setRpcResult(result);
|
setRpcResult(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("RPC request failed:", error);
|
console.error("RPC request failed:", error);
|
||||||
setRpcResult({ result: error as string });
|
setRpcResult({ result: (error as Error).message as string });
|
||||||
} finally {
|
} finally {
|
||||||
setIsRpcRequestPending(false);
|
setIsRpcRequestPending(false);
|
||||||
}
|
}
|
||||||
@ -228,17 +229,7 @@ export default function App() {
|
|||||||
<SLanding center>
|
<SLanding center>
|
||||||
<Banner />
|
<Banner />
|
||||||
<h6>
|
<h6>
|
||||||
<span>{`Using v${version || "2.0.0-beta"}`}</span>
|
<span>{`Using v${version}`}</span>
|
||||||
<sup>
|
|
||||||
(
|
|
||||||
<a
|
|
||||||
style={{ textDecoration: "underline" }}
|
|
||||||
href="https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2-cosmos-provider"
|
|
||||||
>
|
|
||||||
outdated
|
|
||||||
</a>{" "}
|
|
||||||
⚠️)
|
|
||||||
</sup>
|
|
||||||
</h6>
|
</h6>
|
||||||
<SButtonContainer>
|
<SButtonContainer>
|
||||||
<h6>Select Cosmos chain:</h6>
|
<h6>Select Cosmos chain:</h6>
|
129
dapps/react-dapp-v2-cosmos-provider/src/styles/Home.module.css
Normal file
129
dapps/react-dapp-v2-cosmos-provider/src/styles/Home.module.css
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
.container {
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 4rem 0;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding: 2rem 0;
|
||||||
|
border-top: 1px solid #eaeaea;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title a {
|
||||||
|
color: #0070f3;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title a:hover,
|
||||||
|
.title a:focus,
|
||||||
|
.title a:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.15;
|
||||||
|
font-size: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title,
|
||||||
|
.description {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin: 4rem 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0.75rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
|
||||||
|
Bitstream Vera Sans Mono, Courier New, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin: 1rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
text-align: left;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid #eaeaea;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: color 0.15s ease, border-color 0.15s ease;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover,
|
||||||
|
.card:focus,
|
||||||
|
.card:active {
|
||||||
|
color: #0070f3;
|
||||||
|
border-color: #0070f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card h2 {
|
||||||
|
margin: 0 0 1rem 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 1em;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.grid {
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.card,
|
||||||
|
.footer {
|
||||||
|
border-color: #222;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
background: #111;
|
||||||
|
}
|
||||||
|
.logo img {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
}
|
26
dapps/react-dapp-v2-cosmos-provider/src/styles/globals.css
Normal file
26
dapps/react-dapp-v2-cosmos-provider/src/styles/globals.css
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||||
|
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color: white;
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +1,20 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"lib": [
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"esnext"
|
|
||||||
],
|
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"jsx": "preserve",
|
||||||
"jsx": "react-jsx"
|
"incremental": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||||
"src"
|
"exclude": ["node_modules"]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user