thirdweb 5.104.1 → 5.104.2-nightly-c5f9921dc9cf6c62d754f12ce6171d95bd87a590-20250625053652

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/cjs/bridge/Buy.js +0 -2
  2. package/dist/cjs/bridge/Buy.js.map +1 -1
  3. package/dist/cjs/react/core/hooks/useTransactionDetails.js +7 -2
  4. package/dist/cjs/react/core/hooks/useTransactionDetails.js.map +1 -1
  5. package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js +3 -3
  6. package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
  7. package/dist/cjs/react/web/ui/Bridge/BuyWidget.js +14 -4
  8. package/dist/cjs/react/web/ui/Bridge/BuyWidget.js.map +1 -1
  9. package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js +14 -4
  10. package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
  11. package/dist/cjs/react/web/ui/Bridge/ErrorBanner.js +13 -1
  12. package/dist/cjs/react/web/ui/Bridge/ErrorBanner.js.map +1 -1
  13. package/dist/cjs/react/web/ui/Bridge/QuoteLoader.js +20 -1
  14. package/dist/cjs/react/web/ui/Bridge/QuoteLoader.js.map +1 -1
  15. package/dist/cjs/react/web/ui/Bridge/TransactionPayment.js +3 -0
  16. package/dist/cjs/react/web/ui/Bridge/TransactionPayment.js.map +1 -1
  17. package/dist/cjs/react/web/ui/Bridge/TransactionWidget.js +14 -4
  18. package/dist/cjs/react/web/ui/Bridge/TransactionWidget.js.map +1 -1
  19. package/dist/cjs/react/web/ui/Bridge/UnsupportedTokenScreen.js +14 -1
  20. package/dist/cjs/react/web/ui/Bridge/UnsupportedTokenScreen.js.map +1 -1
  21. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentDetails.js +27 -0
  22. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentDetails.js.map +1 -1
  23. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentOverview.js +2 -1
  24. package/dist/cjs/react/web/ui/Bridge/payment-details/PaymentOverview.js.map +1 -1
  25. package/dist/cjs/react/web/ui/Bridge/payment-selection/PaymentSelection.js +13 -0
  26. package/dist/cjs/react/web/ui/Bridge/payment-selection/PaymentSelection.js.map +1 -1
  27. package/dist/cjs/react/web/ui/Bridge/payment-success/SuccessScreen.js +18 -1
  28. package/dist/cjs/react/web/ui/Bridge/payment-success/SuccessScreen.js.map +1 -1
  29. package/dist/cjs/react/web/ui/PayEmbed.js +4 -4
  30. package/dist/cjs/react/web/ui/PayEmbed.js.map +1 -1
  31. package/dist/cjs/stories/Bridge/ErrorBanner.stories.js +2 -1
  32. package/dist/cjs/stories/Bridge/ErrorBanner.stories.js.map +1 -1
  33. package/dist/cjs/stories/Bridge/SuccessScreen.stories.js +7 -0
  34. package/dist/cjs/stories/Bridge/SuccessScreen.stories.js.map +1 -1
  35. package/dist/cjs/stories/Bridge/UnsupportedTokenScreen.stories.js +6 -0
  36. package/dist/cjs/stories/Bridge/UnsupportedTokenScreen.stories.js.map +1 -1
  37. package/dist/cjs/version.js +1 -1
  38. package/dist/cjs/version.js.map +1 -1
  39. package/dist/esm/bridge/Buy.js +0 -2
  40. package/dist/esm/bridge/Buy.js.map +1 -1
  41. package/dist/esm/react/core/hooks/useTransactionDetails.js +7 -2
  42. package/dist/esm/react/core/hooks/useTransactionDetails.js.map +1 -1
  43. package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js +3 -3
  44. package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
  45. package/dist/esm/react/web/ui/Bridge/BuyWidget.js +14 -4
  46. package/dist/esm/react/web/ui/Bridge/BuyWidget.js.map +1 -1
  47. package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js +14 -4
  48. package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
  49. package/dist/esm/react/web/ui/Bridge/ErrorBanner.js +13 -1
  50. package/dist/esm/react/web/ui/Bridge/ErrorBanner.js.map +1 -1
  51. package/dist/esm/react/web/ui/Bridge/QuoteLoader.js +20 -1
  52. package/dist/esm/react/web/ui/Bridge/QuoteLoader.js.map +1 -1
  53. package/dist/esm/react/web/ui/Bridge/TransactionPayment.js +3 -0
  54. package/dist/esm/react/web/ui/Bridge/TransactionPayment.js.map +1 -1
  55. package/dist/esm/react/web/ui/Bridge/TransactionWidget.js +14 -4
  56. package/dist/esm/react/web/ui/Bridge/TransactionWidget.js.map +1 -1
  57. package/dist/esm/react/web/ui/Bridge/UnsupportedTokenScreen.js +14 -1
  58. package/dist/esm/react/web/ui/Bridge/UnsupportedTokenScreen.js.map +1 -1
  59. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentDetails.js +27 -0
  60. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentDetails.js.map +1 -1
  61. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentOverview.js +2 -1
  62. package/dist/esm/react/web/ui/Bridge/payment-details/PaymentOverview.js.map +1 -1
  63. package/dist/esm/react/web/ui/Bridge/payment-selection/PaymentSelection.js +13 -0
  64. package/dist/esm/react/web/ui/Bridge/payment-selection/PaymentSelection.js.map +1 -1
  65. package/dist/esm/react/web/ui/Bridge/payment-success/SuccessScreen.js +18 -1
  66. package/dist/esm/react/web/ui/Bridge/payment-success/SuccessScreen.js.map +1 -1
  67. package/dist/esm/react/web/ui/PayEmbed.js +4 -4
  68. package/dist/esm/react/web/ui/PayEmbed.js.map +1 -1
  69. package/dist/esm/stories/Bridge/ErrorBanner.stories.js +2 -1
  70. package/dist/esm/stories/Bridge/ErrorBanner.stories.js.map +1 -1
  71. package/dist/esm/stories/Bridge/SuccessScreen.stories.js +8 -1
  72. package/dist/esm/stories/Bridge/SuccessScreen.stories.js.map +1 -1
  73. package/dist/esm/stories/Bridge/UnsupportedTokenScreen.stories.js +6 -0
  74. package/dist/esm/stories/Bridge/UnsupportedTokenScreen.stories.js.map +1 -1
  75. package/dist/esm/version.js +1 -1
  76. package/dist/esm/version.js.map +1 -1
  77. package/dist/types/bridge/Buy.d.ts +0 -2
  78. package/dist/types/bridge/Buy.d.ts.map +1 -1
  79. package/dist/types/react/core/hooks/useTransactionDetails.d.ts +3 -1
  80. package/dist/types/react/core/hooks/useTransactionDetails.d.ts.map +1 -1
  81. package/dist/types/react/web/ui/Bridge/BridgeOrchestrator.d.ts.map +1 -1
  82. package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts +1 -3
  83. package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts.map +1 -1
  84. package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts +1 -3
  85. package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts.map +1 -1
  86. package/dist/types/react/web/ui/Bridge/ErrorBanner.d.ts +3 -1
  87. package/dist/types/react/web/ui/Bridge/ErrorBanner.d.ts.map +1 -1
  88. package/dist/types/react/web/ui/Bridge/QuoteLoader.d.ts +2 -1
  89. package/dist/types/react/web/ui/Bridge/QuoteLoader.d.ts.map +1 -1
  90. package/dist/types/react/web/ui/Bridge/TransactionPayment.d.ts.map +1 -1
  91. package/dist/types/react/web/ui/Bridge/TransactionWidget.d.ts +1 -3
  92. package/dist/types/react/web/ui/Bridge/TransactionWidget.d.ts.map +1 -1
  93. package/dist/types/react/web/ui/Bridge/UnsupportedTokenScreen.d.ts +3 -0
  94. package/dist/types/react/web/ui/Bridge/UnsupportedTokenScreen.d.ts.map +1 -1
  95. package/dist/types/react/web/ui/Bridge/payment-details/PaymentDetails.d.ts.map +1 -1
  96. package/dist/types/react/web/ui/Bridge/payment-details/PaymentOverview.d.ts.map +1 -1
  97. package/dist/types/react/web/ui/Bridge/payment-selection/PaymentSelection.d.ts.map +1 -1
  98. package/dist/types/react/web/ui/Bridge/payment-success/SuccessScreen.d.ts +3 -1
  99. package/dist/types/react/web/ui/Bridge/payment-success/SuccessScreen.d.ts.map +1 -1
  100. package/dist/types/react/web/ui/PayEmbed.d.ts +1 -1
  101. package/dist/types/react/web/ui/PayEmbed.d.ts.map +1 -1
  102. package/dist/types/stories/Bridge/ErrorBanner.stories.d.ts.map +1 -1
  103. package/dist/types/stories/Bridge/SuccessScreen.stories.d.ts.map +1 -1
  104. package/dist/types/stories/Bridge/UnsupportedTokenScreen.stories.d.ts.map +1 -1
  105. package/dist/types/version.d.ts +1 -1
  106. package/dist/types/version.d.ts.map +1 -1
  107. package/package.json +1 -1
  108. package/src/bridge/Buy.ts +0 -2
  109. package/src/react/core/hooks/useTransactionDetails.ts +9 -1
  110. package/src/react/web/ui/Bridge/BridgeOrchestrator.tsx +3 -0
  111. package/src/react/web/ui/Bridge/BuyWidget.tsx +21 -4
  112. package/src/react/web/ui/Bridge/CheckoutWidget.tsx +21 -4
  113. package/src/react/web/ui/Bridge/ErrorBanner.tsx +21 -1
  114. package/src/react/web/ui/Bridge/QuoteLoader.tsx +24 -0
  115. package/src/react/web/ui/Bridge/TransactionPayment.tsx +3 -0
  116. package/src/react/web/ui/Bridge/TransactionWidget.tsx +21 -4
  117. package/src/react/web/ui/Bridge/UnsupportedTokenScreen.tsx +18 -1
  118. package/src/react/web/ui/Bridge/payment-details/PaymentDetails.tsx +34 -0
  119. package/src/react/web/ui/Bridge/payment-details/PaymentOverview.tsx +3 -0
  120. package/src/react/web/ui/Bridge/payment-selection/PaymentSelection.tsx +14 -0
  121. package/src/react/web/ui/Bridge/payment-success/SuccessScreen.tsx +22 -0
  122. package/src/react/web/ui/PayEmbed.tsx +4 -1
  123. package/src/stories/Bridge/ErrorBanner.stories.tsx +5 -1
  124. package/src/stories/Bridge/SuccessScreen.stories.tsx +8 -1
  125. package/src/stories/Bridge/UnsupportedTokenScreen.stories.tsx +7 -0
  126. package/src/version.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SuccessScreen.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Bridge/SuccessScreen.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAEvF,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,4DAA4D,CAAC;AAsEpE,UAAU,2BAA4B,SAAQ,kBAAkB;IAC9D,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACjC;AAYD,QAAA,MAAM,IAAI;;;;;;;;qBA1C2D,CAAC;2BAEhE,CAAD;qBACY,CAAC;;;;;;;;;;;;;;;;;;;uBA8BqB,2BAA2B;;;;;;;;;;;CAsCnB,CAAC;AAEhD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAe3B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAShC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAkB5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAYjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAUhC,CAAC"}
