diff --git a/app/features/gift-cards/gift-card-details.tsx b/app/features/gift-cards/gift-card-details.tsx
index ed9f20d7f..fb762f029 100644
--- a/app/features/gift-cards/gift-card-details.tsx
+++ b/app/features/gift-cards/gift-card-details.tsx
@@ -150,14 +150,14 @@ export default function GiftCardDetails({ cardId }: GiftCardDetailsProps) {
diff --git a/app/features/receive/index.ts b/app/features/receive/index.ts
index ebb28b96b..a24bce744 100644
--- a/app/features/receive/index.ts
+++ b/app/features/receive/index.ts
@@ -1,6 +1,19 @@
import ReceiveCashu from './receive-cashu';
import ReceiveCashuToken from './receive-cashu-token';
+import {
+ type ReceiveFlowDefinition,
+ ReceiveFlowProvider,
+ useReceiveFlowStep,
+} from './receive-flow';
import ReceiveInput from './receive-input';
import { ReceiveProvider } from './receive-provider';
-export { ReceiveInput, ReceiveCashuToken, ReceiveCashu, ReceiveProvider };
+export {
+ ReceiveInput,
+ ReceiveCashuToken,
+ ReceiveCashu,
+ ReceiveProvider,
+ ReceiveFlowProvider,
+ useReceiveFlowStep,
+};
+export type { ReceiveFlowDefinition };
diff --git a/app/features/receive/receive-cashu-token.tsx b/app/features/receive/receive-cashu-token.tsx
index cab6552b6..df5801495 100644
--- a/app/features/receive/receive-cashu-token.tsx
+++ b/app/features/receive/receive-cashu-token.tsx
@@ -21,10 +21,7 @@ import { Button } from '~/components/ui/button';
import { useToast } from '~/hooks/use-toast';
import { useFeatureFlag } from '~/lib/feature-flags';
import type { Currency } from '~/lib/money';
-import {
- LinkWithViewTransition,
- useNavigateWithViewTransition,
-} from '~/lib/transitions';
+import { LinkWithViewTransition } from '~/lib/transitions';
import { AccountSelector } from '../accounts/account-selector';
import { GiftCardItem } from '../gift-cards/gift-card-item';
import { getGiftCardImageByUrl } from '../gift-cards/use-discover-cards';
@@ -46,6 +43,7 @@ import {
type ReceiveCashuTokenAccount,
isClaimingToSameCashuAccount,
} from './receive-cashu-token-models';
+import { useReceiveFlowStep } from './receive-flow';
type Props = {
token: Token;
@@ -105,7 +103,7 @@ export default function ReceiveToken({
preferredReceiveAccountId,
}: Props) {
const { toast } = useToast();
- const navigate = useNavigateWithViewTransition();
+ const { back, onSuccess } = useReceiveFlowStep('claimCashuToken');
const { claimableToken, cannotClaimReason } =
useCashuTokenWithClaimableProofs({ token });
const {
@@ -161,10 +159,7 @@ export default function ReceiveToken({
return result.lightningReceiveQuote.transactionId;
},
onSuccess: (transactionId) => {
- navigate(`/transactions/${transactionId}?redirectTo=/`, {
- transition: 'slideLeft',
- applyTo: 'newView',
- });
+ onSuccess(transactionId);
},
onError: (error) => {
console.error('Error claiming token', { cause: error });
@@ -180,9 +175,9 @@ export default function ReceiveToken({
<>
Receive
diff --git a/app/features/receive/receive-cashu.tsx b/app/features/receive/receive-cashu.tsx
index 6e0987f98..16d50f833 100644
--- a/app/features/receive/receive-cashu.tsx
+++ b/app/features/receive/receive-cashu.tsx
@@ -15,10 +15,7 @@ import type { CashuAccount } from '~/features/accounts/account';
import { useEffectNoStrictMode } from '~/hooks/use-effect-no-strict-mode';
import { useToast } from '~/hooks/use-toast';
import type { Money } from '~/lib/money';
-import {
- LinkWithViewTransition,
- useNavigateWithViewTransition,
-} from '~/lib/transitions';
+import { LinkWithViewTransition } from '~/lib/transitions';
import { getDefaultUnit } from '../shared/currencies';
import { MoneyWithConvertedAmount } from '../shared/money-with-converted-amount';
import type { CashuReceiveQuote } from './cashu-receive-quote';
@@ -26,6 +23,7 @@ import {
useCashuReceiveQuote,
useCreateCashuReceiveQuote,
} from './cashu-receive-quote-hooks';
+import { useReceiveFlowStep } from './receive-flow';
type CreateQuoteProps = {
account: CashuAccount;
@@ -110,16 +108,13 @@ export default function ReceiveCashu({ amount, account }: Props) {
const [showOk, setShowOk] = useState(false);
const [, copyToClipboard] = useCopyToClipboard();
const { toast } = useToast();
- const navigate = useNavigateWithViewTransition();
+ const { back, onSuccess } = useReceiveFlowStep('cashuLightningInvoice');
const { quote, errorMessage, isLoading } = useCreateQuote({
account,
amount,
onPaid: (quote) => {
- navigate(`/transactions/${quote.transactionId}?redirectTo=/`, {
- transition: 'fade',
- applyTo: 'newView',
- });
+ onSuccess(quote.transactionId);
},
});
@@ -141,9 +136,9 @@ export default function ReceiveCashu({ amount, account }: Props) {
<>
Receive Ecash
@@ -172,9 +167,9 @@ export default function ReceiveCashu({ amount, account }: Props) {
diff --git a/app/features/receive/receive-scanner.tsx b/app/features/receive/receive-scanner.tsx
index 835132656..54a81648d 100644
--- a/app/features/receive/receive-scanner.tsx
+++ b/app/features/receive/receive-scanner.tsx
@@ -9,20 +9,22 @@ import { QRScanner } from '~/components/qr-scanner';
import { useToast } from '~/hooks/use-toast';
import { extractCashuToken } from '~/lib/cashu';
import { useNavigateWithViewTransition } from '~/lib/transitions';
+import { useReceiveFlowStep } from './receive-flow';
import { useReceiveStore } from './receive-provider';
export default function ReceiveScanner() {
const { toast } = useToast();
const navigate = useNavigateWithViewTransition();
+ const { back, next } = useReceiveFlowStep('scanToken');
const receiveAccountId = useReceiveStore((s) => s.accountId);
return (
<>
Scan
@@ -45,11 +47,12 @@ export default function ReceiveScanner() {
// The hash needs to be set manually before navigating or clientLoader of the destination route won't see it
// See https://github.com/remix-run/remix/discussions/10721
window.history.replaceState(null, '', hash);
+ const tokenAction = next.claimCashuToken(receiveAccountId);
navigate(
- `/receive/cashu/token?selectedAccountId=${receiveAccountId}${hash}`,
+ { ...tokenAction.to, hash },
{
- transition: 'slideLeft',
- applyTo: 'newView',
+ transition: tokenAction.transition,
+ applyTo: tokenAction.applyTo,
},
);
}}
diff --git a/app/features/receive/receive-spark.tsx b/app/features/receive/receive-spark.tsx
index f94b4d626..1b883a640 100644
--- a/app/features/receive/receive-spark.tsx
+++ b/app/features/receive/receive-spark.tsx
@@ -12,12 +12,10 @@ import { Button } from '~/components/ui/button';
import { useEffectNoStrictMode } from '~/hooks/use-effect-no-strict-mode';
import { useToast } from '~/hooks/use-toast';
import type { Money } from '~/lib/money';
-import {
- LinkWithViewTransition,
- useNavigateWithViewTransition,
-} from '~/lib/transitions';
+import { LinkWithViewTransition } from '~/lib/transitions';
import type { SparkAccount } from '../accounts/account';
import { MoneyWithConvertedAmount } from '../shared/money-with-converted-amount';
+import { useReceiveFlowStep } from './receive-flow';
import type { SparkReceiveQuote } from './spark-receive-quote';
import {
useCreateSparkReceiveQuote,
@@ -68,19 +66,16 @@ const useCreateQuote = ({
};
export default function ReceiveSpark({ amount, account }: Props) {
- const navigate = useNavigateWithViewTransition();
const [showOk, setShowOk] = useState(false);
const [, copyToClipboard] = useCopyToClipboard();
const { toast } = useToast();
+ const { back, onSuccess } = useReceiveFlowStep('sparkLightningInvoice');
const { quote, errorMessage, isLoading } = useCreateQuote({
account,
amount,
onPaid: (quote) => {
- navigate(`/transactions/${quote.transactionId}?redirectTo=/`, {
- transition: 'fade',
- applyTo: 'newView',
- });
+ onSuccess(quote.transactionId);
},
});
@@ -98,9 +93,9 @@ export default function ReceiveSpark({ amount, account }: Props) {
<>
Receive
@@ -118,9 +113,9 @@ export default function ReceiveSpark({ amount, account }: Props) {
diff --git a/app/features/send/send-scanner.tsx b/app/features/send/send-scanner.tsx
index dcaa5817f..44fd3640f 100644
--- a/app/features/send/send-scanner.tsx
+++ b/app/features/send/send-scanner.tsx
@@ -6,6 +6,7 @@ import {
} from '~/components/page';
import { QRScanner } from '~/components/qr-scanner';
import { useExchangeRate } from '~/hooks/use-exchange-rate';
+import { useRedirectTo } from '~/hooks/use-redirect-to';
import { useToast } from '~/hooks/use-toast';
import type { Money } from '~/lib/money';
import { useNavigateWithViewTransition } from '~/lib/transitions/view-transition';
@@ -36,6 +37,7 @@ const useConverter = (sendAccount: Account) => {
export default function SendScanner() {
const { toast } = useToast();
const navigate = useNavigateWithViewTransition();
+ const { buildTo } = useRedirectTo('/');
const sendAccount = useSendStore((state) => state.getSourceAccount());
const selectDestination = useSendStore((state) => state.selectDestination);
@@ -57,11 +59,11 @@ export default function SendScanner() {
const { amount } = selectDestinationResult.data;
if (!amount) {
- navigate('/send', {
+ // Navigate to send input to enter the amount
+ return navigate(buildTo('/send'), {
applyTo: 'oldView',
transition: 'slideDown',
});
- return;
}
const convertedAmount =
@@ -89,7 +91,7 @@ export default function SendScanner() {
return;
}
- navigate('/send/confirm', {
+ navigate(buildTo('/send/confirm'), {
applyTo: 'newView',
transition: 'slideUp',
});
@@ -98,7 +100,11 @@ export default function SendScanner() {
return (
<>
-
+
Scan
diff --git a/app/features/send/share-cashu-token.tsx b/app/features/send/share-cashu-token.tsx
index a1c999431..84fdb5115 100644
--- a/app/features/send/share-cashu-token.tsx
+++ b/app/features/send/share-cashu-token.tsx
@@ -20,6 +20,7 @@ import {
CarouselItem,
} from '~/components/ui/carousel';
import useLocationData from '~/hooks/use-location';
+import { useRedirectTo } from '~/hooks/use-redirect-to';
import { useToast } from '~/hooks/use-toast';
import { canShare, shareContent } from '~/lib/share';
import { LinkWithViewTransition } from '~/lib/transitions';
@@ -33,6 +34,7 @@ type Props = {
export function ShareCashuToken({ token }: Props) {
const { toast } = useToast();
const { origin } = useLocationData();
+ const { redirectTo } = useRedirectTo('/');
const [, copyToClipboard] = useCopyToClipboard();
const amount = tokenToMoney(token);
const [showOk, setShowOk] = useState(false);
@@ -45,7 +47,11 @@ export function ShareCashuToken({ token }: Props) {
return (
-
+
Send
{canShare() && (
@@ -110,7 +116,7 @@ export function ShareCashuToken({ token }: Props) {