refactor: moves more client specific methods into ClientContext
This commit is contained in:
parent
0732b09991
commit
dc120c89d2
@ -1,8 +1,5 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
import QRCodeModal from "@walletconnect/legacy-modal";
|
|
||||||
import { SessionTypes } from "@walletconnect/types";
|
|
||||||
import { ERROR, getAppMetadata } from "@walletconnect/utils";
|
|
||||||
import * as encoding from "@walletconnect/encoding";
|
import * as encoding from "@walletconnect/encoding";
|
||||||
import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
import { apiGetChainNamespace, ChainsMap } from "caip-api";
|
||||||
import { formatDirectSignDoc, stringifySignDocValues } from "cosmos-wallet";
|
import { formatDirectSignDoc, stringifySignDocValues } from "cosmos-wallet";
|
||||||
@ -13,21 +10,13 @@ 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, DEFAULT_TEST_CHAINS } from "./constants";
|
||||||
import {
|
import {
|
||||||
DEFAULT_APP_METADATA,
|
|
||||||
DEFAULT_MAIN_CHAINS,
|
|
||||||
DEFAULT_EIP155_METHODS,
|
|
||||||
DEFAULT_COSMOS_METHODS,
|
|
||||||
DEFAULT_TEST_CHAINS,
|
|
||||||
} from "./constants";
|
|
||||||
import {
|
|
||||||
apiGetAccountAssets,
|
|
||||||
AccountAction,
|
AccountAction,
|
||||||
eip712,
|
eip712,
|
||||||
hashPersonalMessage,
|
hashPersonalMessage,
|
||||||
hashTypedDataMessage,
|
hashTypedDataMessage,
|
||||||
verifySignature,
|
verifySignature,
|
||||||
AccountBalances,
|
|
||||||
formatTestTransaction,
|
formatTestTransaction,
|
||||||
ChainNamespaces,
|
ChainNamespaces,
|
||||||
setInitialStateTestnet,
|
setInitialStateTestnet,
|
||||||
@ -78,103 +67,20 @@ export default function App() {
|
|||||||
const {
|
const {
|
||||||
client,
|
client,
|
||||||
session,
|
session,
|
||||||
|
connect,
|
||||||
|
disconnect,
|
||||||
chains,
|
chains,
|
||||||
accounts,
|
accounts,
|
||||||
balances,
|
balances,
|
||||||
fetching,
|
fetching,
|
||||||
loading,
|
loading,
|
||||||
setSession,
|
|
||||||
setPairings,
|
|
||||||
setAccounts,
|
|
||||||
setChains,
|
setChains,
|
||||||
setFetching,
|
|
||||||
setBalances,
|
|
||||||
} = useWalletConnectClient();
|
} = useWalletConnectClient();
|
||||||
|
|
||||||
console.log({
|
|
||||||
client,
|
|
||||||
session,
|
|
||||||
chains,
|
|
||||||
accounts,
|
|
||||||
balances,
|
|
||||||
fetching,
|
|
||||||
loading,
|
|
||||||
setSession,
|
|
||||||
setPairings,
|
|
||||||
setAccounts,
|
|
||||||
setChains,
|
|
||||||
setFetching,
|
|
||||||
setBalances,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadChainData();
|
loadChainData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const connect = async (pairing?: { topic: string }) => {
|
|
||||||
if (typeof client === "undefined") {
|
|
||||||
throw new Error("WalletConnect is not initialized");
|
|
||||||
}
|
|
||||||
console.log("connect", pairing);
|
|
||||||
if (modal === "pairing") {
|
|
||||||
closeModal();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const supportedNamespaces: string[] = [];
|
|
||||||
chains.forEach(chainId => {
|
|
||||||
const [namespace] = chainId.split(":");
|
|
||||||
if (!supportedNamespaces.includes(namespace)) {
|
|
||||||
supportedNamespaces.push(namespace);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const methods: string[] = supportedNamespaces
|
|
||||||
.map(namespace => {
|
|
||||||
switch (namespace) {
|
|
||||||
case "eip155":
|
|
||||||
return DEFAULT_EIP155_METHODS;
|
|
||||||
case "cosmos":
|
|
||||||
return DEFAULT_COSMOS_METHODS;
|
|
||||||
default:
|
|
||||||
throw new Error(`No default methods for namespace: ${namespace}`);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.flat();
|
|
||||||
const session = await client.connect({
|
|
||||||
metadata: getAppMetadata() || DEFAULT_APP_METADATA,
|
|
||||||
pairing,
|
|
||||||
permissions: {
|
|
||||||
blockchain: {
|
|
||||||
chains,
|
|
||||||
},
|
|
||||||
jsonrpc: {
|
|
||||||
methods,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
onSessionConnected(session);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
// ignore rejection
|
|
||||||
}
|
|
||||||
|
|
||||||
// close modal in case it was open
|
|
||||||
QRCodeModal.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
const disconnect = async () => {
|
|
||||||
if (typeof client === "undefined") {
|
|
||||||
throw new Error("WalletConnect is not initialized");
|
|
||||||
}
|
|
||||||
if (typeof session === "undefined") {
|
|
||||||
throw new Error("Session is not connected");
|
|
||||||
}
|
|
||||||
await client.disconnect({
|
|
||||||
topic: session.topic,
|
|
||||||
reason: ERROR.USER_DISCONNECTED.format(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onConnect = () => {
|
const onConnect = () => {
|
||||||
if (typeof client === "undefined") {
|
if (typeof client === "undefined") {
|
||||||
throw new Error("WalletConnect is not initialized");
|
throw new Error("WalletConnect is not initialized");
|
||||||
@ -185,41 +91,6 @@ export default function App() {
|
|||||||
connect();
|
connect();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSessionConnected = async (incomingSession: SessionTypes.Settled) => {
|
|
||||||
setSession(incomingSession);
|
|
||||||
onSessionUpdate(incomingSession.state.accounts, incomingSession.permissions.blockchain.chains);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSessionUpdate = async (accounts: string[], chains: string[]) => {
|
|
||||||
setChains(chains);
|
|
||||||
setAccounts(accounts);
|
|
||||||
await getAccountBalances(accounts);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getAccountBalances = async (_accounts: string[]) => {
|
|
||||||
setFetching(true);
|
|
||||||
try {
|
|
||||||
const arr = await Promise.all(
|
|
||||||
_accounts.map(async account => {
|
|
||||||
const [namespace, reference, address] = account.split(":");
|
|
||||||
const chainId = `${namespace}:${reference}`;
|
|
||||||
const assets = await apiGetAccountAssets(address, chainId);
|
|
||||||
return { account, assets };
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const balances: AccountBalances = {};
|
|
||||||
arr.forEach(({ account, assets }) => {
|
|
||||||
balances[account] = assets;
|
|
||||||
});
|
|
||||||
setBalances(balances);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
} finally {
|
|
||||||
setFetching(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadChainData = async () => {
|
const loadChainData = async () => {
|
||||||
const namespaces = getAllChainNamespaces();
|
const namespaces = getAllChainNamespaces();
|
||||||
const chainData: ChainNamespaces = {};
|
const chainData: ChainNamespaces = {};
|
||||||
|
@ -2,8 +2,16 @@ import Client, { CLIENT_EVENTS } from "@walletconnect/client";
|
|||||||
import { PairingTypes, SessionTypes } from "@walletconnect/types";
|
import { PairingTypes, SessionTypes } from "@walletconnect/types";
|
||||||
import QRCodeModal from "@walletconnect/legacy-modal";
|
import QRCodeModal from "@walletconnect/legacy-modal";
|
||||||
import { createContext, ReactNode, useContext, useEffect, useState } from "react";
|
import { createContext, ReactNode, useContext, useEffect, useState } from "react";
|
||||||
import { DEFAULT_LOGGER, DEFAULT_PROJECT_ID, DEFAULT_RELAY_URL } from "../constants";
|
import {
|
||||||
|
DEFAULT_APP_METADATA,
|
||||||
|
DEFAULT_COSMOS_METHODS,
|
||||||
|
DEFAULT_EIP155_METHODS,
|
||||||
|
DEFAULT_LOGGER,
|
||||||
|
DEFAULT_PROJECT_ID,
|
||||||
|
DEFAULT_RELAY_URL,
|
||||||
|
} from "../constants";
|
||||||
import { AccountBalances, apiGetAccountAssets } from "../helpers";
|
import { AccountBalances, apiGetAccountAssets } from "../helpers";
|
||||||
|
import { ERROR, getAppMetadata } from "@walletconnect/utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
@ -11,18 +19,15 @@ import { AccountBalances, apiGetAccountAssets } from "../helpers";
|
|||||||
interface IContext {
|
interface IContext {
|
||||||
client: Client | undefined;
|
client: Client | undefined;
|
||||||
session: SessionTypes.Created | undefined;
|
session: SessionTypes.Created | undefined;
|
||||||
|
connect: (pairing?: { topic: string }) => Promise<void>;
|
||||||
|
disconnect: () => Promise<void>;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
fetching: boolean;
|
fetching: boolean;
|
||||||
chains: string[];
|
chains: string[];
|
||||||
pairings: string[];
|
pairings: string[];
|
||||||
accounts: string[];
|
accounts: string[];
|
||||||
balances: AccountBalances;
|
balances: AccountBalances;
|
||||||
setSession: any;
|
|
||||||
setPairings: any;
|
|
||||||
setAccounts: any;
|
|
||||||
setChains: any;
|
setChains: any;
|
||||||
setFetching: any;
|
|
||||||
setBalances: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,6 +115,72 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
|
|||||||
await getAccountBalances(accounts);
|
await getAccountBalances(accounts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const connect = async (pairing?: { topic: string }) => {
|
||||||
|
if (typeof client === "undefined") {
|
||||||
|
throw new Error("WalletConnect is not initialized");
|
||||||
|
}
|
||||||
|
console.log("connect", pairing);
|
||||||
|
// TODO:
|
||||||
|
// if (modal === "pairing") {
|
||||||
|
// closeModal();
|
||||||
|
// }
|
||||||
|
try {
|
||||||
|
const supportedNamespaces: string[] = [];
|
||||||
|
chains.forEach(chainId => {
|
||||||
|
const [namespace] = chainId.split(":");
|
||||||
|
if (!supportedNamespaces.includes(namespace)) {
|
||||||
|
supportedNamespaces.push(namespace);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const methods: string[] = supportedNamespaces
|
||||||
|
.map(namespace => {
|
||||||
|
switch (namespace) {
|
||||||
|
case "eip155":
|
||||||
|
return DEFAULT_EIP155_METHODS;
|
||||||
|
case "cosmos":
|
||||||
|
return DEFAULT_COSMOS_METHODS;
|
||||||
|
default:
|
||||||
|
throw new Error(`No default methods for namespace: ${namespace}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flat();
|
||||||
|
const session = await client.connect({
|
||||||
|
metadata: getAppMetadata() || DEFAULT_APP_METADATA,
|
||||||
|
pairing,
|
||||||
|
permissions: {
|
||||||
|
blockchain: {
|
||||||
|
chains,
|
||||||
|
},
|
||||||
|
jsonrpc: {
|
||||||
|
methods,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
onSessionConnected(session);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
// ignore rejection
|
||||||
|
}
|
||||||
|
|
||||||
|
// close modal in case it was open
|
||||||
|
QRCodeModal.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
const disconnect = async () => {
|
||||||
|
if (typeof client === "undefined") {
|
||||||
|
throw new Error("WalletConnect is not initialized");
|
||||||
|
}
|
||||||
|
if (typeof session === "undefined") {
|
||||||
|
throw new Error("Session is not connected");
|
||||||
|
}
|
||||||
|
console.log(client);
|
||||||
|
await client.disconnect({
|
||||||
|
topic: session.topic,
|
||||||
|
reason: ERROR.USER_DISCONNECTED.format(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const getAccountBalances = async (_accounts: string[]) => {
|
const getAccountBalances = async (_accounts: string[]) => {
|
||||||
setFetching(true);
|
setFetching(true);
|
||||||
try {
|
try {
|
||||||
@ -166,12 +237,9 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
|
|||||||
chains,
|
chains,
|
||||||
client,
|
client,
|
||||||
session,
|
session,
|
||||||
setSession,
|
connect,
|
||||||
setPairings,
|
disconnect,
|
||||||
setAccounts,
|
|
||||||
setChains,
|
setChains,
|
||||||
setFetching,
|
|
||||||
setBalances,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
Loading…
Reference in New Issue
Block a user