@rango-dev/provider-metamask 0.0.0-experimental-936229e8-20251208

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +239 -0
  2. package/dist/actions/solana.d.ts +11 -0
  3. package/dist/actions/solana.d.ts.map +1 -0
  4. package/dist/builders/solana.d.ts +8 -0
  5. package/dist/builders/solana.d.ts.map +1 -0
  6. package/dist/constants.d.ts +6 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/legacy/index.d.ts +20 -0
  9. package/dist/legacy/index.d.ts.map +1 -0
  10. package/dist/mod.d.ts +3 -0
  11. package/dist/mod.d.ts.map +1 -0
  12. package/dist/mod.js +2 -0
  13. package/dist/mod.js.map +7 -0
  14. package/dist/namespaces/evm.d.ts +4 -0
  15. package/dist/namespaces/evm.d.ts.map +1 -0
  16. package/dist/namespaces/solana.d.ts +4 -0
  17. package/dist/namespaces/solana.d.ts.map +1 -0
  18. package/dist/provider-metamask.build.json +1 -0
  19. package/dist/provider.d.ts +3 -0
  20. package/dist/provider.d.ts.map +1 -0
  21. package/dist/signer.d.ts +4 -0
  22. package/dist/signer.d.ts.map +1 -0
  23. package/dist/signers/solana.d.ts +12 -0
  24. package/dist/signers/solana.d.ts.map +1 -0
  25. package/dist/types.d.ts +39 -0
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/utils.d.ts +7 -0
  28. package/dist/utils.d.ts.map +1 -0
  29. package/package.json +40 -0
  30. package/readme.md +26 -0
  31. package/src/actions/solana.ts +42 -0
  32. package/src/builders/solana.ts +36 -0
  33. package/src/constants.ts +56 -0
  34. package/src/legacy/index.ts +91 -0
  35. package/src/mod.ts +12 -0
  36. package/src/namespaces/evm.ts +81 -0
  37. package/src/namespaces/solana.ts +45 -0
  38. package/src/provider.ts +23 -0
  39. package/src/signer.ts +29 -0
  40. package/src/signers/solana.ts +88 -0
  41. package/src/types.ts +54 -0
  42. package/src/utils.ts +144 -0
