@b3dotfun/sdk 0.0.41 → 0.0.42-alpha.1

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 (116) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +1 -0
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +18 -2
  3. package/dist/cjs/anyspend/react/components/AnySpendBondKit.js +0 -1
  4. package/dist/cjs/anyspend/react/components/AnySpendBuySpin.js +0 -1
  5. package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  6. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +76 -14
  7. package/dist/cjs/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  8. package/dist/cjs/anyspend/react/components/AnySpendNFT.js +2 -2
  9. package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +0 -1
  10. package/dist/cjs/anyspend/react/components/AnyspendSignatureMint.js +1 -2
  11. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +1 -1
  12. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +2 -1
  13. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +4 -1
  14. package/dist/cjs/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  15. package/dist/cjs/anyspend/react/components/common/PointsBadge.js +7 -0
  16. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +5 -3
  17. package/dist/cjs/anyspend/services/anyspend.d.ts +1 -1
  18. package/dist/cjs/anyspend/services/anyspend.js +2 -0
  19. package/dist/cjs/anyspend/types/api.d.ts +41 -1
  20. package/dist/cjs/anyspend/utils/orderPayload.js +3 -0
  21. package/dist/cjs/bondkit/components/TradingView.js +3 -4
  22. package/dist/cjs/bondkit/swapService.js +3 -0
  23. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +19 -13
  24. package/dist/cjs/global-account/react/hooks/index.d.ts +1 -0
  25. package/dist/cjs/global-account/react/hooks/index.js +3 -1
  26. package/dist/cjs/global-account/react/hooks/useAccountAssets.js +5 -2
  27. package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -1
  28. package/dist/cjs/global-account/react/hooks/useGlobalAccount.d.ts +6 -0
  29. package/dist/cjs/global-account/react/hooks/useGlobalAccount.js +32 -0
  30. package/dist/cjs/global-account/react/hooks/useQueryB3.js +5 -2
  31. package/dist/cjs/global-account/react/hooks/useQueryBSMNT.js +5 -2
  32. package/dist/cjs/global-account/react/hooks/useTokenBalancesByChain.js +7 -1
  33. package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +2 -2
  34. package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +1 -2
  35. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +1 -1
  36. package/dist/cjs/shared/utils/fetchBalances.d.ts +1 -1
  37. package/dist/esm/anyspend/react/components/AnySpend.d.ts +1 -0
  38. package/dist/esm/anyspend/react/components/AnySpend.js +18 -2
  39. package/dist/esm/anyspend/react/components/AnySpendBondKit.js +0 -1
  40. package/dist/esm/anyspend/react/components/AnySpendBuySpin.js +0 -1
  41. package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  42. package/dist/esm/anyspend/react/components/AnySpendCustom.js +43 -14
  43. package/dist/esm/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  44. package/dist/esm/anyspend/react/components/AnySpendNFT.js +2 -2
  45. package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +0 -1
  46. package/dist/esm/anyspend/react/components/AnyspendSignatureMint.js +1 -2
  47. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +1 -1
  48. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +2 -1
  49. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +4 -1
  50. package/dist/esm/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  51. package/dist/esm/anyspend/react/components/common/PointsBadge.js +4 -0
  52. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +5 -3
  53. package/dist/esm/anyspend/services/anyspend.d.ts +1 -1
  54. package/dist/esm/anyspend/services/anyspend.js +2 -0
  55. package/dist/esm/anyspend/types/api.d.ts +41 -1
  56. package/dist/esm/anyspend/utils/orderPayload.js +3 -0
  57. package/dist/esm/bondkit/components/TradingView.js +3 -4
  58. package/dist/esm/bondkit/swapService.js +5 -2
  59. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +19 -13
  60. package/dist/esm/global-account/react/hooks/index.d.ts +1 -0
  61. package/dist/esm/global-account/react/hooks/index.js +1 -0
  62. package/dist/esm/global-account/react/hooks/useAccountAssets.js +2 -2
  63. package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -1
  64. package/dist/esm/global-account/react/hooks/useGlobalAccount.d.ts +6 -0
  65. package/dist/esm/global-account/react/hooks/useGlobalAccount.js +29 -0
  66. package/dist/esm/global-account/react/hooks/useQueryB3.js +5 -2
  67. package/dist/esm/global-account/react/hooks/useQueryBSMNT.js +5 -2
  68. package/dist/esm/global-account/react/hooks/useTokenBalancesByChain.js +4 -1
  69. package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +2 -2
  70. package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -3
  71. package/dist/esm/global-account/react/stores/useModalStore.d.ts +1 -1
  72. package/dist/esm/shared/utils/fetchBalances.d.ts +1 -1
  73. package/dist/styles/index.css +1 -1
  74. package/dist/types/anyspend/react/components/AnySpend.d.ts +1 -0
  75. package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  76. package/dist/types/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  77. package/dist/types/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  78. package/dist/types/anyspend/services/anyspend.d.ts +1 -1
  79. package/dist/types/anyspend/types/api.d.ts +41 -1
  80. package/dist/types/global-account/react/hooks/index.d.ts +1 -0
  81. package/dist/types/global-account/react/hooks/useGlobalAccount.d.ts +6 -0
  82. package/dist/types/global-account/react/stores/useModalStore.d.ts +1 -1
  83. package/dist/types/shared/utils/fetchBalances.d.ts +1 -1
  84. package/package.json +22 -23
  85. package/src/anyspend/react/components/AnySpend.tsx +23 -1
  86. package/src/anyspend/react/components/AnySpendBondKit.tsx +0 -1
  87. package/src/anyspend/react/components/AnySpendBuySpin.tsx +0 -1
  88. package/src/anyspend/react/components/AnySpendCustom.tsx +74 -15
  89. package/src/anyspend/react/components/AnySpendNFT.tsx +3 -0
  90. package/src/anyspend/react/components/AnySpendStakeB3.tsx +0 -1
  91. package/src/anyspend/react/components/AnyspendSignatureMint.tsx +1 -2
  92. package/src/anyspend/react/components/common/CryptoPaySection.tsx +1 -1
  93. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +6 -8
  94. package/src/anyspend/react/components/common/PanelOnramp.tsx +10 -10
  95. package/src/anyspend/react/components/common/PointsBadge.tsx +20 -0
  96. package/src/anyspend/react/hooks/useAnyspendFlow.ts +5 -3
  97. package/src/anyspend/react/hooks/useAnyspendOrderAndTransactions.ts +1 -1
  98. package/src/anyspend/react/hooks/useCoinbaseOnrampOptions.ts +1 -1
  99. package/src/anyspend/services/anyspend.ts +3 -1
  100. package/src/anyspend/types/api.ts +41 -1
  101. package/src/anyspend/utils/orderPayload.ts +3 -0
  102. package/src/bondkit/components/TradingView.tsx +3 -5
  103. package/src/bondkit/swapService.ts +10 -7
  104. package/src/global-account/react/components/B3Provider/B3Provider.tsx +21 -17
  105. package/src/global-account/react/hooks/index.ts +1 -0
  106. package/src/global-account/react/hooks/useAccountAssets.ts +4 -3
  107. package/src/global-account/react/hooks/useAuthentication.ts +1 -1
  108. package/src/global-account/react/hooks/useGlobalAccount.tsx +36 -0
  109. package/src/global-account/react/hooks/useOneBalance.tsx +1 -1
  110. package/src/global-account/react/hooks/useQueryB3.ts +22 -15
  111. package/src/global-account/react/hooks/useQueryBSMNT.ts +22 -15
  112. package/src/global-account/react/hooks/useTokenBalancesByChain.tsx +4 -1
  113. package/src/global-account/react/hooks/useTokenFromUrl.tsx +2 -2
  114. package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +2 -3
  115. package/src/global-account/react/stores/useModalStore.ts +1 -1
  116. package/src/shared/utils/fetchBalances.ts +1 -1
