Skip to content
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

[CHORE]: Remove transaction inconsistencies and improve type safety #6137

Merged
merged 19 commits into from
Oct 10, 2024

Conversation

walmat
Copy link
Contributor

@walmat walmat commented Sep 24, 2024

What changed (plus any additional context for devs)

This PR cleans up a lot of the unused code stemming back from the transaction redux => Zustand refactor. A lot of our types were duplicated and all over the place. Now they all are in @/entities/transactions/... and can be referenced via @/entities.

I also coupled this PR with cleaning up the ProfileScreen => ActivityList since it's touching 100% of the transactions code. Noticed lots of things once converting those two files to typescript.

Note there are still a bit of casts as in this PR that I want to create smaller follow-up PRs for

Screen recordings / screenshots

Simulator.Screen.Recording.-.iPhone.16.Pro.-.2024-10-01.at.13.54.08.mp4

What to test

All things transactions

  • sends
  • swaps
  • mints
  • etc. etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typescript conversion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved all txn types into @/entities

package.json Outdated
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this types declaration file was missing when converting ActivityIndicator to typescript

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typescript conversion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> .tsx

Copy link

socket-security bot commented Oct 1, 2024

New dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@types/[email protected] None 0 7.64 kB types

View full report↗︎

const ActivityListHeaderHeight = 42;
const TRANSACTION_COIN_ROW_VERTICAL_PADDING = 7;

