@b3dotfun/sdk 0.1.2 → 0.1.5

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 (235) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +7 -1
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +66 -15
  3. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -2
  4. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +4 -4
  5. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +6 -0
  6. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +185 -50
  7. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +6 -1
  8. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +19 -4
  9. package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +2 -1
  10. package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.js +2 -2
  11. package/dist/cjs/anyspend/react/components/QRDeposit.d.ts +4 -1
  12. package/dist/cjs/anyspend/react/components/QRDeposit.js +12 -4
  13. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +3 -1
  14. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +7 -5
  15. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +3 -1
  16. package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +4 -3
  17. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
  18. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +7 -6
  19. package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.d.ts +3 -1
  20. package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.js +15 -6
  21. package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.d.ts +3 -1
  22. package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +10 -6
  23. package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +3 -0
  24. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +11 -10
  25. package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +2 -0
  26. package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +9 -9
  27. package/dist/cjs/anyspend/react/components/common/OrderHistory.js +2 -1
  28. package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  29. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +2 -2
  30. package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.d.ts +2 -0
  31. package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +20 -7
  32. package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.d.ts +3 -1
  33. package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.js +3 -2
  34. package/dist/cjs/anyspend/react/components/common/RecipientSelection.d.ts +6 -1
  35. package/dist/cjs/anyspend/react/components/common/RecipientSelection.js +5 -2
  36. package/dist/cjs/anyspend/react/components/common/TabSection.d.ts +3 -1
  37. package/dist/cjs/anyspend/react/components/common/TabSection.js +16 -7
  38. package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.d.ts +2 -0
  39. package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.js +3 -2
  40. package/dist/cjs/anyspend/react/components/common/WarningText.d.ts +8 -7
  41. package/dist/cjs/anyspend/react/components/common/WarningText.js +5 -6
  42. package/dist/cjs/anyspend/react/components/index.d.ts +1 -0
  43. package/dist/cjs/anyspend/react/components/types/classes.d.ts +390 -0
  44. package/dist/cjs/anyspend/react/components/types/classes.js +6 -0
  45. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  46. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  47. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +22 -2
  48. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +119 -15
  49. package/dist/cjs/anyspend/react/hooks/useDirectTransfer.d.ts +17 -0
  50. package/dist/cjs/anyspend/react/hooks/useDirectTransfer.js +46 -0
  51. package/dist/cjs/anyspend/react/hooks/useRecipientAddressState.js +1 -1
  52. package/dist/cjs/anyspend/utils/format.js +12 -2
  53. package/dist/cjs/global-account/react/components/B3DynamicModal.js +1 -5
  54. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +1 -3
  55. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +1 -2
  56. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +1 -4
  57. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +2 -2
  58. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.native.d.ts +1 -1
  59. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.native.js +1 -1
  60. package/dist/cjs/global-account/react/components/B3Provider/LocalSDKProvider.d.ts +1 -4
  61. package/dist/cjs/global-account/react/components/B3Provider/LocalSDKProvider.js +1 -3
  62. package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +1 -3
  63. package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +17 -3
  64. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +19 -152
  65. package/dist/cjs/global-account/react/components/index.d.ts +0 -1
  66. package/dist/cjs/global-account/react/components/index.js +3 -6
  67. package/dist/cjs/global-account/react/hooks/index.d.ts +0 -1
  68. package/dist/cjs/global-account/react/hooks/index.js +2 -4
  69. package/dist/cjs/global-account/react/hooks/useAuth.d.ts +2 -3
  70. package/dist/cjs/global-account/react/hooks/useAuth.js +14 -31
  71. package/dist/cjs/global-account/react/hooks/useTWAuth.d.ts +1 -1
  72. package/dist/cjs/global-account/react/hooks/useTWAuth.js +3 -3
  73. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +8 -19
  74. package/dist/esm/anyspend/react/components/AnySpend.d.ts +7 -1
  75. package/dist/esm/anyspend/react/components/AnySpend.js +68 -17
  76. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -2
  77. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +4 -4
  78. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +6 -0
  79. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +189 -54
  80. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +6 -1
  81. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +19 -4
  82. package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +2 -1
  83. package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.js +2 -2
  84. package/dist/esm/anyspend/react/components/QRDeposit.d.ts +4 -1
  85. package/dist/esm/anyspend/react/components/QRDeposit.js +12 -4
  86. package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +3 -1
  87. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +7 -5
  88. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +3 -1
  89. package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +4 -3
  90. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
  91. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +7 -6
  92. package/dist/esm/anyspend/react/components/common/FeeDetailPanel.d.ts +3 -1
  93. package/dist/esm/anyspend/react/components/common/FeeDetailPanel.js +15 -6
  94. package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.d.ts +3 -1
  95. package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +10 -6
  96. package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +3 -0
  97. package/dist/esm/anyspend/react/components/common/OrderDetails.js +11 -10
  98. package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +2 -0
  99. package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +9 -9
  100. package/dist/esm/anyspend/react/components/common/OrderHistory.js +2 -1
  101. package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  102. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +2 -2
  103. package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.d.ts +2 -0
  104. package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +20 -7
  105. package/dist/esm/anyspend/react/components/common/PointsDetailPanel.d.ts +3 -1
  106. package/dist/esm/anyspend/react/components/common/PointsDetailPanel.js +3 -2
  107. package/dist/esm/anyspend/react/components/common/RecipientSelection.d.ts +6 -1
  108. package/dist/esm/anyspend/react/components/common/RecipientSelection.js +5 -2
  109. package/dist/esm/anyspend/react/components/common/TabSection.d.ts +3 -1
  110. package/dist/esm/anyspend/react/components/common/TabSection.js +16 -7
  111. package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.d.ts +2 -0
  112. package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.js +3 -2
  113. package/dist/esm/anyspend/react/components/common/WarningText.d.ts +8 -7
  114. package/dist/esm/anyspend/react/components/common/WarningText.js +5 -6
  115. package/dist/esm/anyspend/react/components/index.d.ts +1 -0
  116. package/dist/esm/anyspend/react/components/types/classes.d.ts +390 -0
  117. package/dist/esm/anyspend/react/components/types/classes.js +5 -0
  118. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  119. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  120. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +22 -2
  121. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +119 -16
  122. package/dist/esm/anyspend/react/hooks/useDirectTransfer.d.ts +17 -0
  123. package/dist/esm/anyspend/react/hooks/useDirectTransfer.js +43 -0
  124. package/dist/esm/anyspend/react/hooks/useRecipientAddressState.js +1 -1
  125. package/dist/esm/anyspend/utils/format.js +12 -2
  126. package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -5
  127. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +1 -3
  128. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +1 -2
  129. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +1 -4
  130. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -2
  131. package/dist/esm/global-account/react/components/B3Provider/B3Provider.native.d.ts +1 -1
  132. package/dist/esm/global-account/react/components/B3Provider/B3Provider.native.js +1 -1
  133. package/dist/esm/global-account/react/components/B3Provider/LocalSDKProvider.d.ts +1 -4
  134. package/dist/esm/global-account/react/components/B3Provider/LocalSDKProvider.js +1 -3
  135. package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +1 -3
  136. package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +16 -2
  137. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +20 -153
  138. package/dist/esm/global-account/react/components/index.d.ts +0 -1
  139. package/dist/esm/global-account/react/components/index.js +0 -2
  140. package/dist/esm/global-account/react/hooks/index.d.ts +0 -1
  141. package/dist/esm/global-account/react/hooks/index.js +0 -1
  142. package/dist/esm/global-account/react/hooks/useAuth.d.ts +2 -3
  143. package/dist/esm/global-account/react/hooks/useAuth.js +14 -31
  144. package/dist/esm/global-account/react/hooks/useTWAuth.d.ts +1 -1
  145. package/dist/esm/global-account/react/hooks/useTWAuth.js +3 -3
  146. package/dist/esm/global-account/react/stores/useModalStore.d.ts +8 -19
  147. package/dist/styles/index.css +1 -1
  148. package/dist/types/anyspend/react/components/AnySpend.d.ts +7 -1
  149. package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -2
  150. package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +6 -0
  151. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +6 -1
  152. package/dist/types/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +2 -1
  153. package/dist/types/anyspend/react/components/QRDeposit.d.ts +4 -1
  154. package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +3 -1
  155. package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +3 -1
  156. package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
  157. package/dist/types/anyspend/react/components/common/FeeDetailPanel.d.ts +3 -1
  158. package/dist/types/anyspend/react/components/common/FiatPaymentMethod.d.ts +3 -1
  159. package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +3 -0
  160. package/dist/types/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +2 -0
  161. package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
  162. package/dist/types/anyspend/react/components/common/PanelOnrampPayment.d.ts +2 -0
  163. package/dist/types/anyspend/react/components/common/PointsDetailPanel.d.ts +3 -1
  164. package/dist/types/anyspend/react/components/common/RecipientSelection.d.ts +6 -1
  165. package/dist/types/anyspend/react/components/common/TabSection.d.ts +3 -1
  166. package/dist/types/anyspend/react/components/common/TransferCryptoDetails.d.ts +2 -0
  167. package/dist/types/anyspend/react/components/common/WarningText.d.ts +8 -7
  168. package/dist/types/anyspend/react/components/index.d.ts +1 -0
  169. package/dist/types/anyspend/react/components/types/classes.d.ts +390 -0
  170. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  171. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +22 -2
  172. package/dist/types/anyspend/react/hooks/useDirectTransfer.d.ts +17 -0
  173. package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +1 -3
  174. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +1 -4
  175. package/dist/types/global-account/react/components/B3Provider/B3Provider.native.d.ts +1 -1
  176. package/dist/types/global-account/react/components/B3Provider/LocalSDKProvider.d.ts +1 -4
  177. package/dist/types/global-account/react/components/index.d.ts +0 -1
  178. package/dist/types/global-account/react/hooks/index.d.ts +0 -1
  179. package/dist/types/global-account/react/hooks/useAuth.d.ts +2 -3
  180. package/dist/types/global-account/react/hooks/useTWAuth.d.ts +1 -1
  181. package/dist/types/global-account/react/stores/useModalStore.d.ts +8 -19
  182. package/package.json +1 -1
  183. package/src/anyspend/react/components/AnySpend.tsx +164 -36
  184. package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +11 -6
  185. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +278 -69
  186. package/src/anyspend/react/components/AnySpendDeposit.tsx +176 -52
  187. package/src/anyspend/react/components/AnySpendStakeUpsideExactIn.tsx +3 -0
  188. package/src/anyspend/react/components/QRDeposit.tsx +91 -35
  189. package/src/anyspend/react/components/common/CryptoPaySection.tsx +31 -19
  190. package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +14 -4
  191. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +43 -23
  192. package/src/anyspend/react/components/common/FeeDetailPanel.tsx +53 -32
  193. package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +26 -13
  194. package/src/anyspend/react/components/common/OrderDetails.tsx +20 -9
  195. package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +12 -7
  196. package/src/anyspend/react/components/common/OrderHistory.tsx +2 -1
  197. package/src/anyspend/react/components/common/PanelOnramp.tsx +4 -1
  198. package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +118 -40
  199. package/src/anyspend/react/components/common/PointsDetailPanel.tsx +28 -14
  200. package/src/anyspend/react/components/common/RecipientSelection.tsx +20 -5
  201. package/src/anyspend/react/components/common/TabSection.tsx +21 -12
  202. package/src/anyspend/react/components/common/TransferCryptoDetails.tsx +12 -4
  203. package/src/anyspend/react/components/common/WarningText.tsx +10 -10
  204. package/src/anyspend/react/components/index.ts +16 -0
  205. package/src/anyspend/react/components/types/classes.ts +476 -0
  206. package/src/anyspend/react/hooks/index.ts +1 -0
  207. package/src/anyspend/react/hooks/useAnyspendFlow.ts +141 -17
  208. package/src/anyspend/react/hooks/useDirectTransfer.ts +67 -0
  209. package/src/anyspend/react/hooks/useRecipientAddressState.ts +1 -1
  210. package/src/anyspend/utils/format.ts +13 -2
  211. package/src/global-account/react/components/B3DynamicModal.tsx +0 -5
  212. package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +0 -4
  213. package/src/global-account/react/components/B3Provider/B3Provider.native.tsx +1 -1
  214. package/src/global-account/react/components/B3Provider/B3Provider.tsx +1 -11
  215. package/src/global-account/react/components/B3Provider/LocalSDKProvider.tsx +0 -6
  216. package/src/global-account/react/components/B3Provider/RelayKitProviderWrapper.tsx +1 -4
  217. package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +33 -1
  218. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +27 -184
  219. package/src/global-account/react/components/index.ts +0 -3
  220. package/src/global-account/react/hooks/index.ts +0 -1
  221. package/src/global-account/react/hooks/useAuth.ts +14 -31
  222. package/src/global-account/react/hooks/useTWAuth.tsx +3 -5
  223. package/src/global-account/react/stores/useModalStore.ts +7 -20
  224. package/dist/cjs/global-account/react/components/TurnkeyAuthModal.d.ts +0 -8
  225. package/dist/cjs/global-account/react/components/TurnkeyAuthModal.js +0 -86
  226. package/dist/cjs/global-account/react/hooks/useTurnkeyAuth.d.ts +0 -20
  227. package/dist/cjs/global-account/react/hooks/useTurnkeyAuth.js +0 -142
  228. package/dist/esm/global-account/react/components/TurnkeyAuthModal.d.ts +0 -8
  229. package/dist/esm/global-account/react/components/TurnkeyAuthModal.js +0 -83
  230. package/dist/esm/global-account/react/hooks/useTurnkeyAuth.d.ts +0 -20
  231. package/dist/esm/global-account/react/hooks/useTurnkeyAuth.js +0 -136
  232. package/dist/types/global-account/react/components/TurnkeyAuthModal.d.ts +0 -8
  233. package/dist/types/global-account/react/hooks/useTurnkeyAuth.d.ts +0 -20
  234. package/src/global-account/react/components/TurnkeyAuthModal.tsx +0 -243
  235. package/src/global-account/react/hooks/useTurnkeyAuth.ts +0 -171