@@ -10,15 +10,18 @@ import { simpleHashChainToChainName } from "../../../shared/utils/simplehash.js"
10
10
  import invariant from "invariant";
11
11
  import { ChevronRight, ChevronRightCircle, Loader2 } from "lucide-react";
12
12
  import { motion } from "motion/react";
13
- import { useCallback, useEffect, useMemo, useState } from "react";
13
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
14
14
  import { toast } from "sonner";
15
15
  import { base } from "viem/chains";
16
+ import { useFeatureFlags } from "../contexts/FeatureFlagsContext.js";
16
17
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper.js";
17
18
  import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod.js";
18
19
  import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaymentMethod.js";
19
20
  import { OrderDetails } from "./common/OrderDetails.js";
20
21
  import { OrderHistory } from "./common/OrderHistory.js";
21
22
  import { OrderToken } from "./common/OrderToken.js";
23
+ import { PointsBadge } from "./common/PointsBadge.js";
24
+ import { PointsDetailPanel } from "./common/PointsDetailPanel.js";
22
25
  import { RecipientSelection } from "./common/RecipientSelection.js";
23
26
  var PanelView;
24
27
  (function (PanelView) {
@@ -29,8 +32,9 @@ var PanelView;
29
32
  PanelView[PanelView["RECIPIENT_SELECTION"] = 4] = "RECIPIENT_SELECTION";
30
33
  PanelView[PanelView["CRYPTO_PAYMENT_METHOD"] = 5] = "CRYPTO_PAYMENT_METHOD";
31
34
  PanelView[PanelView["FIAT_PAYMENT_METHOD"] = 6] = "FIAT_PAYMENT_METHOD";
35
+ PanelView[PanelView["POINTS_DETAIL"] = 7] = "POINTS_DETAIL";
32
36
  })(PanelView || (PanelView = {}));
