Skip to content

Commit

Permalink
fix: resolve conflicts between evm providers
Browse files Browse the repository at this point in the history
  • Loading branch information
Ikari-Shinji-re authored and yeager-eren committed Apr 20, 2024
1 parent 8091128 commit 9a6734c
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 55 deletions.
1 change: 1 addition & 0 deletions global-wallets-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ declare global {
solana: any;
phantom: any;
xfi: any;
coinbaseWalletExtension: any;
coinbaseSolana: any;
coin98: any;
keplr: any;
Expand Down
23 changes: 22 additions & 1 deletion wallets/provider-coinbase/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
import { Networks, ProviderConnectResult } from '@rango-dev/wallets-shared';
import type { ProviderConnectResult } from '@rango-dev/wallets-shared';

import { Networks } from '@rango-dev/wallets-shared';

export function coinbase() {
const { coinbaseWalletExtension, coinbaseSolana } = window;

const instances = new Map();
if (coinbaseWalletExtension) {
instances.set(Networks.ETHEREUM, coinbaseWalletExtension);
}

if (!!coinbaseSolana) {
instances.set(Networks.SOLANA, coinbaseSolana);
}

if (instances.size === 0) {
return null;
}

return instances;
}

export async function getSolanaAccounts(
instance: any
Expand Down
3 changes: 1 addition & 2 deletions wallets/provider-coinbase/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
canEagerlyConnectToEvm,
canSwitchNetworkToEvm,
chooseInstance,
getCoinbaseInstance as coinbase_instance,
getEvmAccounts,
Networks,
switchNetworkForEvm,
Expand All @@ -26,7 +25,7 @@ import {
solanaBlockchain,
} from 'rango-types';

import { getSolanaAccounts } from './helpers';
import { coinbase as coinbase_instance, getSolanaAccounts } from './helpers';
import signer from './signer';

const WALLET = WalletTypes.COINBASE;
Expand Down
98 changes: 88 additions & 10 deletions wallets/provider-metamask/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,95 @@
import { getCoinbaseInstance } from '@rango-dev/wallets-shared';
function isMetamaskProvider(ethereum: any): boolean {
const isMetamask = !!ethereum?.isMetaMask;
if (!isMetamask) {
return false;
}
/*
* Brave tries to make itself look like MetaMask
* Could also try RPC `web3_clientVersion` if following is unreliable
*/
if (ethereum.isBraveWallet && !ethereum._events && !ethereum._state) {
return false;
}
if (ethereum.isApexWallet) {
return false;
}
if (ethereum.isAvalanche) {
return false;
}
if (ethereum.isBitKeep) {
return false;
}
if (ethereum.isBlockWallet) {
return false;
}
if (ethereum.isCoin98) {
return false;
}
if (ethereum.isFordefi) {
return false;
}
if (ethereum.__XDEFI) {
return false;
}
if (ethereum.isMathWallet) {
return false;
}
if (ethereum.isOkxWallet || ethereum.isOKExWallet) {
return false;
}
if (ethereum.isOneInchIOSWallet || ethereum.isOneInchAndroidWallet) {
return false;
}
if (ethereum.isOpera) {
return false;
}
if (ethereum.isPortal) {
return false;
}
if (ethereum.isRabby) {
return false;
}
if (ethereum.isDefiant) {
return false;
}
if (ethereum.isTokenPocket) {
return false;
}
if (ethereum.isTokenary) {
return false;
}
if (ethereum.isZeal) {
return false;
}
if (ethereum.isZerion) {
return false;
}
return true;
}

export function metamask() {
const isCoinbaseWalletAvailable = !!getCoinbaseInstance();
const { ethereum } = window;

// Some wallets overriding the metamask. So we need to get it properly.
if (isCoinbaseWalletAvailable) {
// Getting intance from overrided structure from coinbase.
return getCoinbaseInstance('metamask');
} else {
if (!!ethereum && ethereum.isMetaMask) {
return ethereum;
if (Array.isArray(ethereum?.providers)) {
/*
* When alternative EVM wallets are enabled and take precedence over MetaMask,
* they append MetaMask or other EVM wallets to the ethereum.providers array.
* example: 'Core' wallet
*/
let providers = ethereum.providers;
//Exceptions exist, such as when only 'MetaMask' and 'Coinbase' are enabled.
if (
providers.length > 0 &&
Array.isArray(ethereum.providers[0]?.providers) &&
providers[0]?.providers.length > 0
) {
providers = providers[0]?.providers;
}

const metamaskProvider = providers.find(isMetamaskProvider);
if (metamaskProvider) {
return metamaskProvider;
}
}
return null;
return ethereum?.isMetaMask ? ethereum : null;
}
6 changes: 3 additions & 3 deletions wallets/provider-xdefi/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SUPPORTED_ETH_CHAINS, SUPPORTED_NETWORKS } from './constants';
type Provider = Map<Network, any>;

export function xdefi() {
const { xfi, ethereum } = window;
const { xfi } = window;

if (!xfi) {
return null;
Expand All @@ -30,8 +30,8 @@ export function xdefi() {
if (xfi.binance) {
instances.set(Networks.BINANCE, xfi.binance);
}
if (ethereum?.__XDEFI) {
instances.set(Networks.ETHEREUM, ethereum);
if (xfi.ethereum) {
instances.set(Networks.ETHEREUM, xfi.ethereum);
}
if (xfi.dogecoin) {
instances.set(Networks.DOGE, xfi.dogecoin);
Expand Down
3 changes: 0 additions & 3 deletions wallets/provider-xdefi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ export const connect: Connect = async ({ instance, meta }) => {
const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM);
const solInstance = chooseInstance(instance, meta, Networks.SOLANA);
const cosmosInstance = chooseInstance(instance, meta, Networks.COSMOS);
if (!ethInstance || !ethInstance.__XDEFI) {
throw new Error("Please 'Prioritise' XDEFI and refresh the page.");
}

const evmResult = await getEvmAccounts(ethInstance);
const nonEvmResults = await getNonEvmAccounts(instance);
Expand Down
36 changes: 0 additions & 36 deletions wallets/shared/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,42 +156,6 @@ export const getSolanaAccounts: Connect = async ({ instance }) => {
};
};

export function getCoinbaseInstance(
lookingFor: 'coinbase' | 'metamask' = 'coinbase'
) {
const { ethereum, coinbaseSolana } = window;
const instances = new Map();
if (ethereum) {
const checker =
lookingFor === 'metamask' ? 'isMetaMask' : 'isCoinbaseWallet';

// If only Coinbase Wallet is installed
if (lookingFor === 'coinbase' && ethereum[checker]) {
instances.set(Networks.ETHEREUM, ethereum);
}
// If Coinbase Wallet and Metamask is installed at the same time.
else if (ethereum.providers?.length) {
const ethInstance = ethereum.providers.find((provider: any) => {
return provider[checker];
});
instances.set(Networks.ETHEREUM, ethInstance);
}
}
if (!!coinbaseSolana && lookingFor === 'coinbase') {
instances.set(Networks.SOLANA, coinbaseSolana);
}

if (instances.size === 0) {
return null;
}

if (lookingFor === 'metamask') {
return instances.get(Networks.ETHEREUM);
}

return instances;
}

export function sortWalletsBasedOnState(wallets: Wallet[]): Wallet[] {
return wallets.sort(
(a, b) =>
Expand Down

0 comments on commit 9a6734c

Please sign in to comment.