Skip to content

Commit ee4e13e

Browse files
committed
[MNY-198] SDK: Fix StepRunner autoStart not working reliably, Remove extra prepare call (#8116)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR primarily focuses on enhancing the `StepRunner` component in the Bridge UI by integrating a `preparedQuote` prop, improving the handling of swap transactions, and refining the relevant hooks and stories. ### Detailed summary - Added `preparedQuote` prop to `SwapWidget` and `StepRunner`. - Updated `StepRunner` to utilize `preparedQuote` for executing steps. - Modified `useStepExecutor` to accept `preparedQuote` instead of `request`. - Cleaned up imports in `useStepExecutor`. - Updated stories to reflect the new `preparedQuote` prop. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 8dc9e41 commit ee4e13e

File tree

5 files changed

+24
-55
lines changed

5 files changed

+24
-55
lines changed

packages/thirdweb/src/react/core/hooks/useStepExecutor.ts

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useQuery } from "@tanstack/react-query";
21
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
32
import type { status as OnrampStatus } from "../../../bridge/OnrampStatus.js";
43
import { ApiError } from "../../../bridge/types/Errors.js";
@@ -10,14 +9,9 @@ import type { Status } from "../../../bridge/types/Status.js";
109
import { getCachedChain } from "../../../chains/utils.js";
1110
import type { ThirdwebClient } from "../../../client/client.js";
1211
import { waitForReceipt } from "../../../transaction/actions/wait-for-tx-receipt.js";
13-
import { stringify } from "../../../utils/json.js";
1412
import type { Account, Wallet } from "../../../wallets/interfaces/wallet.js";
1513
import type { WindowAdapter } from "../adapters/WindowAdapter.js";
16-
import {
17-
type BridgePrepareRequest,
18-
type BridgePrepareResult,
19-
useBridgePrepare,
20-
} from "./useBridgePrepare.js";
14+
import type { BridgePrepareResult } from "./useBridgePrepare.js";
2115