33
- function generateGetRelayQuoteRequest({ orderType, srcChainId, srcToken, dstChainId, dstToken, dstAmount, contractAddress, tokenId, contractType, encodedData, spenderAddress, }) {
37
+ function generateGetRelayQuoteRequest({ orderType, srcChainId, srcToken, dstChainId, dstToken, recipientAddress, dstAmount, contractAddress, tokenId, contractType, encodedData, spenderAddress, }) {
34
38
  switch (orderType) {
35
39
  case "mint_nft": {
36
40
  invariant(contractType, "Contract type is required");
@@ -40,6 +44,7 @@ function generateGetRelayQuoteRequest({ orderType, srcChainId, srcToken, dstChai
40
44
  srcTokenAddress: srcToken.address,
41
45
  dstChain: dstChainId,
42
46
  dstTokenAddress: dstToken.address,
47
+ recipientAddress,
43
48
  price: dstAmount,
44
49
  contractAddress: contractAddress,
45
50
  tokenId: tokenId,
@@ -53,6 +58,7 @@ function generateGetRelayQuoteRequest({ orderType, srcChainId, srcToken, dstChai
53
58
  srcTokenAddress: srcToken.address,
54
59
  dstChain: dstChainId,
55
60
  dstTokenAddress: dstToken.address,
61
+ recipientAddress,
56
62
  price: dstAmount,
57
63
  contractAddress: contractAddress,
58
64
  };
@@ -64,6 +70,7 @@ function generateGetRelayQuoteRequest({ orderType, srcChainId, srcToken, dstChai
64
70
  srcTokenAddress: srcToken.address,
65
71
  dstChain: dstChainId,
66
72
  dstTokenAddress: dstToken.address,
73
+ recipientAddress,
67
74
  fundAmount: dstAmount,
68
75
  contractAddress: contractAddress,
69
76
  };
@@ -75,6 +82,7 @@ function generateGetRelayQuoteRequest({ orderType, srcChainId, srcToken, dstChai
75
82
  srcTokenAddress: srcToken.address,
76
83
  dstChain: dstChainId,
77
84
  dstTokenAddress: dstToken.address,
85
+ recipientAddress,
78
86
  payload: {
79
87
  amount: dstAmount,
80
88
  data: encodedData,
@@ -92,8 +100,9 @@ export function AnySpendCustom(props) {
92
100
  const fingerprintConfig = getFingerprintConfig();
93
101
  return (_jsx(AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: _jsx(AnySpendCustomInner, { ...props }) }));
94
102
  }
95
- function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabProps = "crypto", recipientAddress: recipientAddressProps, spenderAddress, orderType, dstChainId, dstToken, dstAmount, contractAddress, encodedData, metadata, header, onSuccess, showRecipient = true, }) {
103
+ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabProps = "crypto", recipientAddress: recipientAddressProps, spenderAddress, orderType, dstChainId, dstToken, dstAmount, contractAddress, encodedData, metadata, header, onSuccess, showRecipient = true, onShowPointsDetail, }) {
96
104
  const hasMounted = useHasMounted();
105
+ const featureFlags = useFeatureFlags();
97
106
  const searchParams = useSearchParamsSSR();
98
107
  const router = useRouter();
99
108
  const [activePanel, setActivePanel] = useState(loadOrder ? PanelView.ORDER_DETAILS : PanelView.CONFIRM_ORDER);
@@ -108,6 +117,8 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
108
117
  // Update recipient logic to use custom recipient
109
118
  const recipientAddress = customRecipientAddress || currentWallet.address;
110
119
  const [orderId, setOrderId] = useState(loadOrder);
120
+ // Track if onSuccess has been called for the current order
121
+ const onSuccessCalled = React.useRef(false);
111
122
  const [srcChainId, setSrcChainId] = useState(base.id);
112
123
  // Get token list for token balance check
113
124
  const chainName = useMemo(() => simpleHashChainToChainName(srcChainId), [srcChainId]);
@@ -168,10 +179,11 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
168
179
  srcToken: activeTab === "fiat" ? USDC_BASE : srcToken,
169
180
  dstChainId: dstChainId,
170
181
  dstToken: dstToken,
182
+ recipientAddress,
171
183
  dstAmount: dstAmount,
172
184
  contractAddress: contractAddress,
173
- tokenId: metadata.type === "mint_nft" ? metadata.nftContract.tokenId : undefined,
174
- contractType: metadata.type === "mint_nft" ? metadata.nftContract.type : undefined,
185
+ tokenId: orderType === "mint_nft" ? metadata?.nftContract?.tokenId : undefined,
186
+ contractType: orderType === "mint_nft" ? metadata?.nftContract?.type : undefined,
175
187
  encodedData: encodedData,
176
188
  spenderAddress: spenderAddress,
177
189
  });
@@ -184,8 +196,8 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
184
196
  encodedData,
185
197
  metadata?.nftContract?.tokenId,
186
198
  metadata?.nftContract?.type,
187
- metadata?.type,
188
199
  orderType,
200
+ recipientAddress,
189
201
  spenderAddress,
190
202
  srcChainId,
191
203
  srcToken,
@@ -220,12 +232,17 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
220
232
  // Get geo data and onramp options (after quote is available)
221
233
  const { geoData, isOnrampSupported, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(srcFiatAmount);
222
234
  useEffect(() => {
223
- if (oat?.data?.order.status === "executed") {
235
+ if (oat?.data?.order.status === "executed" && !onSuccessCalled.current) {
224
236
  console.log("Calling onSuccess");
225
237
  const txHash = oat?.data?.executeTx?.txHash;
226
238
  onSuccess?.(txHash);
239
+ onSuccessCalled.current = true;
227
240
  }
228
- }, [oat?.data?.executeTx?.txHash, oat?.data?.order.status, onSuccess]);
241
+ }, [oat?.data?.order.status, oat?.data?.executeTx?.txHash, onSuccess]);
242
+ // Reset flag when orderId changes
243
+ useEffect(() => {
244
+ onSuccessCalled.current = false;
245
+ }, [orderId]);
229
246
  const { createOrder: createRegularOrder, isCreatingOrder: isCreatingRegularOrder } = useAnyspendCreateOrder({
230
247
  onSuccess: data => {
231
248
  setOrderId(data.data.id);
@@ -261,7 +278,7 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
261
278
  srcAmount: srcAmount.toString(),
262
279
  recipientAddress,
263
280
  creatorAddress: currentWallet?.wallet?.address,
264
- nft: metadata.type === "mint_nft"
281
+ nft: orderType === "mint_nft"
265
282
  ? metadata.nftContract.type === "erc1155"
266
283
  ? {
267
284
  type: "erc1155",
@@ -282,7 +299,7 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
282
299
  imageUrl: metadata.nftContract.imageUrl,
283
300
  }
284
301
  : undefined,
285
- tournament: metadata.type === "join_tournament" || metadata.type === "fund_tournament"
302
+ tournament: orderType === "join_tournament" || orderType === "fund_tournament"
286
303
  ? {
287
304
  ...metadata.tournament,
288
305
  contractAddress: contractAddress,
@@ -290,13 +307,12 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
290
307
  }
291
308
  : undefined,
292
309
  // only populate payload for custom tx
293
- payload: metadata.type === "custom"
310
+ payload: orderType === "custom"
294
311
  ? {
295
312
  amount: dstAmount,
296
313
  data: encodedData,
297
314
  spenderAddress: spenderAddress,
298
315
  to: contractAddress,
299
- action: metadata.action,
300
316
  }
301
317
  : undefined,
302
318
  };
@@ -421,6 +437,16 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
421
437
  router.push(`${window.location.pathname}?${params.toString()}`);
422
438
  } })), mode === "page" && _jsx("div", { className: "h-12" })] }));
423
439
  const loadingView = (_jsxs("div", { className: cn("mx-auto flex w-full flex-col items-center gap-4 p-5", mode === "modal" && "bg-b3-react-background"), children: [_jsxs(Badge, { variant: "default", className: "bg-b3-react-muted/30 border-b3-react-border hover:bg-b3-react-muted/50 flex items-center gap-3 px-4 py-1 text-base transition-all", children: [_jsx(Loader2, { className: "text-b3-react-foreground size-4 animate-spin" }), _jsx(TextShimmer, { duration: 1, className: "font-sf-rounded text-base font-semibold", children: "Loading..." })] }), _jsxs("div", { className: "flex w-full flex-1 flex-col", children: [_jsxs("div", { className: "mb-4 flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-24" }), _jsxs("div", { className: "mt-2 flex items-center gap-2", children: [_jsx(Skeleton, { className: "h-8 w-48" }), _jsx(Skeleton, { className: "ml-4 h-8 w-32" })] }), _jsx(Skeleton, { className: "mt-4 h-8 w-24" })] }), _jsx(Skeleton, { className: "mb-4 h-12 w-full" }), _jsxs("div", { className: "flex w-full items-center justify-between gap-4", children: [_jsxs(Skeleton, { className: "rounded-lg bg-white/5 p-6 pb-3", children: [_jsx("div", { className: "size-[200px]" }), _jsx("div", { className: "mt-3 flex items-center justify-center gap-2", children: _jsx("div", { className: "size-5 rounded-full" }) })] }), _jsx("div", { className: "flex flex-1 flex-col gap-2", children: [1, 2, 3].map(i => (_jsx(Skeleton, { className: "h-10 w-full" }, i))) })] })] }), _jsxs("div", { className: "bg-b3-react-muted/30 mt-8 w-full rounded-lg p-4", children: [_jsx(Skeleton, { className: "mb-3 h-4 w-48" }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx(Skeleton, { className: "h-10 flex-1" }), _jsx(Skeleton, { className: "h-10 flex-1" })] })] }), _jsx("div", { className: "flex w-full flex-col gap-3", children: [1, 2, 3, 4, 5].map(i => (_jsxs("div", { className: "flex w-full justify-between", children: [_jsx(Skeleton, { className: "h-4 w-24" }), _jsx(Skeleton, { className: "h-4 w-32" })] }, i))) }), _jsx(Skeleton, { className: "h-10 w-full" }), mode === "page" && _jsx("div", { className: "h-12" })] }));
