@b3dotfun/sdk 0.1.68-alpha.0 → 0.1.68-alpha.10

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 (232) hide show
  1. package/dist/cjs/anyspend/platform/client.d.ts +35 -0
  2. package/dist/cjs/anyspend/platform/client.js +158 -0
  3. package/dist/cjs/anyspend/platform/errors.d.ts +38 -0
  4. package/dist/cjs/anyspend/platform/errors.js +77 -0
  5. package/dist/cjs/anyspend/platform/index.d.ts +87 -0
  6. package/dist/cjs/anyspend/platform/index.js +85 -0
  7. package/dist/cjs/anyspend/platform/resources/analytics.d.ts +7 -0
  8. package/dist/cjs/anyspend/platform/resources/analytics.js +12 -0
  9. package/dist/cjs/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
  10. package/dist/cjs/anyspend/platform/resources/checkout-sessions.js +27 -0
  11. package/dist/cjs/anyspend/platform/resources/customers.d.ts +19 -0
  12. package/dist/cjs/anyspend/platform/resources/customers.js +34 -0
  13. package/dist/cjs/anyspend/platform/resources/discount-codes.d.ts +29 -0
  14. package/dist/cjs/anyspend/platform/resources/discount-codes.js +31 -0
  15. package/dist/cjs/anyspend/platform/resources/events.d.ts +14 -0
  16. package/dist/cjs/anyspend/platform/resources/events.js +16 -0
  17. package/dist/cjs/anyspend/platform/resources/notifications.d.ts +18 -0
  18. package/dist/cjs/anyspend/platform/resources/notifications.js +27 -0
  19. package/dist/cjs/anyspend/platform/resources/organization.d.ts +17 -0
  20. package/dist/cjs/anyspend/platform/resources/organization.js +15 -0
  21. package/dist/cjs/anyspend/platform/resources/payment-links.d.ts +21 -0
  22. package/dist/cjs/anyspend/platform/resources/payment-links.js +49 -0
  23. package/dist/cjs/anyspend/platform/resources/products.d.ts +27 -0
  24. package/dist/cjs/anyspend/platform/resources/products.js +31 -0
  25. package/dist/cjs/anyspend/platform/resources/transactions.d.ts +11 -0
  26. package/dist/cjs/anyspend/platform/resources/transactions.js +25 -0
  27. package/dist/cjs/anyspend/platform/resources/webhooks.d.ts +14 -0
  28. package/dist/cjs/anyspend/platform/resources/webhooks.js +33 -0
  29. package/dist/cjs/anyspend/platform/resources/widgets.d.ts +38 -0
  30. package/dist/cjs/anyspend/platform/resources/widgets.js +31 -0
  31. package/dist/cjs/anyspend/platform/types.d.ts +478 -0
  32. package/dist/cjs/anyspend/platform/types.js +5 -0
  33. package/dist/cjs/anyspend/platform/utils/idempotency.d.ts +4 -0
  34. package/dist/cjs/anyspend/platform/utils/idempotency.js +17 -0
  35. package/dist/cjs/anyspend/platform/utils/pagination.d.ts +12 -0
  36. package/dist/cjs/anyspend/platform/utils/pagination.js +22 -0
  37. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +5 -1
  38. package/dist/cjs/anyspend/react/components/AnySpend.js +123 -12
  39. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.d.ts +14 -6
  40. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.js +55 -8
  41. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckoutTrigger.d.ts +3 -1
  42. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckoutTrigger.js +2 -2
  43. package/dist/cjs/anyspend/react/components/checkout/CheckoutPaymentPanel.d.ts +5 -1
  44. package/dist/cjs/anyspend/react/components/checkout/CheckoutPaymentPanel.js +2 -2
  45. package/dist/cjs/anyspend/react/components/checkout/CryptoPayPanel.js +1 -1
  46. package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +5 -1
  47. package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.js +48 -16
  48. package/dist/cjs/anyspend/react/components/checkout/KycGate.d.ts +11 -0
  49. package/dist/cjs/anyspend/react/components/checkout/KycGate.js +203 -0
  50. package/dist/cjs/anyspend/react/components/checkout/VariablePricingInput.d.ts +17 -0
  51. package/dist/cjs/anyspend/react/components/checkout/VariablePricingInput.js +145 -0
  52. package/dist/cjs/anyspend/react/components/index.d.ts +1 -1
  53. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  54. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  55. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.d.ts +2 -0
  56. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +14 -0
  57. package/dist/cjs/anyspend/react/hooks/useKycStatus.d.ts +47 -0
  58. package/dist/cjs/anyspend/react/hooks/useKycStatus.js +124 -0
  59. package/dist/cjs/anyspend/services/anyspend.d.ts +4 -1
  60. package/dist/cjs/anyspend/services/anyspend.js +3 -1
  61. package/dist/cjs/global-account/react/components/B3DynamicModal.js +1 -1
  62. package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +3 -3
  63. package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +1 -1
  64. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +13 -5
  65. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -1
  66. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.d.ts +1 -1
  67. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +21 -24
  68. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +1 -1
  69. package/dist/cjs/global-account/react/hooks/useAuth.js +1 -1
  70. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +3 -1
  71. package/dist/cjs/global-account/react/hooks/useAuthentication.js +82 -24
  72. package/dist/cjs/global-account/react/hooks/useGetAllTWSigners.js +2 -1
  73. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +4 -0
  74. package/dist/cjs/global-account/react/stores/useModalStore.js +2 -0
  75. package/dist/cjs/global-account/react/utils/createWagmiConfig.d.ts +18 -0
  76. package/dist/cjs/global-account/react/utils/createWagmiConfig.js +17 -0
  77. package/dist/esm/anyspend/platform/client.d.ts +35 -0
  78. package/dist/esm/anyspend/platform/client.js +153 -0
  79. package/dist/esm/anyspend/platform/errors.d.ts +38 -0
  80. package/dist/esm/anyspend/platform/errors.js +67 -0
  81. package/dist/esm/anyspend/platform/index.d.ts +87 -0
  82. package/dist/esm/anyspend/platform/index.js +75 -0
  83. package/dist/esm/anyspend/platform/resources/analytics.d.ts +7 -0
  84. package/dist/esm/anyspend/platform/resources/analytics.js +8 -0
  85. package/dist/esm/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
  86. package/dist/esm/anyspend/platform/resources/checkout-sessions.js +23 -0
  87. package/dist/esm/anyspend/platform/resources/customers.d.ts +19 -0
  88. package/dist/esm/anyspend/platform/resources/customers.js +30 -0
  89. package/dist/esm/anyspend/platform/resources/discount-codes.d.ts +29 -0
  90. package/dist/esm/anyspend/platform/resources/discount-codes.js +27 -0
  91. package/dist/esm/anyspend/platform/resources/events.d.ts +14 -0
  92. package/dist/esm/anyspend/platform/resources/events.js +12 -0
  93. package/dist/esm/anyspend/platform/resources/notifications.d.ts +18 -0
  94. package/dist/esm/anyspend/platform/resources/notifications.js +23 -0
  95. package/dist/esm/anyspend/platform/resources/organization.d.ts +17 -0
  96. package/dist/esm/anyspend/platform/resources/organization.js +11 -0
  97. package/dist/esm/anyspend/platform/resources/payment-links.d.ts +21 -0
  98. package/dist/esm/anyspend/platform/resources/payment-links.js +45 -0
  99. package/dist/esm/anyspend/platform/resources/products.d.ts +27 -0
  100. package/dist/esm/anyspend/platform/resources/products.js +27 -0
  101. package/dist/esm/anyspend/platform/resources/transactions.d.ts +11 -0
  102. package/dist/esm/anyspend/platform/resources/transactions.js +21 -0
  103. package/dist/esm/anyspend/platform/resources/webhooks.d.ts +14 -0
  104. package/dist/esm/anyspend/platform/resources/webhooks.js +29 -0
  105. package/dist/esm/anyspend/platform/resources/widgets.d.ts +38 -0
  106. package/dist/esm/anyspend/platform/resources/widgets.js +27 -0
  107. package/dist/esm/anyspend/platform/types.d.ts +478 -0
  108. package/dist/esm/anyspend/platform/types.js +4 -0
  109. package/dist/esm/anyspend/platform/utils/idempotency.d.ts +4 -0
  110. package/dist/esm/anyspend/platform/utils/idempotency.js +14 -0
  111. package/dist/esm/anyspend/platform/utils/pagination.d.ts +12 -0
  112. package/dist/esm/anyspend/platform/utils/pagination.js +19 -0
  113. package/dist/esm/anyspend/react/components/AnySpend.d.ts +5 -1
  114. package/dist/esm/anyspend/react/components/AnySpend.js +124 -13
  115. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.d.ts +14 -6
  116. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.js +55 -8
  117. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckoutTrigger.d.ts +3 -1
  118. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckoutTrigger.js +2 -2
  119. package/dist/esm/anyspend/react/components/checkout/CheckoutPaymentPanel.d.ts +5 -1
  120. package/dist/esm/anyspend/react/components/checkout/CheckoutPaymentPanel.js +2 -2
  121. package/dist/esm/anyspend/react/components/checkout/CryptoPayPanel.js +1 -1
  122. package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +5 -1
  123. package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.js +50 -18
  124. package/dist/esm/anyspend/react/components/checkout/KycGate.d.ts +11 -0
  125. package/dist/esm/anyspend/react/components/checkout/KycGate.js +167 -0
  126. package/dist/esm/anyspend/react/components/checkout/VariablePricingInput.d.ts +17 -0
  127. package/dist/esm/anyspend/react/components/checkout/VariablePricingInput.js +142 -0
  128. package/dist/esm/anyspend/react/components/index.d.ts +1 -1
  129. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  130. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  131. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.d.ts +2 -0
  132. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +14 -0
  133. package/dist/esm/anyspend/react/hooks/useKycStatus.d.ts +47 -0
  134. package/dist/esm/anyspend/react/hooks/useKycStatus.js +117 -0
  135. package/dist/esm/anyspend/services/anyspend.d.ts +4 -1
  136. package/dist/esm/anyspend/services/anyspend.js +3 -1
  137. package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -1
  138. package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +3 -3
  139. package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +1 -1
  140. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +13 -5
  141. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +1 -1
  142. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.d.ts +1 -1
  143. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +21 -24
  144. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +1 -1
  145. package/dist/esm/global-account/react/hooks/useAuth.js +2 -2
  146. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +3 -1
  147. package/dist/esm/global-account/react/hooks/useAuthentication.js +82 -24
  148. package/dist/esm/global-account/react/hooks/useGetAllTWSigners.js +2 -1
  149. package/dist/esm/global-account/react/stores/useModalStore.d.ts +4 -0
  150. package/dist/esm/global-account/react/stores/useModalStore.js +2 -0
  151. package/dist/esm/global-account/react/utils/createWagmiConfig.d.ts +18 -0
  152. package/dist/esm/global-account/react/utils/createWagmiConfig.js +16 -0
  153. package/dist/styles/index.css +1 -1
  154. package/dist/types/anyspend/platform/client.d.ts +35 -0
  155. package/dist/types/anyspend/platform/errors.d.ts +38 -0
  156. package/dist/types/anyspend/platform/index.d.ts +87 -0
  157. package/dist/types/anyspend/platform/resources/analytics.d.ts +7 -0
  158. package/dist/types/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
  159. package/dist/types/anyspend/platform/resources/customers.d.ts +19 -0
  160. package/dist/types/anyspend/platform/resources/discount-codes.d.ts +29 -0
  161. package/dist/types/anyspend/platform/resources/events.d.ts +14 -0
  162. package/dist/types/anyspend/platform/resources/notifications.d.ts +18 -0
  163. package/dist/types/anyspend/platform/resources/organization.d.ts +17 -0
  164. package/dist/types/anyspend/platform/resources/payment-links.d.ts +21 -0
  165. package/dist/types/anyspend/platform/resources/products.d.ts +27 -0
  166. package/dist/types/anyspend/platform/resources/transactions.d.ts +11 -0
  167. package/dist/types/anyspend/platform/resources/webhooks.d.ts +14 -0
  168. package/dist/types/anyspend/platform/resources/widgets.d.ts +38 -0
  169. package/dist/types/anyspend/platform/types.d.ts +478 -0
  170. package/dist/types/anyspend/platform/utils/idempotency.d.ts +4 -0
  171. package/dist/types/anyspend/platform/utils/pagination.d.ts +12 -0
  172. package/dist/types/anyspend/react/components/AnySpend.d.ts +5 -1
  173. package/dist/types/anyspend/react/components/checkout/AnySpendCheckout.d.ts +14 -6
  174. package/dist/types/anyspend/react/components/checkout/AnySpendCheckoutTrigger.d.ts +3 -1
  175. package/dist/types/anyspend/react/components/checkout/CheckoutPaymentPanel.d.ts +5 -1
  176. package/dist/types/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +5 -1
  177. package/dist/types/anyspend/react/components/checkout/KycGate.d.ts +11 -0
  178. package/dist/types/anyspend/react/components/checkout/VariablePricingInput.d.ts +17 -0
  179. package/dist/types/anyspend/react/components/index.d.ts +1 -1
  180. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  181. package/dist/types/anyspend/react/hooks/useAnyspendCreateOnrampOrder.d.ts +2 -0
  182. package/dist/types/anyspend/react/hooks/useKycStatus.d.ts +47 -0
  183. package/dist/types/anyspend/services/anyspend.d.ts +4 -1
  184. package/dist/types/global-account/react/components/SignInWithB3/steps/LoginStep.d.ts +1 -1
  185. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +3 -1
  186. package/dist/types/global-account/react/stores/useModalStore.d.ts +4 -0
  187. package/dist/types/global-account/react/utils/createWagmiConfig.d.ts +18 -0
  188. package/package.json +7 -1
  189. package/src/anyspend/docs/checkout-sessions.md +20 -3
  190. package/src/anyspend/platform/client.ts +198 -0
  191. package/src/anyspend/platform/errors.ts +92 -0
  192. package/src/anyspend/platform/index.ts +129 -0
  193. package/src/anyspend/platform/resources/analytics.ts +10 -0
  194. package/src/anyspend/platform/resources/checkout-sessions.ts +36 -0
  195. package/src/anyspend/platform/resources/customers.ts +54 -0
  196. package/src/anyspend/platform/resources/discount-codes.ts +63 -0
  197. package/src/anyspend/platform/resources/events.ts +22 -0
  198. package/src/anyspend/platform/resources/notifications.ts +37 -0
  199. package/src/anyspend/platform/resources/organization.ts +24 -0
  200. package/src/anyspend/platform/resources/payment-links.ts +74 -0
  201. package/src/anyspend/platform/resources/products.ts +59 -0
  202. package/src/anyspend/platform/resources/transactions.ts +33 -0
  203. package/src/anyspend/platform/resources/webhooks.ts +47 -0
  204. package/src/anyspend/platform/resources/widgets.ts +63 -0
  205. package/src/anyspend/platform/types.ts +532 -0
  206. package/src/anyspend/platform/utils/idempotency.ts +15 -0
  207. package/src/anyspend/platform/utils/pagination.ts +32 -0
  208. package/src/anyspend/react/components/AnySpend.tsx +148 -14
  209. package/src/anyspend/react/components/checkout/AnySpendCheckout.tsx +81 -18
  210. package/src/anyspend/react/components/checkout/AnySpendCheckoutTrigger.tsx +4 -0
  211. package/src/anyspend/react/components/checkout/CheckoutPaymentPanel.tsx +8 -0
  212. package/src/anyspend/react/components/checkout/CryptoPayPanel.tsx +4 -13
  213. package/src/anyspend/react/components/checkout/FiatCheckoutPanel.tsx +86 -17
  214. package/src/anyspend/react/components/checkout/KycGate.tsx +387 -0
  215. package/src/anyspend/react/components/checkout/VariablePricingInput.tsx +247 -0
  216. package/src/anyspend/react/components/index.ts +1 -0
  217. package/src/anyspend/react/hooks/index.ts +1 -0
  218. package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +17 -0
  219. package/src/anyspend/react/hooks/useKycStatus.ts +150 -0
  220. package/src/anyspend/services/anyspend.ts +7 -0
  221. package/src/global-account/react/components/B3DynamicModal.tsx +0 -2
  222. package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +7 -7
  223. package/src/global-account/react/components/SignInWithB3/SignIn.tsx +1 -1
  224. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +13 -5
  225. package/src/global-account/react/components/SignInWithB3/SignInWithB3Privy.tsx +1 -1
  226. package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +35 -25
  227. package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +1 -1
  228. package/src/global-account/react/hooks/useAuth.ts +2 -2
  229. package/src/global-account/react/hooks/useAuthentication.ts +80 -27
  230. package/src/global-account/react/hooks/useGetAllTWSigners.tsx +2 -1
  231. package/src/global-account/react/stores/useModalStore.ts +6 -0
  232. package/src/global-account/react/utils/createWagmiConfig.tsx +18 -0
