Skip to content

Commit

Permalink
feat: cancel tx
Browse files Browse the repository at this point in the history
  • Loading branch information
alter-eggo committed Oct 17, 2024
1 parent 1df5138 commit cba2012
Show file tree
Hide file tree
Showing 21 changed files with 452 additions and 231 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
"@leather.io/crypto": "1.6.2",
"@leather.io/models": "0.17.0",
"@leather.io/query": "2.14.1",
"@leather.io/stacks": "1.1.5",
"@leather.io/stacks": "1.2.0",
"@leather.io/tokens": "0.9.0",
"@leather.io/ui": "1.27.1",
"@leather.io/utils": "0.15.0",
Expand Down
14 changes: 7 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 1 addition & 15 deletions src/app/common/hooks/use-submit-stx-transaction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useCallback } from 'react';

import { bytesToHex } from '@stacks/common';
import { StacksTransaction, broadcastTransaction } from '@stacks/transactions';

import { delay, isError } from '@leather.io/utils';
Expand All @@ -14,7 +13,6 @@ import { useLoading } from '@app/common/hooks/use-loading';
import { safelyFormatHexTxid } from '@app/common/utils/safe-handle-txid';
import { useToast } from '@app/features/toasts/use-toast';
import { useCurrentStacksNetworkState } from '@app/store/networks/networks.hooks';
import { useSubmittedTransactionsActions } from '@app/store/submitted-transactions/submitted-transactions.hooks';

const timeForApiToUpdate = 250;