const getItemLayout = sectionListGetItemLayout({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was causing issues with the SectionList below, so I added a @ts-expect-error declaration for now. Maybe bumping react-native will fix it? But not worried about it for now.

Comment on lines +33 to +41
const keyExtractor = (data: TransactionSections['data'][number]) => {
if ('hash' in data) {
return (data.hash || data.timestamp ? data.timestamp?.toString() : performance.now().toString()) ?? performance.now().toString();
}
return (
(data.displayDetails?.timestampInMs ? data.displayDetails.timestampInMs.toString() : performance.now().toString()) ??
performance.now().toString()
);
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need the key extractor to always fallback to a string, so theoretically we should never hit performance.now calls, but added them in case we do.

const { accountAddress, nativeCurrency } = useAccountSettings();

const { setScrollToTopRef } = useSectionListScrollToTopContext();
const { sections, nextPage, transactionsCount, remainingItemsLabel } = useAccountTransactions();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the sections and transaction stuff in here instead of in ProfileScreen since we don't need to re-render the whole page just the list.


const handleScrollToTopRef = (ref: SectionList<TransactionItemForSectionList, TransactionSections> | null) => {
if (!ref) return;
// @ts-expect-error - no idea why this is not working
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

welcoming ideas on how to get this to work if anyone has one

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  const { setScrollToTopRef } = useSectionListScrollToTopContext<TransactionItemForSectionList, TransactionSections>();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THANK YOU

}}
testID={'wallet-activity-list'}
ListEmptyComponent={<ActivityListEmptyState />}
// @ts-expect-error - mismatch between react-native-section-list-get-item-layout and SectionList
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 34 to 41
const getStatusTitle = useCallback((status: TransactionStatus, title: string) => {
const transactionType = lang.l.transactions.type[title as keyof typeof lang.l.transactions.type];
if (typeof transactionType === 'string') {
return transactionType;
}
return transactionType[status as keyof typeof transactionType] || '';
}, []);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this was intentional or not, but our i18n for some keys had pending | failed | confirmed keys inside of lang.l.transactions.type. I need to test this to confirm.

@@ -61,7 +102,7 @@ export interface RainbowTransaction {
nonce?: number | null;
protocol?: ProtocolType | null;
flashbots?: boolean;
approvalAmount?: 'UNLIMITED' | (string & object);
approvalAmount?: 'UNLIMITED' | (string & Record<string, never>);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keeps type inference but loosens it at the same time

Comment on lines +129 to +135
export enum FlashbotsStatus {
PENDING = 'PENDING',
INCLUDED = 'INCLUDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
UNKNOWN = 'UNKNOWN',
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these were used in a couple different files, so collocated it here and expanded it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lot of stuff in this file was unused so just cleaned up

}
return {
sections: requestsToApprove.concat(sectionedTransactions),
sections: sectionedTransactions as SectionListData<TransactionItemForSectionList, TransactionSections>[],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't love this, but unsure how to make it work without casts

export { getRequestDisplayDetails } from './requests';
export { getDescription } from './transactions';
export { getDescription, convertNewTransactionToRainbowTransaction } from './transactions';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed parseNewTransaction to convertNewTransactionToRainbowTransaction to properly describe what it does

@@ -55,7 +61,7 @@ export async function claimBridge({ parameters, wallet, baseNonce }: ActionProps
const provider = getProvider({ chainId: ChainId.optimism });

const l1GasFeeOptimism = await ethereumUtils.calculateL1FeeOptimism(
// @ts-ignore
// @ts-expect-error - TODO: fix improper arguments here
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be fixed in the send sheet PR, so just ts-expect-error'd it for now

src/raps/references.ts Outdated Show resolved Hide resolved
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @benisgold for visibility, assuming i will need to rebase once your raps work is in?

import { ActivityList } from '../components/activity-list';
import { Page } from '../components/layout';
import { useNavigation } from '../navigation/Navigation';
import { ButtonPressAnimation } from '@/components/animations';
import { useAccountProfile, useAccountSettings, useAccountTransactions, useRequests } from '@/hooks';
import { useAccountProfile, useAccountSettings, useAccountTransactions } from '@/hooks';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useRequests was unused so cleaned up this file a lot

Copy link
Member

@derHowie derHowie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff. Just one question. ✅

src/components/activity-list/ActivityListEmptyState.tsx Outdated Show resolved Hide resolved
@brunobar79
Copy link
Member

Launch in simulator or device for 43d4fad

Comment on lines +65 to +73
useEffect(() => {
if (isLoading) {
onPress();
setIsLoading(false);
}
}, [isLoading, setIsLoading, onPress]);
const onPressWrapper = () => {
setIsLoading(true);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this work?
onPress sets isLoading to true, rerenders run props.onPress, then right after sets isLoading to false wouldn't that just quickly flash the loading component? unless onPress is doing some crazy expensive blocking work

is it not the same as

 const onPressWrapper = () => {
    setIsLoading(true);
    onPress();
    setIsLoading(false);
  };

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I didn't originally write this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaik this is just for fetching the next batch of transactions

Comment on lines +22 to +53
export enum TransactionStatus {
approved = 'approved',
approving = 'approving',
bridging = 'bridging',
bridged = 'bridged',
cancelled = 'cancelled',
cancelling = 'cancelling',
confirmed = 'confirmed',
contract_interaction = 'contract interaction',
deposited = 'deposited',
depositing = 'depositing',
dropped = 'dropped',
failed = 'failed',
minted = 'minted',
minting = 'minting',
pending = 'pending',
purchased = 'purchased',
purchasing = 'purchasing',
received = 'received',
receiving = 'receiving',
self = 'self',
selling = 'selling',
sold = 'sold',
sending = 'sending',
sent = 'sent',
speeding_up = 'speeding up',
swapped = 'swapped',
swapping = 'swapping',
unknown = 'unknown status',
withdrawing = 'withdrawing',
withdrew = 'withdrew',
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this for?
It was a pain to refactor something similar in the bx, I think it's more manageable to have transaction status as 'confirmed' | 'pending' | 'failed' and then in conjunction with transaction type 'swap' | 'send' | 'mint' | ...
we derive the label like a type: 'swap', status: 'confirmed' = 'swapped'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can further be cleaned up, not going to tackle that in this PR as it's already a lot.

src/utils/gas.ts Outdated Show resolved Hide resolved
@brunobar79
Copy link
Member

Launch in simulator or device for 38882f5

@brunobar79
Copy link
Member

Launch in simulator or device for 87d143f

@brunobar79
Copy link
Member

Launch in simulator or device for 70f4755

@brunobar79
Copy link
Member

Launch in simulator or device for fe1be15

@brunobar79
Copy link
Member

Launch in simulator or device for f1a41db

@walmat walmat merged commit 3ac1661 into develop Oct 10, 2024
8 checks passed
@walmat walmat deleted the @matthew/fix-speed-up-and-cancel branch October 10, 2024 20:02
walmat added a commit that referenced this pull request Oct 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants