diff --git a/src/app/components/account/account-title.tsx b/src/app/components/account/account-title.tsx
new file mode 100644
index 00000000000..ff094eb066c
--- /dev/null
+++ b/src/app/components/account/account-title.tsx
@@ -0,0 +1,28 @@
+import { BoxProps } from '@stacks/ui';
+
+import { SoftwareWalletAccountWithAddress } from '@app/store/accounts/account.models';
+import { Title } from '../typography';
+
+interface AccountTitlePlaceholderProps extends BoxProps {
+ account: SoftwareWalletAccountWithAddress;
+}
+export function AccountTitlePlaceholder({ account, ...rest }: AccountTitlePlaceholderProps) {
+ const name = `Account ${account?.index + 1}`;
+ return (
+
+ {name}
+
+ );
+}
+
+interface AccountTitleProps extends BoxProps {
+ account: SoftwareWalletAccountWithAddress;
+ name: string;
+}
+export function AccountTitle({ account, name, ...rest }: AccountTitleProps) {
+ return (
+
+ {name}
+
+ );
+}
diff --git a/src/app/features/account-picker/account-picker.layout.tsx b/src/app/features/account-picker/account-picker.layout.tsx
new file mode 100644
index 00000000000..f5b5d9b903a
--- /dev/null
+++ b/src/app/features/account-picker/account-picker.layout.tsx
@@ -0,0 +1,24 @@
+import { Flex, Stack, Text } from '@stacks/ui';
+
+import { AppIcon } from '@app/components/app-icon';
+import { Title } from '@app/components/typography';
+
+interface AccountPickerLayoutProps {
+ appName?: string;
+ children: React.ReactNode;
+}
+export function AccountPickerLayout(props: AccountPickerLayoutProps) {
+ const { appName, children } = props;
+ return (
+
+
+
+
+ Choose an account
+ to connect to {appName}
+
+
+ {children}
+
+ );
+}
diff --git a/src/app/pages/choose-account/components/accounts.tsx b/src/app/features/account-picker/accounts.tsx
similarity index 77%
rename from src/app/pages/choose-account/components/accounts.tsx
rename to src/app/features/account-picker/accounts.tsx
index ee0f6e864dd..ee1445d270a 100644
--- a/src/app/pages/choose-account/components/accounts.tsx
+++ b/src/app/features/account-picker/accounts.tsx
@@ -1,10 +1,10 @@
-import { useCallback, Suspense, memo, useState, useMemo } from 'react';
+import { Suspense, memo, useMemo } from 'react';
import { FiPlusCircle } from 'react-icons/fi';
import { Virtuoso } from 'react-virtuoso';
import { Box, BoxProps, color, FlexProps, Spinner, Stack } from '@stacks/ui';
import { truncateMiddle } from '@stacks/ui-utils';
-import { Caption, Text, Title } from '@app/components/typography';
+import { Caption, Text } from '@app/components/typography';
import { useAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { useWallet } from '@app/common/hooks/use-wallet';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
@@ -20,34 +20,11 @@ import {
import { slugify } from '@app/common/utils';
import { useAccounts, useHasCreatedAccount } from '@app/store/accounts/account.hooks';
import { useAddressBalances } from '@app/query/balance/balance.hooks';
+import { AccountTitle, AccountTitlePlaceholder } from '@app/components/account/account-title';
const loadingProps = { color: '#A1A7B3' };
const getLoadingProps = (loading: boolean) => (loading ? loadingProps : {});
-interface AccountTitlePlaceholderProps extends BoxProps {
- account: SoftwareWalletAccountWithAddress;
-}
-const AccountTitlePlaceholder = ({ account, ...rest }: AccountTitlePlaceholderProps) => {
- const name = `Account ${account?.index + 1}`;
- return (
-
- {name}
-
- );
-};
-
-interface AccountTitleProps extends BoxProps {
- account: SoftwareWalletAccountWithAddress;
- name: string;
-}
-const AccountTitle = ({ account, name, ...rest }: AccountTitleProps) => {
- return (
-
- {name}
-
- );
-};
-
interface AccountItemProps extends FlexProps {
selectedAddress?: string | null;
isLoading: boolean;
@@ -131,21 +108,14 @@ const AddAccountAction = memo(() => {
);
});
-export const Accounts = memo(() => {
- const { wallet, finishSignIn } = useWallet();
- const accounts = useAccounts();
- const { decodedAuthRequest } = useOnboardingState();
- const [selectedAccount, setSelectedAccount] = useState(null);
-
- const signIntoAccount = useCallback(
- async (index: number) => {
- setSelectedAccount(index);
- await finishSignIn(index);
- },
- [finishSignIn]
- );
+interface AccountPickerProps {
+ selectedAccountIndex: number | null;
+ onAccountSelected(index: number): void;
+}
+export function AccountPicker(props: AccountPickerProps) {
+ const { onAccountSelected, selectedAccountIndex } = props;
- if (!wallet || !accounts || !decodedAuthRequest) return null;
+ const accounts = useAccounts();
return (
<>
@@ -158,12 +128,12 @@ export const Accounts = memo(() => {
itemContent={(index, account) => (
onAccountSelected(index)}
/>
)}
/>
>
);
-});
+}
diff --git a/src/app/pages/account-authentication/account-authentication.tsx b/src/app/pages/account-authentication/account-authentication.tsx
new file mode 100644
index 00000000000..237d6e09a30
--- /dev/null
+++ b/src/app/pages/account-authentication/account-authentication.tsx
@@ -0,0 +1,45 @@
+import { memo, useCallback, useEffect, useState } from 'react';
+
+import { useRouteHeader } from '@app/common/hooks/use-route-header';
+import { useWallet } from '@app/common/hooks/use-wallet';
+import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
+import { Header } from '@app/components/header';
+import { AccountPicker } from '@app/features/account-picker/accounts';
+import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
+import { useAccounts } from '@app/store/accounts/account.hooks';
+import { AccountPickerLayout } from '@app/features/account-picker/account-picker.layout';
+
+export const AuthenticateAccount = memo(() => {
+ const accounts = useAccounts();
+ const { name: appName } = useAppDetails();
+ const { decodedAuthRequest } = useOnboardingState();
+ const { cancelAuthentication, wallet, finishSignIn } = useWallet();
+ const [selectedAccountIndex, setSelectedAccountIndex] = useState(null);
+
+ useRouteHeader();
+
+ const signIntoAccount = async (index: number) => {
+ setSelectedAccountIndex(index);
+ await finishSignIn(index);
+ };
+
+ const handleUnmount = useCallback(async () => {
+ cancelAuthentication();
+ }, [cancelAuthentication]);
+
+ useEffect(() => {
+ window.addEventListener('beforeunload', handleUnmount);
+ return () => window.removeEventListener('beforeunload', handleUnmount);
+ }, [handleUnmount]);
+
+ if (!wallet || !accounts || !decodedAuthRequest) return null;
+
+ return (
+
+ signIntoAccount(index)}
+ selectedAccountIndex={selectedAccountIndex}
+ />
+
+ );
+});
diff --git a/src/app/pages/choose-account-request/account-request.tsx b/src/app/pages/choose-account-request/account-request.tsx
new file mode 100644
index 00000000000..a9c13d53f90
--- /dev/null
+++ b/src/app/pages/choose-account-request/account-request.tsx
@@ -0,0 +1,39 @@
+import { useRouteHeader } from '@app/common/hooks/use-route-header';
+import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
+import { Header } from '@app/components/header';
+import { AccountPicker } from '@app/features/account-picker/accounts';
+import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
+import { useAccounts } from '@app/store/accounts/account.hooks';
+import { AccountPickerLayout } from '@app/features/account-picker/account-picker.layout';
+
+export function AccountRequest() {
+ const accounts = useAccounts();
+ const { name: appName } = useAppDetails();
+ const { decodedAuthRequest } = useOnboardingState();
+ // const [selectedAccountIndex, setSelectedAccountIndex] = useState(null);
+
+ useRouteHeader();
+
+ const returnAccountDetailsToApp = async (index: number) => {
+ // setSelectedAccountIndex(index);
+ // await finishSignIn(index);
+ };
+
+ // const handleUnmount = useCallback(async () => {
+ // cancelAuthentication();
+ // }, [cancelAuthentication]);
+
+ // useEffect(() => {
+ // window.addEventListener('beforeunload', handleUnmount);
+ // return () => window.removeEventListener('beforeunload', handleUnmount);
+ // }, [handleUnmount]);
+
+ return (
+
+ returnAccountDetailsToApp(index)}
+ selectedAccountIndex={0}
+ />
+
+ );
+}
diff --git a/src/app/pages/choose-account/choose-account.tsx b/src/app/pages/choose-account/choose-account.tsx
deleted file mode 100644
index eb2ef917cb1..00000000000
--- a/src/app/pages/choose-account/choose-account.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { memo, useCallback, useEffect } from 'react';
-import { Flex, Stack, Text } from '@stacks/ui';
-
-import { useRouteHeader } from '@app/common/hooks/use-route-header';
-import { Title } from '@app/components/typography';
-import { AppIcon } from '@app/components/app-icon';
-import { useWallet } from '@app/common/hooks/use-wallet';
-import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
-import { Header } from '@app/components/header';
-import { Accounts } from '@app/pages/choose-account/components/accounts';
-
-export const ChooseAccount = memo(() => {
- const { name: appName } = useAppDetails();
- const { cancelAuthentication } = useWallet();
-
- useRouteHeader();
-
- const handleUnmount = useCallback(async () => {
- cancelAuthentication();
- }, [cancelAuthentication]);
-
- useEffect(() => {
- window.addEventListener('beforeunload', handleUnmount);
- return () => window.removeEventListener('beforeunload', handleUnmount);
- }, [handleUnmount]);
-
- return (
-
-
-
-
- Choose an account
- to connect to {appName}
-
-
-
-
- );
-});
diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx
index cc9e90159d7..1e33e4061b9 100644
--- a/src/app/routes/app-routes.tsx
+++ b/src/app/routes/app-routes.tsx
@@ -5,7 +5,7 @@ import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { Container } from '@app/components/container/container';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { MagicRecoveryCode } from '@app/pages/onboarding/magic-recovery-code/magic-recovery-code';
-import { ChooseAccount } from '@app/pages/choose-account/choose-account';
+import { AuthenticateAccount } from '@app/pages/account-authentication/account-authentication';
import { TransactionRequest } from '@app/pages/transaction-request/transaction-request';
import { SignIn } from '@app/pages/onboarding/sign-in/sign-in';
import { ReceiveTokens } from '@app/pages/receive-tokens/receive-tokens';
@@ -112,7 +112,7 @@ export function AppRoutes(): JSX.Element | null {
element={
>}>
-
+
}
diff --git a/src/background/legacy-external-message-handler.ts b/src/background/legacy-external-message-handler.ts
index bbf468bd6e4..dfbcfa1c962 100644
--- a/src/background/legacy-external-message-handler.ts
+++ b/src/background/legacy-external-message-handler.ts
@@ -17,6 +17,8 @@ async function openRequestInFullPage(path: string, urlParams: URLSearchParams) {
export function inferLegacyMessage(message: any): message is LegacyMessageFromContentScript {
// Now that we use a RPC communication style, we can infer
// legacy message types by presence of an id
+ // Types incorrectly state this is `undefined`
+ // @ts-ignore
return !Object.hasOwn(message, 'id');
}
diff --git a/src/inpage/inpage.ts b/src/inpage/inpage.ts
index 0253411f553..f9e1937249d 100644
--- a/src/inpage/inpage.ts
+++ b/src/inpage/inpage.ts
@@ -155,3 +155,9 @@ declare global {
randomUUID: () => string;
}
}
+
+// declare global {
+// interface Window {
+// StacksProvider?: Provider;
+// }
+// }