Skip to content

feat: Add CreateSnapAccount component #30611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion test/e2e/flask/solana/switching-network-accounts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ describe('Switching between account from different networks', function (this: Su
await headerNavbar.check_ifNetworkPickerClickable(true);
await headerNavbar.check_currentSelectedNetwork('Localhost 8545');
await headerNavbar.openAccountMenu();
await accountListPage.addAccount({ accountType: ACCOUNT_TYPE.Solana });
await accountListPage.addAccount({
accountType: ACCOUNT_TYPE.Solana,
accountName: 'Solana Account 2',
});
await headerNavbar.check_ifNetworkPickerClickable(true);
await headerNavbar.check_currentSelectedNetwork('Solana Mainnet');
await headerNavbar.check_accountLabel('Solana Account 2');
Expand Down
124 changes: 92 additions & 32 deletions ui/components/multichain/account-list-menu/account-list-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import {
KeyringAccountType,
///: END:ONLY_INCLUDE_IF
} from '@metamask/keyring-api';
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
import { CaipChainId } from '@metamask/utils';
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
import {
BITCOIN_WALLET_NAME,
Expand Down Expand Up @@ -77,10 +80,8 @@ import {
getIsSolanaSupportEnabled,
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(multi-srp,solana)
getMetaMaskHdKeyrings,
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
getHdKeyringOfSelectedAccountOrPrimaryKeyring,
getMetaMaskHdKeyrings,
///: END:ONLY_INCLUDE_IF
} from '../../../selectors';
import { setSelectedAccount } from '../../../store/actions';
Expand Down Expand Up @@ -131,6 +132,9 @@ import {
AccountOverviewTabKey,
} from '../../../../shared/constants/app-state';
import { CreateEthAccount } from '../create-eth-account';
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
import { CreateSnapAccount } from '../create-snap-account';
///: END:ONLY_INCLUDE_IF
import { ImportAccount } from '../import-account';
///: BEGIN:ONLY_INCLUDE_IF(solana)
import {
Expand Down Expand Up @@ -159,6 +163,10 @@ const ACTION_MODES = {
// Same but for testnet
ADD_BITCOIN_TESTNET: 'add-bitcoin-testnet',
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(solana)
// Displays the add account form controls (for solana account)
ADD_SOLANA: 'add-solana',
///: END:ONLY_INCLUDE_IF
// Displays the import account form controls
IMPORT: 'import',
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
Expand All @@ -168,6 +176,26 @@ const ACTION_MODES = {
///: END:ONLY_INCLUDE_IF
};

///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
const SNAP_CLIENT_CONFIG_MAP: Record<
string,
{ clientType: WalletClientType | null; chainId: CaipChainId | null }
> = {
[ACTION_MODES.ADD_BITCOIN]: {
clientType: WalletClientType.Bitcoin,
chainId: MultichainNetworks.BITCOIN,
},
[ACTION_MODES.ADD_BITCOIN_TESTNET]: {
clientType: WalletClientType.Bitcoin,
chainId: MultichainNetworks.BITCOIN_TESTNET,
},
[ACTION_MODES.ADD_SOLANA]: {
clientType: WalletClientType.Solana,
chainId: MultichainNetworks.SOLANA,
},
};
///: END:ONLY_INCLUDE_IF

/**
* Gets the title for a given action mode.
*
Expand All @@ -190,6 +218,10 @@ export const getActionTitle = (
case ACTION_MODES.ADD_BITCOIN_TESTNET:
return t('addAccount');
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(solana)
case ACTION_MODES.ADD_SOLANA:
return t('addAccount');
///: END:ONLY_INCLUDE_IF
case ACTION_MODES.IMPORT:
return t('importPrivateKey');
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
Expand Down Expand Up @@ -252,6 +284,11 @@ export const AccountListMenu = ({
///: END:ONLY_INCLUDE_IF
const [searchQuery, setSearchQuery] = useState('');
const [actionMode, setActionMode] = useState(ACTION_MODES.LIST);
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
const [previousActionMode, setPreviousActionMode] = useState(
ACTION_MODES.LIST,
);
///: END:ONLY_INCLUDE_IF(multi-srp)
const hiddenAddresses = useSelector(getHiddenAccountsList);
const updatedAccountsList = useSelector(getUpdatedAndSortedAccounts);
const filteredUpdatedAccountList = useMemo(
Expand All @@ -267,6 +304,9 @@ export const AccountListMenu = ({
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
const addSnapAccountEnabled = useSelector(getIsAddSnapAccountEnabled);
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
const multiSrpEnabled = true;
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
const isAddWatchEthereumAccountEnabled = useSelector(
getIsWatchEthereumAccountEnabled,
Expand Down Expand Up @@ -363,7 +403,7 @@ export const AccountListMenu = ({
onBack = () => setActionMode(ACTION_MODES.LIST);
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
} else if (actionMode === ACTION_MODES.SELECT_SRP) {
onBack = () => setActionMode(ACTION_MODES.ADD);
onBack = () => setActionMode(previousActionMode);
///: END:ONLY_INCLUDE_IF
} else {
onBack = () => setActionMode(ACTION_MODES.MENU);
Expand Down Expand Up @@ -445,6 +485,29 @@ export const AccountListMenu = ({
searchQuery,
]);

const onActionComplete = useCallback(
async (confirmed: boolean) => {
if (confirmed) {
onClose();
} else {
setActionMode(ACTION_MODES.LIST);
}
},
[onClose, setActionMode],
);

///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
const onSelectSrp = useCallback(() => {
setPreviousActionMode(actionMode);
setActionMode(ACTION_MODES.SELECT_SRP);
}, [setActionMode, actionMode]);

const { clientType, chainId } = SNAP_CLIENT_CONFIG_MAP[actionMode] || {
clientType: null,
chainId: null,
};
///: END:ONLY_INCLUDE_IF

return (
<Modal isOpen onClose={onClose}>
<ModalOverlay />
Expand All @@ -463,36 +526,37 @@ export const AccountListMenu = ({
{actionMode === ACTION_MODES.ADD ? (
<Box paddingLeft={4} paddingRight={4} paddingBottom={4}>
<CreateEthAccount
onActionComplete={(confirmed) => {
if (confirmed) {
onClose();
} else {
setActionMode(ACTION_MODES.LIST);
}
}}
onActionComplete={onActionComplete}
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
selectedKeyringId={selectedKeyringId}
onSelectSrp={() => setActionMode(ACTION_MODES.SELECT_SRP)}
onSelectSrp={onSelectSrp}
///: END:ONLY_INCLUDE_IF(multi-srp)
/>
</Box>
) : null}
{
///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
clientType && chainId ? (
<Box paddingLeft={4} paddingRight={4} paddingBottom={4}>
<CreateSnapAccount
onActionComplete={onActionComplete}
selectedKeyringId={selectedKeyringId}
onSelectSrp={onSelectSrp}
clientType={clientType}
chainId={chainId}
/>
</Box>
) : null
///: END:ONLY_INCLUDE_IF
}
{actionMode === ACTION_MODES.IMPORT ? (
<Box
paddingLeft={4}
paddingRight={4}
paddingBottom={4}
paddingTop={0}
>
<ImportAccount
onActionComplete={(confirmed) => {
if (confirmed) {
onClose();
} else {
setActionMode(ACTION_MODES.LIST);
}
}}
/>
<ImportAccount onActionComplete={onActionComplete} />
</Box>
) : null}
{
Expand All @@ -505,15 +569,7 @@ export const AccountListMenu = ({
paddingTop={0}
style={{ overflowY: 'scroll' }}
>
<ImportSrp
onActionComplete={(confirmed: boolean) => {
if (confirmed) {
onClose();
} else {
setActionMode(ACTION_MODES.LIST);
}
}}
/>
<ImportSrp onActionComplete={onActionComplete} />
</Box>
)
///: END:ONLY_INCLUDE_IF
Expand All @@ -524,7 +580,7 @@ export const AccountListMenu = ({
<SrpList
onActionComplete={(keyringId: string) => {
setSelectedKeyringId(keyringId);
setActionMode(ACTION_MODES.ADD);
setActionMode(previousActionMode);
}}
/>
)
Expand Down Expand Up @@ -582,12 +638,16 @@ export const AccountListMenu = ({
},
});

if (multiSrpEnabled) {
return setActionMode(ACTION_MODES.ADD_SOLANA);
}

// The account creation + renaming is handled by the
// Snap account bridge, so we need to close the current
// modal
onClose();

await solanaWalletSnapClient.createAccount(
return await solanaWalletSnapClient.createAccount(
MultichainNetworks.SOLANA,
primaryKeyring.metadata.id,
);
Expand Down
Loading
Loading