Skip to content

Commit

Permalink
chore: move namespaces info to provider and remove the hardcoded mapp…
Browse files Browse the repository at this point in the history
…ing in wallets-shared
  • Loading branch information
yeager-eren committed Jan 1, 2025
1 parent d072edb commit 63e289a
Show file tree
Hide file tree
Showing 15 changed files with 206 additions and 109 deletions.
4 changes: 2 additions & 2 deletions wallets/core/src/hub/store/providers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Namespace } from '../../namespaces/common/types.js';
import type { State as InternalProviderState } from '../provider/mod.js';
import type { CommonNamespaceKeys } from '../provider/types.js';
import type { StateCreator } from 'zustand';

import { produce } from 'immer';
Expand All @@ -8,7 +8,7 @@ import { guessProviderStateSelector, type State } from './mod.js';

type Browsers = 'firefox' | 'chrome' | 'edge' | 'brave' | 'homepage';
type Property<N extends string, V> = { name: N; value: V };
type DetachedInstances = Property<'detached', CommonNamespaceKeys[]>;
type DetachedInstances = Property<'detached', Namespace[]>;

export type ProviderInfo = {
name: string;
Expand Down
28 changes: 25 additions & 3 deletions wallets/core/src/legacy/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,28 @@ export type InstallObjects = {
DEFAULT: string;
};

interface NeedsNamespace {
selection: 'single' | 'multiple';
data: {
label: string;
/**
* By using a matched `blockchain.name` (in meta) and `id`, we show logo in Namespace modal
* e.g. ETH
*/
id: string;
value: Namespace;
}[];
}

interface NeedsDerivationPath {
data: {
id: string;
label: string;
namespace: Namespace;
generateDerivationPath: (index: string) => string;
}[];
}

export type WalletInfo = {
name: string;
img: string;
Expand All @@ -93,9 +115,9 @@ export type WalletInfo = {
showOnMobile?: boolean;
isContractWallet?: boolean;
mobileWallet?: boolean;
namespaces?: Namespace[];
singleNamespace?: boolean;
needsDerivationPath?: boolean;

needsDerivationPath?: NeedsDerivationPath;
needsNamespace?: NeedsNamespace;
};

export type State = {
Expand Down
53 changes: 50 additions & 3 deletions wallets/provider-ledger/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,56 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
},
color: 'black',
supportedChains,
namespaces: ['EVM', 'Solana'],
singleNamespace: true,
showOnMobile: false,
needsDerivationPath: true,
needsDerivationPath: {
data: [
{
id: 'metamask',
label: `Metamask (m/44'/60'/0'/0/index)`,
namespace: 'EVM',
generateDerivationPath: (index: string) => `44'/60'/0'/0/${index}`,
},
{
id: 'ledgerLive',
label: `LedgerLive (m/44'/60'/index'/0/0)`,
namespace: 'EVM',
generateDerivationPath: (index: string) => `44'/60'/${index}'/0/0`,
},
{
id: 'legacy',
label: `Legacy (m/44'/60'/0'/index)`,
namespace: 'EVM',
generateDerivationPath: (index: string) => `44'/60'/0'/${index}`,
},
{
id: `(m/44'/501'/index')`,
label: `(m/44'/501'/index')`,
namespace: 'Solana',
generateDerivationPath: (index: string) => `44'/501'/${index}'`,
},
{
id: `(m/44'/501'/0'/index)`,
label: `(m/44'/501'/0'/index)`,
namespace: 'Solana',
generateDerivationPath: (index: string) => `44'/501'/0'/${index}`,
},
],
},

needsNamespace: {
selection: 'single',
data: [
{
label: 'EVM',
value: 'EVM',
id: 'ETH',
},
{
label: 'Solana',
value: 'Solana',
id: 'SOLANA',
},
],
},
};
};
2 changes: 1 addition & 1 deletion wallets/provider-phantom/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const info: ProviderInfo = {
{
name: 'detached',
// if you are adding a new namespace, don't forget to also update `getWalletInfo`
value: ['solana', 'evm'],
value: ['Solana', 'EVM'],
},
],
};
16 changes: 16 additions & 0 deletions wallets/provider-phantom/src/legacy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
EVM_SUPPORTED_CHAINS.includes(chain.name as Networks)
),
],

needsNamespace: {
selection: 'multiple',
data: [
{
label: 'EVM',
value: 'EVM',
id: 'ETH',
},
{
label: 'Solana',
value: 'Solana',
id: 'SOLANA',
},
],
},
};
};

Expand Down
49 changes: 46 additions & 3 deletions wallets/provider-trezor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
if (ethereumBlockchain) {
supportedChains.push(ethereumBlockchain);
}

return {
name: 'Trezor',
img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/trezor/icon.svg',
Expand All @@ -95,9 +96,51 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
},
color: 'black',
supportedChains,
namespaces: ['EVM'],
singleNamespace: true,
showOnMobile: false,
needsDerivationPath: true,

