Files
explorer-monorepo/frontend/src/utils/walletWatchToken.ts

65 lines
1.8 KiB
TypeScript
Raw Normal View History

import type { WalletChain } from '@/components/wallet/AddToMetaMask'
import { toWalletAddEthereumChainParams } from '@/utils/walletAddEthereumChain'
import {
buildWatchAssetRpcRequest,
type WatchAssetToken,
} from '@/utils/walletWatchAsset'
import {
isMobileWalletContext,
type EthereumProvider,
} from '@/utils/walletProviderEnv'
export async function switchOrAddChain(
ethereum: EthereumProvider,
chain: WalletChain,
): Promise<boolean> {
try {
await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: chain.chainId }],
})
return true
} catch (e) {
const err = e as { code?: number }
if (err.code !== 4902) return false
}
try {
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [
toWalletAddEthereumChainParams(chain, {
preferSingleRpc: isMobileWalletContext(),
}),
],
})
return true
} catch {
return false
}
}
export async function watchTokenInWallet(
ethereum: EthereumProvider,
token: WatchAssetToken,
chain: WalletChain,
): Promise<{ ok: boolean; added?: boolean; error?: string }> {
const switched = await switchOrAddChain(ethereum, chain)
if (!switched) {
return { ok: false, error: `Failed to switch to ${chain.chainName}. Add the network first, then retry.` }
}
try {
const added = await ethereum.request(
buildWatchAssetRpcRequest(token, isMobileWalletContext()),
)
return { ok: true, added: Boolean(added) }
} catch (e) {
const err = e as { code?: number; message?: string }
if (err.code === 4001 || /rejected|denied|not been authorized/i.test(err.message || '')) {
return { ok: false, error: 'Wallet request was rejected. Approve the popup to add the token.' }
}
return { ok: false, error: err.message || 'Could not add token to wallet.' }
}
}