-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwallet.ts
132 lines (121 loc) · 3.81 KB
/
wallet.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { reactive, ref, toRaw } from "vue";
import { ethers, Signer } from "ethers";
import Web3Modal from "web3modal";
import { getChainData } from "./chain/tools";
import { providerOptions } from "./chain/walletConnectConfig";
import { useConnectedStore } from "./store";
import type { JsonRpcProvider, Provider } from "@ethersproject/providers";
import { getBalance } from "./chain";
const defaultChainId = +import.meta.env.VITE_CHAINID;
export const chainId = ref<number>(defaultChainId);
const rpc = import.meta.env.VITE_RPC_URL;
// @ts-ignore
export let provider: Provider = reactive(ethers.getDefaultProvider(rpc));
export let signer: Signer = reactive({} as Signer);
export const walletAddress = ref<string>("");
export function useProvider(): Provider {
return toRaw(provider);
}
export function useSigner(): Signer {
return toRaw(signer);
}
export function useSignerOrProvider():
| Provider
| Signer {
if (signer._isSigner) {
return toRaw(signer);
}
return toRaw(provider);
}
export const initializing = ref<Promise<boolean>>();
export function useInitializing(): Promise<boolean> {
return initializing.value as Promise<boolean>;
}
const web3Modal = new Web3Modal({
theme: "dark",
network: getChainData(chainId.value).network,
cacheProvider: true,
providerOptions,
});
export async function resetApp() {
const store = useConnectedStore();
store.setConnected(false);
store.setAddress("");
store.setBalance(0);
web3Modal.clearCachedProvider();
}
export function subscribeProvider(provider: JsonRpcProvider) {
if (!provider.on) {
return;
}
provider.on("close", () => resetApp());
provider.on("accountsChanged", async () => {
const store = useConnectedStore();
store.setBalance(await getBalance());
});
provider.on("chainChanged", async (_chainId: number) => {
chainId.value = parseInt(String(_chainId), 16);
const store = useConnectedStore();
store.setBalance(await getBalance());
});
provider.on("disconnect", () => {
resetApp();
});
}
export async function onConnect(chainIds: Array<number>) {
const store = useConnectedStore();
// eslint-disable-next-line no-async-promise-executor
initializing.value = new Promise(async (resolve) => {
const modalProvider = await web3Modal.connect();
const _provider = new ethers.providers.Web3Provider(modalProvider);
const _signer = _provider.getSigner();
const _network = await _provider.getNetwork();
provider = reactive(_provider as unknown as Provider);
signer = reactive(_signer);
chainId.value = _network.chainId;
if (chainIds.length == 1 && chainIds[0] != chainId.value) {
await switchChain(chainIds[0]);
}
walletAddress.value = await _signer.getAddress();
store.setAddress(await _signer.getAddress());
store.setConnected(true);
subscribeProvider(_provider as unknown as JsonRpcProvider);
resolve(true);
});
store.setBalance(await getBalance());
}
async function switchChain(_chainId: number): Promise<void> {
const chainData = getChainData(_chainId);
if (!chainData) {
throw new Error(`Chain ${_chainId} not found`);
}
try {
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [
{
chainId: chainData.native_currency.hex,
chainName: chainData.name,
rpcUrls: [chainData.rpc],
blockExplorerUrls: [chainData.explorer],
nativeCurrency: {
name: chainData.native_currency.name,
symbol: chainData.native_currency.symbol,
decimals: 18,
},
},
],
});
chainId.value = _chainId;
} catch (e) {
console.error(e);
}
try {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: chainData.native_currency.hex }],
});
} catch (e) {
console.error(e);
}
}