diff --git a/packages/common/src/api/user.ts b/packages/common/src/api/user.ts index f50a611af51..7a94ffc0b84 100644 --- a/packages/common/src/api/user.ts +++ b/packages/common/src/api/user.ts @@ -7,7 +7,6 @@ import { USDCTransactionMethod, USDCTransactionType } from 'models/USDCTransactions' -import { getRootSolanaAccount } from 'services/audius-backend/solana' import { Nullable } from 'utils/typeUtils' import { Id } from './utils' @@ -25,27 +24,15 @@ type GetUSDCTransactionListArgs = { /** * Parser to reformat transactions as they come back from the API. * @param transaction the transaction to parse - * @param rootSolanaAccount? Optionally a root solana account can be passed - * to reformat the metadata field to include specific contextual information. - * In the case of withdrawals, this is useful in recognizing a "self-send", - * which is a cash transfer out. */ const parseTransaction = ({ - transaction, - rootSolanaAccount + transaction }: { transaction: full.TransactionDetails - rootSolanaAccount?: string }): USDCTransactionDetails => { - const { change, balance, transactionType, method, metadata, ...rest } = - transaction + const { change, balance, transactionType, method, ...rest } = transaction return { ...rest, - metadata: !rootSolanaAccount - ? metadata - : rootSolanaAccount === metadata.toString() - ? 'Cash' - : metadata, transactionType: transactionType as USDCTransactionType, method: method as USDCTransactionMethod, change: change as StringUSDC, @@ -149,18 +136,7 @@ const userApi = createApi({ encodedDataSignature }) - let rootSolanaAccount: string - if ( - type === full.GetUSDCTransactionsTypeEnum.Transfer && - method === full.GetUSDCTransactionCountMethodEnum.Send - ) { - rootSolanaAccount = ( - await getRootSolanaAccount(context.audiusBackend) - ).publicKey.toString() - } - return data.map((transaction) => - parseTransaction({ transaction, rootSolanaAccount }) - ) + return data.map((transaction) => parseTransaction({ transaction })) }, options: { retry: true } }, @@ -201,3 +177,4 @@ export const { export const userApiReducer = userApi.reducer export const userApiFetch = userApi.fetch export const userApiActions = userApi.actions +export const userApiUtils = userApi.util diff --git a/packages/common/src/audius-query/createApi.ts b/packages/common/src/audius-query/createApi.ts index cb44e6bc5cb..b3daef7cffa 100644 --- a/packages/common/src/audius-query/createApi.ts +++ b/packages/common/src/audius-query/createApi.ts @@ -111,7 +111,14 @@ export const createApi = < if (updateAction) { dispatch(updateAction({ fetchArgs, nonNormalizedData: newState })) } + }, + reset: (endpointName) => (dispatch: Dispatch) => { + const resetAction = + slice.actions[`reset${capitalize(endpointName as string)}`] + if (resetAction) { + dispatch(resetAction()) } + } } return api diff --git a/packages/common/src/audius-query/hooks/usePaginatedQuery.ts b/packages/common/src/audius-query/hooks/usePaginatedQuery.ts index 39cd7f39ad6..b77ed2bba80 100644 --- a/packages/common/src/audius-query/hooks/usePaginatedQuery.ts +++ b/packages/common/src/audius-query/hooks/usePaginatedQuery.ts @@ -1,4 +1,4 @@ -import { useCallback, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { isEqual } from 'lodash' import { useCustomCompareEffect } from 'react-use' @@ -57,19 +57,18 @@ export const useAllPaginatedQuery = < ) => { const [loadingMore, setLoadingMore] = useState(false) const { pageSize, ...queryHookOptions } = options + const [forceLoad, setForceLoad] = useState(false) const [page, setPage] = useState(0) const [status, setStatus] = useState(Status.IDLE) const [allData, setAllData] = useState([]) - useCustomCompareEffect( - () => { - setAllData([]) - setPage(0) - setLoadingMore(false) - }, - [baseArgs], - isEqual - ) + const reset = useCallback(() => { + setAllData([]) + setPage(0) + setLoadingMore(false) + }, []) + + useCustomCompareEffect(reset, [baseArgs], isEqual) const args = { ...baseArgs, @@ -78,6 +77,13 @@ export const useAllPaginatedQuery = < } as ArgsType const result = useQueryHook(args, queryHookOptions) + useEffect(() => { + if (forceLoad) { + result.forceRefresh() + setForceLoad(false) + } + }, [result, forceLoad]) + useCustomCompareEffect( () => { setStatus(result.status) @@ -113,12 +119,14 @@ export const useAllPaginatedQuery = < setLoadingMore(true) setPage(page + 1) }, [stillLoadingCurrentPage, page]) + return { ...result, // TODO: add another status for reloading status: allData?.length > 0 ? Status.SUCCESS : status, data: allData, isLoadingMore: stillLoadingCurrentPage, + reset, loadMore, hasMore } diff --git a/packages/common/src/audius-query/types.ts b/packages/common/src/audius-query/types.ts index caaa4b47ccf..151b2b58924 100644 --- a/packages/common/src/audius-query/types.ts +++ b/packages/common/src/audius-query/types.ts @@ -47,6 +47,9 @@ export type Api = { > ) => void ) => ThunkAction + reset: ( + endpointName: EndpointName + ) => ThunkAction } /** * Allows for pre-fetching of related data into the cache. Does not return the data. diff --git a/packages/common/src/hooks/useCoinflowAdapter.ts b/packages/common/src/hooks/useCoinflowAdapter.ts index cb7352e1a33..e7925955ba9 100644 --- a/packages/common/src/hooks/useCoinflowAdapter.ts +++ b/packages/common/src/hooks/useCoinflowAdapter.ts @@ -74,7 +74,7 @@ export const useCoinflowWithdrawalAdapter = () => { }) } initWallet() - }, [audiusBackend]) + }, [audiusBackend, feePayerOverride]) return adapter } diff --git a/packages/common/src/models/USDCTransactions.ts b/packages/common/src/models/USDCTransactions.ts index 60adf4d2709..5e982d723cf 100644 --- a/packages/common/src/models/USDCTransactions.ts +++ b/packages/common/src/models/USDCTransactions.ts @@ -5,7 +5,8 @@ import { StringUSDC } from './Wallet' export enum USDCTransactionType { PURCHASE_STRIPE = 'purchase_stripe', PURCHASE_CONTENT = 'purchase_content', - TRANSFER = 'transfer' + TRANSFER = 'transfer', + WITHDRAWAL = 'withdrawal' } export enum USDCTransactionMethod { diff --git a/packages/common/src/store/ui/withdraw-usdc/selectors.ts b/packages/common/src/store/ui/withdraw-usdc/selectors.ts index ecf8587485e..b14d05e8353 100644 --- a/packages/common/src/store/ui/withdraw-usdc/selectors.ts +++ b/packages/common/src/store/ui/withdraw-usdc/selectors.ts @@ -27,3 +27,7 @@ export const getCoinflowState = (state: CommonState) => { export const getWithdrawTransaction = (state: CommonState) => { return state.withdrawUSDC.withdrawTransaction } + +export const getLastCompletedTransactionSignature = (state: CommonState) => { + return state.withdrawUSDC.lastCompletedTransactionSignature +} diff --git a/packages/common/src/store/ui/withdraw-usdc/slice.ts b/packages/common/src/store/ui/withdraw-usdc/slice.ts index d805d14e60c..a21611869b6 100644 --- a/packages/common/src/store/ui/withdraw-usdc/slice.ts +++ b/packages/common/src/store/ui/withdraw-usdc/slice.ts @@ -14,6 +14,7 @@ type WithdrawUSDCState = { withdrawTransaction?: string destinationError?: Error amountError?: Error + lastCompletedTransactionSignature?: string } const initialState: WithdrawUSDCState = { @@ -61,6 +62,7 @@ const slice = createSlice({ state.withdrawTransaction = action.payload.transaction state.withdrawError = undefined state.withdrawStatus = Status.SUCCESS + state.lastCompletedTransactionSignature = action.payload.transaction }, withdrawUSDCFailed: (state, action: PayloadAction<{ error: Error }>) => { state.withdrawStatus = Status.ERROR diff --git a/packages/web/src/components/usdc-transaction-details-modal/USDCTransactionDetailsModal.tsx b/packages/web/src/components/usdc-transaction-details-modal/USDCTransactionDetailsModal.tsx index 71fa88d6328..f60d76168d1 100644 --- a/packages/web/src/components/usdc-transaction-details-modal/USDCTransactionDetailsModal.tsx +++ b/packages/web/src/components/usdc-transaction-details-modal/USDCTransactionDetailsModal.tsx @@ -1,7 +1,8 @@ import { formatUSDCWeiToUSDString, useUSDCTransactionDetailsModal, - makeSolanaTransactionLink + makeSolanaTransactionLink, + USDCTransactionType } from '@audius/common' import { Button } from '@audius/harmony' import { @@ -77,20 +78,24 @@ export const USDCTransactionDetailsModal = () => { label={messages.amountSent} value={`$${formatUSDCWeiToUSDString(transactionDetails.change)}`} /> - - - {messages.destinationWallet} - - - - } - value={`${transactionDetails.metadata ?? '-'}`} - /> + {/* Skip the destination wallet entry for withdrawals to cash */} + {transactionDetails.transactionType !== + USDCTransactionType.WITHDRAWAL ? ( + + + {messages.destinationWallet} + + + + } + value={`${transactionDetails.metadata ?? '-'}`} + /> + ) : null}