@@ -32,8 +32,8 @@ import React, { useMemo } from "react";
32
32
  import { encodeFunctionData } from "viem";
33
33
  import { AnySpendCustom } from "./AnySpendCustom";
34
34
 
35
- // Collector Club Shop contract on Base
36
- const CC_SHOP_ADDRESS = "0x47366E64E4917dd4DdC04Fb9DC507c1dD2b87294";
35
+ // Default Collector Club Shop contract on Base
36
+ const DEFAULT_CC_SHOP_ADDRESS = "0x47366E64E4917dd4DdC04Fb9DC507c1dD2b87294";
37
37
  const BASE_CHAIN_ID = 8453;
38
38
 
39
39
  // ABI for buyPacksFor function only
@@ -83,9 +83,13 @@ export interface AnySpendCollectorClubPurchaseProps {
83
83
  */
84
84
  recipientAddress: string;
85
85
  /**
86
- * Optional spender address (defaults to contract address)
86
+ * Optional spender address (defaults to shop address)
87
87
  */
88
88
  spenderAddress?: string;
89
+ /**
90
+ * Collector Club Shop contract address (defaults to Base mainnet shop)
91
+ */
92
+ ccShopAddress?: string;
89
93
  /**
90
94
  * Success callback
91
95
  */
@@ -124,7 +128,8 @@ export function AnySpendCollectorClubPurchase({
124
128
  pricePerPack,
125
129
  paymentToken = USDC_BASE,
126
130
  recipientAddress,
127
- spenderAddress = CC_SHOP_ADDRESS,
131
+ ccShopAddress = DEFAULT_CC_SHOP_ADDRESS,
132
+ spenderAddress,
128
133
  onSuccess,
129
134
  header,
130
135
  showRecipient = true,
@@ -180,12 +185,12 @@ export function AnySpendCollectorClubPurchase({
180
185
  mode={mode}
181
186
  activeTab={activeTab}
182
187
  recipientAddress={recipientAddress}
183
- spenderAddress={spenderAddress}
188
+ spenderAddress={spenderAddress ?? ccShopAddress}
184
189
  orderType="custom"
185
190
  dstChainId={BASE_CHAIN_ID}
186
191
  dstToken={paymentToken}
187
192
  dstAmount={totalAmount}
188
- contractAddress={CC_SHOP_ADDRESS}
193
+ contractAddress={ccShopAddress}
189
194
  encodedData={encodedData}
190
195
  metadata={{
191
196
  packId,
@@ -1,3 +1,4 @@
1
+ import { getChainName, getExplorerTxUrl } from "@b3dotfun/sdk/anyspend";
1
2
  import { useGasPrice } from "@b3dotfun/sdk/anyspend/react";
2
3
  import { components } from "@b3dotfun/sdk/anyspend/types/api";
3
4
  import { GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
@@ -9,17 +10,20 @@ import {
9
10
  toast,
10
11
  TransitionPanel,
11
12
  useAccountWallet,
13
+ useModalStore,
12
14
  } from "@b3dotfun/sdk/global-account/react";
13
15
  import { cn } from "@b3dotfun/sdk/shared/utils/cn";
14
16
  import { formatUnits } from "@b3dotfun/sdk/shared/utils/number";
15
17
  import invariant from "invariant";
16
- import { ArrowDown, Loader2 } from "lucide-react";
18
+ import { ArrowDown, CheckCircle, Loader2 } from "lucide-react";
17
19
  import { motion } from "motion/react";
18
- import { useEffect, useMemo, useRef } from "react";
20
+ import { useEffect, useMemo, useRef, useState } from "react";
21
+ import type { AnySpendCustomExactInClasses } from "./types/classes";
19
22
 
20
23
  import { useSetActiveWallet } from "thirdweb/react";
21
24
  import { B3_TOKEN } from "../../constants";
22
- import { PanelView, useAnyspendFlow } from "../hooks/useAnyspendFlow";
25
+ import { useDirectTransfer } from "../hooks/useDirectTransfer";
26
+ import { generateEncodedData, PanelView, useAnyspendFlow } from "../hooks/useAnyspendFlow";
23
27
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
24
28
  import { CryptoPaySection } from "./common/CryptoPaySection";
25
29
  import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
@@ -52,6 +56,7 @@ export interface AnySpendCustomExactInProps {
52
56
  sourceTokenChainId?: number;
53
57
  destinationToken: components["schemas"]["Token"];
54
58
  destinationChainId: number;
59
+ destinationTokenAmount?: string;
55
60
  onSuccess?: (amount: string) => void;
56
61
  onOpenCustomModal?: () => void;
57
62
  mainFooter?: React.ReactNode;
@@ -74,6 +79,10 @@ export interface AnySpendCustomExactInProps {
74
79
  customRecipientLabel?: string;
75
80
  /** Custom label for the return home button (overrides "Return to Home" / "Close") */
76
81
  returnHomeLabel?: string;
82
+ /** Custom class names for styling specific elements */
83
+ classes?: AnySpendCustomExactInClasses;
84
+ /** When true, allows direct transfer without swap if source and destination token/chain are the same */
85
+ allowDirectTransfer?: boolean;
77
86
  }
78
87
 
79
88
  export function AnySpendCustomExactIn(props: AnySpendCustomExactInProps) {
@@ -102,14 +111,18 @@ function AnySpendCustomExactInInner({
102
111
  customUsdInputValues,
103
112
  preferEoa,
104
113
  customExactInConfig,
114
+ destinationTokenAmount,
105
115
  orderType = "custom_exact_in",
106
116
  minDestinationAmount,
107
117
  header,
108
118
  returnToHomeUrl,
109
119
  customRecipientLabel,
110
120
  returnHomeLabel,
121
+ classes,
122
+ allowDirectTransfer = false,
111
123
  }: AnySpendCustomExactInProps) {
112
124
  const actionLabel = customExactInConfig?.action ?? "Custom Execution";
125
+ const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
113
126
 
114
127
  const DESTINATION_TOKEN_DETAILS = {
115
128
  SYMBOL: destinationToken.symbol ?? "TOKEN",
@@ -131,8 +144,11 @@ function AnySpendCustomExactInInner({
131
144
  srcAmount,
132
145
  setSrcAmount,
133
146
  dstAmount,
147
+ dstAmountInput,
148
+ setDstAmountInput,
134
149
  isSrcInputDirty,
135
150
  setIsSrcInputDirty,
151
+ tradeType,
136
152
  selectedCryptoPaymentMethod,
137
153
  effectiveCryptoPaymentMethod,
138
154
  setSelectedCryptoPaymentMethod,
@@ -146,7 +162,9 @@ function AnySpendCustomExactInInner({
146
162
  isBalanceLoading,
147
163
  anyspendQuote,
148
164
  isLoadingAnyspendQuote,
165
+ isQuoteLoading,
149
166
  activeInputAmountInWei,
167
+ activeOutputAmountInWei,
150
168
  geoData,
151
169
  coinbaseAvailablePaymentMethods,
152
170
  stripeWeb2Support,
@@ -166,10 +184,27 @@ function AnySpendCustomExactInInner({
166
184
  slippage: SLIPPAGE_PERCENT,
167
185
  disableUrlParamManagement: true,
168
186
  orderType,
187
+ customExactInConfig,
169
188
  });
170
189
 
171
190
  const { connectedEOAWallet } = useAccountWallet();
172
191
  const setActiveWallet = useSetActiveWallet();
192
+ const { executeDirectTransfer, isTransferring: isSwitchingOrExecuting } = useDirectTransfer();
193
+
194
+ // Check if source and destination are the same token on the same chain
195
+ const isSameChainSameToken = useMemo(() => {
196
+ return (
197
+ paymentType === "crypto" &&
198
+ selectedSrcChainId === selectedDstChainId &&
199
+ selectedSrcToken?.address?.toLowerCase() === selectedDstToken?.address?.toLowerCase()
200
+ );
201
+ }, [paymentType, selectedSrcChainId, selectedDstChainId, selectedSrcToken?.address, selectedDstToken?.address]);
202
+
203
+ // Check if this is a direct transfer
204
+ const isDirectTransfer = isSameChainSameToken && allowDirectTransfer;
205
+
206
+ // State for direct transfer success
207
+ const [directTransferTxHash, setDirectTransferTxHash] = useState<string | undefined>();
173
208
 
174
209
  // Get gas price for source chain (where the user pays from)
175
210
  const { gasPrice: gasPriceData, isLoading: isLoadingGas } = useGasPrice(selectedSrcChainId);
@@ -184,6 +219,18 @@ function AnySpendCustomExactInInner({
184
219
  }
185
220
  }, [preferEoa, connectedEOAWallet, setActiveWallet]);
186
221
 
222
+ // Prefill destination amount if provided (for EXACT_OUTPUT mode)
223
+ const appliedDestinationAmount = useRef(false);
224
+ useEffect(() => {
225
+ if (destinationTokenAmount && !appliedDestinationAmount.current) {
226
+ appliedDestinationAmount.current = true;
227
+ // Convert wei to human-readable format
228
+ const formattedAmount = formatUnits(destinationTokenAmount, destinationToken.decimals);
229
+ setDstAmountInput(formattedAmount);
230
+ setIsSrcInputDirty(false); // Switch to EXACT_OUTPUT mode
231
+ }
232
+ }, [destinationTokenAmount, destinationToken.decimals, setDstAmountInput, setIsSrcInputDirty]);
233
+
187
234
  const selectedRecipientOrDefault = selectedRecipientAddress ?? recipientAddress;
188
235
 
189
236
  const expectedDstAmountRaw = anyspendQuote?.data?.currencyOut?.amount ?? "0";
@@ -212,22 +259,34 @@ function AnySpendCustomExactInInner({
212
259
  };
213
260
 
214
261
  const btnInfo: { text: string; disable: boolean; error: boolean; loading: boolean } = useMemo(() => {
215
- if (activeInputAmountInWei === "0") return { text: "Enter an amount", disable: true, error: false, loading: false };
262
+ // Check for empty amount based on trade type
263
+ const isAmountEmpty =
264
+ tradeType === "EXACT_OUTPUT" ? !dstAmountInput || dstAmountInput === "0" : activeInputAmountInWei === "0";
265
+
266
+ const isDirectTransfer = isSameChainSameToken && allowDirectTransfer;
267
+
268
+ if (isAmountEmpty) return { text: "Enter an amount", disable: true, error: false, loading: false };
216
269
  if (orderType === "hype_duel" && selectedSrcToken?.address?.toLowerCase() === B3_TOKEN.address.toLowerCase()) {
217
270
  return { text: "Convert to HYPE using B3", disable: false, error: false, loading: false };
218
271
  }
219
- if (isLoadingAnyspendQuote) return { text: "Loading quote...", disable: true, error: false, loading: true };
220
- if (isCreatingOrder || isCreatingOnrampOrder)
221
- return { text: "Creating order...", disable: true, error: false, loading: true };
272
+ if (isQuoteLoading && !isDirectTransfer)
273
+ return { text: "Loading quote...", disable: true, error: false, loading: true };
274
+ if (isCreatingOrder || isCreatingOnrampOrder || isSwitchingOrExecuting)
275
+ return {
276
+ text: isSwitchingOrExecuting ? "Transferring..." : "Creating order...",
277
+ disable: true,
278
+ error: false,
279
+ loading: true,
280
+ };
222
281
  if (!selectedRecipientOrDefault) return { text: "Select recipient", disable: false, error: false, loading: false };
223
- if (!anyspendQuote || !anyspendQuote.success)
282
+ if ((!anyspendQuote || !anyspendQuote.success) && !isDirectTransfer)
224
283
  return { text: "Get quote error", disable: true, error: true, loading: false };
225
284
 
226
- // Check minimum destination amount if specified
227
- // Check minimum destination amount if specified
285
+ // Check minimum destination amount if specified (skip for direct transfers)
228
286
  if (
287
+ !isDirectTransfer &&
229
288
  minDestinationAmount &&
230
- anyspendQuote.data?.currencyOut?.amount &&
289
+ anyspendQuote?.data?.currencyOut?.amount &&
231
290
  anyspendQuote.data.currencyOut.currency &&
232
291
  anyspendQuote.data.currencyOut.currency.decimals != null
233
292
  ) {
@@ -256,8 +315,12 @@ function AnySpendCustomExactInInner({
256
315
  ) {
257
316
  return { text: "Insufficient balance", disable: true, error: true, loading: false };
258
317
  }
259
- // Use different text based on order type
260
- const buttonText = orderType === "hype_duel" ? "Continue to deposit" : `Execute ${actionLabel}`;
318
+ // Use different text based on order type and whether it's a direct transfer
319
+ const buttonText = isDirectTransfer
320
+ ? "Transfer"
321
+ : orderType === "hype_duel"
322
+ ? "Continue to deposit"
323
+ : `Execute ${actionLabel}`;
261
324
  return { text: buttonText, disable: false, error: false, loading: false };
262
325
  }
263
326
 
@@ -271,9 +334,10 @@ function AnySpendCustomExactInInner({
271
334
  return { text: "Continue", disable: false, error: false, loading: false };
272
335
  }, [
273
336
  activeInputAmountInWei,
274
- isLoadingAnyspendQuote,
337
+ isQuoteLoading,
275
338
  isCreatingOrder,
276
339
  isCreatingOnrampOrder,
340
+ isSwitchingOrExecuting,
277
341
  selectedRecipientOrDefault,
278
342
  anyspendQuote,
279
343
  paymentType,
@@ -286,6 +350,10 @@ function AnySpendCustomExactInInner({
286
350
  DESTINATION_TOKEN_DETAILS.SYMBOL,
287
351
  orderType,
288
352
  selectedSrcToken,
353
+ tradeType,
354
+ dstAmountInput,
355
+ isSameChainSameToken,
356
+ allowDirectTransfer,
289
357
  ]);
290
358
 
291
359
  const onMainButtonClick = async () => {
@@ -327,7 +395,12 @@ function AnySpendCustomExactInInner({
327
395
  );
328
396
 
329
397
  const mainView = (
330
- <div className="anyspend-custom-exact-in-container mx-auto flex w-[460px] max-w-full flex-col items-center gap-2">
398
+ <div
399
+ className={
400
+ classes?.container ||
401
+ "anyspend-custom-exact-in-container mx-auto flex w-[460px] max-w-full flex-col items-center gap-2"
402
+ }
403
+ >
331
404
  {headerContent}
332
405
 
333
406
  <div className="relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2">
@@ -382,9 +455,10 @@ function AnySpendCustomExactInInner({
382
455
  >
383
456
  <Button
384
457
  variant="ghost"
385
- className={cn(
386
- "swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl",
387
- )}
458
+ className={
459
+ classes?.swapDirectionButton ||
460
+ "swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"
461
+ }
388
462
  >
389
463
  <div className="relative flex items-center justify-center transition-opacity">
390
464
  <ArrowDown className="text-as-primary/50 h-5 w-5" />
@@ -395,12 +469,12 @@ function AnySpendCustomExactInInner({
395
469
  {paymentType === "crypto" && (
396
470
  <CryptoReceiveSection
397
471
  isDepositMode={false}
398
- isBuyMode={true}
472
+ isBuyMode={false}
399
473
  effectiveRecipientAddress={selectedRecipientOrDefault}
400
474
  recipientName={recipientName || undefined}
401
475
  customRecipientLabel={customRecipientLabel}
402
476
  onSelectRecipient={() => setActivePanel(PanelView.RECIPIENT_SELECTION)}
403
- dstAmount={dstAmount}
477
+ dstAmount={isSrcInputDirty ? dstAmount : dstAmountInput}
404
478
  dstToken={selectedDstToken}
405
479
  dstTokenSymbol={DESTINATION_TOKEN_DETAILS.SYMBOL}
406
480
  dstTokenLogoURI={DESTINATION_TOKEN_DETAILS.LOGO_URI}
@@ -410,11 +484,11 @@ function AnySpendCustomExactInInner({
410
484
  isSrcInputDirty={isSrcInputDirty}
411
485
  onChangeDstAmount={value => {
412
486
  setIsSrcInputDirty(false);
413
- setSrcAmount(value);
487
+ setDstAmountInput(value);
414
488
  }}
415
- anyspendQuote={anyspendQuote}
416
- onShowPointsDetail={() => setActivePanel(PanelView.POINTS_DETAIL)}
417
- onShowFeeDetail={() => setActivePanel(PanelView.FEE_DETAIL)}
489
+ anyspendQuote={isDirectTransfer ? undefined : anyspendQuote}
490
+ onShowPointsDetail={isDirectTransfer ? undefined : () => setActivePanel(PanelView.POINTS_DETAIL)}
491
+ onShowFeeDetail={isDirectTransfer ? undefined : () => setActivePanel(PanelView.FEE_DETAIL)}
418
492
  />
419
493
  )}
420
494
  </div>
@@ -430,10 +504,15 @@ function AnySpendCustomExactInInner({
430
504
  accentColor={"hsl(var(--as-brand))"}
431
505
  disabled={btnInfo.disable}
432
506
  onClick={onMainButtonClick}
433
- className={cn(
434
- "as-main-button relative w-full",
435
- btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand",
436
- )}
507
+ className={
508
+ (btnInfo.error && classes?.mainButtonError) ||
509
+ (btnInfo.disable && classes?.mainButtonDisabled) ||
510
+ classes?.mainButton ||
511
+ cn(
512
+ "as-main-button relative w-full",
513
+ btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand",
514
+ )
515
+ }
437
516
  textClassName={cn(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white")}
438
517
  >
439
518
  <div className="flex items-center justify-center gap-2">
@@ -443,9 +522,9 @@ function AnySpendCustomExactInInner({
443
522
  </ShinyButton>
444
523
  </motion.div>
445
524
 
446
- {/* Gas indicator - show when source chain has gas data */}
447
- {gasPriceData && !isLoadingGas && paymentType === "crypto" && (
448
- <GasIndicator gasPrice={gasPriceData} className="mt-2 w-full" />
525
+ {/* Gas indicator - show when source chain has gas data, hide for direct transfers */}
526
+ {gasPriceData && !isLoadingGas && paymentType === "crypto" && !isDirectTransfer && (
527
+ <GasIndicator gasPrice={gasPriceData} className={classes?.gasIndicator || "mt-2 w-full"} />
449
528
  )}
450
529
 
451
530
  {mainFooter ? mainFooter : null}
@@ -454,24 +533,78 @@ function AnySpendCustomExactInInner({
454
533
 
455
534
  const handleCryptoOrder = async () => {
456
535
  try {
457
- invariant(anyspendQuote, "Relay price is not found");
536
+ const isDirectTransfer = isSameChainSameToken && allowDirectTransfer;
537
+
538
+ if (!isDirectTransfer) {
539
+ invariant(anyspendQuote, "Relay price is not found");
540
+ }
458
541
  invariant(selectedRecipientOrDefault, "Recipient address is not found");
459
542
 
460
- const srcAmountBigInt = BigInt(activeInputAmountInWei);
461
- const payload = buildCustomPayload(selectedRecipientOrDefault);
462
-
463
- createOrder({
464
- recipientAddress: selectedRecipientOrDefault,
465
- orderType,
466
- srcChain: selectedSrcChainId,
467
- dstChain: selectedDstChainId,
468
- srcToken: selectedSrcToken,
469
- dstToken: selectedDstToken,
470
- srcAmount: srcAmountBigInt.toString(),
471
- expectedDstAmount: expectedDstAmountRaw,
472
- creatorAddress: globalAddress,
473
- payload,
474
- });
543
+ // Handle direct transfer case (same token/chain) - bypass backend, transfer directly
544
+ if (isDirectTransfer) {
545
+ const srcAmountBigInt = BigInt(activeInputAmountInWei);
546
+
547
+ const txHash = await executeDirectTransfer({
548
+ chainId: selectedSrcChainId,
549
+ tokenAddress: selectedSrcToken.address,
550
+ recipientAddress: selectedRecipientOrDefault,
551
+ amount: srcAmountBigInt,
552
+ method: effectiveCryptoPaymentMethod,
553
+ });
554
+
555
+ if (txHash) {
556
+ setDirectTransferTxHash(txHash);
557
+ setActivePanel(PanelView.DIRECT_TRANSFER_SUCCESS);
558
+ }
559
+ return;
560
+ }
561
+
562
+ // At this point, anyspendQuote is guaranteed to be defined (invariant above ensures this)
563
+ if (tradeType === "EXACT_OUTPUT") {
564
+ // EXACT_OUTPUT mode: create a custom order (like AnySpendStakeUpside)
565
+ const srcAmountFromQuote = anyspendQuote?.data?.currencyIn?.amount;
566
+ invariant(srcAmountFromQuote, "Source amount from quote is not found");
567
+
568
+ const expectedDstAmount = anyspendQuote?.data?.currencyOut?.amount ?? "0";
569
+ const encodedData = generateEncodedData(customExactInConfig, activeOutputAmountInWei);
570
+
571
+ createOrder({
572
+ recipientAddress: selectedRecipientOrDefault,
573
+ orderType: "custom",
574
+ srcChain: selectedSrcChainId,
575
+ dstChain: selectedDstChainId,
576
+ srcToken: selectedSrcToken,
577
+ dstToken: selectedDstToken,
578
+ srcAmount: srcAmountFromQuote,
579
+ expectedDstAmount,
580
+ creatorAddress: globalAddress,
581
+ payload: {
582
+ amount: activeOutputAmountInWei,
583
+ data: encodedData,
584
+ to: customExactInConfig ? normalizeAddress(customExactInConfig.to) : undefined,
585
+ spenderAddress: customExactInConfig?.spenderAddress
586
+ ? normalizeAddress(customExactInConfig.spenderAddress)
587
+ : undefined,
588
+ },
589
+ });
590
+ } else {
591
+ // EXACT_INPUT mode: create custom_exact_in order (original behavior)
592
+ const srcAmountBigInt = BigInt(activeInputAmountInWei);
593
+ const payload = buildCustomPayload(selectedRecipientOrDefault);
594
+
595
+ createOrder({
596
+ recipientAddress: selectedRecipientOrDefault,
597
+ orderType,
598
+ srcChain: selectedSrcChainId,
599
+ dstChain: selectedDstChainId,
600
+ srcToken: selectedSrcToken,
601
+ dstToken: selectedDstToken,
602
+ srcAmount: srcAmountBigInt.toString(),
603
+ expectedDstAmount: expectedDstAmountRaw,
604
+ creatorAddress: globalAddress,
605
+ payload,
606
+ });
607
+ }
475
608
  } catch (err: any) {
476
609
  console.error(err);
477
610
  toast.error("Failed to create order: " + err.message);
@@ -509,24 +642,52 @@ function AnySpendCustomExactInInner({
509
642
  return;
510
643
  }
511
644
 
512
- const payload = buildCustomPayload(selectedRecipientOrDefault);
513
-
514
- createOnrampOrder({
515
- recipientAddress: selectedRecipientOrDefault,
516
- orderType,
517
- dstChain: selectedDstChainId,
518
- dstToken: selectedDstToken,
519
- srcFiatAmount: srcAmount,
520
- onramp: {
521
- vendor,
522
- paymentMethod: paymentMethodString,
523
- country: geoData?.country || "US",
524
- redirectUrl: window.location.origin,
525
- },
526
- expectedDstAmount: expectedDstAmountRaw,
527
- creatorAddress: globalAddress,
528
- payload,
529
- });
645
+ const onrampOptions = {
646
+ vendor,
647
+ paymentMethod: paymentMethodString,
648
+ country: geoData?.country || "US",
649
+ redirectUrl: window.location.origin,
650
+ };
651
+
652
+ if (tradeType === "EXACT_OUTPUT") {
653
+ // EXACT_OUTPUT mode: create a custom order (like AnySpendStakeUpside)
654
+ const expectedDstAmount = anyspendQuote.data?.currencyOut?.amount ?? "0";
655
+ const encodedData = generateEncodedData(customExactInConfig, activeOutputAmountInWei);
656
+
657
+ createOnrampOrder({
658
+ recipientAddress: selectedRecipientOrDefault,
659
+ orderType: "custom",
660
+ dstChain: selectedDstChainId,
661
+ dstToken: selectedDstToken,
662
+ srcFiatAmount: srcAmount,
663
+ onramp: onrampOptions,
664
+ expectedDstAmount,
665
+ creatorAddress: globalAddress,
666
+ payload: {
667
+ amount: activeOutputAmountInWei,
668
+ data: encodedData,
669
+ to: customExactInConfig ? normalizeAddress(customExactInConfig.to) : undefined,
670
+ spenderAddress: customExactInConfig?.spenderAddress
671
+ ? normalizeAddress(customExactInConfig.spenderAddress)
672
+ : undefined,
673
+ },
674
+ });
675
+ } else {
676
+ // EXACT_INPUT mode: create custom_exact_in order (original behavior)
677
+ const payload = buildCustomPayload(selectedRecipientOrDefault);
678
+
679
+ createOnrampOrder({
680
+ recipientAddress: selectedRecipientOrDefault,
681
+ orderType,
682
+ dstChain: selectedDstChainId,
683
+ dstToken: selectedDstToken,
684
+ srcFiatAmount: srcAmount,
685
+ onramp: onrampOptions,
686
+ expectedDstAmount: expectedDstAmountRaw,
687
+ creatorAddress: globalAddress,
688
+ payload,
689
+ });
690
+ }
530
691
  } catch (err: any) {
531
692
  console.error(err);
532
693
  toast.error("Failed to create order: " + err.message);
@@ -625,13 +786,60 @@ function AnySpendCustomExactInInner({
625
786
  />
626
787
  ) : null;
627
788
 
789
+ const directTransferSuccessView = (
790
+ <motion.div
791
+ initial={{ opacity: 0, scale: 0.95 }}
792
+ animate={{ opacity: 1, scale: 1 }}
793
+ className="flex flex-col items-center justify-center gap-6 py-8"
794
+ >
795
+ <div className="flex h-16 w-16 items-center justify-center rounded-full bg-green-500/20">
796
+ <CheckCircle className="h-10 w-10 text-green-500" />
797
+ </div>
798
+ <div className="text-center">
799
+ <h2 className="text-as-primary mb-2 text-xl font-bold">Transfer Complete!</h2>
800
+ <p className="text-as-primary/60 text-sm">
801
+ {srcAmount} {selectedSrcToken.symbol} sent on {getChainName(selectedSrcChainId)}
802
+ </p>
803
+ <p className="text-as-primary/60 mt-1 text-sm">
804
+ to {selectedRecipientOrDefault?.slice(0, 6)}...{selectedRecipientOrDefault?.slice(-4)}
805
+ </p>
806
+ </div>
807
+ {directTransferTxHash && (
808
+ <a
809
+ href={getExplorerTxUrl(selectedSrcChainId, directTransferTxHash || "")}
810
+ target="_blank"
811
+ rel="noopener noreferrer"
812
+ className="text-as-brand text-sm underline"
813
+ >
814
+ View Transaction
815
+ </a>
816
+ )}
817
+ <Button
818
+ className="bg-as-brand hover:bg-as-brand/90 mt-4 w-full rounded-xl py-3 font-semibold text-white"
819
+ onClick={() => {
820
+ onSuccess?.(srcAmount);
821
+ if (returnToHomeUrl) {
822
+ window.location.href = returnToHomeUrl;
823
+ } else {
824
+ setB3ModalOpen(false);
825
+ }
826
+ }}
827
+ >
828
+ {returnHomeLabel || (returnToHomeUrl ? "Return to Home" : "Done")}
829
+ </Button>
830
+ </motion.div>
831
+ );
832
+
628
833
  return (
629
834
  <StyleRoot>
630
835
  <div
631
- className={cn(
632
- "anyspend-container font-inter bg-as-surface-primary mx-auto w-full max-w-[460px] p-6",
633
- mode === "page" && "border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl",
634
- )}
836
+ className={
837
+ classes?.root ||
838
+ cn(
839
+ "anyspend-container font-inter bg-as-surface-primary mx-auto w-full max-w-[460px] p-6",
840
+ mode === "page" && "border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl",
841
+ )
842
+ }
635
843
  >
636
844
  <TransitionPanel
637
845
  activeIndex={
@@ -662,6 +870,7 @@ function AnySpendCustomExactInInner({
662
870
  <div key="loading-view">{loadingView}</div>,
663
871
  <div key="points-detail-view">{pointsDetailView}</div>,
664
872
  <div key="fee-detail-view">{feeDetailView}</div>,
873
+ <div key="direct-transfer-success-view">{directTransferSuccessView}</div>,
665
874
  ]}
666
875
  </TransitionPanel>
667
876
  </div>