Skip to content

Commit

Permalink
Merge branch 'ledger-btc-mvp' of github.com:secretkeylabs/xverse-web-…
Browse files Browse the repository at this point in the history
…extension into ledger-btc-mvp
  • Loading branch information
dhriaznov committed Jul 7, 2023
2 parents 2f1961e + d0b6254 commit f02989e
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 105 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@
2. Check `Developer mode`
3. Click on `Load unpacked extension`
4. Select the `build` folder.

### Developing with local dependencies

Use esm build, and reference your filesystem in package.json

For example, if your xverse-core and xverse-web-extension are in same directory,
make or pull your local changes to xverse-core, then:

```
cd ../xverse-core && npm i && npm run build:esm && \
cd $OLDPWD && npm i --legacy-peer-deps @secretkeylabs/xverse-core@../xverse-core && npm start
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"@stacks/connect": "^6.10.2",
"@stacks/encryption": "4.3.5",
"@stacks/stacks-blockchain-api-types": "^6.1.1",
"@stacks/transactions": "^4.3.8",
"@tanstack/query-sync-storage-persister": "^4.29.1",
"@tanstack/react-query": "^4.29.3",
"@tanstack/react-query-devtools": "^4.29.3",
"@tanstack/react-query-persist-client": "^4.29.3",
"@stacks/transactions": "^4.3.8",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
74 changes: 74 additions & 0 deletions src/app/hooks/useResetUserFlow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';

const resetUserFlowChannel = 'resetUserFlow';

/*
* Extend UserFlowConfigKey here
*
* resetTo: should be a valid route
*
*/
const userFlowConfig: Record<string, { resetTo: string }> = {
'/send-btc': { resetTo: '/send-btc' },
'/confirm-btc-tx': { resetTo: '/send-btc' },
'/send-brc20': { resetTo: '/send-brc20' },
'/confirm-inscription-request': { resetTo: '/send-brc20' },
'/ordinal-detail': { resetTo: '/nft-dashboard' },
'/send-ordinal': { resetTo: '/nft-dashboard' },
'/confirm-ordinal-tx': { resetTo: '/nft-dashboard' },
'/nft-detail': { resetTo: '/nft-dashboard' },
'/send-nft': { resetTo: '/nft-dashboard' },
'/confirm-nft-tx': { resetTo: '/nft-dashboard' },
};
type UserFlowConfigKey = keyof typeof userFlowConfig;

/*
* Usage:
*
* To subscribe:
* const { subscribeToResetUserFlow } = useResetUserFlow();
* useEffect(() => subscribeToResetUserFlow('/nft-detail'), []);
*
* To broadcast (once on first render):
* const { broadcastResetUserFlow, closeChannel } = useResetUserFlow();
* useEffect(() => broadcastResetUserFlow(), []);
*
* Both subscribe and broadcast methods return the cleanup callback,
* but you can also use closeChannel, which only returns a close callback:
* const { closeChannel } = useResetUserFlow();
* useEffect(() => closeChannel, []);
*
*/
export const useResetUserFlow = () => {
const navigate = useNavigate();

const resetUserFlow = (path: UserFlowConfigKey) => {
// TODO: infer UserFlowConfigKey from location?
if (!userFlowConfig[path]) {
return;
}
navigate(userFlowConfig[path]?.resetTo);
};

const broadcastChannel = useMemo(() => new BroadcastChannel(resetUserFlowChannel), []);
const closeChannel = () => broadcastChannel.close();

const broadcastResetUserFlow = () => {
broadcastChannel.postMessage('reset');
return closeChannel;
};

const subscribeToResetUserFlow = (path: UserFlowConfigKey) => {
broadcastChannel.onmessage = (message) => {
if (message.data !== 'reset') {
return;
}
resetUserFlow(path);
};
return closeChannel;
};
return { subscribeToResetUserFlow, broadcastResetUserFlow, closeChannel };
};

export default useResetUserFlow;
11 changes: 8 additions & 3 deletions src/app/screens/accountList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import styled from 'styled-components';
import Plus from '@assets/img/dashboard/plus.svg';
import ConnectLedger from '@assets/img/dashboard/connect_ledger.svg';
import { useDispatch } from 'react-redux';
import { selectAccount, setShouldResetUserFlow } from '@stores/wallet/actions/actionCreators';
import { selectAccount } from '@stores/wallet/actions/actionCreators';
import Seperator from '@components/seperator';
import { Account } from '@secretkeylabs/xverse-core/types';
import useWalletSelector from '@hooks/useWalletSelector';
import useWalletReducer from '@hooks/useWalletReducer';
import React, { useMemo } from 'react';
import React, { useEffect, useMemo } from 'react';
import { useResetUserFlow } from '@hooks/useResetUserFlow';

const Container = styled.div`
display: flex;
Expand Down Expand Up @@ -89,6 +90,10 @@ function AccountList(): JSX.Element {
return accountsList;
}, [accountsList, ledgerAccountsList, network]);