440
+ // Render points badge if conditions are met
441
+ const renderPointsBadge = () => {
442
+ if (featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0) {
443
+ return (_jsx(PointsBadge, { pointsAmount: anyspendQuote.data.pointsAmount, pointsMultiplier: anyspendQuote.data.pointsMultiplier, onClick: () => {
444
+ onShowPointsDetail?.();
445
+ setActivePanel(PanelView.POINTS_DETAIL);
446
+ } }));
447
+ }
448
+ return null;
449
+ };
424
450
  // Confirm order view.
425
451
  const confirmOrderView = (_jsxs("div", { className: "relative mx-auto flex w-full flex-col items-center", children: [header({ anyspendPrice: anyspendQuote, isLoadingAnyspendPrice: isLoadingAnyspendQuote }), _jsxs(Tabs, { value: activeTab, onValueChange: value => setActiveTab(value), className: "bg-b3-react-background max-h-[60dvh] w-full overflow-y-auto p-5", children: [_jsx("div", { className: "w-full", children: _jsxs("div", { className: "bg-as-surface-secondary relative mb-4 grid h-10 grid-cols-2 rounded-xl", children: [_jsx("div", { className: cn("bg-as-brand absolute bottom-0 left-0 top-0 z-0 rounded-xl transition-transform duration-100", "h-full w-1/2", activeTab === "fiat" ? "translate-x-full" : "translate-x-0"), style: { willChange: "transform" } }), _jsx("button", { className: cn("relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100", activeTab === "crypto" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent"), onClick: () => {
426
452
  setActiveTab("crypto");
@@ -445,7 +471,7 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
445
471
  opacity: hasMounted ? 1 : 0,
446
472
  y: hasMounted ? 0 : 20,
447
473
  filter: hasMounted ? "blur(0px)" : "blur(10px)",
448
- }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "relative flex w-full items-center justify-between", children: [_jsxs("span", { className: "text-as-tertiarry text-sm", children: ["Total ", _jsx("span", { className: "text-as-tertiarry", children: "(with fee)" })] }), _jsxs("span", { className: "text-as-primary font-semibold", children: [formattedSrcAmount || "--", " ", srcToken.symbol] })] })] })] }), _jsx("div", { className: cn("flex w-full flex-col items-center justify-between gap-2"), children: _jsx(motion.div, { initial: false, animate: {
474
+ }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "relative flex w-full items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-tertiarry text-sm", children: ["Total ", _jsx("span", { className: "text-as-tertiarry", children: "(with fee)" })] }), renderPointsBadge()] }), _jsxs("span", { className: "text-as-primary font-semibold", children: [formattedSrcAmount || "--", " ", srcToken.symbol] })] })] })] }), _jsx("div", { className: cn("flex w-full flex-col items-center justify-between gap-2"), children: _jsx(motion.div, { initial: false, animate: {
449
475
  opacity: hasMounted ? 1 : 0,
450
476
  y: hasMounted ? 0 : 20,
451
477
  filter: hasMounted ? "blur(0px)" : "blur(10px)",
@@ -457,7 +483,7 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
457
483
  opacity: hasMounted ? 1 : 0,
458
484
  y: hasMounted ? 0 : 20,
459
485
  filter: hasMounted ? "blur(0px)" : "blur(10px)",
460
- }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "relative flex w-full items-center justify-between", children: [_jsxs("span", { className: "text-as-tertiarry text-sm", children: ["Total ", _jsx("span", { className: "text-as-tertiarry", children: "(USD)" })] }), _jsxs("span", { className: "text-as-primary text-xl font-semibold", children: ["$", srcFiatAmount || "0.00"] })] })] }), _jsx("div", { className: cn("flex w-full flex-col items-center justify-between gap-2"), children: _jsx(motion.div, { initial: false, animate: {
486
+ }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "relative flex w-full items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-tertiarry text-sm", children: ["Total ", _jsx("span", { className: "text-as-tertiarry", children: "(USD)" })] }), renderPointsBadge()] }), _jsxs("span", { className: "text-as-primary text-xl font-semibold", children: ["$", srcFiatAmount || "0.00"] })] })] }), _jsx("div", { className: cn("flex w-full flex-col items-center justify-between gap-2"), children: _jsx(motion.div, { initial: false, animate: {
461
487
  opacity: hasMounted ? 1 : 0,
462
488
  y: hasMounted ? 0 : 20,
463
489
  filter: hasMounted ? "blur(0px)" : "blur(10px)",
@@ -484,6 +510,8 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
484
510
  setSelectedFiatPaymentMethod(method);
485
511
  setActivePanel(PanelView.CONFIRM_ORDER);
486
512
  }, srcAmountOnRamp: srcFiatAmount }) }));
513
+ // Points detail view
514
+ const pointsDetailView = (_jsx("div", { className: cn("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4"), children: _jsx(PointsDetailPanel, { pointsAmount: anyspendQuote?.data?.pointsAmount || 0, onBack: () => setActivePanel(PanelView.CONFIRM_ORDER) }) }));
487
515
  // Return the TransitionPanel with all views
488
516
  return (_jsx(StyleRoot, { children: _jsx(TransitionPanel, { activeIndex: orderId
489
517
  ? oat
@@ -503,5 +531,6 @@ function AnySpendCustomInner({ loadOrder, mode = "modal", activeTab: activeTabPr
503
531
  _jsx("div", { className: "w-full", children: recipientSelectionView }, "recipient-selection-view"),
504
532
  _jsx("div", { className: "w-full", children: cryptoPaymentMethodView }, "crypto-payment-method-view"),
505
533
  _jsx("div", { className: "w-full", children: fiatPaymentMethodView }, "fiat-payment-method-view"),
534
+ _jsx("div", { className: "w-full", children: pointsDetailView }, "points-detail-view"),
506
535
  ] }) }));
507
536
  }
@@ -1,8 +1,9 @@
1
1
  import { components } from "../../../anyspend/types/api";