1
+ {"version":3,"file":"SuccessScreen.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Bridge/SuccessScreen.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAEvF,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,4DAA4D,CAAC;AAsEpE,UAAU,2BAA4B,SAAQ,kBAAkB;IAC9D,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACjC;AAYD,QAAA,MAAM,IAAI;;;;;;;;qBA1C8C,CAAC;2BACjD,CAAL;qBAEG,CAAD;;;;;;;;;;;;;;;;;;;uBA8BkC,2BAA2B;;;;;;;;;;;CAsCnB,CAAC;AAEhD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAQrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAgB3B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAUhC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAmB5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAajC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAWhC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"UnsupportedTokenScreen.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Bridge/UnsupportedTokenScreen.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,qDAAqD,CAAC;AAI7D,UAAU,oCACR,SAAQ,2BAA2B;IACnC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACjC;AAcD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;uBAVD,oCAAoC;;;;;;;;;;;CAkCW,CAAC;AAEzD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,KAc/B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KAcpC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAcjC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KActC,CAAC"}
1
+ {"version":3,"file":"UnsupportedTokenScreen.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Bridge/UnsupportedTokenScreen.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,qDAAqD,CAAC;AAM7D,UAAU,oCACR,SAAQ,2BAA2B;IACnC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACjC;AAcD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;uBAVD,oCAAoC;;;;;;;;;;;CAkCW,CAAC;AAEzD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,KAe/B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KAepC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAejC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KAetC,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const version = "5.104.1";
1
+ export declare const version = "5.104.2-nightly-c5f9921dc9cf6c62d754f12ce6171d95bd87a590-20250625053652";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,YAAY,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,4EAA4E,CAAC"}
package/package.json CHANGED
@@ -375,7 +375,7 @@
375
375
  }
376
376
  },
