📄 src/web3/wallet/walletMeta.ts
D-OPEN SOVEREIGN
1import { Browser, parseUserAgent, Platform } from './browsers';
2import { type WalletType } from '../client/types';
3
4export interface WalletMeta {
5 readonly displayName: string;
6 readonly logoUrl: string;
7 readonly description: string;
8 readonly website: string;
9 getInstallUrl(browser?: Browser): string;
10 isInstalled(): boolean;
11 isInstallable(): boolean;
12}
13
14const METAMASK_LOGO_BASE64 =
15 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLQogIC0gICAvKgogIC0gICAgKiBDb3B5cmlnaHQgKGMpIDIwMjYgRGF0YVBvbmQgRC1MaWJyYXJ5IFB0eSBMdGQuICgiVGhlIFNhbmN0dWFyeSIpCiAgLSAgICAqIE5vbi1Qcm9maXQgUHVibGljIExpYnJhcnkg4oCUIFRoZSBXb3JsZCBMaWJyYXJ5CiAgLSAgICAqCiAgLSAgICAqIExpY2Vuc2VkIHVuZGVyIHRoZSBELU9wZW4gQ29kZSBTb3ZlcmVpZ24gTGljZW5jZSB2MS4wCiAgLSAgICAqIGh0dHBzOi8vcmVnaXN0cnkud29ybGQuYmlibGlvdGVjaC5jb20vbGljZW5jZQogIC0gICAgKgogIC0gICAgKiBUZWNobmljYWwgR3VhcmRpYW4gKCJUaGUgU2hpZWxkIik6IFBvbmQgRW50ZXJwcmlzZSBQdHkgTHRkLiAoQUNOIDY5NCA3NDcgOTg3KQogIC0gICAgKiBBbGwgbGlhYmlsaXR5IGNsYWltcyBkaXJlY3RlZCB0byBQb25kIEVudGVycHJpc2UgUHR5IEx0ZC4KICAtICAgICogTW9kaWZpY2F0aW9uIGF1dG9tYXRpY2FsbHkgdm9pZHMgdGhlIGNlcnRpZmllZCBsaWFiaWxpdHkgcHJvdGVjdGlvbi4KICAtICAgICogR292ZXJuaW5nIGxhdzogU291dGggQXVzdHJhbGlhLgogIC0gICAgKi8KICAtCiAgLS0+Cgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgaWQ9IkxheWVyXzEiIHg9IjAiIHk9IjAiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMxOC42IDMxOC42Ij4KICA8c3R5bGU+CiAgICAuc3QxLC5zdDZ7ZmlsbDojZTQ3NjFiO3N0cm9rZTojZTQ3NjFiO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH0uc3Q2e2ZpbGw6I2Y2ODUxYjtzdHJva2U6I2Y2ODUxYn0KICA8L3N0eWxlPgogIDxwYXRoIGZpbGw9IiNlMjc2MWIiIHN0cm9rZT0iI2UyNzYxYiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJtMjc0LjEgMzUuNS05OS41IDczLjlMMTkzIDY1Ljh6Ii8+CiAgPHBhdGggZD0ibTQ0LjQgMzUuNSA5OC43IDc0LjYtMTcuNS00NC4zem0xOTMuOSAxNzEuMy0yNi41IDQwLjYgNTYuNyAxNS42IDE2LjMtNTUuM3ptLTIwNC40LjlMNTAuMSAyNjNsNTYuNy0xNS42LTI2LjUtNDAuNnoiIGNsYXNzPSJzdDEiLz4KICA8cGF0aCBkPSJtMTAzLjYgMTM4LjItMTUuOCAyMy45IDU2LjMgMi41LTItNjAuNXptMTExLjMgMC0zOS0zNC44LTEuMyA2MS4yIDU2LjItMi41ek0xMDYuOCAyNDcuNGwzMy44LTE2LjUtMjkuMi0yMi44em03MS4xLTE2LjUgMzMuOSAxNi41LTQuNy0zOS4zeiIgY2xhc3M9InN0MSIvPgogIDxwYXRoIGZpbGw9IiNkN2MxYjMiIHN0cm9rZT0iI2Q3YzFiMyIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJtMjExLjggMjQ3LjQtMzMuOS0xNi41IDIuNyAyMi4xLS4zIDkuM3ptLTEwNSAwIDMxLjUgMTQuOS0uMi05LjMgMi41LTIyLjF6Ii8+CiAgPHBhdGggZmlsbD0iIzIzMzQ0NyIgc3Ryb2tlPSIjMjMzNDQ3IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Im0xMzguOCAxOTMuNS0yOC4yLTguMyAxOS45LTkuMXptNDAuOSAwIDguMy0xNy40IDIwIDkuMXoiLz4KICA8cGF0aCBmaWxsPSIjY2Q2MTE2IiBzdHJva2U9IiNjZDYxMTYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0ibTEwNi44IDI0Ny40IDQuOC00MC42LTMxLjMuOXpNMjA3IDIwNi44bDQuOCA0MC42IDI2LjUtMzkuN3ptMjMuOC00NC43LTU2LjIgMi41IDUuMiAyOC45IDguMy0xNy40IDIwIDkuMXptLTEyMC4yIDIzLjEgMjAtOS4xIDguMiAxNy40IDUuMy0yOC45LTU2LjMtMi41eiIvPgogIDxwYXRoIGZpbGw9IiNlNDc1MWYiIHN0cm9rZT0iI2U0NzUxZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJtODcuOCAxNjIuMSAyMy42IDQ2LS44LTIyLjl6bTEyMC4zIDIzLjEtMSAyMi45IDIzLjctNDZ6bS02NC0yMC42LTUuMyAyOC45IDYuNiAzNC4xIDEuNS00NC45em0zMC41IDAtMi43IDE4IDEuMiA0NSA2LjctMzQuMXoiLz4KICA8cGF0aCBkPSJtMTc5LjggMTkzLjUtNi43IDM0LjEgNC44IDMuMyAyOS4yLTIyLjggMS0yMi45em0tNjkuMi04LjMuOCAyMi45IDI5LjIgMjIuOCA0LjgtMy4zLTYuNi0zNC4xeiIgY2xhc3M9InN0NiIvPgogIDxwYXRoIGZpbGw9IiNjMGFkOWUiIHN0cm9rZT0iI2MwYWQ5ZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJtMTgwLjMgMjYyLjMuMy05LjMtMi41LTIuMmgtMzcuN2wtMi4zIDIuMi4yIDkuMy0zMS41LTE0LjkgMTEgOSAyMi4zIDE1LjVoMzguM2wyMi40LTE1LjUgMTEtOXoiLz4KICA8cGF0aCBmaWxsPSIjMTYxNjE2IiBzdHJva2U9IiMxNjE2MTYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0ibTE3Ny45IDIzMC45LTQuOC0zLjNoLTI3LjdsLTQuOCAzLjMtMi41LIUyLjEgMi4zLTIuMmgzNy43bDIuNSAyLjJ6Ii8+CiAgPHBhdGggZmlsbD0iIzc2M2QxNiIgc3Ryb2tlPSIjNzYzZDE2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Im0yNzguMyAxMTQuMiA4LjUtNDAuOC0xMi43LTM3LjktOTYuMiA3MS40IDM3IDMxLjMgNTIuMyAxNS4zIDExLjYtMTMuNS01LTMuNiA4LTcuMy02LjItNC44IDgtNi4xek0zMS44IDczLjRsOC41IDQwLjgtNS40IDQgOCA2LjEtNi4xIDQuOCA4IDcuMy01IDMuNiAxMS41IDEzLjUgNTIuMy0xNS4zID3LTMxLjMtOTYuMi03MS40eiIvPgogIDxwYXRoIGQ9Im0yNjcuMiAxNTMuNS01Mi4zLTE1LjMgMTUuOSAyMy45LTIzLjcgNDYgMzEuMi0uNGg0Ni41em0tMTYzLjYtMTUuMy01Mi4zIDE1LjMtMTcuNCA1NC4yaDQ2LjRsMzEuMS40LTIzLjYtNDZ6bTcxIDI2LjQgMy4zLTU3LjcgMTUuMi00MS4xaC02Ny41bDE1IDQxLjEgMy41IDU3LjcgMS4yIDE4LjIuMSA0NC44aDI3LjdsLjItNDQuOHoiIGNsYXNzPSJzdDYiLz4KPC9zdmc+';
16
17export const walletMeta: Record<WalletType, WalletMeta> = {
18 metamask: {
19 displayName: 'MetaMask',
20 logoUrl: METAMASK_LOGO_BASE64,
21 description: 'The most popular Ethereum wallet extension',
22 website: 'https://metamask.io/',
23 isInstalled(): boolean {
24 return (
25 typeof window !== 'undefined' &&
26 typeof (window as any).ethereum !== 'undefined' &&
27 (window as any).ethereum.isMetaMask
28 );
29 },
30 isInstallable(): boolean {
31 try {
32 this.getInstallUrl();
33 return true;
34 } catch {
35 return false;
36 }
37 },
38 getInstallUrl(customBrowser?: Browser): string {
39 const { browser, platform } = parseUserAgent();
40 const targetBrowser = customBrowser || browser;
41
42 switch (platform) {
43 case Platform.android:
44 return 'https://play.google.com/store/apps/details?id=io.metamask';
45 case Platform.ios:
46 return 'https://apps.apple.com/us/app/metamask-crypto-wallet/id1438144202';
47 case Platform.browsers:
48 switch (targetBrowser) {
49 case Browser.chromium:
50 case Browser.brave:
51 return 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn';
52 case Browser.firefox:
53 return 'https://addons.mozilla.org/en-US/firefox/addon/ether-metamask/';
54 case Browser.opera:
55 return 'https://addons.opera.com/en/extensions/details/metamask/';
56 case Browser.edge:
57 return 'https://microsoftedge.microsoft.com/addons/detail/metamask/ejbalbakoplchlghecdalmeeeajnimhm';
58 default:
59 throw new Error(`Browser ${targetBrowser} is not supported for installation of MetaMask extension.`);
60 }
61 default:
62 throw new Error(`Platform ${platform} is not supported for MetaMask.`);
63 }
64 },
65 },
66 private_key: {
67 displayName: 'Private Key',
68 logoUrl: '',
69 description: 'Direct embedded wallet using a raw private key',
70 website: '',
71 isInstalled(): boolean {
72 return true;
73 },
74 isInstallable(): boolean {
75 return false;
76 },
77 getInstallUrl(): string {
78 return '';
79 },
80 },
81};
82