package/readme.md ADDED
@@ -0,0 +1,26 @@
1
+ # MetaMask
2
+ MetaMask Wallet integration for hub.
3
+ [Homepage](https://metamask.io/) | [Docs](https://docs.metamask.io/)
4
+
5
+ More about implementation status can be found [here](../readme.md).
6
+
7
+ ## Implementation notes/limitations
8
+
9
+ ### Group
10
+ MetaMask supports both **EVM** and **Solana**.
11
+
12
+ ### Feature
13
+
14
+ #### ⚠️ Switch Account
15
+
16
+ In MetaMask, you can have only one active account at a time, which may belong to either the Solana or EVM namespace. When you connect to MetaMask, it connects to the currently active account—this account could belong to either namespace. Additionally, MetaMask may also establish a random connection to another account from the opposite namespace.
17
+
18
+ When a user switches accounts in MetaMask, the wallet emits an update event tied to the currently active namespace—either EVM or Solana.
19
+ The switchAccount notification is scoped to that active namespace, meaning only the relevant provider will receive the update.
20
+
21
+ Regardless of which namespace triggers the event, MetaMask always executes transactions using the correct account for the selected chain.
22
+ This ensures consistent behavior and prevents cross-namespace conflicts between Solana and EVM contexts.
23
+
24
+ ---
25
+
26
+ More wallet information can be found in [readme.md](../readme.md).
@@ -0,0 +1,42 @@
1
+ import type { WalletStandardSolanaInstance } from '../types.js';
2
+ import type { Context, FunctionWithContext } from '@rango-dev/wallets-core';
3
+
4
+ import {
5
+ type SolanaActions,
6
+ utils,
7
+ } from '@rango-dev/wallets-core/namespaces/solana';
8
+
9
+ function connect(
10
+ getInstance: () => WalletStandardSolanaInstance
11
+ ): FunctionWithContext<SolanaActions['connect'], Context> {
12
+ return async () => {
13
+ const solanaInstance = getInstance();
14
+ const connectResult = await solanaInstance.features[
15
+ 'standard:connect'
16
+ ].connect();
17
+ return utils.formatAccountsToCAIP(
18
+ connectResult.accounts.map((account) => account.address)
19
+ );
20
+ };
21
+ }
22
+ function canEagerConnect(getInstance: () => WalletStandardSolanaInstance) {
23
+ return async () => {
24
+ const solanaInstance = getInstance();
25
+
26
+ if (!solanaInstance) {
27
+ throw new Error(
28
+ 'Trying to eagerly connect to your Solana wallet, but it seems that its instance is not available.'
29
+ );
30
+ }
31
+
32
+ try {
33
+ const result = await solanaInstance.features['standard:connect'].connect({
34
+ silent: true,
35
+ });
36
+ return !!result.accounts.length;
37
+ } catch {
38
+ return false;
39
+ }
40
+ };
41
+ }
42
+ export const solanaActions = { connect, canEagerConnect };
@@ -0,0 +1,36 @@
1
+ import type { WalletStandardSolanaInstance } from '../types.js';
2
+ import type { StandardEventsChangeProperties } from '@wallet-standard/features';
3
+
4
+ import { ChangeAccountSubscriberBuilder } from '@rango-dev/wallets-core/namespaces/common';
5
+ import {
6
+ type SolanaActions,
7
+ utils,
8
+ } from '@rango-dev/wallets-core/namespaces/solana';
9
+
10
+ // Hooks
11
+ const changeAccountSubscriber = (
12
+ getInstance: () => WalletStandardSolanaInstance
13
+ ) =>
14
+ new ChangeAccountSubscriberBuilder<
15
+ StandardEventsChangeProperties,
16
+ WalletStandardSolanaInstance,
17
+ SolanaActions
18
+ >()
19
+ .getInstance(getInstance)
20
+ .onSwitchAccount((event, context) => {
21
+ if (!event.payload.accounts?.length) {
22
+ context.action('disconnect');
23
+ event.preventDefault();
24
+ }
25
+ })
26
+ .format(async (_, event) =>
27
+ utils.formatAccountsToCAIP(
28
+ event.accounts!.map((account) => account.address)
29
+ )
30
+ )
31
+ .addEventListener((instance, callback) => {
32
+ instance.features['standard:events'].on('change', callback);
33
+ })
34
+ .removeEventListener((_, __) => {});
35
+
36
+ export const solanaBuilders = { changeAccountSubscriber };
@@ -0,0 +1,56 @@
1
+ import { type ProviderMetadata } from '@rango-dev/wallets-core';
2
+ import {
3
+ type BlockchainMeta,
4
+ evmBlockchains,
5
+ solanaBlockchain,
6
+ } from 'rango-types';
7
+
8
+ import getSigners from './signer.js';
9
+ import { getInstanceOrThrow } from './utils.js';
10
+
11
+ export const WALLET_ID = 'metamask';
12
+ export const WALLET_STANDARD_NAME = 'MetaMask';
13
+ export const SOLANA_WALLET_STANDARD_MAINNET = 'solana:mainnet';
14
+ export const metadata: ProviderMetadata = {
15
+ name: 'MetaMask',
16
+ icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/metamask/icon.svg',
17
+ extensions: {
18
+ chrome:
19
+ 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en',
20
+ brave:
21
+ 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en',
22
+ firefox: 'https://addons.mozilla.org/en-US/firefox/addon/ether-metamask',
23
+ edge: 'https://microsoftedge.microsoft.com/addons/detail/metamask/ejbalbakoplchlghecdalmeeeajnimhm?hl=en-US',
24
+ homepage: 'https://metamask.io/download/',
25
+ },
26
+ properties: [
27
+ {
28
+ name: 'namespaces',
29
+ value: {
30
+ selection: 'multiple',
31
+ data: [
32
+ {
33
+ label: 'EVM',
34
+ value: 'EVM',
35
+ id: 'ETH',
36
+ getSupportedChains: (allBlockchains: BlockchainMeta[]) =>
37
+ evmBlockchains(allBlockchains),
38
+ },
39
+ {
40
+ label: 'Solana',
41
+ value: 'Solana',
42
+ id: 'SOLANA',
43
+ getSupportedChains: (allBlockchains: BlockchainMeta[]) =>
44
+ solanaBlockchain(allBlockchains),
45
+ },
46
+ ],
47
+ },
48
+ },
49
+ {
50
+ name: 'signers',
51
+ value: {
52
+ getSigners: async () => getSigners(getInstanceOrThrow()),
53
+ },
54
+ },
55
+ ],
56
+ };
@@ -0,0 +1,91 @@
1
+ import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy';
2
+ import type {
3
+ CanEagerConnect,
4
+ CanSwitchNetwork,
5
+ Connect,
6
+ Subscribe,
7
+ SwitchNetwork,
8
+ WalletInfo,
9
+ } from '@rango-dev/wallets-shared';
10
+ import type { BlockchainMeta, SignerFactory } from 'rango-types';
11
+
12
+ import {
13
+ canEagerlyConnectToEvm,
14
+ canSwitchNetworkToEvm,
15
+ getEvmAccounts,
16
+ subscribeToEvm,
17
+ switchNetworkForEvm,
18
+ WalletTypes,
19
+ } from '@rango-dev/wallets-shared';
20
+ import { evmBlockchains } from 'rango-types';
21
+
22
+ import signer from '../signer.js';
23
+ import { metamask as metamask_instance } from '../utils.js';
24
+
25
+ const WALLET = WalletTypes.META_MASK;
26
+
27
+ export const config = {
28
+ type: WALLET,
29
+ };
30
+
31
+ export const getInstance = metamask_instance;
32
+ export const connect: Connect = async ({ instance }) => {
33
+ /*
34
+ * Note: We need to get `chainId` here, because for the first time
35
+ * after opening the browser, wallet is locked, and don't give us accounts and chainId
36
+ * on `check` phase, so `network` will be null. For this case we need to get chainId
37
+ * whenever we are requesting accounts.
38
+ */
39
+ const { accounts, chainId } = await getEvmAccounts(instance);
40
+
41
+ return {
42
+ accounts,
43
+ chainId,
44
+ };
45
+ };
46
+
47
+ export const subscribe: Subscribe = subscribeToEvm;
48
+
49
+ export const switchNetwork: SwitchNetwork = switchNetworkForEvm;
50
+
51
+ export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm;
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ type Provider = any;
54
+ export const getSigners: (provider: Provider) => Promise<SignerFactory> =
55
+ signer;
56
+
57
+ export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm;
58
+
59
+ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
60
+ allBlockChains
61
+ ) => {
62
+ const evms = evmBlockchains(allBlockChains);
63
+ return {
64
+ name: 'MetaMask',
65
+ img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/metamask/icon.svg',
66
+ installLink: {
67
+ CHROME:
68
+ 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en',
69
+ BRAVE:
70
+ 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en',
71
+
72
+ FIREFOX: 'https://addons.mozilla.org/en-US/firefox/addon/ether-metamask',
73
+ EDGE: 'https://microsoftedge.microsoft.com/addons/detail/metamask/ejbalbakoplchlghecdalmeeeajnimhm?hl=en-US',
74
+ DEFAULT: 'https://metamask.io/download/',
75
+ },
76
+ color: '#dac7ae',
77
+ supportedChains: evms,
78
+ };
79
+ };
80
+ const buildLegacyProvider: () => LegacyProviderInterface = () => ({
81
+ config,
82
+ getInstance,
83
+ connect,
84
+ subscribe,
85
+ getSigners,
86
+ getWalletInfo,
87
+ canSwitchNetworkTo,
88
+ canEagerConnect,
89
+ });
90
+
91
+ export { buildLegacyProvider };
package/src/mod.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { defineVersions } from '@rango-dev/wallets-core/utils';
2
+
3
+ import { buildLegacyProvider } from './legacy/index.js';
4
+ import { buildProvider } from './provider.js';
5
+
6
+ const versions = () =>
7
+ defineVersions()
8
+ .version('0.0.0', buildLegacyProvider())
9
+ .version('1.0.0', buildProvider())
10
+ .build();
11
+
12
+ export { versions };
@@ -0,0 +1,81 @@
1
+ import type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm';
2
+
3
+ import { ActionBuilder, NamespaceBuilder } from '@rango-dev/wallets-core';
4
+ import {
5
+ builders as commonBuilders,
6
+ connectAndUpdateStateForMultiNetworks,
7
+ intoConnecting,
8
+ intoConnectionFinished,
9
+ standardizeAndThrowError,
10
+ } from '@rango-dev/wallets-core/namespaces/common';
11
+ import {
12
+ actions,
13
+ builders,
14
+ utils,
15
+ } from '@rango-dev/wallets-core/namespaces/evm';
16
+
17
+ import { WALLET_ID } from '../constants.js';
18
+ import { evmMetamask } from '../utils.js';
19
+
20
+ const [changeAccountSubscriber, changeAccountCleanup] = builders
21
+ .changeAccountSubscriber(evmMetamask)
22
+ /*
23
+ * Metamask returns an array of connected accounts with the active one first.
24
+ * Since we only need the active account, we take the first element as a workaround.
25
+ */
26
+ .format(async (instance, accounts) => {
27
+ const chainId = await instance.request({ method: 'eth_chainId' });
28
+ return utils.formatAccountsToCAIP([accounts[0]], chainId);
29
+ })
30
+ .build();
31
+
32
+ const connect = new ActionBuilder<EvmActions, 'connect'>('connect')
33
+ .action(actions.connect(evmMetamask))
34
+ /*
35
+ * Metamask Wallet's `connect` returns a list where the currently selected account
36
+ * is always the first item. We're directly taking this first item as the active account.
37
+ *
38
+ * ***NOTE***: Please keep it synced with `wallets/core/src/namespaces/solana/builders.ts`.
39
+ *
40
+ */
41
+ .and((_, connectResult) => ({
42
+ ...connectResult,
43
+ accounts: [connectResult.accounts[0]],
44
+ }))
45
+ .and(connectAndUpdateStateForMultiNetworks)
46
+ .before(intoConnecting)
47
+ .before(changeAccountSubscriber)
48
+ .or(changeAccountCleanup)
49
+ .or(standardizeAndThrowError)
50
+ .after(intoConnectionFinished)
51
+ .build();
52
+
53
+ const canEagerConnect = builders
54
+ .canEagerConnect()
55
+ .action(actions.canEagerConnect(evmMetamask))
56
+ .build();
57
+
58
+ const disconnect = commonBuilders
59
+ .disconnect<EvmActions>()
60
+ .after(changeAccountCleanup)
61
+ .build();
62
+
63
+ const canSwitchNetwork = builders
64
+ .canSwitchNetwork()
65
+ .action(actions.canSwitchNetwork())
66
+ .build();
67
+
68
+ const getChainId = builders
69
+ .getChainId()
70
+ .action(actions.getChainId(evmMetamask))
71
+ .build();
72
+
73
+ const evm = new NamespaceBuilder<EvmActions>('EVM', WALLET_ID)
74
+ .action(connect)
75
+ .action(disconnect)
76
+ .action(canSwitchNetwork)
77
+ .action(canEagerConnect)
78
+ .action(getChainId)
79
+ .build();
80
+
81
+ export { evm };
@@ -0,0 +1,45 @@
1
+ import { ActionBuilder, NamespaceBuilder } from '@rango-dev/wallets-core';
2
+ import {
3
+ builders as commonBuilders,
4
+ standardizeAndThrowError,
5
+ } from '@rango-dev/wallets-core/namespaces/common';
6
+ import {
7
+ builders,
8
+ type SolanaActions,
9
+ } from '@rango-dev/wallets-core/namespaces/solana';
10
+
11
+ import { solanaActions } from '../actions/solana.js';
12
+ import { solanaBuilders } from '../builders/solana.js';
13
+ import { WALLET_ID } from '../constants.js';
14
+ import { solanaMetamask } from '../utils.js';
15
+
16
+ const [changeAccountSubscriber, changeAccountCleanup] = solanaBuilders
17
+ .changeAccountSubscriber(solanaMetamask)
18
+ .build();
19
+
20
+ const connect = builders
21
+ .connect()
22
+ .action(solanaActions.connect(solanaMetamask))
23
+ .before(changeAccountSubscriber)
24
+ .or(changeAccountCleanup)
25
+ .or(standardizeAndThrowError)
26
+ .build();
27
+
28
+ const canEagerConnect = new ActionBuilder<SolanaActions, 'canEagerConnect'>(
29
+ 'canEagerConnect'
30
+ )
31
+ .action(solanaActions.canEagerConnect(solanaMetamask))
32
+ .build();
33
+
34
+ const disconnect = commonBuilders
35
+ .disconnect<SolanaActions>()
36
+ .after(changeAccountCleanup)
37
+ .build();
38
+
39
+ const solana = new NamespaceBuilder<SolanaActions>('Solana', WALLET_ID)
40
+ .action(connect)
41
+ .action(disconnect)
42
+ .action(canEagerConnect)
43
+ .build();
44
+
45
+ export { solana };
@@ -0,0 +1,23 @@
1
+ import { ProviderBuilder } from '@rango-dev/wallets-core';
2
+
3
+ import { metadata, WALLET_ID } from './constants.js';
4
+ import { evm } from './namespaces/evm.js';
5
+ import { solana } from './namespaces/solana.js';
6
+ import { metamask as metamask } from './utils.js';
7
+
8
+ const buildProvider = () =>
9
+ new ProviderBuilder(WALLET_ID)
10
+ .init(function (context) {
11
+ const [, setState] = context.state();
12
+
13
+ if (metamask()) {
14
+ setState('installed', true);
15
+ console.debug('[metamask] instance detected.', context);
16
+ }
17
+ })
18
+ .config('metadata', metadata)
19
+ .add('evm', evm)
20
+ .add('solana', solana)
21
+ .build();
22
+
23
+ export { buildProvider };
package/src/signer.ts ADDED
@@ -0,0 +1,29 @@
1
+ import type { Provider } from './types.js';
2
+ import type { SignerFactory } from 'rango-types';
3
+
4
+ import { LegacyNetworks as Networks } from '@rango-dev/wallets-core/legacy';
5
+ import {
6
+ dynamicImportWithRefinedError,
7
+ getNetworkInstance,
8
+ } from '@rango-dev/wallets-shared';
9
+ import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';
10
+
11
+ import { MetamaskSolanaSigner } from './signers/solana.js';
12
+
13
+ export default async function getSigners(
14
+ provider: Provider
15
+ ): Promise<SignerFactory> {
16
+ const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM);
17
+ const solanaProvider = getNetworkInstance(provider, Networks.SOLANA);
18
+
19
+ const signers = new DefaultSignerFactory();
20
+ const { DefaultEvmSigner } = await dynamicImportWithRefinedError(
21
+ async () => await import('@rango-dev/signer-evm')
22
+ );
23
+ signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider));
24
+ signers.registerSigner(
25
+ TxType.SOLANA,
26
+ new MetamaskSolanaSigner(solanaProvider)
27
+ );
28
+ return signers;
29
+ }
@@ -0,0 +1,88 @@
1
+ import type { WalletStandardSolanaInstance } from '../types.js';
2
+
3
+ import {
4
+ generalSolanaTransactionExecutor,
5
+ type SolanaWeb3Signer,
6
+ } from '@rango-dev/signer-solana';
7
+ import base58 from 'bs58';
8
+ import {
9
+ type GenericSigner,
10
+ SignerError,
11
+ SignerErrorCode,
12
+ type SolanaTransaction,
13
+ } from 'rango-types';
14
+
15
+ async function executeSolanaTransaction(
16
+ tx: SolanaTransaction,
17
+ solanaProvider: WalletStandardSolanaInstance
18
+ ): Promise<string> {
19
+ const DefaultSolanaSigner: SolanaWeb3Signer = async (
20
+ solanaWeb3Transaction
21
+ ) => {
22
+ const [currentAccount] = solanaProvider.accounts;
23
+ if (!currentAccount.publicKey) {
24
+ throw new SignerError(
25
+ SignerErrorCode.SIGN_TX_ERROR,
26
+ 'Please make sure the required account is connected properly.'
27
+ );
28
+ }
29
+
30
+ if (tx.from !== currentAccount.address) {
31
+ throw new SignerError(
32
+ SignerErrorCode.SIGN_TX_ERROR,
33
+ `Your connected account doesn't match with the required account. Please ensure that you are connected with the correct account and try again.`
34
+ );
35
+ }
36
+
37
+ try {
38
+ const [signOutput] = await solanaProvider.features[
39
+ 'solana:signTransaction'
40
+ ].signTransaction({
41
+ account: currentAccount,
42
+ transaction: solanaWeb3Transaction.serialize(),
43
+ });
44
+ return signOutput.signedTransaction;
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ } catch (e: any) {
47
+ const REJECTION_CODE = 4001;
48
+ if (e && Object.hasOwn(e, 'code') && e.code === REJECTION_CODE) {
49
+ throw new SignerError(SignerErrorCode.REJECTED_BY_USER, undefined, e);
50
+ }
51
+ throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, e);
52
+ }
53
+ };
54
+ return await generalSolanaTransactionExecutor(tx, DefaultSolanaSigner);
55
+ }
56
+
57
+ export class MetamaskSolanaSigner implements GenericSigner<SolanaTransaction> {
58
+ private _provider: WalletStandardSolanaInstance;
59
+
60
+ constructor(provider: WalletStandardSolanaInstance) {
61
+ this._provider = provider;
62
+ }
63
+
64
+ get provider(): WalletStandardSolanaInstance {
65
+ return this._provider;
66
+ }
67
+
68
+ async signMessage(msg: string): Promise<string> {
69
+ try {
70
+ const encodedMessage = new TextEncoder().encode(msg);
71
+ const [account] = this.provider.accounts;
72
+ const [signOutput] = await this._provider.features[
73
+ 'solana:signMessage'
74
+ ].signMessage({
75
+ message: encodedMessage,
76
+ account,
77
+ });
78
+ return base58.encode(signOutput.signature);
79
+ } catch (error) {
80
+ throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error);
81
+ }
82
+ }
83
+
84
+ async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> {
85
+ const hash = await executeSolanaTransaction(tx, this._provider);
86
+ return { hash };
87
+ }
88
+ }
package/src/types.ts ADDED
@@ -0,0 +1,54 @@
1
+ import type { LegacyNetworks } from '@rango-dev/wallets-core/legacy';
2
+ import type { ProviderAPI as EvmProviderApi } from '@rango-dev/wallets-core/namespaces/evm';
3
+ import type { WalletWithFeatures as StandardWalletWithFeatures } from '@wallet-standard/base';
4
+
5
+ import {
6
+ type SolanaSignMessageFeature,
7
+ type SolanaSignTransactionFeature,
8
+ } from '@solana/wallet-standard-features';
9
+ import {
10
+ type StandardConnectFeature,
11
+ type StandardEventsFeature,
12
+ } from '@wallet-standard/features';
13
+
14
+ export type WalletStandardSolanaInstance = StandardWalletWithFeatures<
15
+ StandardConnectFeature &
16
+ StandardEventsFeature &
17
+ SolanaSignTransactionFeature &
18
+ SolanaSignMessageFeature
19
+ >;
20
+ export type MetamaskEvmProviderApi = EvmProviderApi & {
21
+ isMetaMask?: boolean;
22
+ isBraveWallet?: boolean;
23
+ _events?: boolean;
24
+ _state?: boolean;
25
+ isApexWallet?: boolean;
26
+ isAvalanche?: boolean;
27
+ isBitKeep?: boolean;
28
+ isBlockWallet?: boolean;
29
+ isCoin98?: boolean;
30
+ isFordefi?: boolean;
31
+ __XDEFI?: boolean;
32
+ isMathWallet?: boolean;
33
+ isOkxWallet?: boolean;
34
+ isOKExWallet?: boolean;
35
+ isOneInchIOSWallet?: boolean;
36
+ isOneInchAndroidWallet?: boolean;
37
+ isOpera?: boolean;
38
+ isPortal?: boolean;
39
+ isRabby?: boolean;
40
+ isDefiant?: boolean;
41
+ isTokenPocket?: boolean;
42
+ isTokenary?: boolean;
43
+ isZeal?: boolean;
44
+ isZerion?: boolean;
45
+ isSafePal?: boolean;
46
+ };
47
+ export type ProviderObject = {
48
+ [LegacyNetworks.ETHEREUM]: MetamaskEvmProviderApi;
49
+ [LegacyNetworks.SOLANA]: WalletStandardSolanaInstance;
50
+ };
51
+ export type Provider = Map<
52
+ keyof ProviderObject,
53
+ ProviderObject[keyof ProviderObject]
54
+ >;