Create useWallet() composable and share wallet state

This commit is contained in:
silverpill 2022-06-06 22:51:12 +00:00
parent 6fa6044100
commit a7d0560002
2 changed files with 71 additions and 45 deletions

63
src/composables/wallet.ts Normal file
View file

@ -0,0 +1,63 @@
import { ref } from "vue"
import { useInstanceInfo } from "@/store/instance"
import {
getWallet,
getWeb3Provider,
parseCAIP2_chainId,
} from "@/utils/ethereum"
const walletAddress = ref<string | null>(null)
const walletError = ref<string | null>(null)
function disconnectWallet(callback: () => void) {
callback()
walletAddress.value = null
walletError.value = null
}
async function connectWallet(
onDisconnect: () => void,
): Promise<void> {
const { instance } = useInstanceInfo()
if (!instance.value?.blockchain_id) {
throw new Error("blockchain integration disabled")
}
let web3Provider
try {
web3Provider = getWeb3Provider()
} catch (error) {
walletError.value = "wallet not found"
return
}
const signer = await getWallet(web3Provider)
if (!signer) {
walletError.value = "wallet not connected"
return
}
walletAddress.value = await signer.getAddress()
const walletProvider = web3Provider.provider as any
walletProvider.on("chainChanged", (chainId: string) => {
disconnectWallet(onDisconnect)
})
walletProvider.on("accountsChanged", () => {
disconnectWallet(onDisconnect)
})
walletProvider.on("disconnect", () => {
disconnectWallet(onDisconnect)
})
const instanceChainId = parseCAIP2_chainId(instance.value.blockchain_id)
const walletChainId = await web3Provider.send("eth_chainId", [])
if (walletChainId !== instanceChainId) {
walletError.value = "incorrect network"
}
}
export function useWallet() {
return {
connectWallet,
walletAddress,
walletError,
}
}

View file

@ -77,22 +77,18 @@ import {
SubscriptionState, SubscriptionState,
} from "@/api/subscriptions" } from "@/api/subscriptions"
import Sidebar from "@/components/Sidebar.vue" import Sidebar from "@/components/Sidebar.vue"
import { useWallet } from "@/composables/wallet"
import { useInstanceInfo } from "@/store/instance" import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user" import { useCurrentUser } from "@/store/user"
import { import { ethereumAddressMatch, getWeb3Provider } from "@/utils/ethereum"
ethereumAddressMatch,
getWallet,
getWeb3Provider,
parseCAIP2_chainId,
} from "@/utils/ethereum"
const route = useRoute() const route = useRoute()
const { currentUser, ensureAuthToken } = $(useCurrentUser()) const { currentUser, ensureAuthToken } = $(useCurrentUser())
const { instance, getActorAddress } = $(useInstanceInfo()) const { instance, getActorAddress } = $(useInstanceInfo())
const { connectWallet: connectEthereumWallet } = useWallet()
let { walletAddress, walletError } = $(useWallet())
let profile = $ref<Profile | null>(null) let profile = $ref<Profile | null>(null)
let profileEthereumAddress = $ref<string | null>(null) let profileEthereumAddress = $ref<string | null>(null)
let walletConnected = $ref(false)
let walletError = $ref<string | null>(null)
let subscriptionConfigured = $ref<boolean | null>(null) let subscriptionConfigured = $ref<boolean | null>(null)
let subscription = $ref<Subscription | null>(null) let subscription = $ref<Subscription | null>(null)
let subscriptionState = $ref<SubscriptionState | null>(null) let subscriptionState = $ref<SubscriptionState | null>(null)
@ -120,55 +116,22 @@ function canConnectWallet(): boolean {
Boolean(instance?.blockchain_contract_address) && Boolean(instance?.blockchain_contract_address) &&
// Only profiles with verified address can have subscription // Only profiles with verified address can have subscription
profileEthereumAddress !== null && profileEthereumAddress !== null &&
!walletConnected walletAddress === null
) )
} }
function disconnectWallet() { function reset() {
subscriptionConfigured = null subscriptionConfigured = null
subscription = null subscription = null
subscriptionState = null subscriptionState = null
subscriberAddress = null subscriberAddress = null
walletConnected = false
walletError = null
} }
async function connectWallet() { async function connectWallet() {
if (!profileEthereumAddress || !instance?.blockchain_id) { await connectEthereumWallet(reset)
if (!profileEthereumAddress || !walletAddress) {
return return
} }
let web3Provider
try {
web3Provider = getWeb3Provider()
} catch (error) {
walletError = "wallet not found"
return
}
const signer = await getWallet(web3Provider)
if (!signer) {
walletError = "wallet not connected"
return
}
const walletAddress = await signer.getAddress()
web3Provider.provider.on("chainChanged", (chainId: string) => {
disconnectWallet()
})
web3Provider.provider.on("accountsChanged", () => {
disconnectWallet()
})
web3Provider.provider.on("disconnect", () => {
disconnectWallet()
})
walletConnected = true
const instanceChainId = parseCAIP2_chainId(instance.blockchain_id)
const walletChainId = await web3Provider.send("eth_chainId", [])
if (walletChainId !== instanceChainId) {
// Wrong network
walletError = "incorrect network"
return
}
if (isCurrentUser() && !ethereumAddressMatch(walletAddress, profileEthereumAddress)) { if (isCurrentUser() && !ethereumAddressMatch(walletAddress, profileEthereumAddress)) {
// Recipient must use verified account // Recipient must use verified account
walletError = "incorrect wallet address" walletError = "incorrect wallet address"