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,
} from "@/api/subscriptions"
import Sidebar from "@/components/Sidebar.vue"
import { useWallet } from "@/composables/wallet"
import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user"
import {
ethereumAddressMatch,
getWallet,
getWeb3Provider,
parseCAIP2_chainId,
} from "@/utils/ethereum"
import { ethereumAddressMatch, getWeb3Provider } from "@/utils/ethereum"
const route = useRoute()
const { currentUser, ensureAuthToken } = $(useCurrentUser())
const { instance, getActorAddress } = $(useInstanceInfo())
const { connectWallet: connectEthereumWallet } = useWallet()
let { walletAddress, walletError } = $(useWallet())
let profile = $ref<Profile | 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 subscription = $ref<Subscription | null>(null)
let subscriptionState = $ref<SubscriptionState | null>(null)
@ -120,55 +116,22 @@ function canConnectWallet(): boolean {
Boolean(instance?.blockchain_contract_address) &&
// Only profiles with verified address can have subscription
profileEthereumAddress !== null &&
!walletConnected
walletAddress === null
)
}
function disconnectWallet() {
function reset() {
subscriptionConfigured = null
subscription = null
subscriptionState = null
subscriberAddress = null
walletConnected = false
walletError = null
}
async function connectWallet() {
if (!profileEthereumAddress || !instance?.blockchain_id) {
await connectEthereumWallet(reset)
if (!profileEthereumAddress || !walletAddress) {
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)) {
// Recipient must use verified account
walletError = "incorrect wallet address"