2
- export declare function AnySpendNFT({ loadOrder, mode, recipientAddress, nftContract, onSuccess, }: {
2
+ export declare function AnySpendNFT({ loadOrder, mode, recipientAddress, nftContract, onSuccess, onShowPointsDetail, }: {
3
3
  loadOrder?: string;
4
4
  mode?: "modal" | "page";
5
5
  recipientAddress?: string;
6
6
  nftContract: components["schemas"]["NftContract"];
7
7
  onSuccess?: (txHash?: string) => void;
8
+ onShowPointsDetail?: () => void;
8
9
  }): import("react/jsx-runtime").JSX.Element;
@@ -26,7 +26,7 @@ const CONTRACT_URI_ABI = [
26
26
  type: "function",
27
27
  },
28
28
  ];
29
- export function AnySpendNFT({ loadOrder, mode = "modal", recipientAddress, nftContract, onSuccess, }) {
29
+ export function AnySpendNFT({ loadOrder, mode = "modal", recipientAddress, nftContract, onSuccess, onShowPointsDetail, }) {
30
30
  const [imageUrlWithFallback, setFallbackImageUrl] = useState(nftContract.imageUrl);
31
31
  const [isLoadingFallback, setIsLoadingFallback] = useState(false);
32
32
  // Fetch contract metadata when imageUrl is empty
@@ -86,7 +86,7 @@ export function AnySpendNFT({ loadOrder, mode = "modal", recipientAddress, nftCo
86
86
  return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, activeTab: "fiat", recipientAddress: recipientAddress, orderType: "mint_nft", dstChainId: nftContract.chainId, dstToken: nftContract.currency, dstAmount: nftContract.price, contractAddress: nftContract.contractAddress, encodedData: "0x", metadata: {
87
87
  type: "mint_nft",
88
88
  nftContract: nftContract,
89
- }, header: header, onSuccess: onSuccess }));
89
+ }, header: header, onSuccess: onSuccess, onShowPointsDetail: onShowPointsDetail }));
90
90
  }
91
91
  function DropdownMenu({ nftContract }) {
92
92
  const [open, setOpen] = useState(false);
@@ -258,7 +258,6 @@ export function AnySpendStakeB3({ loadOrder, mode = "modal", recipientAddress, s
258
258
  }
259
259
  const encodedData = generateEncodedDataForStakingB3(userStakeAmount, recipientAddress);
260
260
  return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: recipientAddress, orderType: "custom", dstChainId: base.id, dstToken: B3_TOKEN, dstAmount: userStakeAmount, contractAddress: ERC20Staking, encodedData: encodedData, metadata: {
261
- type: "custom",
262
261
  action: "stake B3",
263
262
  }, header: header, onSuccess: onSuccess, showRecipient: true }));
264
263
  }
@@ -66,8 +66,7 @@ export function AnyspendSignatureMint({ loadOrder, mode = "modal", signatureData
66
66
  }
67
67
  const encodedData = generateEncodedDataForSignatureMint(signatureData);
68
68
  const price = parseEther(signatureData.payload.price?.toString() || "0");
69
- return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: signatureData.payload.to, orderType: "custom", dstChainId: signatureData.collection.chainId, dstToken: dstToken, dstAmount: price.toString(), contractAddress: signatureData.collection.address, encodedData: encodedData, metadata: {
70
- type: "custom",
69
+ return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: signatureData.payload.to, orderType: "custom", dstChainId: signatureData.collection.chainId, dstToken: dstToken, dstAmount: price.toString(), contractAddress: signatureData.collection.address || "", encodedData: encodedData, metadata: {
71
70
  action: "Signature Mint",
72
71
  }, header: header, onSuccess: onSuccess, showRecipient: true }));
73
72
  }
@@ -15,7 +15,7 @@ export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, se
15
15
  // Determine which address to use based on payment method
16
16
  const walletAddress = selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
17
17
  ? connectedSmartWallet?.getAccount()?.address
18
- : connectedEOAWallet?.getAccount()?.address || connectedSmartWallet?.getAccount()?.address;
18
+ : connectedEOAWallet?.getAccount()?.address;
19
19
  const { data: profileData } = useProfile({ address: walletAddress });
20
20
  const connectedName = profileData?.displayName;
21
21
  // Add ref to track if we've applied metadata
@@ -7,6 +7,7 @@ import { ChevronRight } from "lucide-react";
7
7
  import { motion } from "motion/react";
8
8
  import { useFeatureFlags } from "../../contexts/FeatureFlagsContext.js";
9
9
  import { OrderTokenAmount } from "./OrderTokenAmount.js";
10
+ import { PointsBadge } from "./PointsBadge.js";
10
11
  export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, }) {
11
12
  const featureFlags = useFeatureFlags();
12
13
  return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: isDepositMode ? "Deposit" : "Receive" }), selectedRecipientAddress ? (_jsx("button", { className: cn("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg"), onClick: onSelectRecipient, children: _jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry flex items-center gap-1 text-sm", children: recipientName ? formatUsername(recipientName) : shortenAddress(selectedRecipientAddress || "") }), _jsx(ChevronRight, { className: "h-4 w-4" })] }) })) : (_jsx("button", { className: "text-as-primary/70 flex items-center gap-1 rounded-lg", onClick: onSelectRecipient, children: _jsx("div", { className: "text-sm font-medium", children: "Select recipient" }) }))] }), isBuyMode || isDepositMode ? (
@@ -48,5 +49,5 @@ export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false,
48
49
  }
49
50
  // Using inline style to ensure color displays
50
51
  return (_jsxs("span", { className: "ml-2", style: { color: percentageNum >= 10 ? "red" : "#FFD700" }, children: ["(", isNegative ? "-" : "", percentage, "%)"] }));
51
- })()] }), featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (_jsxs("button", { className: "bg-as-brand hover:scale-102 active:scale-98 active:scale-98 relative flex cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-all", onClick: () => onShowPointsDetail?.(), children: [_jsx("div", { className: "pointer-events-none absolute inset-0 h-full w-full rounded-lg border border-white/10 border-t-white/20 bg-gradient-to-b from-white/10 to-white/0" }), _jsxs("span", { className: "text-xs text-white", children: ["+", anyspendQuote.data.pointsAmount.toLocaleString(), " pts"] })] }, `points-${anyspendQuote.data.pointsAmount}`))] })] }));
52
+ })()] }), featureFlags.showPoints && anyspendQuote?.data?.pointsAmount > 0 && (_jsx(PointsBadge, { pointsAmount: anyspendQuote.data.pointsAmount, pointsMultiplier: anyspendQuote.data.pointsMultiplier, onClick: () => onShowPointsDetail?.() }))] })] }));
52
53
  }