const { broadcastResetUserFlow, closeChannel } = useResetUserFlow();
// destructor
useEffect(() => closeChannel, []);

const handleAccountSelect = (account: Account) => {
dispatch(
selectAccount(
Expand All @@ -106,7 +111,7 @@ function AccountList(): JSX.Element {
account.accountName
)
);
dispatch(setShouldResetUserFlow(true));
broadcastResetUserFlow();
navigate('/');
};

Expand Down
19 changes: 4 additions & 15 deletions src/app/screens/confirmBtcTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import useBtcClient from '@hooks/useBtcClient';
import { isLedgerAccount } from '@utils/helper';
import BigNumber from 'bignumber.js';
import { LedgerTransactionType } from '@screens/ledger/confirmLedgerTransaction';
import { useDispatch } from 'react-redux';
import { setShouldResetUserFlow } from '@stores/wallet/actions/actionCreators';
import { useResetUserFlow } from '@hooks/useResetUserFlow';

const BottomBarContainer = styled.h1((props) => ({
marginTop: props.theme.spacing(5),
Expand All @@ -27,7 +26,7 @@ const BottomBarContainer = styled.h1((props) => ({
function ConfirmBtcTransaction() {
const navigate = useNavigate();
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });
const { ordinalsAddress, btcAddress, selectedAccount, shouldResetUserFlow } = useWalletSelector();
const { ordinalsAddress, btcAddress, selectedAccount } = useWalletSelector();
const btcClient = useBtcClient();
const [recipientAddress, setRecipientAddress] = useState('');
const [signedTx, setSignedTx] = useState<string>('');
Expand All @@ -41,7 +40,6 @@ function ConfirmBtcTransaction() {
fee, amount, signedTxHex, recipient, isRestoreFundFlow, unspentUtxos, isBrc20TokenFlow,
feePerVByte,
} = location.state;
const dispatch = useDispatch();

const {
isLoading,
Expand All @@ -62,17 +60,8 @@ function ConfirmBtcTransaction() {
});
};

useEffect(() => {
if (shouldResetUserFlow) {
navigate('/send-btc', {
state: {
amount,
recipientAddress,
},
});
dispatch(setShouldResetUserFlow(false));
}
}, [shouldResetUserFlow]);
const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/confirm-btc-tx'), []);

const onContinueButtonClick = () => {
mutate({ signedTx });
Expand Down
6 changes: 5 additions & 1 deletion src/app/screens/confirmInscriptionRequest/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import OrdinalsIcon from '@assets/img/nftDashboard/white_ordinals_icon.svg';
import SettingIcon from '@assets/img/dashboard/faders_horizontal.svg';
import { isLedgerAccount } from '@utils/helper';
import { LedgerTransactionType } from '@screens/ledger/confirmLedgerTransaction';
import { useResetUserFlow } from '@hooks/useResetUserFlow';

const OuterContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -137,7 +138,7 @@ function ConfirmInscriptionRequest() {
feePerVByte,
} = location.state;
const {
btcAddress, network, selectedAccount, seedPhrase, btcFiatRate,
btcAddress, network, selectedAccount, seedPhrase, btcFiatRate
} = useWalletSelector();
const btcClient = useBtcClient();
const [signedTx, setSignedTx] = useState<string>('');
Expand All @@ -152,6 +153,9 @@ function ConfirmInscriptionRequest() {

const content = useMemo(() => textContent && JSON.parse(textContent), [textContent]);

const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/confirm-inscription-request'), []);

useEffect(() => {
axios
.get<string>(brcContent, {
Expand Down
15 changes: 4 additions & 11 deletions src/app/screens/confirmNftTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useEffect } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { StacksTransaction } from '@secretkeylabs/xverse-core/types';
import { broadcastSignedTransaction } from '@secretkeylabs/xverse-core/transactions';
import ArrowLeft from '@assets/img/dashboard/arrow_left.svg';
import BottomBar from '@components/tabBar';
import AssetIcon from '@assets/img/transactions/Assets.svg';
import ConfirmStxTransationComponent from '@components/confirmStxTransactionComponent';
Expand All @@ -20,8 +19,7 @@ import useWalletSelector from '@hooks/useWalletSelector';
import useStxWalletData from '@hooks/queries/useStxWalletData';
import { isLedgerAccount } from '@utils/helper';
import { LedgerTransactionType } from '@screens/ledger/confirmLedgerTransaction';
import { setShouldResetUserFlow } from '@stores/wallet/actions/actionCreators';
import { useDispatch } from 'react-redux';
import { useResetUserFlow } from '@hooks/useResetUserFlow';

const ScrollContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -98,10 +96,9 @@ const ReviewTransactionText = styled.h1((props) => ({
function ConfirmNftTransaction() {
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });
const isGalleryOpen: boolean = document.documentElement.clientWidth > 360;
const { selectedAccount, shouldResetUserFlow } = useWalletSelector();
const { selectedAccount } = useWalletSelector();
const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
const { id } = useParams();
const { nftData } = useNftDataSelector();
const nftIdDetails = id!.split('::');
Expand Down Expand Up @@ -164,12 +161,8 @@ function ConfirmNftTransaction() {
mutate({ signedTx: txs[0] });
};

useEffect(() => {
if (shouldResetUserFlow) {
navigate('/nft-dashboard');
dispatch(setShouldResetUserFlow(false));
}
}, [shouldResetUserFlow]);
const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/confirm-nft-tx'), []);

const handleOnCancelClick = () => {
navigate(-1);
Expand Down
15 changes: 4 additions & 11 deletions src/app/screens/confirmOrdinalTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import styled from 'styled-components';
import { useMutation } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import ArrowLeft from '@assets/img/dashboard/arrow_left.svg';
import BottomBar from '@components/tabBar';
import useNftDataSelector from '@hooks/stores/useNftDataSelector';
import AccountHeaderComponent from '@components/accountHeader';
Expand All @@ -16,8 +15,7 @@ import useBtcClient from '@hooks/useBtcClient';
import { isLedgerAccount } from '@utils/helper';
import useWalletSelector from '@hooks/useWalletSelector';
import { LedgerTransactionType } from '@screens/ledger/confirmLedgerTransaction';
import { useDispatch } from 'react-redux';
import { setShouldResetUserFlow } from '@stores/wallet/actions/actionCreators';
import { useResetUserFlow } from '@hooks/useResetUserFlow';

const ScrollContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -91,12 +89,11 @@ const NftContainer = styled.div((props) => ({
function ConfirmOrdinalTransaction() {
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });
const isGalleryOpen: boolean = document.documentElement.clientWidth > 360;
const { selectedAccount, shouldResetUserFlow } = useWalletSelector();
const { selectedAccount } = useWalletSelector();
const navigate = useNavigate();
const btcClient = useBtcClient();
const [recipientAddress, setRecipientAddress] = useState('');
const location = useLocation();
const dispatch = useDispatch();
const {
fee, feePerVByte, signedTxHex, ordinalUtxo,
} = location.state;
Expand Down Expand Up @@ -157,12 +154,8 @@ function ConfirmOrdinalTransaction() {
navigate(-1);
};

useEffect(() => {
if (shouldResetUserFlow) {
navigate('/nft-dashboard');
dispatch(setShouldResetUserFlow(false));
}
}, [shouldResetUserFlow]);
const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/confirm-ordinal-tx'), []);

return (
<>
Expand Down
4 changes: 4 additions & 0 deletions src/app/screens/nftDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { NftDetailResponse } from '@secretkeylabs/xverse-core/types';
import { MoonLoader } from 'react-spinners';
import AccountHeaderComponent from '@components/accountHeader';
import SmallActionButton from '@components/smallActionButton';
import { useResetUserFlow } from '@hooks/useResetUserFlow';
import NftAttribute from './nftAttribute';
import DescriptionTile from './descriptionTile';

Expand Down Expand Up @@ -272,6 +273,9 @@ function NftDetailScreen() {
const [showShareNftOptions, setShowNftOptions] = useState<boolean>(false);
const isGalleryOpen: boolean = document.documentElement.clientWidth > 360;

const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/nft-detail'), []);

useEffect(() => {
const data = nftData.find((nftItem) => Number(nftItem?.token_id) === Number(nftIdDetails[2].slice(1)));
if (!data) {
Expand Down
4 changes: 4 additions & 0 deletions src/app/screens/ordinalDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import styled, { useTheme } from 'styled-components';
import { useResetUserFlow } from '@hooks/useResetUserFlow';
import OrdinalAttributeComponent from './ordinalAttributeComponent';

const Container = styled.div`
Expand Down Expand Up @@ -286,6 +287,9 @@ function OrdinalDetailScreen() {
[selectedOrdinal],
);

const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/ordinal-detail'), []);

useEffect(() => {
if (selectedOrdinal) {
if (
Expand Down
8 changes: 6 additions & 2 deletions src/app/screens/sendBrc20/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components';
import BigNumber from 'bignumber.js';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation, useNavigate } from 'react-router-dom';
import {
Expand All @@ -10,6 +10,7 @@ import {
ErrorCodes,
} from '@secretkeylabs/xverse-core';
import { Recipient } from '@secretkeylabs/xverse-core/transactions/btc';
import { useResetUserFlow } from '@hooks/useResetUserFlow';
import useWalletSelector from '@hooks/useWalletSelector';
import TopRow from '@components/topRow';
import BottomBar from '@components/tabBar';
Expand Down Expand Up @@ -53,7 +54,7 @@ function SendBrc20Screen() {
const { t } = useTranslation('translation');
const navigate = useNavigate();
const {
btcAddress, ordinalsAddress, selectedAccount, seedPhrase, network, btcFiatRate, brcCoinsList,
btcAddress, ordinalsAddress, selectedAccount, seedPhrase, network, btcFiatRate, brcCoinsList
} = useWalletSelector();
const [amountError, setAmountError] = useState('');
const [amountToSend, setAmountToSend] = useState('');
Expand All @@ -65,6 +66,9 @@ function SendBrc20Screen() {
const coinName = location.search ? location.search.split('coinName=')[1] : undefined;
const fungibleToken = location.state?.fungibleToken || brcCoinsList?.find((coin) => coin.name === coinName);

const { subscribeToResetUserFlow } = useResetUserFlow();
useEffect(() => subscribeToResetUserFlow('/send-brc20'), []);

const handleBackButtonClick = () => {
if (showForm) {
setAmountError('');
Expand Down
Loading

0 comments on commit f02989e

Please sign in to comment.