@@ -3,6 +3,7 @@ import { ecosystemWalletId } from "@b3dotfun/sdk/shared/constants";
3
3
  import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
4
4
  import { Chain } from "thirdweb";
5
5
  import { ConnectEmbed, darkTheme, lightTheme } from "thirdweb/react";
6
+ import { useMemo } from "react";
6
7
  import { Account, ecosystemWallet, SingleStepAuthArgsType } from "thirdweb/wallets";
7
8
  /**
8
9
  * Props for the LoginStep component
@@ -49,42 +50,40 @@ export function LoginStepContainer({ children, partnerId }: LoginStepContainerPr
49
50
  );
50
51
  }
51
52
 
52
- export function LoginStep({ onSuccess, chain }: LoginStepProps) {
53
- const { partnerId, theme } = useB3Config();
54
- const wallet = ecosystemWallet(ecosystemWalletId, {
55
- partnerId: partnerId,
56
- });
57
- const { onConnect } = useAuthentication(partnerId);
53
+ /** Inner component that only mounts when partnerId is a non-empty string.
54
+ * Keeps all hooks unconditional without calling useAuthentication(""). */
55
+ function LoginStepContent({
56
+ onSuccess,
57
+ chain,
58
+ partnerId,
59
+ theme,
60
+ }: {
61
+ onSuccess: (account: Account) => Promise<void>;
62
+ chain: Chain;
63
+ partnerId: string;
64
+ theme: string;
65
+ }) {
66
+ const wallet = useMemo(() => ecosystemWallet(ecosystemWalletId, { partnerId }), [partnerId]);
67
+ // skipAutoConnect: AuthenticationProvider already owns the auto-connect instance.
68
+ // Creating another here would cause a second authentication cycle (another 401 attempt)
69
+ // that makes the modal flash between spinner and blank before finally showing the login form.
70
+ const { onConnect } = useAuthentication(partnerId, { skipAutoConnect: true });
58
71
 
59
72
  return (
60
73
  <LoginStepContainer partnerId={partnerId}>
61
74
  <ConnectEmbed
62
75
  showThirdwebBranding={false}
76
+ autoConnect={false}
63
77
  client={client}
64
78
  chain={chain}
65
79
  wallets={[wallet]}
66
80
  theme={
67
81
  theme === "light"
68
- ? lightTheme({
69
- colors: {
70
- modalBg: "hsl(var(--b3-react-background))",
71
- },
72
- })
73
- : darkTheme({
74
- colors: {
75
- modalBg: "hsl(var(--b3-react-background))",
76
- },
77
- })
82
+ ? lightTheme({ colors: { modalBg: "hsl(var(--b3-react-background))" } })
83
+ : darkTheme({ colors: { modalBg: "hsl(var(--b3-react-background))" } })
78
84
  }
79
- style={{
80
- width: "100%",
81
- height: "100%",
82
- border: 0,
83
- }}
84
- header={{
85
- title: "Sign in with B3",
86
- titleIcon: "https://cdn.b3.fun/b3_logo.svg",
87
- }}
85
+ style={{ width: "100%", height: "100%", border: 0 }}
86
+ header={{ title: "Sign in with B3", titleIcon: "https://cdn.b3.fun/b3_logo.svg" }}
88
87
  className="b3-login-step"
89
88
  onConnect={async (wallet, allConnectedWallets) => {
90
89
  await onConnect(wallet, allConnectedWallets);
@@ -96,3 +95,14 @@ export function LoginStep({ onSuccess, chain }: LoginStepProps) {
96
95
  </LoginStepContainer>
97
96
  );
98
97
  }
98
+
99
+ export function LoginStep({ onSuccess, chain }: LoginStepProps) {
100
+ const { partnerId, theme } = useB3Config();
101
+
102
+ // partnerId may be undefined during the brief B3Provider hydration window.
103
+ // Return null rather than rendering ConnectEmbed with an invalid ecosystem
104
+ // wallet config (which causes a blank screen).
105
+ if (!partnerId) return null;
106
+
107
+ return <LoginStepContent onSuccess={onSuccess} chain={chain} partnerId={partnerId} theme={theme} />;
108
+ }
@@ -43,7 +43,7 @@ export function LoginStepCustom({
43
43
  const { connect } = useConnect(partnerId, chain);
44
44
  const setIsAuthenticating = useAuthStore(state => state.setIsAuthenticating);
45
45
  const setIsAuthenticated = useAuthStore(state => state.setIsAuthenticated);
46
- const { logout } = useAuthentication(partnerId);
46
+ const { logout } = useAuthentication(partnerId, { skipAutoConnect: true });
47
47
  const { connect: connectTW } = useConnectTW();
48
48
 
49
49
  // Split strategies into auth and wallet types
@@ -18,7 +18,7 @@ import { Wallet, ecosystemWallet } from "thirdweb/wallets";
18
18
  import { preAuthenticate } from "thirdweb/wallets/in-app";
19
19
  import { useAccount, useConnect, useSwitchAccount } from "wagmi";
20
20
  import { LocalSDKContext } from "../components/B3Provider/LocalSDKProvider";
21
- import { createWagmiConfig } from "../utils/createWagmiConfig";
21
+ import { getCachedWagmiConfig } from "../utils/createWagmiConfig";
22
22
  import { useSearchParam } from "./useSearchParamsSSR";
23
23
  import { useUserQuery } from "./useUserQuery";
24
24
 
@@ -47,7 +47,7 @@ export function useAuth() {
47
47
  const useAutoConnectLoadingPrevious = useRef(false);
48
48
  const referralCode = useSearchParam("referralCode");
49
49
  const { partnerId } = useB3Config();
50
- const wagmiConfig = createWagmiConfig({ partnerId });
50
+ const wagmiConfig = getCachedWagmiConfig({ partnerId });
51
51
  const { connect } = useConnect();
52
52
  const activeWagmiAccount = useAccount();
53
53
  const { switchAccount } = useSwitchAccount();
@@ -24,11 +24,26 @@ import { useUserQuery } from "./useUserQuery";
24
24
 
25
25
  const debug = debugB3React("useAuthentication");
26
26
 
27
- export function useAuthentication(partnerId: string) {
27
+ export function useAuthentication(partnerId: string, { skipAutoConnect = false }: { skipAutoConnect?: boolean } = {}) {
28
28
  const { onConnectCallback, onLogoutCallback } = useContext(LocalSDKContext);
29
29
  const { disconnect } = useDisconnect();
30
30
  const wallets = useConnectedWallets();
31
+ // Keep refs so logout() always disconnects current wallets, not stale closure values.
32
+ // autoConnectCore captures onConnect (and thus logout) from the first render before wallets
33
+ // are populated — without these refs, logout() would capture wallets=[] and disconnect nothing.
34
+ const walletsRef = useRef(wallets);
35
+ useEffect(() => {
36
+ walletsRef.current = wallets;
37
+ }, [wallets]);
31
38
  const activeWallet = useActiveWallet();
39
+ // Track the active wallet by ref so logout() can disconnect the exact reference
40
+ // stored in thirdweb's activeWalletStore. walletsRef.current (from useConnectedWallets)
41
+ // may hold a different object reference than what thirdweb considers "active",
42
+ // causing the identity check in onWalletDisconnect to fail silently.
43
+ const activeWalletRef = useRef(activeWallet);
44
+ useEffect(() => {
45
+ activeWalletRef.current = activeWallet;
46
+ }, [activeWallet]);
32
47
  const isAuthenticated = useAuthStore(state => state.isAuthenticated);
33
48
  const setIsAuthenticated = useAuthStore(state => state.setIsAuthenticated);
34
49
  const setIsConnected = useAuthStore(state => state.setIsConnected);
@@ -153,23 +168,31 @@ export function useAuthentication(partnerId: string) {
153
168
 
154
169
  const logout = useCallback(
155
170
  async (callback?: () => void) => {
156
- if (activeWallet) {
157
- debug("@@logout:activeWallet", activeWallet);
158
- disconnect(activeWallet);
159
- debug("@@logout:activeWallet", activeWallet);
160
- }
161
-
162
- // Log out of each wallet
163
- wallets.forEach(wallet => {
164
- console.log("@@logging out", wallet);
165
- disconnect(wallet);
171
+ // Only disconnect ecosystem/smart wallets, preserve EOA wallets (e.g. MetaMask)
172
+ // so they remain available after re-login.
173
+ // Use walletsRef.current (not the stale closure value) so we always get current wallets —
174
+ // autoConnectCore captures logout from the first render when wallets is still [].
175
+ walletsRef.current.forEach(wallet => {
176
+ debug("@@logout:wallet", wallet.id);
177
+ if (wallet.id.startsWith("ecosystem.") || wallet.id === "smart") {
178
+ disconnect(wallet);
179
+ }
166
180
  });
167
181
 
168
- // Delete localStorage thirdweb:connected-wallet-ids
169
- // https://npc-labs.slack.com/archives/C070E6HNG85/p1750185115273099
182
+ // Always disconnect the active wallet to clear thirdweb's activeAccountStore.
183
+ // Without this, any auto-reconnected wallet (e.g. Coinbase Wallet, MetaMask)
184
+ // keeps activeAccount set, and ConnectEmbed renders show=false (blank modal).
185
+ // We use the exact reference from activeWalletRef because thirdweb's
186
+ // onWalletDisconnect uses strict identity (===) to decide whether to clear
187
+ // activeAccountStore.
188
+ if (activeWalletRef.current) {
189
+ debug("@@logout:disconnecting active wallet", activeWalletRef.current.id);
190
+ disconnect(activeWalletRef.current);
191
+ }
192
+
193
+ // Clear user-specific storage but preserve wallet connection state
194
+ // so EOA wallets (e.g. MetaMask) can auto-reconnect on next login
170
195
  if (typeof localStorage !== "undefined") {
171
- localStorage.removeItem("thirdweb:connected-wallet-ids");
172
- localStorage.removeItem("wagmi.store");
173
196
  localStorage.removeItem("lastAuthProvider");
174
197
  localStorage.removeItem("b3-user");
175
198
  }
@@ -179,6 +202,9 @@ export function useAuthentication(partnerId: string) {
179
202
 
180
203
  setIsAuthenticated(false);
181
204
  setIsConnected(false);
205
+ // Reset isAuthenticating so any in-flight page-load auto-connect that set it true
206
+ // does not keep the login modal spinner stuck after logout() is called.
207
+ setIsAuthenticating(false);
182
208
  setUser();
183
209
  callback?.();
184
210
 
@@ -186,34 +212,53 @@ export function useAuthentication(partnerId: string) {
186
212
  await onLogoutCallback();
187
213
  }
188
214
  },
189
- [activeWallet, disconnect, wallets, setIsAuthenticated, setUser, setIsConnected, onLogoutCallback],
215
+ // wallets intentionally omitted we use walletsRef.current so this callback stays stable
216
+ // and always operates on current wallets even when captured in stale closures.
217
+ // eslint-disable-next-line react-hooks/exhaustive-deps
218
+ [disconnect, setIsAuthenticated, setIsAuthenticating, setUser, setIsConnected, onLogoutCallback],
190
219
  );
191
220
 
192
221
  const onConnect = useCallback(
193
222
  async (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => {
194
223
  debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
224
+ const ecosystemWalletToDisconnect = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
195
225
  try {
196
- const wallet = allConnectedWallets.find(wallet => wallet.id.startsWith("ecosystem."));
197
-
198
- if (!wallet) {
226
+ if (!ecosystemWalletToDisconnect) {
199
227
  throw new Error("No smart wallet found during auto-connect");
200
228
  }
201
229
 
202
- debug("@@useAuthentication:onConnect", { wallet });
230
+ debug("@@useAuthentication:onConnect", { wallet: ecosystemWalletToDisconnect });
203
231
  setHasStartedConnecting(true);
204
232
  setIsConnected(true);
205
233
  setIsAuthenticating(true);
206
- await setActiveWallet(wallet);
207
- const userAuth = await authenticateUser(wallet);
234
+ await setActiveWallet(ecosystemWalletToDisconnect);
235
+ const userAuth = await authenticateUser(ecosystemWalletToDisconnect);
208
236
 
209
237
  if (userAuth && onConnectCallback) {
210
- await onConnectCallback(wallet, userAuth.accessToken);
238
+ await onConnectCallback(ecosystemWalletToDisconnect, userAuth.accessToken);
211
239
  }
212
240
  } catch (error) {
213
241
  debug("@@useAuthentication:onConnect:failed", { error });
214
242
  setIsAuthenticated(false);
215
243
  setUser(undefined);
216
-
244
+ // Directly disconnect the ecosystem wallet we set active above.
245
+ // We can't rely on logout()'s activeWalletRef here because it's updated
246
+ // via useEffect (deferred until after paint), but this callback may run
247
+ // entirely within a single React commit cycle — before the ref updates.
248
+ if (ecosystemWalletToDisconnect) {
249
+ debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", ecosystemWalletToDisconnect.id);
250
+ disconnect(ecosystemWalletToDisconnect);
251
+ }
252
+ // Also disconnect the wallet that autoConnectCore set as active.
253
+ // When only a non-ecosystem wallet (e.g. MetaMask) auto-reconnects,
254
+ // ecosystemWalletToDisconnect is undefined, so the block above is skipped.
255
+ // But autoConnectCore already set this wallet as thirdweb's activeWallet,
256
+ // leaving activeAccount set. ConnectEmbed checks show = !activeAccount,
257
+ // so if we don't clear it, the login form renders blank.
258
+ if (_walleAutoConnectedWith && _walleAutoConnectedWith !== ecosystemWalletToDisconnect) {
259
+ debug("@@useAuthentication:onConnect:disconnecting auto-connected wallet", _walleAutoConnectedWith.id);
260
+ disconnect(_walleAutoConnectedWith);
261
+ }
217
262
  await logout();
218
263
  } finally {
219
264
  setIsAuthenticating(false);
@@ -229,6 +274,7 @@ export function useAuthentication(partnerId: string) {
229
274
  isAuthenticated,
230
275
  isAuthenticating,
231
276
  isConnected,
277
+ disconnect,
232
278
  setHasStartedConnecting,
233
279
  setIsConnected,
234
280
  setIsAuthenticating,
@@ -243,9 +289,13 @@ export function useAuthentication(partnerId: string) {
243
289
 
244
290
  const { isLoading: useAutoConnectLoading } = useAutoConnect({
245
291
  client,
246
- wallets: [wallet],
292
+ // When skipAutoConnect is true (e.g. LoginStepContent, SignInWithB3Flow), pass an empty
293
+ // wallets array so useAutoConnect completes immediately without firing onConnect.
294
+ // Only AuthenticationProvider (the primary instance) should own auto-connect.
295
+ wallets: skipAutoConnect ? [] : [wallet],
247
296
  onConnect,
248
297
  onTimeout: () => {
298
+ if (skipAutoConnect) return;
249
299
  logout().catch(error => {
250
300
  debug("@@useAuthentication:logout on timeout failed", { error });
251
301
  });
@@ -253,14 +303,17 @@ export function useAuthentication(partnerId: string) {
253
303
  });
254
304
 
255
305
  /**
256
- * useAutoConnectLoading starts as false
306
+ * useAutoConnectLoading starts as false.
307
+ * Only the primary (non-skip) instance manages isAuthenticating via this effect
308
+ * to avoid race conditions when multiple useAuthentication instances are mounted.
257
309
  */
258
310
  useEffect(() => {
311
+ if (skipAutoConnect) return;
259
312
  if (!useAutoConnectLoading && useAutoConnectLoadingPrevious.current && !hasStartedConnecting) {
260
313
  setIsAuthenticating(false);
261
314
  }
262
315
  useAutoConnectLoadingPrevious.current = useAutoConnectLoading;
263
- }, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating]);
316
+ }, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating, skipAutoConnect]);
264
317
 
265
318
  const isReady = isAuthenticated && !isAuthenticating;
266
319
 
@@ -130,7 +130,8 @@ export function useGetAllTWSigners({ chain, accountAddress, queryOptions }: UseG
130
130
  });
131
131
  return result;
132
132
  },
133
- enabled: Boolean(chain && accountAddress),
133
+ // Respect queryOptions.enabled if explicitly set (e.g. signersEnabled=false from SignInWithB3Flow)
134
+ enabled: queryOptions?.enabled !== false && Boolean(chain && accountAddress),
134
135
  refetchOnMount: true,
135
136
  refetchOnWindowFocus: true,
136
137
  refetchOnReconnect: true,
@@ -712,6 +712,10 @@ interface ModalState {
712
712
  setLinkingState: (isLinking: boolean, method?: string | null) => void;
713
713
  /** Function to update closable property of current content without adding to history */
714
714
  setClosable: (closable: boolean) => void;
715
+ /** Whether a third-party iframe (e.g. Persona KYC) is currently active over the modal */
716
+ personaActive: boolean;
717
+ /** Function to mark a third-party iframe as active/inactive */
718
+ setPersonaActive: (active: boolean) => void;
715
719
  }
716
720
 
717
721
  /**
@@ -755,4 +759,6 @@ export const useModalStore = create<ModalState>(set => ({
755
759
  set(state => ({
756
760
  contentType: state.contentType ? { ...state.contentType, closable } : null,
757
761
  })),
762
+ personaActive: false,
763
+ setPersonaActive: (active: boolean) => set({ personaActive: active }),
758
764
  }));
@@ -38,3 +38,21 @@ export function createWagmiConfig(options: CreateWagmiConfigOptions) {
38
38
  connectors: finalConnectors,
39
39
  });
40
40
  }
41
+
42
+ /** Module-level cache — wagmi configs must not be recreated on every render. */
43
+ const wagmiConfigCache = new Map<string, ReturnType<typeof createWagmiConfig>>();
44
+
45
+ /**
46
+ * Returns a cached wagmi config for the given partnerId.
47
+ * Use this instead of calling createWagmiConfig() directly inside React components or hooks
48
+ * to avoid registering duplicate EventEmitter listeners on every render.
49
+ */
50
+ export function getCachedWagmiConfig(options: CreateWagmiConfigOptions) {
51
+ const key = options.partnerId;
52
+ let config = wagmiConfigCache.get(key);
53
+ if (!config) {
54
+ config = createWagmiConfig(options);
55
+ wagmiConfigCache.set(key, config);
56
+ }
57
+ return config;
58
+ }