Skip to content

Commit 1c64203

Browse files
update status legacy function
1 parent a1f5b91 commit 1c64203

File tree

2 files changed

+136
-35
lines changed

2 files changed

+136
-35
lines changed

packages/thirdweb/src/pay/buyWithFiat/getQuote.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { prepare as prepareOnramp } from "../../bridge/Onramp.js";
2+
import { getCachedChain } from "../../chains/utils.js";
23
import type { ThirdwebClient } from "../../client/client.js";
34
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
5+
import { getContract } from "../../contract/contract.js";
6+
import { decimals } from "../../extensions/erc20/read/decimals.js";
47
import type { CurrencyMeta } from "../../react/web/ui/ConnectWallet/screens/Buy/fiat/currencies.js";
5-
import { toTokens, toWei } from "../../utils/units.js";
8+
import { toTokens, toUnits } from "../../utils/units.js";
69
import type { FiatProvider, PayTokenInfo } from "../utils/commonTypes.js";
710
/**
811
* Parameters for [`getBuyWithFiatQuote`](https://portal.thirdweb.com/references/typescript/v5/getBuyWithFiatQuote) function
@@ -291,8 +294,19 @@ export async function getBuyWithFiatQuote(
291294
// Choose provider or default to STRIPE
292295
const onrampProvider = mapProviderToOnramp(params.preferredProvider);
293296

297+
const d =
298+
params.toTokenAddress !== NATIVE_TOKEN_ADDRESS
299+
? await decimals({
300+
contract: getContract({
301+
client: params.client,
302+
address: params.toTokenAddress,
303+
chain: getCachedChain(params.toChainId),
304+
}),
305+
})
306+
: 18;
307+
294308
// Prepare amount in wei if provided
295-
const amountWei = params.toAmount ? toWei(params.toAmount) : undefined;
309+
const amountWei = params.toAmount ? toUnits(params.toAmount, d) : undefined;
296310

297311
// Call new Onramp.prepare to get the quote & link
298312
const prepared = await prepareOnramp({
@@ -314,32 +328,25 @@ export async function getBuyWithFiatQuote(
314328
const firstStep = hasSteps
315329
? (prepared.steps[0] as (typeof prepared.steps)[number])
316330
: undefined;
317-
const lastStep = hasSteps
318-
? (prepared.steps[
319-
prepared.steps.length - 1
320-
] as (typeof prepared.steps)[number])
321-
: undefined;
322331

323332
// Estimated duration in seconds – sum of all step durations
324-
const estimatedDurationSeconds = Math.ceil(
325-
prepared.steps.reduce((acc, s) => acc + s.estimatedExecutionTimeMs, 0) /
326-
1000,
333+
const estimatedDurationSeconds = Math.max(
334+
120,
335+
Math.ceil(
336+
prepared.steps.reduce((acc, s) => acc + s.estimatedExecutionTimeMs, 0) /
337+
1000,
338+
),
327339
);
328340

329-
const estimatedToAmountMinWeiBigInt =
330-
lastStep?.destinationAmount ?? prepared.destinationAmount;
341+
const estimatedToAmountMinWeiBigInt = prepared.destinationAmount;
331342

332343
const maxSlippageBPS = params.maxSlippageBPS ?? 0;
333344
const slippageWei =
334345
(estimatedToAmountMinWeiBigInt * BigInt(maxSlippageBPS)) / 10000n;
335346
const toAmountMinWeiBigInt = estimatedToAmountMinWeiBigInt - slippageWei;
336347

337-
const tokenDecimals = lastStep?.destinationToken.decimals ?? 18;
338-
const estimatedToAmountMin = toTokens(
339-
estimatedToAmountMinWeiBigInt,
340-
tokenDecimals,
341-
);
342-
const toAmountMin = toTokens(toAmountMinWeiBigInt, tokenDecimals);
348+
const estimatedToAmountMin = toTokens(estimatedToAmountMinWeiBigInt, d);
349+
const toAmountMin = toTokens(toAmountMinWeiBigInt, d);
343350

344351
// Helper to convert a Token → PayTokenInfo
345352
const tokenToPayTokenInfo = (token: {

packages/thirdweb/src/pay/buyWithFiat/getStatus.ts

Lines changed: 111 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
import { status as onrampStatus } from "../../bridge/OnrampStatus.js";
12
import type { ThirdwebClient } from "../../client/client.js";
2-
import { getClientFetch } from "../../utils/fetch.js";
33
import type {
44
PayOnChainTransactionDetails,
55
PayTokenInfo,
66
} from "../utils/commonTypes.js";
7-
import { getPayBuyWithFiatStatusEndpoint } from "../utils/definitions.js";
87

98
/**
109
* Parameters for the [`getBuyWithFiatStatus`](https://portal.thirdweb.com/references/typescript/v5/getBuyWithFiatStatus) function
@@ -156,7 +155,6 @@ export type BuyWithFiatStatus =
156155
* })
157156
*
158157
* // when the fiatStatus.status is "ON_RAMP_TRANSFER_COMPLETED" - the process is complete
159-
* // when the fiatStatus.status is "CRYPTO_SWAP_REQUIRED" - start the swap process
160158
* ```
161159
* @deprecated
162160
* @buyCrypto
@@ -165,25 +163,121 @@ export async function getBuyWithFiatStatus(
165163
params: GetBuyWithFiatStatusParams,
166164
): Promise<BuyWithFiatStatus> {
167165
try {
168-
const queryParams = new URLSearchParams({
169-
intentId: params.intentId,
166+
const result = await onrampStatus({
167+
id: params.intentId,
168+
client: params.client,
170169
});
171170

172-
const queryString = queryParams.toString();
173-
const url = `${getPayBuyWithFiatStatusEndpoint()}?${queryString}`;
174-
175-
const response = await getClientFetch(params.client)(url);
176-
177-
if (!response.ok) {
178-
const error = await response.text().catch(() => null);
179-
throw new Error(
180-
`HTTP error! status: ${response.status} - ${response.statusText}: ${error || "unknown error"}`,
181-
);
171+
return toBuyWithFiatStatus({ intentId: params.intentId, result });
172+
} catch (error) {
173+
// If the session is not found, the Onramp.status endpoint will return a 404 which we map to
174+
// a `NONE` status (instead of throwing). Any other error is re-thrown so that the caller is aware.
175+
const message = error instanceof Error ? error.message : String(error);
176+
if (message.includes("404")) {
177+
return buildPlaceholderStatus({
178+
intentId: params.intentId,
179+
status: "NONE",
180+
});
182181
}
183182

184-
return (await response.json()).result;
185-
} catch (error) {
186183
console.error("Fetch error:", error);
187184
throw new Error(`Fetch failed: ${error}`);
188185
}
189186
}
187+
188+
////////////////////////////////////////////////////////////////////////////////
189+
// Helpers
190+
////////////////////////////////////////////////////////////////////////////////
191+
192+
function toBuyWithFiatStatus(args: {
193+
intentId: string;
194+
result: Awaited<ReturnType<typeof onrampStatus>>;
195+
}): BuyWithFiatStatus {
196+
const { intentId, result } = args;
197+
198+
// Map status constants from the Bridge.Onramp.status response to BuyWithFiatStatus equivalents.
199+
const STATUS_MAP: Record<
200+
typeof result.status,
201+
"NONE" | "PENDING_PAYMENT" | "PAYMENT_FAILED" | "ON_RAMP_TRANSFER_COMPLETED"
202+
> = {
203+
CREATED: "PENDING_PAYMENT",
204+
PENDING: "PENDING_PAYMENT",
205+
FAILED: "PAYMENT_FAILED",
206+
COMPLETED: "ON_RAMP_TRANSFER_COMPLETED",
207+
} as const;
208+
209+
const mappedStatus = STATUS_MAP[result.status];
210+
211+
return buildPlaceholderStatus({
212+
intentId,
213+
status: mappedStatus,
214+
purchaseData: result.purchaseData,
215+
});
216+
}
217+
218+
function buildPlaceholderStatus(args: {
219+
intentId: string;
220+
status:
221+
| "NONE"
222+
| "PENDING_PAYMENT"
223+
| "PAYMENT_FAILED"
224+
| "ON_RAMP_TRANSFER_COMPLETED";
225+
purchaseData?: unknown;
226+
}): BuyWithFiatStatus {
227+
const { intentId, status, purchaseData } = args;
228+
229+
// Build a minimal—but type-complete—object that satisfies BuyWithFiatStatus.
230+
const emptyToken: PayTokenInfo = {
231+
chainId: 0,
232+
tokenAddress: "",
233+
decimals: 18,
234+
priceUSDCents: 0,
235+
name: "",
236+
symbol: "",
237+
};
238+
239+
type BuyWithFiatStatusWithData = Exclude<
240+
BuyWithFiatStatus,
241+
{ status: "NOT_FOUND" }
242+
>;
243+
244+
const quote: BuyWithFiatStatusWithData["quote"] = {
245+
estimatedOnRampAmount: "0",
246+
estimatedOnRampAmountWei: "0",
247+
248+
estimatedToTokenAmount: "0",
249+
estimatedToTokenAmountWei: "0",
250+
251+
fromCurrency: {
252+
amount: "0",
253+
amountUnits: "USD",
254+
decimals: 2,
255+
currencySymbol: "USD",
256+
},
257+
fromCurrencyWithFees: {
258+
amount: "0",
259+
amountUnits: "USD",
260+
decimals: 2,
261+
currencySymbol: "USD",
262+
},
263+
onRampToken: emptyToken,
264+
toToken: emptyToken,
265+
estimatedDurationSeconds: 0,
266+
createdAt: new Date().toISOString(),
267+
} as BuyWithFiatStatusWithData["quote"];
268+
269+
// The source/destination fields can only be filled accurately when extra context is returned
270+
// by the API. Since Bridge.Onramp.status doesn't yet provide these details, we omit them for
271+
// now (they are optional).
272+
273+
const base: Exclude<BuyWithFiatStatus, { status: "NOT_FOUND" }> = {
274+
intentId,
275+
status,
276+
toAddress: "",
277+
fromAddress: "",
278+
quote,
279+
purchaseData: purchaseData as object | undefined,
280+
};
281+
282+
return base;
283+
}

0 commit comments

Comments
 (0)