diff --git a/packages/@divvi/mobile/src/navigator/Navigator.tsx b/packages/@divvi/mobile/src/navigator/Navigator.tsx
index 431217e740e..bf00190f9a7 100644
--- a/packages/@divvi/mobile/src/navigator/Navigator.tsx
+++ b/packages/@divvi/mobile/src/navigator/Navigator.tsx
@@ -243,6 +243,11 @@ const sendScreens = (Navigator: typeof Stack) => (
component={SendConfirmation}
options={sendConfirmationScreenNavOptions as NativeStackNavigationOptions}
/>
+
(
component={SelectCountry}
options={SelectCountry.navigationOptions as NativeStackNavigationOptions}
/>
-
>
)
diff --git a/packages/@divvi/mobile/src/navigator/types.tsx b/packages/@divvi/mobile/src/navigator/types.tsx
index d83a707aac5..0c327ca2ed5 100644
--- a/packages/@divvi/mobile/src/navigator/types.tsx
+++ b/packages/@divvi/mobile/src/navigator/types.tsx
@@ -10,6 +10,7 @@ import { KeylessBackupFlow, KeylessBackupOrigin } from 'src/keylessBackup/types'
import { Screens } from 'src/navigator/Screens'
import { Nft } from 'src/nfts/types'
import { EarnPosition } from 'src/positions/types'
+import type { PreparedTransactionsResult } from 'src/public'
import { Recipient } from 'src/recipients/recipient'
import { QrCode, TransactionDataInput } from 'src/send/types'
import { AssetTabType } from 'src/tokens/types'
@@ -29,10 +30,18 @@ type NestedNavigatorParams = {
: { screen: K; params: ParamList[K] }
}[keyof ParamList]
+interface SendConfirmationFromExternalParams {
+ origin: SendOrigin
+ transactionData: TransactionDataInput
+ isFromScan: boolean
+ prepareTransactionsResult?: never
+}
+
interface SendConfirmationParams {
origin: SendOrigin
transactionData: TransactionDataInput
isFromScan: boolean
+ prepareTransactionsResult: PreparedTransactionsResult
}
type SendEnterAmountParams = {
@@ -249,7 +258,7 @@ export type StackParamList = {
}
| undefined
[Screens.SendConfirmation]: SendConfirmationParams
- [Screens.SendConfirmationFromExternal]: SendConfirmationParams
+ [Screens.SendConfirmationFromExternal]: SendConfirmationFromExternalParams
[Screens.SendEnterAmount]: SendEnterAmountParams
[Screens.JumpstartEnterAmount]: undefined
[Screens.JumpstartSendConfirmation]: {
diff --git a/packages/@divvi/mobile/src/send/SendConfirmation.test.tsx b/packages/@divvi/mobile/src/send/SendConfirmation.test.tsx
index 43bca6ec783..834ea946467 100644
--- a/packages/@divvi/mobile/src/send/SendConfirmation.test.tsx
+++ b/packages/@divvi/mobile/src/send/SendConfirmation.test.tsx
@@ -43,6 +43,7 @@ const mockScreenProps = getMockStackScreenProps(Screens.SendConfirmation, {
},
origin: SendOrigin.AppSendFlow,
isFromScan: false,
+ prepareTransactionsResult: undefined as never,
})
const mockFeeCurrencies = [
diff --git a/packages/@divvi/mobile/src/send/SendConfirmation.tsx b/packages/@divvi/mobile/src/send/SendConfirmation.tsx
index 1849790d018..da687f3211e 100644
--- a/packages/@divvi/mobile/src/send/SendConfirmation.tsx
+++ b/packages/@divvi/mobile/src/send/SendConfirmation.tsx
@@ -63,7 +63,7 @@ export default function SendConfirmation(props: Props) {
refreshPreparedTransactions,
clearPreparedTransactions,
prepareTransactionLoading,
- } = usePrepareSendTransactions()
+ } = usePrepareSendTransactions(props.route.params.prepareTransactionsResult)
const fromExternal = props.route.name === Screens.SendConfirmationFromExternal
const tokenInfo = useTokenInfo(tokenId)
@@ -88,9 +88,15 @@ export default function SendConfirmation(props: Props) {
)
useEffect(() => {
+ // do not refresh if prepared transactions is available in the route params
+ if (!fromExternal) {
+ return
+ }
+
if (!walletAddress || !tokenInfo) {
return // should never happen
}
+
clearPreparedTransactions()
const debouncedRefreshTransactions = setTimeout(() => {
return refreshPreparedTransactions({
@@ -102,7 +108,7 @@ export default function SendConfirmation(props: Props) {
})
}, DEBOUNCE_TIME_MS)
return () => clearTimeout(debouncedRefreshTransactions)
- }, [tokenInfo, tokenAmount, recipient, walletAddress, feeCurrencies])
+ }, [tokenInfo, tokenAmount, recipient, walletAddress, feeCurrencies, fromExternal])
const disableSend =
isSending || !prepareTransactionsResult || prepareTransactionsResult.type !== 'possible'
diff --git a/packages/@divvi/mobile/src/send/SendEnterAmount.test.tsx b/packages/@divvi/mobile/src/send/SendEnterAmount.test.tsx
index 906b45365ab..35506907e59 100644
--- a/packages/@divvi/mobile/src/send/SendEnterAmount.test.tsx
+++ b/packages/@divvi/mobile/src/send/SendEnterAmount.test.tsx
@@ -129,13 +129,14 @@ describe('SendEnterAmount', () => {
})
it('should handle navigating to the next step', async () => {
- jest.mocked(usePrepareSendTransactions).mockReturnValue({
+ const mockedPrepareTransactions = {
prepareTransactionsResult: mockPrepareTransactionsResultPossible,
prepareTransactionLoading: false,
refreshPreparedTransactions: jest.fn(),
clearPreparedTransactions: jest.fn(),
prepareTransactionError: undefined,
- })
+ }
+ jest.mocked(usePrepareSendTransactions).mockReturnValue(mockedPrepareTransactions)
const { getByTestId, getByText } = render(
@@ -163,9 +164,10 @@ describe('SendEnterAmount', () => {
underlyingTokenSymbol: 'CELO',
amountEnteredIn: 'token',
})
- expect(navigate).toHaveBeenCalledWith(Screens.SendConfirmation, {
+ expect(navigate).toHaveBeenLastCalledWith(Screens.SendConfirmation, {
origin: params.origin,
isFromScan: params.isFromScan,
+ prepareTransactionsResult: mockedPrepareTransactions.prepareTransactionsResult,
transactionData: {
tokenId: mockCeloTokenId,
recipient: params.recipient,
diff --git a/packages/@divvi/mobile/src/send/SendEnterAmount.tsx b/packages/@divvi/mobile/src/send/SendEnterAmount.tsx
index 5437e8435cb..ca5911e82b1 100644
--- a/packages/@divvi/mobile/src/send/SendEnterAmount.tsx
+++ b/packages/@divvi/mobile/src/send/SendEnterAmount.tsx
@@ -50,6 +50,7 @@ function SendEnterAmount({ route }: Props) {
navigate(Screens.SendConfirmation, {
origin,
isFromScan,
+ prepareTransactionsResult,
transactionData: {
tokenId: token.tokenId,
recipient,
@@ -76,13 +77,14 @@ function SendEnterAmount({ route }: Props) {
})
}
+ const prepareTransactions = usePrepareSendTransactions()
const {
prepareTransactionsResult,
refreshPreparedTransactions,
clearPreparedTransactions,
prepareTransactionError,
prepareTransactionLoading,
- } = usePrepareSendTransactions()
+ } = prepareTransactions
const walletAddress = useSelector(walletAddressSelector)
diff --git a/packages/@divvi/mobile/src/send/usePrepareSendTransactions.ts b/packages/@divvi/mobile/src/send/usePrepareSendTransactions.ts
index 5cbd3714ea1..287e8efe9b8 100644
--- a/packages/@divvi/mobile/src/send/usePrepareSendTransactions.ts
+++ b/packages/@divvi/mobile/src/send/usePrepareSendTransactions.ts
@@ -6,23 +6,25 @@ import Logger from 'src/utils/Logger'
import {
prepareERC20TransferTransaction,
prepareSendNativeAssetTransaction,
+ type PreparedTransactionsResult,
} from 'src/viem/prepareTransactions'
const TAG = 'src/send/usePrepareSendTransactions'
+type PrepareSendTransactionsCallbackProps = {
+ amount: BigNumber
+ token: TokenBalance
+ recipientAddress: string
+ walletAddress: string
+ feeCurrencies: TokenBalance[]
+}
export async function prepareSendTransactionsCallback({
amount,
token,
recipientAddress,
walletAddress,
feeCurrencies,
-}: {
- amount: BigNumber
- token: TokenBalance
- recipientAddress: string
- walletAddress: string
- feeCurrencies: TokenBalance[]
-}) {
+}: PrepareSendTransactionsCallbackProps) {
if (amount.isLessThanOrEqualTo(0)) {
return
}
@@ -54,18 +56,28 @@ export async function prepareSendTransactionsCallback({
/**
* Hook to prepare transactions for sending crypto.
*/
-export function usePrepareSendTransactions() {
- const prepareTransactions = useAsyncCallback(prepareSendTransactionsCallback, {
- onError: (error) => {
- Logger.error(TAG, `prepareTransactionsOutput: ${error}`)
+export function usePrepareSendTransactions(
+ existingPrepareTransactionResult?: PreparedTransactionsResult
+) {
+ const prepareTransactions = useAsyncCallback(
+ (props: PrepareSendTransactionsCallbackProps) => {
+ if (existingPrepareTransactionResult) return
+ return prepareSendTransactionsCallback(props)
},
- })
+ {
+ onError: (error) => {
+ Logger.error(TAG, `prepareTransactionsOutput: ${error}`)
+ },
+ }
+ )
return {
- prepareTransactionsResult: prepareTransactions.result,
+ prepareTransactionsResult: existingPrepareTransactionResult ?? prepareTransactions.result,
refreshPreparedTransactions: prepareTransactions.execute,
clearPreparedTransactions: prepareTransactions.reset,
prepareTransactionError: prepareTransactions.error,
- prepareTransactionLoading: prepareTransactions.loading,
+ prepareTransactionLoading: existingPrepareTransactionResult
+ ? false
+ : prepareTransactions.loading,
}
}
diff --git a/packages/@divvi/mobile/src/send/utils.test.ts b/packages/@divvi/mobile/src/send/utils.test.ts
index 3db7c0d0811..be3722ab09a 100644
--- a/packages/@divvi/mobile/src/send/utils.test.ts
+++ b/packages/@divvi/mobile/src/send/utils.test.ts
@@ -130,7 +130,7 @@ describe('send/utils', () => {
])
.run()
expect(navigate).toHaveBeenCalledWith(
- Screens.SendConfirmation,
+ Screens.SendConfirmationFromExternal,
expect.objectContaining({
transactionData: {
recipient: { address: mockData.address, recipientType: RecipientType.Address },
@@ -165,7 +165,7 @@ describe('send/utils', () => {
])
.run()
expect(navigate).toHaveBeenCalledWith(
- Screens.SendConfirmation,
+ Screens.SendConfirmationFromExternal,
expect.objectContaining({
transactionData: {
recipient: { address: mockData.address, recipientType: RecipientType.Address },
@@ -242,7 +242,7 @@ describe('send/utils', () => {
])
.run()
expect(navigate).toHaveBeenCalledWith(
- Screens.SendConfirmation,
+ Screens.SendConfirmationFromExternal,
expect.objectContaining({
origin: SendOrigin.AppSendFlow,
transactionData: mockTransactionData,
@@ -270,7 +270,7 @@ describe('send/utils', () => {
])
.run()
expect(navigate).toHaveBeenCalledWith(
- Screens.SendConfirmation,
+ Screens.SendConfirmationFromExternal,
expect.objectContaining({
origin: SendOrigin.AppSendFlow,
transactionData: mockTransactionData,
@@ -295,7 +295,7 @@ describe('send/utils', () => {
])
.run()
expect(navigate).toHaveBeenCalledWith(
- Screens.SendConfirmation,
+ Screens.SendConfirmationFromExternal,
expect.objectContaining({
origin: SendOrigin.AppSendFlow,
transactionData: {
diff --git a/packages/@divvi/mobile/src/send/utils.ts b/packages/@divvi/mobile/src/send/utils.ts
index d737978677a..bab02e4d023 100644
--- a/packages/@divvi/mobile/src/send/utils.ts
+++ b/packages/@divvi/mobile/src/send/utils.ts
@@ -93,7 +93,7 @@ export function* handleSendPaymentData({
tokenId: tokenInfo.tokenId,
}
- navigate(Screens.SendConfirmation, {
+ navigate(Screens.SendConfirmationFromExternal, {
transactionData,
isFromScan,
origin: SendOrigin.AppSendFlow,