@@ -10,6 +10,7 @@ import { toast } from "sonner";
10
10
  import { useFeatureFlags } from "../../contexts/FeatureFlagsContext.js";
11
11
  import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
12
12
  import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat.js";
13
+ import { PointsBadge } from "./PointsBadge.js";
13
14
  export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken = false, anyspendQuote, onShowPointsDetail, }) {
14
15
  const featureFlags = useFeatureFlags();
15
16
  // Get geo-based onramp options to access fee information
@@ -75,5 +76,7 @@ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPayme
75
76
  : "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && !hideDstToken && (_jsx(OrderTokenAmountFiat, { address: _recipientAddress, context: "to", inputValue: destinationAmount || "0", onChangeInput: () => { }, chainId: destinationChainId, setChainId: onDestinationChainChange || (() => { }), token: destinationToken, setToken: onDestinationTokenChange || (() => { }) }))] }), _jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary mt-4 flex w-full flex-col gap-3 rounded-xl border p-4", children: [_jsxs("div", { className: "flex w-full items-center justify-between gap-2", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm", children: "Recipient" }), _recipientAddress ? (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(recipientSelectionPanelIndex), children: [_jsx("span", { className: "text-sm", children: recipientName ? formatUsername(recipientName) : formatAddress(_recipientAddress) }), _jsx(ChevronRight, { size: 16 })] })) : (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx(Wallet, { className: "text-as-brand", size: 16 }), "Select recipient", _jsx(ChevronRight, { size: 16 })] }))] }), _jsx("div", { className: "divider w-full" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: "Expected to receive" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-primary font-semibold", children: [destinationAmount || "0", " ", dstTokenSymbol || destinationToken?.symbol || ""] }), _jsxs("span", { className: "text-as-tertiarry text-sm", children: ["on ", destinationChainId ? ALL_CHAINS[destinationChainId]?.name : ""] }), destinationToken && destinationChainId && destinationToken.metadata?.logoURI && (_jsx("img", { src: ALL_CHAINS[destinationChainId]?.logoUrl, alt: "Chain", className: "h-4 w-4 rounded-full" }))] })] }), _jsx("div", { className: "divider w-full" }), _jsx("div", { className: "", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: (() => {
76
77
  const fee = getFeeFromApi(selectedPaymentMethod || FiatPaymentMethod.NONE);
77
78
  return fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total";
78
- })() }), featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (_jsxs("button", { className: "bg-as-brand hover:scale-102 active:scale-98 relative flex cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-all", onClick: () => onShowPointsDetail?.(), children: [_jsx("div", { className: "pointer-events-none absolute inset-0 h-full w-full rounded-lg border border-white/10 border-t-white/20 bg-gradient-to-b from-white/10 to-white/0" }), _jsxs("span", { className: "text-xs text-white", children: ["+", anyspendQuote.data.pointsAmount.toLocaleString(), " pts"] })] }, `points-${anyspendQuote.data.pointsAmount}`))] }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)] })] }) })] })] }));
79
+ })() }), featureFlags.showPoints &&
80
+ anyspendQuote?.data?.pointsAmount &&
81
+ anyspendQuote?.data?.pointsAmount > 0 && (_jsx(PointsBadge, { pointsAmount: anyspendQuote.data.pointsAmount, pointsMultiplier: anyspendQuote.data.pointsMultiplier, onClick: () => onShowPointsDetail?.() }))] }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)] })] }) })] })] }));
79
82
  }
@@ -0,0 +1,7 @@
1
+ interface PointsBadgeProps {
2
+ pointsAmount: number;
3
+ pointsMultiplier?: number;
4
+ onClick?: () => void;
5
+ }
6
+ export declare function PointsBadge({ pointsAmount, pointsMultiplier, onClick }: PointsBadgeProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function PointsBadge({ pointsAmount, pointsMultiplier, onClick }) {
3
+ return (_jsxs("button", { className: "bg-as-brand hover:scale-102 active:scale-98 relative flex cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-all", onClick: onClick, children: [_jsx("div", { className: "pointer-events-none absolute inset-0 h-full w-full rounded-lg border border-white/10 border-t-white/20 bg-gradient-to-b from-white/10 to-white/0" }), _jsxs("span", { className: "relative text-xs text-white", children: ["+", pointsAmount.toLocaleString(), " pts", pointsMultiplier && pointsMultiplier > 1 && _jsxs("span", { className: "ml-1 opacity-80", children: ["(", pointsMultiplier, "x)"] })] })] }));
4
+ }
@@ -107,15 +107,17 @@ export function useAnyspendFlow({ paymentType = "crypto", recipientAddress, load
107
107
  }
108
108
  };
109
109
  // Get quote
110
- const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals).toString();
110
+ // For fiat payments, always use USDC decimals (6) regardless of selectedSrcToken
111
+ const effectiveDecimals = paymentType === "fiat" ? USDC_BASE.decimals : selectedSrcToken.decimals;
112
+ const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), effectiveDecimals).toString();
111
113
  const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote({
112
114
  srcChain: paymentType === "fiat" ? base.id : selectedSrcChainId,
113
115
  dstChain: isDepositMode ? base.id : selectedDstChainId, // For deposits, always Base; for swaps, use selected destination
114
116
  srcTokenAddress: paymentType === "fiat" ? USDC_BASE.address : selectedSrcToken.address,
115
117
  dstTokenAddress: isDepositMode ? B3_TOKEN.address : selectedSrcToken.address, // For deposits, always B3
116
- type: "swap",
117
- tradeType: "EXACT_INPUT",
118
+ type: "hype_duel",
118
119
  amount: activeInputAmountInWei,
120
+ recipientAddress: selectedRecipientAddress,
119
121
  onrampVendor: paymentType === "fiat" ? getOnrampVendor(selectedFiatPaymentMethod) : undefined,
120
122
  });
121
123
  // Get geo options for fiat
@@ -28,7 +28,7 @@ export declare const anyspendService: {
28
28
  }>;
29
29
  getOrderAndTransactions: (orderId: string | undefined) => Promise<GetOrderAndTxsResponse>;
30
30
  getOrderHistory: (creatorAddress: string | undefined, limit?: number, offset?: number) => Promise<GetOrderHistoryResponse>;
