@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
@@ -1,142 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.useTurnkeyAuth = useTurnkeyAuth;
7
- const debug_1 = require("../../../shared/utils/debug");
8
- const react_1 = require("react");
9
- const app_1 = __importDefault(require("../../app"));
10
- const components_1 = require("../components");
11
- const stores_1 = require("../stores");
12
- const useAuth_1 = require("./useAuth");
13
- const debug = (0, debug_1.debugB3React)("useTurnkeyAuth");
14
- /**
15
- * Hook for Turnkey email-based OTP authentication
16
- *
17
- * Usage:
18
- * 1. Call initiateLogin(email) → User receives OTP email
19
- * 2. Call verifyOtp(...) → Verifies OTP and authenticates with b3-api
20
- * 3. User is authenticated, JWT stored in cookies automatically
21
- */
22
- function useTurnkeyAuth() {
23
- const [isLoading, setIsLoading] = (0, react_1.useState)(false);
24
- const [error, setError] = (0, react_1.useState)(null);
25
- const setIsAuthenticating = (0, stores_1.useAuthStore)(state => state.setIsAuthenticating);
26
- const setIsAuthenticated = (0, stores_1.useAuthStore)(state => state.setIsAuthenticated);
27
- const { partnerId } = (0, components_1.useB3Config)();
28
- const { authenticate } = (0, useAuth_1.useAuth)();
29
- /**
30
- * Step 1: Initiate login with email
31
- * - Calls backend turnkey-jwt strategy (init action) to create sub-org (if needed) and send OTP
32
- * - Returns otpId to use in verification step
33
- *
34
- * Note: Uses the turnkey-jwt authentication strategy, not the service directly.
35
- * The turnkey-jwt strategy handles both OTP flow (init/verify) and final authentication.
36
- */
37
- const initiateLogin = (0, react_1.useCallback)(async (email) => {
38
- setIsLoading(true);
39
- setError(null);
40
- setIsAuthenticating(true);
41
- try {
42
- debug(`Initiating login for: ${email}`);
43
- // Use authentication service with turnkey-jwt strategy (init action)
44
- // userId is resolved from authentication context on the backend (params.user.userId)
45
- // Backend will get userId from _params.user?.userId if authenticated, or handle unauthenticated case
46
- // So we only need to send email
47
- debug(`Calling app.authenticate with turnkey-jwt strategy (init action)`, { email });
48
- const response = await app_1.default.authenticate({
49
- strategy: "turnkey-jwt",
50
- action: "init",
51
- email,
52
- });
53
- // The strategy returns the TurnkeyAuthInitResponse directly
54
- const data = response;
55
- debug(`OTP initialized successfully. OtpId: ${data.otpId}`);
56
- return data;
57
- }
58
- catch (err) {
59
- debug("Error initiating login:", err);
60
- // Provide more detailed error information
61
- let errorMessage = "Failed to send OTP email. Please try again.";
62
- if (err.message) {
63
- errorMessage = err.message;
64
- }
65
- else if (err.name === "TypeError" && err.message?.includes("fetch")) {
66
- errorMessage = "Network error: Unable to reach the server. Please check your connection and try again.";
67
- }
68
- else if (err.code === "ECONNREFUSED" || err.code === "ENOTFOUND") {
69
- errorMessage = "Connection error: Unable to reach the server. Please check your internet connection.";
70
- }
71
- else if (err.response) {
72
- // FeathersJS error response
73
- errorMessage = err.response.message || err.message || errorMessage;
74
- debug("FeathersJS error response:", err.response);
75
- }
76
- setError(errorMessage);
77
- throw err;
78
- }
79
- finally {
80
- setIsLoading(false);
81
- setIsAuthenticating(false);
82
- }
83
- }, [setIsAuthenticating]);
84
- /**
85
- * Step 2: Verify OTP and authenticate
86
- * - Verifies OTP with backend via turnkey-jwt strategy (verify action)
87
- * - Gets Turnkey session JWT from the verify response
88
- * - Authenticates with b3-api using "turnkey-jwt" strategy
89
- * - JWT automatically stored in cookies by SDK
90
- */
91
- const verifyOtp = (0, react_1.useCallback)(async (otpId, otpCode) => {
92
- setIsLoading(true);
93
- setError(null);
94
- setIsAuthenticating(true);
95
- try {
96
- debug(`Verifying OTP...`, { otpId });
97
- // Step 1: Verify OTP with backend using turnkey-jwt strategy (verify action)
98
- // This returns the Turnkey session JWT
99
- const response = await app_1.default.authenticate({
100
- strategy: "turnkey-jwt",
101
- action: "verify",
102
- otpId,
103
- otpCode,
104
- });
105
- // The strategy returns the TurnkeyAuthVerifyResponse directly
106
- const verifyResult = response;
107
- const { turnkeySessionJwt } = verifyResult;
108
- debug(`OTP verified! Got Turnkey session JWT. Authenticating with b3-api...`);
109
- // Step 2: Authenticate with b3-api using Turnkey JWT
110
- // Use the unified useAuth hook for authentication with "turnkey-jwt" strategy
111
- const authResult = await authenticate(turnkeySessionJwt, partnerId || "");
112
- debug(`Successfully authenticated with b3-api!`, authResult);
113
- // Update auth store to reflect authenticated state
114
- setIsAuthenticated(true);
115
- // Return user data
116
- return {
117
- user: authResult.user,
118
- };
119
- }
120
- catch (err) {
121
- debug("Error verifying OTP:", err);
122
- const errorMessage = err.message || "Failed to verify OTP. Please try again.";
123
- setError(errorMessage);
124
- setIsAuthenticated(false);
125
- throw err;
126
- }
127
- finally {
128
- setIsLoading(false);
129
- setIsAuthenticating(false);
130
- }
131
- }, [partnerId, setIsAuthenticating, setIsAuthenticated, authenticate]);
132
- const clearError = (0, react_1.useCallback)(() => {
133
- setError(null);
134
- }, []);
135
- return {
136
- initiateLogin,
137
- verifyOtp,
138
- isLoading,
139
- error,
140
- clearError,
141
- };
142
- }
@@ -1,8 +0,0 @@
1
- interface TurnkeyAuthModalProps {
2
- onClose: () => void;
3
- onSuccess: (_user: any) => void;
4
- initialEmail?: string;
5
- skipToOtp?: boolean;
6
- }
7
- export declare function TurnkeyAuthModal({ onClose, onSuccess, initialEmail, skipToOtp }: TurnkeyAuthModalProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,83 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
3
- import { useTurnkeyAuth } from "../hooks/useTurnkeyAuth.js";
4
- export function TurnkeyAuthModal({ onClose, onSuccess, initialEmail = "", skipToOtp = false }) {
5
- const [step, setStep] = useState(skipToOtp ? "otp" : "email");
6
- const [email, setEmail] = useState(initialEmail);
7
- const [otpCode, setOtpCode] = useState("");
8
- const [otpId, setOtpId] = useState("");
9
- const autoSubmitTriggeredRef = useRef(false);
10
- const { initiateLogin, verifyOtp, isLoading, error, clearError } = useTurnkeyAuth();
11
- // Update email when initialEmail changes
12
- useEffect(() => {
13
- if (initialEmail && initialEmail !== email) {
14
- setEmail(initialEmail);
15
- }
16
- }, [initialEmail, email]);
17
- // Auto-submit email form if skipToOtp is true - triggers on mount when skipToOtp=true
18
- useEffect(() => {
19
- if (skipToOtp && email && step === "otp" && !otpId && !isLoading && !autoSubmitTriggeredRef.current) {
20
- autoSubmitTriggeredRef.current = true;
21
- // Call initiateLogin directly to get OTP
22
- initiateLogin(email)
23
- .then(result => {
24
- setOtpId(result.otpId);
25
- })
26
- .catch(err => {
27
- console.error("Failed to initiate login:", err);
28
- });
29
- }
30
- // eslint-disable-next-line react-hooks/exhaustive-deps
31
- }, [skipToOtp, email, step, otpId, isLoading]);
32
- const handleEmailSubmit = async (e) => {
33
- e.preventDefault();
34
- try {
35
- const result = await initiateLogin(email);
36
- setOtpId(result.otpId);
37
- setStep("otp");
38
- }
39
- catch (err) {
40
- // Error is handled by the hook
41
- console.error("Failed to initiate login:", err);
42
- }
43
- };
44
- const handleOtpSubmit = async (e) => {
45
- e.preventDefault();
46
- try {
47
- const result = await verifyOtp(otpId, otpCode);
48
- setStep("success");
49
- // Auto-close after success and notify parent
50
- setTimeout(() => {
51
- onSuccess(result.user);
52
- handleClose();
53
- }, 1500);
54
- }
55
- catch (err) {
56
- // Error is handled by the hook
57
- console.error("Failed to verify OTP:", err);
58
- }
59
- };
60
- const handleClose = () => {
61
- // Reset state
62
- setStep("email");
63
- setEmail("");
64
- setOtpCode("");
65
- setOtpId("");
66
- autoSubmitTriggeredRef.current = false;
67
- clearError();
68
- onClose();
69
- };
70
- const handleResendOtp = async () => {
71
- try {
72
- const result = await initiateLogin(email);
73
- setOtpId(result.otpId);
74
- clearError();
75
- }
76
- catch (err) {
77
- console.error("Failed to resend OTP:", err);
78
- }
79
- };
80
- const isTurnkeyPrimary = process.env.NEXT_PUBLIC_TURNKEY_PRIMARY === "true";
81
- const walletBrand = isTurnkeyPrimary ? "Smart Wallet" : "AnySpend Wallet";
82
- return (_jsxs("div", { className: "font-neue-montreal p-8", children: [step === "email" && (_jsxs(_Fragment, { children: [_jsxs("h2", { className: "mb-6 text-center text-2xl font-bold text-gray-900 dark:text-white", children: ["Setup your ", walletBrand] }), _jsxs("div", { className: "mb-6 space-y-3 text-center text-sm text-gray-600 dark:text-gray-400", children: [_jsxs("p", { children: [isTurnkeyPrimary ? "We use a secure," : "AnySpend uses a secure,", _jsx("br", {}), "embedded wallet to fund your workflows."] }), _jsxs("p", { children: ["Please provide an email address to secure", _jsx("br", {}), "your wallet."] })] }), _jsxs("form", { onSubmit: handleEmailSubmit, className: "space-y-4", children: [_jsx("div", { children: _jsx("input", { type: "email", placeholder: "email", value: email, onChange: e => setEmail(e.target.value), required: true, disabled: isLoading, className: "w-full rounded-lg border border-gray-300 px-4 py-3 text-center text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 disabled:cursor-not-allowed disabled:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500" }) }), error && (_jsx("div", { className: "rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-400", children: error })), _jsx("button", { type: "submit", disabled: isLoading || !email, className: "w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-all duration-200 hover:bg-blue-700 disabled:cursor-not-allowed disabled:bg-gray-300 dark:disabled:bg-gray-700", children: isLoading ? (_jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" }), "Sending..."] })) : ("Continue") })] })] })), step === "otp" && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mb-4 text-center text-2xl font-bold text-gray-900 dark:text-white", children: "2FA Security" }), _jsx("div", { className: "mb-6 space-y-3 text-center text-sm text-gray-600 dark:text-gray-400", children: _jsxs("p", { children: [isTurnkeyPrimary ? "We use a secure," : "AnySpend uses a secure,", _jsx("br", {}), "embedded wallet to fund your workflows.", _jsx("br", {}), "Please provide 2FA code sent to your email."] }) }), _jsxs("form", { onSubmit: handleOtpSubmit, className: "space-y-4", children: [_jsx("div", { children: _jsx("input", { type: "text", placeholder: "Enter code", value: otpCode, onChange: e => setOtpCode(e.target.value.toUpperCase()), required: true, disabled: isLoading, autoFocus: true, className: "w-full rounded-lg border border-gray-300 px-4 py-3 text-center font-mono text-lg uppercase tracking-wider text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 disabled:cursor-not-allowed disabled:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500", maxLength: 20 }) }), error && (_jsx("div", { className: "rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-400", children: error })), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("button", { type: "submit", disabled: isLoading || !otpCode, className: "w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-all duration-200 hover:bg-blue-700 disabled:cursor-not-allowed disabled:bg-gray-300 dark:disabled:bg-gray-700", children: isLoading ? (_jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" }), "Verifying..."] })) : ("Confirm") }), _jsx("button", { type: "button", onClick: handleResendOtp, disabled: isLoading, className: "text-sm text-blue-600 hover:text-blue-700 hover:underline disabled:cursor-not-allowed disabled:text-gray-400 dark:text-blue-400 dark:hover:text-blue-300", children: "Resend code" })] })] })] })), step === "success" && (_jsxs("div", { className: "text-center", children: [_jsx("div", { className: "mb-6 flex items-center justify-center", children: _jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/20", children: _jsx("svg", { className: "h-8 w-8 text-green-600 dark:text-green-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }) }), _jsx("h2", { className: "mb-2 text-2xl font-bold text-gray-900 dark:text-white", children: "Successfully Authenticated!" }), _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: "Redirecting..." })] }))] }));
83
- }
@@ -1,20 +0,0 @@
1
- import { TurnkeyAuthInitResponse } from "@b3dotfun/b3-api";
2
- interface UseTurnkeyAuthReturn {
3
- initiateLogin: (_email: string) => Promise<TurnkeyAuthInitResponse>;
4
- verifyOtp: (_otpId: string, _otpCode: string) => Promise<{
5
- user: any;
6
- }>;
7
- isLoading: boolean;
8
- error: string | null;
9
- clearError: () => void;
10
- }
11
- /**
12
- * Hook for Turnkey email-based OTP authentication
13
- *
14
- * Usage:
15
- * 1. Call initiateLogin(email) → User receives OTP email
16
- * 2. Call verifyOtp(...) → Verifies OTP and authenticates with b3-api
17
- * 3. User is authenticated, JWT stored in cookies automatically
18
- */
19
- export declare function useTurnkeyAuth(): UseTurnkeyAuthReturn;
20
- export {};
@@ -1,136 +0,0 @@
1
- import { debugB3React } from "../../../shared/utils/debug.js";
2
- import { useCallback, useState } from "react";
3
- import app from "../../app.js";
4
- import { useB3Config } from "../components/index.js";
5
- import { useAuthStore } from "../stores/index.js";
6
- import { useAuth } from "./useAuth.js";
7
- const debug = debugB3React("useTurnkeyAuth");
8
- /**
9
- * Hook for Turnkey email-based OTP authentication
10
- *
11
- * Usage:
12
- * 1. Call initiateLogin(email) → User receives OTP email
13
- * 2. Call verifyOtp(...) → Verifies OTP and authenticates with b3-api
14
- * 3. User is authenticated, JWT stored in cookies automatically
15
- */
16
- export function useTurnkeyAuth() {
17
- const [isLoading, setIsLoading] = useState(false);
18
- const [error, setError] = useState(null);
19
- const setIsAuthenticating = useAuthStore(state => state.setIsAuthenticating);
20
- const setIsAuthenticated = useAuthStore(state => state.setIsAuthenticated);
21
- const { partnerId } = useB3Config();
22
- const { authenticate } = useAuth();
23
- /**
24
- * Step 1: Initiate login with email
25
- * - Calls backend turnkey-jwt strategy (init action) to create sub-org (if needed) and send OTP
26
- * - Returns otpId to use in verification step
27
- *
28
- * Note: Uses the turnkey-jwt authentication strategy, not the service directly.
29
- * The turnkey-jwt strategy handles both OTP flow (init/verify) and final authentication.
30
- */
31
- const initiateLogin = useCallback(async (email) => {
32
- setIsLoading(true);
33
- setError(null);
34
- setIsAuthenticating(true);
35
- try {
36
- debug(`Initiating login for: ${email}`);
37
- // Use authentication service with turnkey-jwt strategy (init action)
38
- // userId is resolved from authentication context on the backend (params.user.userId)
39
- // Backend will get userId from _params.user?.userId if authenticated, or handle unauthenticated case
40
- // So we only need to send email
41
- debug(`Calling app.authenticate with turnkey-jwt strategy (init action)`, { email });
42
- const response = await app.authenticate({
43
- strategy: "turnkey-jwt",
44
- action: "init",
45
- email,
46
- });
47
- // The strategy returns the TurnkeyAuthInitResponse directly
48
- const data = response;
49
- debug(`OTP initialized successfully. OtpId: ${data.otpId}`);
50
- return data;
51
- }
52
- catch (err) {
53
- debug("Error initiating login:", err);
54
- // Provide more detailed error information
55
- let errorMessage = "Failed to send OTP email. Please try again.";
56
- if (err.message) {
57
- errorMessage = err.message;
58
- }
59
- else if (err.name === "TypeError" && err.message?.includes("fetch")) {
60
- errorMessage = "Network error: Unable to reach the server. Please check your connection and try again.";
61
- }
62
- else if (err.code === "ECONNREFUSED" || err.code === "ENOTFOUND") {
63
- errorMessage = "Connection error: Unable to reach the server. Please check your internet connection.";
64
- }
65
- else if (err.response) {
66
- // FeathersJS error response
67
- errorMessage = err.response.message || err.message || errorMessage;
68
- debug("FeathersJS error response:", err.response);
69
- }
70
- setError(errorMessage);
71
- throw err;
72
- }
73
- finally {
74
- setIsLoading(false);
75
- setIsAuthenticating(false);
76
- }
77
- }, [setIsAuthenticating]);
78
- /**
79
- * Step 2: Verify OTP and authenticate
80
- * - Verifies OTP with backend via turnkey-jwt strategy (verify action)
81
- * - Gets Turnkey session JWT from the verify response
82
- * - Authenticates with b3-api using "turnkey-jwt" strategy
83
- * - JWT automatically stored in cookies by SDK
84
- */
85
- const verifyOtp = useCallback(async (otpId, otpCode) => {
86
- setIsLoading(true);
87
- setError(null);
88
- setIsAuthenticating(true);
89
- try {
90
- debug(`Verifying OTP...`, { otpId });
91
- // Step 1: Verify OTP with backend using turnkey-jwt strategy (verify action)
92
- // This returns the Turnkey session JWT
93
- const response = await app.authenticate({
94
- strategy: "turnkey-jwt",
95
- action: "verify",
96
- otpId,
97
- otpCode,
98
- });
99
- // The strategy returns the TurnkeyAuthVerifyResponse directly
100
- const verifyResult = response;
101
- const { turnkeySessionJwt } = verifyResult;
102
- debug(`OTP verified! Got Turnkey session JWT. Authenticating with b3-api...`);
103
- // Step 2: Authenticate with b3-api using Turnkey JWT
104
- // Use the unified useAuth hook for authentication with "turnkey-jwt" strategy
105
- const authResult = await authenticate(turnkeySessionJwt, partnerId || "");
106
- debug(`Successfully authenticated with b3-api!`, authResult);
107
- // Update auth store to reflect authenticated state
108
- setIsAuthenticated(true);
109
- // Return user data
110
- return {
111
- user: authResult.user,
112
- };
113
- }
114
- catch (err) {
115
- debug("Error verifying OTP:", err);
116
- const errorMessage = err.message || "Failed to verify OTP. Please try again.";
117
- setError(errorMessage);
118
- setIsAuthenticated(false);
119
- throw err;
120
- }
121
- finally {
122
- setIsLoading(false);
123
- setIsAuthenticating(false);
124
- }
125
- }, [partnerId, setIsAuthenticating, setIsAuthenticated, authenticate]);
126
- const clearError = useCallback(() => {
127
- setError(null);
128
- }, []);
129
- return {
130
- initiateLogin,
131
- verifyOtp,
132
- isLoading,
133
- error,
134
- clearError,
135
- };
136
- }
@@ -1,8 +0,0 @@
1
- interface TurnkeyAuthModalProps {
2
- onClose: () => void;
3
- onSuccess: (_user: any) => void;
4
- initialEmail?: string;
5
- skipToOtp?: boolean;
6
- }
7
- export declare function TurnkeyAuthModal({ onClose, onSuccess, initialEmail, skipToOtp }: TurnkeyAuthModalProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,20 +0,0 @@
1
- import { TurnkeyAuthInitResponse } from "@b3dotfun/b3-api";
2
- interface UseTurnkeyAuthReturn {
3
- initiateLogin: (_email: string) => Promise<TurnkeyAuthInitResponse>;
4
- verifyOtp: (_otpId: string, _otpCode: string) => Promise<{
5
- user: any;
6
- }>;
7
- isLoading: boolean;
8
- error: string | null;
9
- clearError: () => void;
10
- }
11
- /**
12
- * Hook for Turnkey email-based OTP authentication
13
- *
14
- * Usage:
15
- * 1. Call initiateLogin(email) → User receives OTP email
16
- * 2. Call verifyOtp(...) → Verifies OTP and authenticates with b3-api
17
- * 3. User is authenticated, JWT stored in cookies automatically
18
- */
19
- export declare function useTurnkeyAuth(): UseTurnkeyAuthReturn;
20
- export {};
@@ -1,243 +0,0 @@
1
- import React, { useEffect, useRef, useState } from "react";
2
- import { useTurnkeyAuth } from "../hooks/useTurnkeyAuth";
3
-
4
- type ModalStep = "email" | "otp" | "success";
5
-
6
- interface TurnkeyAuthModalProps {
7
- onClose: () => void;
8
- onSuccess: (_user: any) => void;
9
- initialEmail?: string;
10
- skipToOtp?: boolean;
11
- }
12
-
13
- export function TurnkeyAuthModal({ onClose, onSuccess, initialEmail = "", skipToOtp = false }: TurnkeyAuthModalProps) {
14
- const [step, setStep] = useState<ModalStep>(skipToOtp ? "otp" : "email");
15
- const [email, setEmail] = useState(initialEmail);
16
- const [otpCode, setOtpCode] = useState("");
17
- const [otpId, setOtpId] = useState("");
18
- const autoSubmitTriggeredRef = useRef(false);
19
-
20
- const { initiateLogin, verifyOtp, isLoading, error, clearError } = useTurnkeyAuth();
21
-
22
- // Update email when initialEmail changes
23
- useEffect(() => {
24
- if (initialEmail && initialEmail !== email) {
25
- setEmail(initialEmail);
26
- }
27
- }, [initialEmail, email]);
28
-
29
- // Auto-submit email form if skipToOtp is true - triggers on mount when skipToOtp=true
30
- useEffect(() => {
31
- if (skipToOtp && email && step === "otp" && !otpId && !isLoading && !autoSubmitTriggeredRef.current) {
32
- autoSubmitTriggeredRef.current = true;
33
- // Call initiateLogin directly to get OTP
34
- initiateLogin(email)
35
- .then(result => {
36
- setOtpId(result.otpId);
37
- })
38
- .catch(err => {
39
- console.error("Failed to initiate login:", err);
40
- });
41
- }
42
- // eslint-disable-next-line react-hooks/exhaustive-deps
43
- }, [skipToOtp, email, step, otpId, isLoading]);
44
-
45
- const handleEmailSubmit = async (e: React.FormEvent) => {
46
- e.preventDefault();
47
-
48
- try {
49
- const result = await initiateLogin(email);
50
- setOtpId(result.otpId);
51
- setStep("otp");
52
- } catch (err) {
53
- // Error is handled by the hook
54
- console.error("Failed to initiate login:", err);
55
- }
56
- };
57
-
58
- const handleOtpSubmit = async (e: React.FormEvent) => {
59
- e.preventDefault();
60
-
61
- try {
62
- const result = await verifyOtp(otpId, otpCode);
63
- setStep("success");
64
-
65
- // Auto-close after success and notify parent
66
- setTimeout(() => {
67
- onSuccess(result.user);
68
- handleClose();
69
- }, 1500);
70
- } catch (err) {
71
- // Error is handled by the hook
72
- console.error("Failed to verify OTP:", err);
73
- }
74
- };
75
-
76
- const handleClose = () => {
77
- // Reset state
78
- setStep("email");
79
- setEmail("");
80
- setOtpCode("");
81
- setOtpId("");
82
- autoSubmitTriggeredRef.current = false;
83
- clearError();
84
- onClose();
85
- };
86
-
87
- const handleResendOtp = async () => {
88
- try {
89
- const result = await initiateLogin(email);
90
- setOtpId(result.otpId);
91
- clearError();
92
- } catch (err) {
93
- console.error("Failed to resend OTP:", err);
94
- }
95
- };
96
-
97
- const isTurnkeyPrimary = process.env.NEXT_PUBLIC_TURNKEY_PRIMARY === "true";
98
- const walletBrand = isTurnkeyPrimary ? "Smart Wallet" : "AnySpend Wallet";
99
-
100
- return (
101
- <div className="font-neue-montreal p-8">
102
- {/* Email Step */}
103
- {step === "email" && (
104
- <>
105
- <h2 className="mb-6 text-center text-2xl font-bold text-gray-900 dark:text-white">
106
- Setup your {walletBrand}
107
- </h2>
108
- <div className="mb-6 space-y-3 text-center text-sm text-gray-600 dark:text-gray-400">
109
- <p>
110
- {isTurnkeyPrimary ? "We use a secure," : "AnySpend uses a secure,"}
111
- <br />
112
- embedded wallet to fund your workflows.
113
- </p>
114
- <p>
115
- Please provide an email address to secure
116
- <br />
117
- your wallet.
118
- </p>
119
- </div>
120
-
121
- <form onSubmit={handleEmailSubmit} className="space-y-4">
122
- <div>
123
- <input
124
- type="email"
125
- placeholder="email"
126
- value={email}
127
- onChange={e => setEmail(e.target.value)}
128
- required
129
- disabled={isLoading}
130
- className="w-full rounded-lg border border-gray-300 px-4 py-3 text-center text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 disabled:cursor-not-allowed disabled:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500"
131
- />
132
- </div>
133
-
134
- {error && (
135
- <div className="rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-400">
136
- {error}
137
- </div>
138
- )}
139
-
140
- <button
141
- type="submit"
142
- disabled={isLoading || !email}
143
- className="w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-all duration-200 hover:bg-blue-700 disabled:cursor-not-allowed disabled:bg-gray-300 dark:disabled:bg-gray-700"
144
- >
145
- {isLoading ? (
146
- <span className="flex items-center justify-center gap-2">
147
- <div className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></div>
148
- Sending...
149
- </span>
150
- ) : (
151
- "Continue"
152
- )}
153
- </button>
154
- </form>
155
- </>
156
- )}
157
-
158
- {/* OTP Step */}
159
- {step === "otp" && (
160
- <>
161
- <h2 className="mb-4 text-center text-2xl font-bold text-gray-900 dark:text-white">2FA Security</h2>
162
- <div className="mb-6 space-y-3 text-center text-sm text-gray-600 dark:text-gray-400">
163
- <p>
164
- {isTurnkeyPrimary ? "We use a secure," : "AnySpend uses a secure,"}
165
- <br />
166
- embedded wallet to fund your workflows.
167
- <br />
168
- Please provide 2FA code sent to your email.
169
- </p>
170
- </div>
171
-
172
- <form onSubmit={handleOtpSubmit} className="space-y-4">
173
- <div>
174
- <input
175
- type="text"
176
- placeholder="Enter code"
177
- value={otpCode}
178
- onChange={e => setOtpCode(e.target.value.toUpperCase())}
179
- required
180
- disabled={isLoading}
181
- autoFocus
182
- className="w-full rounded-lg border border-gray-300 px-4 py-3 text-center font-mono text-lg uppercase tracking-wider text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 disabled:cursor-not-allowed disabled:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:placeholder-gray-500"
183
- maxLength={20}
184
- />
185
- </div>
186
-
187
- {error && (
188
- <div className="rounded-md bg-red-50 p-3 text-sm text-red-800 dark:bg-red-900/20 dark:text-red-400">
189
- {error}
190
- </div>
191
- )}
192
-
193
- <div className="flex flex-col gap-2">
194
- <button
195
- type="submit"
196
- disabled={isLoading || !otpCode}
197
- className="w-full rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white transition-all duration-200 hover:bg-blue-700 disabled:cursor-not-allowed disabled:bg-gray-300 dark:disabled:bg-gray-700"
198
- >
199
- {isLoading ? (
200
- <span className="flex items-center justify-center gap-2">
201
- <div className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></div>
202
- Verifying...
203
- </span>
204
- ) : (
205
- "Confirm"
206
- )}
207
- </button>
208
-
209
- <button
210
- type="button"
211
- onClick={handleResendOtp}
212
- disabled={isLoading}
213
- className="text-sm text-blue-600 hover:text-blue-700 hover:underline disabled:cursor-not-allowed disabled:text-gray-400 dark:text-blue-400 dark:hover:text-blue-300"
214
- >
215
- Resend code
216
- </button>
217
- </div>
218
- </form>
219
- </>
220
- )}
221
-
222
- {/* Success Step */}
223
- {step === "success" && (
224
- <div className="text-center">
225
- <div className="mb-6 flex items-center justify-center">
226
- <div className="flex h-16 w-16 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/20">
227
- <svg
228
- className="h-8 w-8 text-green-600 dark:text-green-400"
229
- fill="none"
230
- viewBox="0 0 24 24"
231
- stroke="currentColor"
232
- >
233
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
234
- </svg>
235
- </div>
236
- </div>
237
- <h2 className="mb-2 text-2xl font-bold text-gray-900 dark:text-white">Successfully Authenticated!</h2>
238
- <p className="text-sm text-gray-600 dark:text-gray-400">Redirecting...</p>
239
- </div>
240
- )}
241
- </div>
242
- );
243
- }