@enjin-io/metamask-enjin-adapter
Version:
131 lines (108 loc) • 3.1 kB
text/typescript
import type { EIP6963AnnounceProviderEvent, EIP1193Provider } from './types';
export function hasMetaMask(): boolean {
if (!window.ethereum) {
return false;
}
return window.ethereum.isMetaMask;
}
export async function hasSnapsSupport(
provider: EIP1193Provider = window.ethereum
): Promise<boolean> {
try {
if (provider.isMetaMask && !provider.isPhantom) {
await provider.request({
method: 'wallet_getSnaps'
});
return true;
}
return false;
} catch {
return false;
}
}
export async function getMetaMask(): Promise<EIP1193Provider | null> {
if (typeof window === 'undefined') {
return null;
}
if (await hasSnapsSupport()) {
return window.ethereum;
}
if (window.ethereum?.detected) {
for (const provider of window.ethereum.detected) {
if (await hasSnapsSupport(provider)) {
return provider;
}
}
}
if (window.ethereum?.providers) {
for (const provider of window.ethereum.providers) {
if (await hasSnapsSupport(provider)) {
return provider;
}
}
}
const eip6963Provider = await getMetaMaskEIP6963Provider();
if (eip6963Provider && (await hasSnapsSupport(eip6963Provider))) {
return eip6963Provider;
}
return null;
}
export function getMetaMaskEIP6963Provider(): Promise<EIP1193Provider> {
return new Promise<EIP1193Provider>((resolve, reject) => {
let isResolved = false;
const handleAnnounce = (event: EIP6963AnnounceProviderEvent): void => {
if (event.detail.provider.isMetaMask && !event.detail.provider.isPhantom) {
resolve(event.detail.provider);
isResolved = true;
}
};
window.addEventListener('eip6963:announceProvider', handleAnnounce as unknown as EventListener);
window.dispatchEvent(new Event('eip6963:requestProvider'));
setTimeout(() => {
window.removeEventListener(
'eip6963:announceProvider',
handleAnnounce as unknown as EventListener
);
if (!isResolved) {
reject(new Error('MetaMask provider not found'));
}
}, 1000);
});
}
export async function isPolkadotSnapInstalled(
snapOrigin: string,
version?: string
): Promise<boolean> {
try {
const walletSnaps = await getWalletSnaps();
if (!walletSnaps) return false;
return !!Object.values(walletSnaps).find(
(permission) => permission.id === snapOrigin && (!version || permission.version === version)
);
} catch (e) {
console.error('Failed to obtain installed snaps', e);
return false;
}
}
export type GetSnapsResponse = {
[k: string]: {
permissionName?: string;
id?: string;
version?: string;
initialPermissions?: { [k: string]: unknown };
};
};
async function getWalletSnaps(): Promise<GetSnapsResponse | undefined> {
const metamask = await getMetaMask();
return await metamask?.request({
method: 'wallet_getSnaps'
});
}
export async function isMetamaskSnapsSupported(): Promise<boolean> {
try {
await getWalletSnaps();
return true;
} catch (e) {
return false;
}
}