31
- getCoinbaseOnrampOptions: (country: string, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
31
+ getCoinbaseOnrampOptions: (country: string | undefined, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
32
32
  checkStripeSupport: (usdAmount?: string, visitorData?: VisitorData) => Promise<{
33
33
  stripeOnramp: boolean;
34
34
  stripeWeb2: components["schemas"]["StripeWeb2Support"];
@@ -63,6 +63,7 @@ export const anyspendService = {
63
63
  return data;
64
64
  },
65
65
  getOrderAndTransactions: async (orderId) => {
66
+ invariant(orderId, "orderId is required");
66
67
  const response = await fetch(`${ANYSPEND_MAINNET_BASE_URL}/orders/${orderId}`);
67
68
  const data = await response.json();
68
69
  return data;
@@ -80,6 +81,7 @@ export const anyspendService = {
80
81
  return data;
81
82
  },
82
83
  getCoinbaseOnrampOptions: async (country, visitorData) => {
84
+ invariant(country, "country is required");
83
85
  const params = new URLSearchParams({
84
86
  country,
85
87
  // include fingerprintId and requestId in the query params
@@ -503,11 +503,16 @@ export interface paths {
503
503
  * @example 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
504
504
  */
505
505
  dstTokenAddress: string;
506
+ /**
507
+ * @description Recipient address
508
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
509
+ */
510
+ recipientAddress?: string;
506
511
  /**
507
512
  * @description Type of trade execution
508
513
  * @enum {string}
509
514
  */
510
- tradeType: "EXACT_INPUT" | "EXPECTED_OUTPUT" | "EXACT_OUTPUT";
515
+ tradeType: "EXACT_INPUT" | "EXACT_OUTPUT";
511
516
  /**
512
517
  * @description Amount to quote
513
518
  * @example 1000000000000000000
@@ -544,6 +549,11 @@ export interface paths {
544
549
  * @example 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
545
550
  */
546
551
  dstTokenAddress: string;
552
+ /**
553
+ * @description Recipient address
554
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
555
+ */
556
+ recipientAddress?: string;
547
557
  /** @description Custom payload for execution */
548
558
  payload: {
549
559
  /** @description Encoded transaction data */
@@ -567,6 +577,11 @@ export interface paths {
567
577
  dstChain: number;
568
578
  srcTokenAddress: string;
569
579
  dstTokenAddress: string;
580
+ /**
581
+ * @description Recipient address
582
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
583
+ */
584
+ recipientAddress?: string;
570
585
  /** @enum {string} */
571
586
  onrampVendor?: "coinbase" | "stripe" | "stripe-web2";
572
587
  contractAddress: string;
@@ -581,6 +596,11 @@ export interface paths {
581
596
  dstChain: number;
582
597
  srcTokenAddress: string;
583
598
  dstTokenAddress: string;
599
+ /**
600
+ * @description Recipient address
601
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
602
+ */
603
+ recipientAddress?: string;
584
604
  /** @enum {string} */
585
605
  onrampVendor?: "coinbase" | "stripe" | "stripe-web2";
586
606
  contractAddress: string;
@@ -592,6 +612,11 @@ export interface paths {
592
612
  dstChain: number;
593
613
  srcTokenAddress: string;
594
614
  dstTokenAddress: string;
615
+ /**
616
+ * @description Recipient address
617
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
618
+ */
619
+ recipientAddress?: string;
595
620
  /** @enum {string} */
596
621
  onrampVendor?: "coinbase" | "stripe" | "stripe-web2";
597
622
  contractAddress: string;
@@ -622,6 +647,11 @@ export interface paths {
622
647
  * @example 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
623
648
  */
624
649
  dstTokenAddress: string;
650
+ /**
651
+ * @description Recipient address
652
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
653
+ */
654
+ recipientAddress?: string;
625
655
  /**
626
656
  * @description Amount to quote
627
657
  * @example 1000000000000000000
@@ -1087,6 +1117,11 @@ export interface components {
1087
1117
  * @example 990000
1088
1118
  */
1089
1119
  actualDstAmount: string | null;
1120
+ /**
1121
+ * @description Amount in after fee
1122
+ * @example 990000
1123
+ */
1124
+ amountInAfterFee: string | null;
1090
1125
  };
1091
1126
  /** @description HypeDuel-specific payload */
1092
1127
  HypeDuelPayload: {
@@ -1100,6 +1135,11 @@ export interface components {
1100
1135
  * @example 990000
1101
1136
  */
1102
1137
  actualDstAmount: string | null;
1138
+ /**
1139
+ * @description Amount in after fee
1140
+ * @example 990000
1141
+ */
1142
+ amountInAfterFee: string | null;
1103
1143
  };
1104
1144
  /** @description Custom execution payload */
1105
1145
  CustomPayload: {
@@ -6,6 +6,7 @@ export const buildPayload = (orderType, params) => {
6
6
  return {
7
7
  expectedDstAmount,
8
8
  actualDstAmount: null,
9
+ amountInAfterFee: null,
9
10
  };
10
11
  case "mint_nft":
11
12
  if (nft?.type === "erc1155") {
@@ -20,6 +21,7 @@ export const buildPayload = (orderType, params) => {
20
21
  return {
21
22
  contractAddress: normalizeAddress(nft.contractAddress),
22
23
  nftPrice: nft?.price || "",
24
+ tokenId: null,
23
25
  contractType: nft?.type,
24
26
  };
25
27
  }
@@ -42,6 +44,7 @@ export const buildPayload = (orderType, params) => {
42
44
  return {
43
45
  expectedDstAmount,
44
46
  actualDstAmount: null,
47
+ amountInAfterFee: null,
45
48
  };
46
49
  default:
47
50
  throw new Error(`Invalid order type: ${orderType}`);
@@ -1,15 +1,14 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { loadScriptFromCDN } from "./utils/cdn-loader.js";
4
- import { formatNumberSmall } from "./utils/format.js";
5
3
  import { Loader2 } from "lucide-react";
6
4
  import { useEffect, useRef, useState } from "react";
5
+ import { loadScriptFromCDN } from "./utils/cdn-loader.js";
6
+ import { formatNumberSmall } from "./utils/format.js";
7
7
  // TradingView will be available on window after loading from CDN
8
8
  // Datafeed will be implemented inline
9
9
  // Mock loading overlay - replace with your actual loading component
10
10
  const GifLoadingOverlay = ({ className }) => (_jsx("div", { className: `absolute inset-0 flex items-center justify-center bg-white/50 backdrop-blur-sm ${className || ""}`, children: _jsx(Loader2, { className: "text-secondary-grey h-8 w-8 animate-spin" }) }));
11
11
  const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
12
- const theme = "light";
13
12
  // Use token info for the current trade
14
13
  const currentTrade = {
15
14
  product_id: tokenAddress && tokenSymbol ? `${tokenSymbol}-${tokenAddress}` : "BONDKIT",
@@ -245,7 +244,7 @@ const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
245
244
  tvWidgetRef.current = null;
246
245
  }
247
246
  };
248
- }, [theme, librariesLoaded]);
247
+ }, [librariesLoaded, currentTrade?.product_id, tradingViewDefaultInterval, tradingViewTimezone]);
249
248
  useEffect(() => {
250
249
  if (chartLoaded &&
251
250
  currentTrade?.product_id &&
@@ -1,6 +1,6 @@
1
- import { parseUnits, formatUnits, encodeAbiParameters, parseAbiParameters, getContract, createPublicClient, http, } from "viem";
1
+ import { createPublicClient, encodeAbiParameters, formatUnits, getContract, http, parseAbiParameters, parseUnits, } from "viem";
2
2
  import { base } from "viem/chains";
3
- import { UniversalRouterAddress, QuoterAddress, Permit2Address, BaseMainnetRpcUrl } from "./constants.js";
3
+ import { BaseMainnetRpcUrl, Permit2Address, QuoterAddress, UniversalRouterAddress } from "./constants.js";
4
4
  // Minimal ABIs needed for swap functionality
5
5
  const UNIVERSAL_ROUTER_ABI = [
6
6
  {
@@ -187,6 +187,9 @@ export class BondkitSwapService {
187
187
  */
188
188
  async getV4Config() {
189
189
  await this.initializeV4Config();
190
+ if (!this.v4Config) {
191
+ throw new Error("Failed to initialize V4 configuration");
192
+ }
190
193
  return this.v4Config;
191
194
  }
192
195
  /**
@@ -48,23 +48,29 @@ export function B3Provider({ theme = "light", children, accountOverride, environ
48
48
  client,
49
49
  };
50
50
  }, [partnerId]);
51
+ // Stringify rpcUrls for stable comparison to prevent wagmiConfig recreation
52
+ // when parent component passes new object references with same content
53
+ const rpcUrlsString = useMemo(() => (rpcUrls ? JSON.stringify(rpcUrls) : undefined), [rpcUrls]);
51
54
  /**
52
55
  * Creates wagmi config with optional custom RPC URLs
53
56
  * @param rpcUrls - Optional mapping of chain IDs to RPC URLs
54
57
  */
55
- const wagmiConfig = useMemo(() => createConfig({
56
- chains: [supportedChains[0], ...supportedChains.slice(1)],
57
- transports: Object.fromEntries(supportedChains.map(chain => [chain.id, http(rpcUrls?.[chain.id])])),
58
- connectors: [
59
- inAppWalletConnector({
60
- ...(ecocystemConfig || {}),
61
- client,
62
- }),
63
- // injected(),
64
- // coinbaseWallet({ appName: "HypeDuel" }),
65
- ],
66
- }), [partnerId]);
67
- return (_jsx(ThirdwebProvider, { children: _jsx(WagmiProvider, { config: wagmiConfig, reconnectOnMount: false, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx(TooltipProvider, { children: _jsx(InnerProvider, { accountOverride: accountOverride, environment: environment, theme: theme, automaticallySetFirstEoa: !!automaticallySetFirstEoa, clientType: clientType, children: _jsxs(RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, _jsx(StyleRoot, { id: "b3-root" }), _jsx(Toaster, { theme: theme, position: toaster?.position, style: toaster?.style })] }) }) }) }) }) }));
58
+ const wagmiConfig = useMemo(() => {
59
+ const parsedRpcUrls = rpcUrlsString ? JSON.parse(rpcUrlsString) : undefined;
60
+ return createConfig({
61
+ chains: [supportedChains[0], ...supportedChains.slice(1)],
62
+ transports: Object.fromEntries(supportedChains.map(chain => [chain.id, http(parsedRpcUrls?.[chain.id])])),
63
+ connectors: [
64
+ inAppWalletConnector({
65
+ ...(ecocystemConfig || {}),
66
+ client,
67
+ }),
68
+ // injected(),
69
+ // coinbaseWallet({ appName: "HypeDuel" }),
70
+ ],
71
+ });
72
+ }, [ecocystemConfig, rpcUrlsString]);
73
+ return (_jsx(ThirdwebProvider, { children: _jsx(WagmiProvider, { config: wagmiConfig, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx(TooltipProvider, { children: _jsx(InnerProvider, { accountOverride: accountOverride, environment: environment, theme: theme, automaticallySetFirstEoa: !!automaticallySetFirstEoa, clientType: clientType, children: _jsxs(RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, _jsx(StyleRoot, { id: "b3-root" }), _jsx(Toaster, { theme: theme, position: toaster?.position, style: toaster?.style })] }) }) }) }) }) }));
68
74
  }
69
75
  /**
70
76
  * Inner provider component that provides the actual B3Context
@@ -14,6 +14,7 @@ export { useExchangeRate } from "./useExchangeRate";
14
14
  export { useFirstEOA } from "./useFirstEOA";
15
15
  export { useGetAllTWSigners, type TWSignerWithMetadata } from "./useGetAllTWSigners";
16
16
  export { useGetGeo } from "./useGetGeo";
17
+ export { useGlobalAccount } from "./useGlobalAccount";
17
18
  export { useHandleConnectWithPrivy } from "./useHandleConnectWithPrivy";
18
19
  export { useHasMounted } from "./useHasMounted";
19
20
  export { useIsMobile } from "./useIsMobile";
@@ -14,6 +14,7 @@ export { useExchangeRate } from "./useExchangeRate.js";
14
14
  export { useFirstEOA } from "./useFirstEOA.js";
15
15
  export { useGetAllTWSigners } from "./useGetAllTWSigners.js";
16
16
  export { useGetGeo } from "./useGetGeo.js";
17
+ export { useGlobalAccount } from "./useGlobalAccount.js";
17
18
  export { useHandleConnectWithPrivy } from "./useHandleConnectWithPrivy.js";
18
19
  export { useHasMounted } from "./useHasMounted.js";
19
20
  export { useIsMobile } from "./useIsMobile.js";