Expand All @@ -27,7 +25,6 @@ interface UseSubmitTransactionCallbackArgs {
onError(error: Error | string): void;
}
export function useSubmitTransactionCallback({ loadingKey }: UseSubmitTransactionArgs) {
const submittedTransactionsActions = useSubmittedTransactionsActions();
const toast = useToast();
const refreshAccountData = useRefreshAllAccountData();

Expand All @@ -47,10 +44,6 @@ export function useSubmitTransactionCallback({ loadingKey }: UseSubmitTransactio
setIsIdle();
} else {
logger.info('Transaction broadcast', response);
submittedTransactionsActions.newTransactionSubmitted({
rawTx: bytesToHex(transaction.serialize()),
txid: safelyFormatHexTxid(response.txid),
});

await delay(500);

Expand All @@ -65,13 +58,6 @@ export function useSubmitTransactionCallback({ loadingKey }: UseSubmitTransactio
setIsIdle();
}
},
[
setIsLoading,
stacksNetwork,
toast,
setIsIdle,
submittedTransactionsActions,
refreshAccountData,
]
[setIsLoading, stacksNetwork, toast, setIsIdle, refreshAccountData]
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { css } from 'leather-styles/css';
import { HStack, styled } from 'leather-styles/jsx';

import { ChevronDownIcon, ChevronsRightIcon, CloseIcon, DropdownMenu, Flag } from '@leather.io/ui';

interface Props {
onIncreaseFee(): void;
onCancelTransaction(): void;
}

export function StacksTransactionActionMenu({ onIncreaseFee, onCancelTransaction }: Props) {
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger
className={css({
zIndex: 10,
borderRadius: 'sm',
px: 'space.01',
_hover: {
background: 'ink.component-background-hover',
},
})}
>
<Flag spacing="space.02" reverse img={<ChevronDownIcon variant="small" />}>
<styled.span textStyle="label.03">Options</styled.span>
</Flag>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content
align="end"
side="bottom"
sideOffset={8}
className={css({
zIndex: 100,
width: 'settingsMenuWidth',
})}
>
<DropdownMenu.Group>
<DropdownMenu.Item
data-testid={''}
onClick={e => {
e.stopPropagation();
onIncreaseFee();
}}
>
<HStack>
<ChevronsRightIcon />
<styled.span textStyle="label.02">Increase fee</styled.span>
</HStack>
</DropdownMenu.Item>
<DropdownMenu.Item
data-testid={''}
onClick={e => {
e.stopPropagation();
onCancelTransaction();
}}
>
<HStack>
<CloseIcon />
<styled.span textStyle="label.02">Cancel transaction</styled.span>
</HStack>
</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useLocation, useNavigate } from 'react-router-dom';
import { useLocation, useMatch, useNavigate } from 'react-router-dom';

Check failure on line 1 in src/app/components/stacks-transaction-item/stacks-transaction-item.tsx

View workflow job for this annotation

GitHub Actions / typecheck

'useLocation' is declared but its value is never read.

import { StacksTx } from '@leather.io/models';

Expand All @@ -20,7 +20,7 @@ import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/s
import { useIsPrivateMode } from '@app/store/settings/settings.selectors';

import { TransactionItemLayout } from '../transaction-item/transaction-item.layout';
import { IncreaseFeeButton } from './increase-fee-button';
import { StacksTransactionActionMenu } from './stacks-transaction-action-menu';
import { StacksTransactionIcon } from './stacks-transaction-icon';
import { StacksTransactionStatus } from './stacks-transaction-status';

Expand All @@ -44,7 +44,6 @@ export function StacksTransactionItem({
const currentAccount = useCurrentStacksAccount();
const isPrivate = useIsPrivateMode();

const { pathname } = useLocation();
const navigate = useNavigate();
const { whenWallet } = useWalletType();

Expand All @@ -58,10 +57,21 @@ export function StacksTransactionItem({
});
};

const onIncreaseFee = () => {
const isOriginator = transaction?.sender_address === currentAccount?.address;
const isPending = transaction && isPendingTx(transaction);

const txCaption = transaction ? getTxCaption(transaction) : caption || '';
const txIcon = transaction ? <StacksTransactionIcon transaction={transaction} /> : icon;
const txTitle = transaction ? getTxTitle(transaction) : title || '';
const txValue = transaction ? getTxValue(transaction, isOriginator) : value;

function handleTransactionAction(action: 'cancel' | 'increaseFee') {
if (!transaction) return;

const routeUrl = RouteUrls.IncreaseStxFee.replace(':txid', transaction.tx_id);
const routeUrl =
action === 'increaseFee'
? RouteUrls.IncreaseStacksFee.replace(':txid', transaction.tx_id)
: RouteUrls.CancelStacksTransaction.replace(':txid', transaction.tx_id);

whenWallet({
ledger: () =>
Expand All @@ -71,28 +81,27 @@ export function StacksTransactionItem({
})(),
software: () => navigate(routeUrl),
})();
};
}

const isOriginator = transaction?.sender_address === currentAccount?.address;
const isPending = transaction && isPendingTx(transaction);
const cancelTransactionMatch = useMatch(RouteUrls.CancelStacksTransaction);

Check failure on line 86 in src/app/components/stacks-transaction-item/stacks-transaction-item.tsx

View workflow job for this annotation

GitHub Actions / lint-eslint

React Hook "useMatch" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?
const increaseFeeMatch = useMatch(RouteUrls.IncreaseStacksFee);

Check failure on line 87 in src/app/components/stacks-transaction-item/stacks-transaction-item.tsx

View workflow job for this annotation

GitHub Actions / lint-eslint

React Hook "useMatch" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?

const isTransactionActionRoute = !!cancelTransactionMatch || !!increaseFeeMatch;

const txCaption = transaction ? getTxCaption(transaction) : caption || '';
const txIcon = transaction ? <StacksTransactionIcon transaction={transaction} /> : icon;
const txTitle = transaction ? getTxTitle(transaction) : title || '';
const txValue = transaction ? getTxValue(transaction, isOriginator) : value;
const increaseFeeButton = (
<IncreaseFeeButton
isEnabled={isOriginator && isPending}
isSelected={pathname === RouteUrls.IncreaseStxFee}
onIncreaseFee={onIncreaseFee}
/>
);
const txStatus = transaction && <StacksTransactionStatus transaction={transaction} />;

const rightElement =
isOriginator && isPending && !isTransactionActionRoute ? (
<StacksTransactionActionMenu
onIncreaseFee={() => handleTransactionAction('increaseFee')}
onCancelTransaction={() => handleTransactionAction('cancel')}
/>
) : undefined;

return (
<TransactionItemLayout
openTxLink={openTxLink}
rightElement={isOriginator && isPending ? increaseFeeButton : undefined}
rightElement={rightElement}
txCaption={txCaption}
txIcon={txIcon}
txStatus={txStatus}
Expand Down

This file was deleted.

Loading

0 comments on commit cba2012

Please sign in to comment.