needsNamespace: {
selection: 'single',
data: [
{
id: 'ETH',
value: 'EVM',
label: 'Ethereum',
},
],
},
needsDerivationPath: {
data: [
{
id: 'metamask',
label: `Metamask (m/44'/60'/0'/0/index)`,
namespace: 'EVM',
generateDerivationPath: (index: string) => `44'/60'/0'/0/${index}`,
},
{
id: 'ledgerLive',
label: `LedgerLive (m/44'/60'/index'/0/0)`,
namespace: 'EVM',
generateDerivationPath: (index: string) => `44'/60'/${index}'/0/0`,
},
{
id: 'legacy',
label: `Legacy (m/44'/60'/0'/index)`,
namespace: 'EVM',
generateDerivationPath: (index: string) => `44'/60'/0'/${index}`,
},
{
id: `(m/44'/501'/index')`,
label: `(m/44'/501'/index')`,
namespace: 'Solana',
generateDerivationPath: (index: string) => `44'/501'/${index}'`,
},
{
id: `(m/44'/501'/0'/index)`,
label: `(m/44'/501'/0'/index)`,
namespace: 'Solana',
generateDerivationPath: (index: string) => `44'/501'/0'/${index}`,
},
],
},
};
};
9 changes: 7 additions & 2 deletions wallets/react/src/hub/useHubAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,18 +280,23 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
}
});

const walletInfoFromLegacy = provider.getWalletInfo(
params.allBlockChains || []
);

return {
name: info.name,
img: info.icon,
installLink: installLink,
// We don't have this values anymore, fill them with some values that communicate this.
color: 'red',
supportedChains: provider.getWalletInfo(params.allBlockChains || [])
.supportedChains,
supportedChains: walletInfoFromLegacy.supportedChains,
isContractWallet: false,
mobileWallet: false,
// if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate.
showOnMobile: undefined,
needsNamespace: walletInfoFromLegacy.needsNamespace,
needsDerivationPath: walletInfoFromLegacy.needsDerivationPath,

isHub: true,
properties: wallet.info()?.properties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export function WalletList(props: PropTypes) {
const isDisconnected = wallet.state === WalletState.DISCONNECTED;
const isConnectedButDifferentThanTargetNamespace = wallet.isHub
? !conciseAddress
: !!wallet.namespaces && !conciseAddress;
: !!wallet.needsNamespace && !conciseAddress;

if (isDisconnected) {
setSelectedWalletToConnect(wallet);
Expand Down
67 changes: 30 additions & 37 deletions widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
Radio,
RadioRoot,
} from '@rango-dev/ui';
import { namespaces } from '@rango-dev/wallets-shared';
import React, { useMemo, useState } from 'react';
import React, { useState } from 'react';

import { useAppStore } from '../../store/AppStore';
import { WalletImageContainer } from '../HeaderButtons/HeaderButtons.styles';
Expand All @@ -23,25 +22,14 @@ import { getBlockchainLogo } from './Namespaces.helpers';
import { NamespaceList } from './Namespaces.styles';

export function Namespaces(props: PropTypes) {
const { singleNamespace, availableNamespaces, providerImage } = props.value;
const { targetWallet } = props.value;
const singleNamespace = targetWallet.needsNamespace?.selection === 'single';
const providerImage = targetWallet.image;

const [selectedNamespaces, setSelectedNamespaces] = useState<Namespace[]>([]);

const blockchains = useAppStore().blockchains();

const namespacesInfo = useMemo(
() =>
availableNamespaces?.map((namespace) => ({
name: namespace,
logo: getBlockchainLogo(
blockchains,
namespaces[namespace].mainBlockchain
),
title: namespaces[namespace].title,
})),
[availableNamespaces]
);

const onSelect = (namespace: Namespace) => {
if (singleNamespace) {
setSelectedNamespaces([namespace]);
Expand Down Expand Up @@ -83,28 +71,33 @@ export function Namespaces(props: PropTypes) {
<NamespaceList>
{wrapRadioRoot(
<>
{namespacesInfo?.map((namespaceInfoItem) => (
<ListItemButton
key={namespaceInfoItem.name}
id={namespaceInfoItem.name}
title={namespaceInfoItem.title}
hasDivider
style={{ height: 60 }}
onClick={() => onSelect(namespaceInfoItem.name)}
start={<Image src={namespaceInfoItem.logo} size={22} />}
end={
singleNamespace ? (
<Radio value={namespaceInfoItem.name} />
) : (
<Checkbox
checked={selectedNamespaces.includes(
namespaceInfoItem.name
)}
{targetWallet.needsNamespace?.data.map((ns) => {
return (
<ListItemButton
key={ns.id}
id={ns.id}
title={ns.label}
hasDivider
style={{ height: 60 }}
onClick={() => onSelect(ns.value)}
start={
<Image
src={getBlockchainLogo(blockchains, ns.id)}
size={22}
/>
)
}
/>
))}
}
end={
singleNamespace ? (
<Radio value={ns.value} />
) : (
<Checkbox
checked={selectedNamespaces.includes(ns.value)}
/>
)
}
/>
);
})}
</>
)}
</NamespaceList>
Expand Down
Loading

0 comments on commit 63e289a

Please sign in to comment.