2216
/**
2317
* Type for completed status results from Bridge.status and Onramp.status
@@ -35,8 +29,7 @@ export type CompletedStatusResult =
3529
* Options for the step executor hook
3630
*/
3731
interface StepExecutorOptions {
38-
/** Prepared quote returned by Bridge.prepare */
39-
request: BridgePrepareRequest;
32+
preparedQuote: BridgePrepareResult;
4033
/** Wallet instance providing getAccount() & sendTransaction */
4134
wallet?: Wallet;
4235
/** Window adapter for opening on-ramp URLs (web / RN) */
@@ -67,7 +60,7 @@ interface StepExecutorResult {
6760
currentTxIndex?: number;
6861
progress: number; // 0–100
6962
onrampStatus?: "pending" | "executing" | "completed" | "failed";
70-
executionState: "fetching" | "idle" | "executing" | "auto-starting";
63+
executionState: "idle" | "executing" | "auto-starting";
7164
steps?: RouteStep[];
7265
error?: ApiError;
7366
start: () => void;
@@ -100,16 +93,14 @@ export function useStepExecutor(
10093
options: StepExecutorOptions,
10194
): StepExecutorResult {
10295
const {
103-
request,
10496
wallet,
10597
windowAdapter,
10698
client,
10799
autoStart = false,
108100
onComplete,
101+
preparedQuote,
109102
} = options;
110103

111-
const { data: preparedQuote, isLoading } = useBridgePrepare(request);
112-
113104
// Flatten all transactions upfront
114105
const flatTxs = useMemo(
115106
() => (preparedQuote?.steps ? flattenRouteSteps(preparedQuote.steps) : []),
@@ -121,30 +112,14 @@ export function useStepExecutor(
121112
undefined,
122113
);
123114
const [executionState, setExecutionState] = useState<
124-
"fetching" | "idle" | "executing" | "auto-starting"
115+
"idle" | "executing" | "auto-starting"
125116
>("idle");
126117
const [error, setError] = useState<ApiError | undefined>(undefined);
127118
const [completedTxs, setCompletedTxs] = useState<Set<number>>(new Set());
128119
const [onrampStatus, setOnrampStatus] = useState<
129120
"pending" | "executing" | "completed" | "failed" | undefined
130121
>(preparedQuote?.type === "onramp" ? "pending" : undefined);
131122

132-
useQuery({
133-
queryFn: async () => {
134-
if (!isLoading) {
135-
setExecutionState("idle");
136-
} else {
137-
setExecutionState("fetching");
138-
}
139-
return executionState;
140-
},
141-
queryKey: [
142-
"bridge-quote-execution-state",
143-
stringify(preparedQuote?.steps),
144-
isLoading,
145-
],
146-
});
147-
148123
// Cancellation tracking
149124
const abortControllerRef = useRef<AbortController | null>(null);
150125

packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ export function BridgeOrchestrator({
379379

380380
{state.value === "execute" && quote && state.context.request && (
381381
<StepRunner
382+
preparedQuote={quote}
382383
autoStart={true}
383384
client={client}
384385
onBack={() => {

packages/thirdweb/src/react/web/ui/Bridge/StepRunner.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import {
1212
radius,
1313
spacing,
1414
} from "../../../core/design-system/index.js";
15-
import type { BridgePrepareRequest } from "../../../core/hooks/useBridgePrepare.js";
15+
import type {
16+
BridgePrepareRequest,
17+
BridgePrepareResult,
18+
} from "../../../core/hooks/useBridgePrepare.js";
1619
import {
1720
type CompletedStatusResult,
1821
useStepExecutor,
@@ -62,6 +65,11 @@ interface StepRunnerProps {
6265
* Called when user clicks the back button
6366
*/
6467
onBack?: () => void;
68+
69+
/**
70+
* Prepared quote to use
71+
*/
72+
preparedQuote: BridgePrepareResult;
6573
}
6674

6775
export function StepRunner({
@@ -74,6 +82,7 @@ export function StepRunner({
7482
onCancel,
7583
onBack,
7684
autoStart,
85+
preparedQuote,
7786
}: StepRunnerProps) {
7887
const theme = useCustomTheme();
7988

@@ -94,8 +103,8 @@ export function StepRunner({
94103
onComplete: (completedStatuses: CompletedStatusResult[]) => {
95104
onComplete(completedStatuses);
96105
},
97-
request,
98106
wallet,
107+
preparedQuote,
99108
windowAdapter,
100109
});
101110

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ function SwapWidgetContent(props: SwapWidgetProps) {
448448
<StepRunner
449449
title="Processing Swap"
450450
autoStart={true}
451+
preparedQuote={screen.preparedQuote}
451452
client={props.client}
452453
onBack={() => {
453454
setScreen({

packages/thirdweb/src/stories/Bridge/StepRunner.stories.tsx

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import type { CompletedStatusResult } from "../../react/core/hooks/useStepExecut
77
import { StepRunner } from "../../react/web/ui/Bridge/StepRunner.js";
88
import type { Wallet } from "../../wallets/interfaces/wallet.js";
99
import { ModalThemeWrapper, storyClient } from "../utils.js";
10-
import { STORY_MOCK_WALLET, simpleBuyRequest } from "./fixtures.js";
10+
import {
11+
STORY_MOCK_WALLET,
12+
simpleBuyQuote,
13+
simpleBuyRequest,
14+
} from "./fixtures.js";
1115

1216
// Mock window adapter
1317
const mockWindowAdapter: WindowAdapter = {
@@ -32,7 +36,7 @@ const StepRunnerWithTheme = (props: StepRunnerWithThemeProps) => {
3236
const { theme, ...componentProps } = props;
3337
return (
3438
<ModalThemeWrapper theme={theme}>
35-
<StepRunner {...componentProps} />
39+
<StepRunner {...componentProps} preparedQuote={simpleBuyQuote} />
3640
</ModalThemeWrapper>
3741
);
3842
};
@@ -59,29 +63,8 @@ const meta = {
5963
},
6064
component: StepRunnerWithTheme,
6165
parameters: {
62-
docs: {
63-
description: {
64-
component:
65-
"**StepRunner** executes prepared route steps sequentially, showing real-time progress and transaction status.\n\n" +
66-
"## Features\n" +
67-
"- **Real Execution**: Uses useStepExecutor hook for actual transaction processing\n" +
68-
"- **Progress Tracking**: Visual progress bar and step-by-step status updates\n" +
69-
"- **Error Handling**: Retry functionality for failed transactions\n" +
70-
"- **Transaction Batching**: Optimizes multiple transactions when possible\n" +
71-
"- **Onramp Support**: Handles fiat-to-crypto onramp flows\n\n" +
72-
"## Props\n" +
73-
"- `steps`: Array of RouteStep objects from Bridge.prepare()\n" +
74-
"- `wallet`: Connected wallet for transaction signing\n" +
75-
"- `client`: ThirdwebClient instance\n" +
76-
"- `windowAdapter`: Platform-specific window/URL handler\n" +
77-
"- `onramp`: Optional onramp configuration\n\n" +
78-
"## Integration\n" +
79-
"This component is typically used within the BridgeOrchestrator after route preparation.",
80-
},
81-
},
8266
layout: "centered",
8367
},
84-
tags: ["autodocs"],
8568
title: "Bridge/StepRunner",
8669
} satisfies Meta<typeof StepRunnerWithTheme>;
8770

0 commit comments

Comments
 (0)