377
377
  "typings": "./dist/types/exports/thirdweb.d.ts",
378
- "version": "5.104.1",
378
+ "version": "5.104.2-nightly-c5f9921dc9cf6c62d754f12ce6171d95bd87a590-20250625053652",
379
379
  "scripts": {
380
380
  "bench": "vitest -c ./test/vitest.config.ts bench",
381
381
  "bench:compare": "bun run ./benchmarks/run.ts",
package/src/bridge/Buy.ts CHANGED
@@ -99,7 +99,6 @@ import type { PreparedQuote, Quote } from "./types/Quote.js";
99
99
  *
100
100
  * @throws Will throw an error if there is an issue fetching the quote.
101
101
  * @bridge Buy
102
- * @beta
103
102
  */
104
103
  export async function quote(options: quote.Options): Promise<quote.Result> {
105
104
  const {
@@ -326,7 +325,6 @@ export declare namespace quote {
326
325
  *
327
326
  * @throws Will throw an error if there is an issue fetching the quote.
328
327
  * @bridge Buy
329
- * @beta
330
328
  */
331
329
  export async function prepare(
332
330
  options: prepare.Options,
@@ -14,6 +14,8 @@ import type { PreparedTransaction } from "../../../transaction/prepare-transacti
14
14
  import { getTransactionGasCost } from "../../../transaction/utils.js";
15
15
  import { resolvePromisedValue } from "../../../utils/promise/resolve-promised-value.js";
16
16
  import { toTokens } from "../../../utils/units.js";
17
+ import type { Wallet } from "../../../wallets/interfaces/wallet.js";
18
+ import { hasSponsoredTransactionsEnabled } from "../../../wallets/smart/is-smart-wallet.js";
17
19
  import {
18
20
  formatCurrencyAmount,
19
21
  formatTokenAmount,
@@ -40,6 +42,7 @@ interface TransactionDetails {
40
42
  interface UseTransactionDetailsOptions {
41
43
  transaction: PreparedTransaction;
42
44
  client: ThirdwebClient;
45
+ wallet: Wallet | undefined;
43
46
  }
44
47
 
45
48
  /**
@@ -49,8 +52,10 @@ interface UseTransactionDetailsOptions {
49
52
  export function useTransactionDetails({
50
53
  transaction,
51
54
  client,
55
+ wallet,
52
56
  }: UseTransactionDetailsOptions) {
53
57
  const chainMetadata = useChainMetadata(transaction.chain);
58
+ const hasSponsoredTransactions = hasSponsoredTransactionsEnabled(wallet);
54
59
 
55
60
  return useQuery({
56
61
  enabled: !!transaction.to && !!chainMetadata.data,
@@ -76,7 +81,9 @@ export function useTransactionDetails({
76
81
  erc20Value ? erc20Value.tokenAddress : NATIVE_TOKEN_ADDRESS,
77
82
  transaction.chain.id,
78
83
  ).catch(() => null),
79
- getTransactionGasCost(transaction).catch(() => null),
84
+ hasSponsoredTransactions
85
+ ? 0n
86
+ : getTransactionGasCost(transaction).catch(() => null),
80
87
  ]);
81
88
 
82
89
  // Process function info from ABI if available
@@ -172,6 +179,7 @@ export function useTransactionDetails({
172
179
  transaction.to,
173
180
  transaction.chain.id,
174
181
  transaction.erc20Value?.toString(),
182
+ hasSponsoredTransactions,
175
183
  ],
176
184
  });
177
185
  }
@@ -217,6 +217,7 @@ export function BridgeOrchestrator({
217
217
  {/* Error Banner */}
218
218
  {state.value === "error" && state.context.currentError && (
219
219
  <ErrorBanner
220
+ client={client}
220
221
  error={state.context.currentError}
221
222
  onCancel={onCancel}
222
223
  onRetry={handleRetry}
@@ -282,6 +283,7 @@ export function BridgeOrchestrator({
282
283
  amount={state.context.destinationAmount}
283
284
  client={client}
284
285
  destinationToken={state.context.destinationToken}
286
+ mode={uiOptions.mode}
285
287
  onBack={() => {
286
288
  send({ type: "BACK" });
287
289
  }}
@@ -332,6 +334,7 @@ export function BridgeOrchestrator({
332
334
  state.context.quote &&
333
335
  state.context.completedStatuses && (
334
336
  <SuccessScreen
337
+ client={client}
335
338
  completedStatuses={state.context.completedStatuses}
336
339
  onDone={handleBuyComplete}
337
340
  preparedQuote={state.context.quote}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useQuery } from "@tanstack/react-query";
4
+ import { trackPayEvent } from "../../../../analytics/track/pay.js";
4
5
  import type { Token } from "../../../../bridge/index.js";
5
6
  import type { Chain } from "../../../../chains/types.js";
6
7
  import type { ThirdwebClient } from "../../../../client/client.js";
@@ -260,14 +261,24 @@ type UIOptionsResult =
260
261
  *
261
262
  * Refer to the [`BuyWidgetConnectOptions`](https://portal.thirdweb.com/references/typescript/v5/BuyWidgetConnectOptions) type for more details.
262
263
  *
263
- * @bridge
264
- * @beta
265
- * @react
264
+ * @bridge Widgets
266
265
  */
267
266
  export function BuyWidget(props: BuyWidgetProps) {
268
267
  const localeQuery = useConnectLocale(props.locale || "en_US");
269
268
  const theme = props.theme || "dark";
270
269
 
270
+ useQuery({
271
+ queryFn: () => {
272
+ trackPayEvent({
273
+ client: props.client,
274
+ event: "ub:ui:buy_widget:render",
275
+ toChainId: props.chain.id,
276
+ toToken: props.tokenAddress,
277
+ });
278
+ },
279
+ queryKey: ["buy_widget:render"],
280
+ });
281
+
271
282
  const bridgeDataQuery = useQuery({
272
283
  queryFn: async (): Promise<UIOptionsResult> => {
273
284
  if (
@@ -343,7 +354,13 @@ export function BuyWidget(props: BuyWidgetProps) {
343
354
  );
344
355
  } else if (bridgeDataQuery.data?.type === "unsupported_token") {
345
356
  // Show unsupported token screen
346
- content = <UnsupportedTokenScreen chain={bridgeDataQuery.data.chain} />;
357
+ content = (
358
+ <UnsupportedTokenScreen
359
+ chain={bridgeDataQuery.data.chain}
360
+ client={props.client}
361
+ tokenAddress={props.tokenAddress}
362
+ />
363
+ );
347
364
  } else if (bridgeDataQuery.data?.type === "success") {
348
365
  // Show normal bridge orchestrator
349
366
  content = (
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useQuery } from "@tanstack/react-query";
4
+ import { trackPayEvent } from "../../../../analytics/track/pay.js";
4
5
  import type { Token } from "../../../../bridge/index.js";
5
6
  import type { Chain } from "../../../../chains/types.js";
6
7
  import type { ThirdwebClient } from "../../../../client/client.js";
@@ -243,14 +244,24 @@ type UIOptionsResult =
243
244
  *
244
245
  * Refer to the [`CheckoutWidgetConnectOptions`](https://portal.thirdweb.com/references/typescript/v5/CheckoutWidgetConnectOptions) type for more details.
245
246
  *
246
- * @bridge
247
- * @beta
248
- * @react
247
+ * @bridge Widgets
249
248
  */
250
249
  export function CheckoutWidget(props: CheckoutWidgetProps) {
251
250
  const localeQuery = useConnectLocale(props.locale || "en_US");
252
251
  const theme = props.theme || "dark";
253
252
 
253
+ useQuery({
254
+ queryFn: () => {
255
+ trackPayEvent({
256
+ client: props.client,
257
+ event: "ub:ui:checkout_widget:render",
258
+ toChainId: props.chain.id,
259
+ toToken: props.tokenAddress,
260
+ });
261
+ },
262
+ queryKey: ["checkout_widget:render"],
263
+ });
264
+
254
265
  const bridgeDataQuery = useQuery({
255
266
  queryFn: async (): Promise<UIOptionsResult> => {
256
267
  const token = await getToken(
@@ -306,7 +317,13 @@ export function CheckoutWidget(props: CheckoutWidgetProps) {
306
317
  );
307
318
  } else if (bridgeDataQuery.data?.type === "unsupported_token") {
308
319
  // Show unsupported token screen
309
- content = <UnsupportedTokenScreen chain={bridgeDataQuery.data.chain} />;
320
+ content = (
321
+ <UnsupportedTokenScreen
322
+ chain={bridgeDataQuery.data.chain}
323
+ client={props.client}
324
+ tokenAddress={props.tokenAddress}
325
+ />
326
+ );
310
327
  } else if (bridgeDataQuery.data?.type === "success") {
311
328
  // Show normal bridge orchestrator
312
329
  content = (
@@ -1,5 +1,8 @@
1
1
  "use client";
2
2
  import { CrossCircledIcon } from "@radix-ui/react-icons";
3
+ import { useQuery } from "@tanstack/react-query";
4
+ import { trackPayEvent } from "../../../../analytics/track/pay.js";
5
+ import type { ThirdwebClient } from "../../../../client/client.js";
3
6
  import { useCustomTheme } from "../../../core/design-system/CustomThemeProvider.js";
4
7
  import { iconSize } from "../../../core/design-system/index.js";
5
8
  import { useBridgeError } from "../../../core/hooks/useBridgeError.js";
@@ -22,13 +25,30 @@ interface ErrorBannerProps {
22
25
  * Called when user wants to cancel
23
26
  */
24
27
  onCancel?: () => void;
28
+ client: ThirdwebClient;
25
29
  }
26
30
 
27
- export function ErrorBanner({ error, onRetry, onCancel }: ErrorBannerProps) {
31
+ export function ErrorBanner({
32
+ error,
33
+ onRetry,
34
+ onCancel,
35
+ client,
36
+ }: ErrorBannerProps) {
28
37
  const theme = useCustomTheme();
29
38
 
30
39
  const { userMessage } = useBridgeError({ error });
31
40
 
41
+ useQuery({
42
+ queryFn: () => {
43
+ trackPayEvent({
44
+ client,
45
+ error: error.message,
46
+ event: "ub:ui:error",
47
+ });
48
+ },
49
+ queryKey: ["error_banner", userMessage],
50
+ });
51
+
32
52
  return (
33
53
  <Container flex="column" fullHeight gap="md" p="lg">
34
54
  {/* Error Icon and Message */}
@@ -1,5 +1,7 @@
1
1
  "use client";
2
+ import { useQuery } from "@tanstack/react-query";
2
3
  import { useEffect } from "react";
4
+ import { trackPayEvent } from "../../../../analytics/track/pay.js";
3
5
  import type { Token } from "../../../../bridge/types/Token.js";
4
6
  import type { ThirdwebClient } from "../../../../client/client.js";
5
7
  import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js";
@@ -79,9 +81,11 @@ interface QuoteLoaderProps {
79
81
  * Fee payer for direct transfers (defaults to sender)
80
82
  */
81
83
  feePayer?: "sender" | "receiver";
84
+ mode: "fund_wallet" | "direct_payment" | "transaction";
82
85
  }
83
86
 
84
87
  export function QuoteLoader({
88
+ mode,
85
89
  destinationToken,
86
90
  paymentMethod,
87
91
  amount,
@@ -109,6 +113,26 @@ export function QuoteLoader({
109
113
  });
110
114
  const prepareQuery = useBridgePrepare(request);
111
115
 
116
+ useQuery({
117
+ queryFn: () => {
118
+ trackPayEvent({
119
+ chainId:
120
+ paymentMethod.type === "wallet"
121
+ ? paymentMethod.originToken.chainId
122
+ : undefined,
123
+ client,
124
+ event: `ub:ui:loading_quote:${mode}`,
125
+ fromToken:
126
+ paymentMethod.type === "wallet"
127
+ ? paymentMethod.originToken.address
128
+ : undefined,
129
+ toChainId: destinationToken.chainId,
130
+ toToken: destinationToken.address,
131
+ });
132
+ },
133
+ queryKey: ["loading_quote", paymentMethod.type],
134
+ });
135
+
112
136
  // Handle successful quote
113
137
  useEffect(() => {
114
138
  if (prepareQuery.data) {
@@ -15,6 +15,7 @@ import {
15
15
  import { useChainMetadata } from "../../../core/hooks/others/useChainQuery.js";
16
16
  import { useTransactionDetails } from "../../../core/hooks/useTransactionDetails.js";
17
17
  import { useActiveAccount } from "../../../core/hooks/wallets/useActiveAccount.js";
18
+ import { useActiveWallet } from "../../../core/hooks/wallets/useActiveWallet.js";
18
19
  import { ConnectButton } from "../ConnectWallet/ConnectButton.js";
19
20
  import { PoweredByThirdweb } from "../ConnectWallet/PoweredByTW.js";
20
21
  import { Container, Line } from "../components/basic.js";
@@ -57,6 +58,7 @@ export function TransactionPayment({
57
58
  }: TransactionPaymentProps) {
58
59
  const theme = useCustomTheme();
59
60
  const activeAccount = useActiveAccount();
61
+ const wallet = useActiveWallet();
60
62
 
61
63
  // Get chain metadata for native currency symbol
62
64
  const chainMetadata = useChainMetadata(uiOptions.transaction.chain);
@@ -65,6 +67,7 @@ export function TransactionPayment({
65
67
  const transactionDataQuery = useTransactionDetails({
66
68
  client,
67
69
  transaction: uiOptions.transaction,
70
+ wallet,
68
71
  });
69
72
 
70
73
  const contractName =
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useQuery } from "@tanstack/react-query";
4
+ import { trackPayEvent } from "../../../../analytics/track/pay.js";
4
5
  import type { Token } from "../../../../bridge/index.js";
5
6
  import type { Chain } from "../../../../chains/types.js";
6
7
  import type { ThirdwebClient } from "../../../../client/client.js";
@@ -267,14 +268,24 @@ type UIOptionsResult =
267
268
  *
268
269
  * Refer to the [`TransactionWidgetConnectOptions`](https://portal.thirdweb.com/references/typescript/v5/TransactionWidgetConnectOptions) type for more details.
269
270
  *
270
- * @bridge
271
- * @beta
272
- * @react
271
+ * @bridge Widgets
273
272
  */
274
273
  export function TransactionWidget(props: TransactionWidgetProps) {
275
274
  const localeQuery = useConnectLocale(props.locale || "en_US");
276
275
  const theme = props.theme || "dark";
277
276
 
277
+ useQuery({
278
+ queryFn: () => {
279
+ trackPayEvent({
280
+ chainId: props.transaction.chain.id,
281
+ client: props.client,
282
+ event: "ub:ui:transaction_widget:render",
283
+ toToken: props.tokenAddress,
284
+ });
285
+ },
286
+ queryKey: ["transaction_widget:render"],
287
+ });
288
+
278
289
  const bridgeDataQuery = useQuery({
279
290
  queryFn: async (): Promise<UIOptionsResult> => {
280
291
  let erc20Value = props.transaction.erc20Value;
@@ -331,7 +342,13 @@ export function TransactionWidget(props: TransactionWidgetProps) {
331
342
  );
332
343
  } else if (bridgeDataQuery.data?.type === "unsupported_token") {
333
344
  // Show unsupported token screen
334
- content = <UnsupportedTokenScreen chain={bridgeDataQuery.data.chain} />;
345
+ content = (
346
+ <UnsupportedTokenScreen
347
+ chain={bridgeDataQuery.data.chain}
348
+ client={props.client}
349
+ tokenAddress={props.tokenAddress}
350
+ />
351
+ );
335
352
  } else if (bridgeDataQuery.data?.type === "success") {
336
353
  // Show normal bridge orchestrator
337
354
  content = (
@@ -1,4 +1,7 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import { trackPayEvent } from "../../../../analytics/track/pay.js";
1
3
  import type { Chain } from "../../../../chains/types.js";
4
+ import type { ThirdwebClient } from "../../../../client/client.js";
2
5
  import { iconSize } from "../../../core/design-system/index.js";
3
6
  import { useChainMetadata } from "../../../core/hooks/others/useChainQuery.js";
4
7
  import { AccentFailIcon } from "../ConnectWallet/icons/AccentFailIcon.js";
@@ -11,6 +14,8 @@ export interface UnsupportedTokenScreenProps {
11
14
  * The chain the token is on
12
15
  */
13
16
  chain: Chain;
17
+ client: ThirdwebClient;
18
+ tokenAddress?: string;
14
19
  }
15
20
 
16
21
  /**
@@ -18,10 +23,22 @@ export interface UnsupportedTokenScreenProps {
18
23
  * @internal
19
24
  */
20
25
  export function UnsupportedTokenScreen(props: UnsupportedTokenScreenProps) {
21
- const { chain } = props;
26
+ const { chain, tokenAddress, client } = props;
22
27
 
23
28
  const { data: chainMetadata } = useChainMetadata(chain);
24
29
 
30
+ useQuery({
31
+ queryFn: () => {
32
+ trackPayEvent({
33
+ chainId: chain.id,
34
+ client,
35
+ event: "ub:ui:unsupported_token",
36
+ fromToken: tokenAddress,
37
+ });
38
+ },
39
+ queryKey: ["unsupported_token"],
40
+ });
41
+
25
42
  if (chainMetadata?.testnet) {
26
43
  return (
27
44
  <Container
@@ -1,4 +1,6 @@
1
1
  "use client";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { trackPayEvent } from "../../../../../analytics/track/pay.js";
2
4
  import type { ThirdwebClient } from "../../../../../client/client.js";
3
5
  import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
4
6
  import { radius, spacing } from "../../../../core/design-system/index.js";
@@ -68,6 +70,38 @@ export function PaymentDetails({
68
70
  }
69
71
  };
70
72
 
73
+ useQuery({
74
+ queryFn: () => {
75
+ if (
76
+ preparedQuote.type === "buy" ||
77
+ preparedQuote.type === "sell" ||
78
+ preparedQuote.type === "transfer"
79
+ ) {
80
+ trackPayEvent({
81
+ chainId:
82
+ preparedQuote.type === "transfer"
83
+ ? preparedQuote.intent.chainId
84
+ : preparedQuote.intent.originChainId,
85
+ client,
86
+ event: "payment_details",
87
+ fromToken:
88
+ preparedQuote.type === "transfer"
89
+ ? preparedQuote.intent.tokenAddress
90
+ : preparedQuote.intent.originTokenAddress,
91
+ toChainId:
92
+ preparedQuote.type === "transfer"
93
+ ? preparedQuote.intent.chainId
94
+ : preparedQuote.intent.destinationChainId,
95
+ toToken:
96
+ preparedQuote.type === "transfer"
97
+ ? preparedQuote.intent.tokenAddress
98
+ : preparedQuote.intent.destinationTokenAddress,
99
+ });
100
+ }
101
+ },
102
+ queryKey: ["payment_details", preparedQuote.type],
103
+ });
104
+
71
105
  // Extract common data based on quote type
72
106
  const getDisplayData = () => {
73
107
  switch (preparedQuote.type) {
@@ -188,6 +188,7 @@ export function PaymentOverview(props: {
188
188
  {props.uiOptions.mode === "transaction" && (
189
189
  <TransactionOverViewCompact
190
190
  client={props.client}
191
+ paymentMethod={props.paymentMethod}
191
192
  uiOptions={props.uiOptions}
192
193
  />
193
194
  )}
@@ -198,12 +199,14 @@ export function PaymentOverview(props: {
198
199
 
199
200
  const TransactionOverViewCompact = (props: {
200
201
  uiOptions: Extract<UIOptions, { mode: "transaction" }>;
202
+ paymentMethod: PaymentMethod;
201
203
  client: ThirdwebClient;
202
204
  }) => {
203
205
  const theme = useCustomTheme();
204
206
  const txInfo = useTransactionDetails({
205
207
  client: props.client,
206
208
  transaction: props.uiOptions.transaction,
209
+ wallet: props.paymentMethod.payerWallet,
207
210
  });
208
211
 
209
212
  if (!txInfo.data) {
@@ -1,5 +1,7 @@
1
1
  "use client";
2
+ import { useQuery } from "@tanstack/react-query";
2
3
  import { useEffect, useState } from "react";
4
+ import { trackPayEvent } from "../../../../../analytics/track/pay.js";
3
5
  import type { Token } from "../../../../../bridge/types/Token.js";
4
6
  import { defineChain } from "../../../../../chains/utils.js";
5
7
  import type { ThirdwebClient } from "../../../../../client/client.js";
@@ -96,6 +98,18 @@ export function PaymentSelection({
96
98
  type: "walletSelection",
97
99
  });
98
100
 
101
+ useQuery({
102
+ queryFn: () => {
103
+ trackPayEvent({
104
+ client,
105
+ event: "payment_selection",
106
+ toChainId: destinationToken.chainId,
107
+ toToken: destinationToken.address,
108
+ });
109
+ },
110
+ queryKey: ["payment_selection"],
111
+ });
112
+
99
113
  const payerWallet =
100
114
  currentStep.type === "tokenSelection"
101
115
  ? currentStep.selectedWallet
@@ -1,6 +1,9 @@
1
1
  "use client";
2
2
  import { CheckIcon } from "@radix-ui/react-icons";
3
+ import { useQuery } from "@tanstack/react-query";
3
4
  import { useState } from "react";
5
+ import { trackPayEvent } from "../../../../../analytics/track/pay.js";
6
+ import type { ThirdwebClient } from "../../../../../client/client.js";
4
7
  import type { WindowAdapter } from "../../../../core/adapters/WindowAdapter.js";
5
8
  import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
6
9
  import { iconSize } from "../../../../core/design-system/index.js";
@@ -37,6 +40,8 @@ export interface SuccessScreenProps {
37
40
  * Window adapter for opening URLs
38
41
  */
39
42
  windowAdapter: WindowAdapter;
43
+
44
+ client: ThirdwebClient;
40
45
  }
41
46
 
42
47
  type ViewState = "success" | "detail";
@@ -47,10 +52,27 @@ export function SuccessScreen({
47
52
  completedStatuses,
48
53
  onDone,
49
54
  windowAdapter,
55
+ client,
50
56
  }: SuccessScreenProps) {
51
57
  const theme = useCustomTheme();
52
58
  const [viewState, setViewState] = useState<ViewState>("success");
53
59
 
60
+ useQuery({
61
+ queryFn: () => {
62
+ if (preparedQuote.type === "buy" || preparedQuote.type === "sell") {
63
+ trackPayEvent({
64
+ chainId: preparedQuote.intent.originChainId,
65
+ client: client,
66
+ event: "ub:ui:success_screen",
67
+ fromToken: preparedQuote.intent.originTokenAddress,
68
+ toChainId: preparedQuote.intent.destinationChainId,
69
+ toToken: preparedQuote.intent.destinationTokenAddress,
70
+ });
71
+ }
72
+ },
73
+ queryKey: ["success_screen", preparedQuote.type],
74
+ });
75
+
54
76
  if (viewState === "detail") {
55
77
  return (
56
78
  <PaymentReceipt
@@ -307,7 +307,7 @@ export type PayEmbedProps = {
307
307
  *
308
308
  * Refer to the [`PayEmbedConnectOptions`](https://portal.thirdweb.com/references/typescript/v5/PayEmbedConnectOptions) type for more details.
309
309
  *
310
- * @buyCrypto
310
+ * @deprecated Use `BuyWidget`, `CheckoutWidget` or `TransactionWidget` instead.
311
311
  */
312
312
  export function PayEmbed(props: PayEmbedProps) {
313
313
  const localeQuery = useConnectLocale(props.locale || "en_US");
@@ -356,6 +356,7 @@ export function PayEmbed(props: PayEmbedProps) {
356
356
  amount={props.payOptions.prefillBuy.amount || "0.01"}
357
357
  chain={props.payOptions.prefillBuy.chain}
358
358
  client={props.client}
359
+ onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
359
360
  theme={theme}
360
361
  title={metadata?.name || "Buy"}
361
362
  tokenAddress={
@@ -374,6 +375,7 @@ export function PayEmbed(props: PayEmbedProps) {
374
375
  description={metadata?.description}
375
376
  image={metadata?.image}
376
377
  name={metadata?.name || "Checkout"}
378
+ onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
377
379
  seller={props.payOptions.paymentInfo.sellerAddress as Address}
378
380
  theme={theme}
379
381
  tokenAddress={
@@ -389,6 +391,7 @@ export function PayEmbed(props: PayEmbedProps) {
389
391
  client={props.client}
390
392
  description={metadata?.description}
391
393
  image={metadata?.image}
394
+ onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
392
395
  theme={theme}
393
396
  title={metadata?.name}
394
397
  transaction={props.payOptions.transaction}
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
+ import { createThirdwebClient } from "../../client/client.js";
2
3
  import type { Theme } from "../../react/core/design-system/index.js";
3
4
  import { ErrorBanner } from "../../react/web/ui/Bridge/ErrorBanner.js";
4
5
  import { ModalThemeWrapper } from "../utils.js";
@@ -25,7 +26,10 @@ const ErrorBannerWithTheme = (props: ErrorBannerWithThemeProps) => {
25
26
  const { theme, ...componentProps } = props;
26
27
  return (
27
28
  <ModalThemeWrapper theme={theme}>
28
- <ErrorBanner {...componentProps} />
29
+ <ErrorBanner
30
+ client={createThirdwebClient({ clientId: "test" })}
31
+ {...componentProps}
32
+ />
29
33
  </ModalThemeWrapper>
30
34
  );
31
35
  };