@0xkey-io/react-wallet-kit 0.1.0

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 (326) hide show
  1. package/LICENSE +201 -0
  2. package/README.MD +116 -0
  3. package/dist/_virtual/_rollupPluginBabelHelpers.mjs +307 -0
  4. package/dist/_virtual/_rollupPluginBabelHelpers.mjs.map +1 -0
  5. package/dist/components/auth/Action.d.ts +10 -0
  6. package/dist/components/auth/Action.d.ts.map +1 -0
  7. package/dist/components/auth/Action.js +76 -0
  8. package/dist/components/auth/Action.js.map +1 -0
  9. package/dist/components/auth/Action.mjs +97 -0
  10. package/dist/components/auth/Action.mjs.map +1 -0
  11. package/dist/components/auth/Email.d.ts +6 -0
  12. package/dist/components/auth/Email.d.ts.map +1 -0
  13. package/dist/components/auth/Email.js +77 -0
  14. package/dist/components/auth/Email.js.map +1 -0
  15. package/dist/components/auth/Email.mjs +98 -0
  16. package/dist/components/auth/Email.mjs.map +1 -0
  17. package/dist/components/auth/OAuth.d.ts +13 -0
  18. package/dist/components/auth/OAuth.d.ts.map +1 -0
  19. package/dist/components/auth/OAuth.js +63 -0
  20. package/dist/components/auth/OAuth.js.map +1 -0
  21. package/dist/components/auth/OAuth.mjs +68 -0
  22. package/dist/components/auth/OAuth.mjs.map +1 -0
  23. package/dist/components/auth/OTP.d.ts +21 -0
  24. package/dist/components/auth/OTP.d.ts.map +1 -0
  25. package/dist/components/auth/OTP.js +218 -0
  26. package/dist/components/auth/OTP.js.map +1 -0
  27. package/dist/components/auth/OTP.mjs +301 -0
  28. package/dist/components/auth/OTP.mjs.map +1 -0
  29. package/dist/components/auth/OrSeparator.d.ts +2 -0
  30. package/dist/components/auth/OrSeparator.d.ts.map +1 -0
  31. package/dist/components/auth/OrSeparator.js +20 -0
  32. package/dist/components/auth/OrSeparator.js.map +1 -0
  33. package/dist/components/auth/OrSeparator.mjs +18 -0
  34. package/dist/components/auth/OrSeparator.mjs.map +1 -0
  35. package/dist/components/auth/Passkey.d.ts +7 -0
  36. package/dist/components/auth/Passkey.d.ts.map +1 -0
  37. package/dist/components/auth/Passkey.js +34 -0
  38. package/dist/components/auth/Passkey.js.map +1 -0
  39. package/dist/components/auth/Passkey.mjs +30 -0
  40. package/dist/components/auth/Passkey.mjs.map +1 -0
  41. package/dist/components/auth/Phone.d.ts +6 -0
  42. package/dist/components/auth/Phone.d.ts.map +1 -0
  43. package/dist/components/auth/Phone.js +67 -0
  44. package/dist/components/auth/Phone.js.map +1 -0
  45. package/dist/components/auth/Phone.mjs +92 -0
  46. package/dist/components/auth/Phone.mjs.map +1 -0
  47. package/dist/components/auth/Wallet.d.ts +34 -0
  48. package/dist/components/auth/Wallet.d.ts.map +1 -0
  49. package/dist/components/auth/Wallet.js +517 -0
  50. package/dist/components/auth/Wallet.js.map +1 -0
  51. package/dist/components/auth/Wallet.mjs +618 -0
  52. package/dist/components/auth/Wallet.mjs.map +1 -0
  53. package/dist/components/auth/index.d.ts +9 -0
  54. package/dist/components/auth/index.d.ts.map +1 -0
  55. package/dist/components/auth/index.js +457 -0
  56. package/dist/components/auth/index.js.map +1 -0
  57. package/dist/components/auth/index.mjs +672 -0
  58. package/dist/components/auth/index.mjs.map +1 -0
  59. package/dist/components/design/Buttons.d.ts +29 -0
  60. package/dist/components/design/Buttons.d.ts.map +1 -0
  61. package/dist/components/design/Buttons.js +87 -0
  62. package/dist/components/design/Buttons.js.map +1 -0
  63. package/dist/components/design/Buttons.mjs +79 -0
  64. package/dist/components/design/Buttons.mjs.map +1 -0
  65. package/dist/components/design/Failure.d.ts +9 -0
  66. package/dist/components/design/Failure.d.ts.map +1 -0
  67. package/dist/components/design/Failure.js +33 -0
  68. package/dist/components/design/Failure.js.map +1 -0
  69. package/dist/components/design/Failure.mjs +34 -0
  70. package/dist/components/design/Failure.mjs.map +1 -0
  71. package/dist/components/design/Inputs.d.ts +9 -0
  72. package/dist/components/design/Inputs.d.ts.map +1 -0
  73. package/dist/components/design/Inputs.js +135 -0
  74. package/dist/components/design/Inputs.js.map +1 -0
  75. package/dist/components/design/Inputs.mjs +133 -0
  76. package/dist/components/design/Inputs.mjs.map +1 -0
  77. package/dist/components/design/Lottie/Dynamic.d.ts +2 -0
  78. package/dist/components/design/Lottie/Dynamic.d.ts.map +1 -0
  79. package/dist/components/design/Lottie/Dynamic.js +9 -0
  80. package/dist/components/design/Lottie/Dynamic.js.map +1 -0
  81. package/dist/components/design/Lottie/Dynamic.mjs +24 -0
  82. package/dist/components/design/Lottie/Dynamic.mjs.map +1 -0
  83. package/dist/components/design/Lottie/Wrapper.d.ts +8 -0
  84. package/dist/components/design/Lottie/Wrapper.d.ts.map +1 -0
  85. package/dist/components/design/Lottie/Wrapper.js +26 -0
  86. package/dist/components/design/Lottie/Wrapper.js.map +1 -0
  87. package/dist/components/design/Lottie/Wrapper.mjs +42 -0
  88. package/dist/components/design/Lottie/Wrapper.mjs.map +1 -0
  89. package/dist/components/design/Spinners.d.ts +9 -0
  90. package/dist/components/design/Spinners.d.ts.map +1 -0
  91. package/dist/components/design/Spinners.js +38 -0
  92. package/dist/components/design/Spinners.js.map +1 -0
  93. package/dist/components/design/Spinners.mjs +37 -0
  94. package/dist/components/design/Spinners.mjs.map +1 -0
  95. package/dist/components/design/Success.d.ts +8 -0
  96. package/dist/components/design/Success.d.ts.map +1 -0
  97. package/dist/components/design/Success.js +82 -0
  98. package/dist/components/design/Success.js.map +1 -0
  99. package/dist/components/design/Success.mjs +86 -0
  100. package/dist/components/design/Success.mjs.map +1 -0
  101. package/dist/components/design/Svg.d.ts +13 -0
  102. package/dist/components/design/Svg.d.ts.map +1 -0
  103. package/dist/components/design/Svg.js +165 -0
  104. package/dist/components/design/Svg.js.map +1 -0
  105. package/dist/components/design/Svg.mjs +161 -0
  106. package/dist/components/design/Svg.mjs.map +1 -0
  107. package/dist/components/export/Export.d.ts +13 -0
  108. package/dist/components/export/Export.d.ts.map +1 -0
  109. package/dist/components/export/Export.js +169 -0
  110. package/dist/components/export/Export.js.map +1 -0
  111. package/dist/components/export/Export.mjs +213 -0
  112. package/dist/components/export/Export.mjs.map +1 -0
  113. package/dist/components/export/ExportWarning.d.ts +15 -0
  114. package/dist/components/export/ExportWarning.d.ts.map +1 -0
  115. package/dist/components/export/ExportWarning.js +141 -0
  116. package/dist/components/export/ExportWarning.js.map +1 -0
  117. package/dist/components/export/ExportWarning.mjs +174 -0
  118. package/dist/components/export/ExportWarning.mjs.map +1 -0
  119. package/dist/components/import/Import.d.ts +20 -0
  120. package/dist/components/import/Import.d.ts.map +1 -0
  121. package/dist/components/import/Import.js +290 -0
  122. package/dist/components/import/Import.js.map +1 -0
  123. package/dist/components/import/Import.mjs +422 -0
  124. package/dist/components/import/Import.mjs.map +1 -0
  125. package/dist/components/onramp/OnRamp.d.ts +14 -0
  126. package/dist/components/onramp/OnRamp.d.ts.map +1 -0
  127. package/dist/components/onramp/OnRamp.js +61 -0
  128. package/dist/components/onramp/OnRamp.js.map +1 -0
  129. package/dist/components/onramp/OnRamp.mjs +79 -0
  130. package/dist/components/onramp/OnRamp.mjs.map +1 -0
  131. package/dist/components/send-transaction/SendTransaction.d.ts +12 -0
  132. package/dist/components/send-transaction/SendTransaction.d.ts.map +1 -0
  133. package/dist/components/send-transaction/SendTransaction.js +65 -0
  134. package/dist/components/send-transaction/SendTransaction.js.map +1 -0
  135. package/dist/components/send-transaction/SendTransaction.mjs +89 -0
  136. package/dist/components/send-transaction/SendTransaction.mjs.map +1 -0
  137. package/dist/components/send-transaction/helpers.d.ts +4 -0
  138. package/dist/components/send-transaction/helpers.d.ts.map +1 -0
  139. package/dist/components/send-transaction/helpers.js +37 -0
  140. package/dist/components/send-transaction/helpers.js.map +1 -0
  141. package/dist/components/send-transaction/helpers.mjs +34 -0
  142. package/dist/components/send-transaction/helpers.mjs.map +1 -0
  143. package/dist/components/sign/Message.d.ts +18 -0
  144. package/dist/components/sign/Message.d.ts.map +1 -0
  145. package/dist/components/sign/Message.js +132 -0
  146. package/dist/components/sign/Message.js.map +1 -0
  147. package/dist/components/sign/Message.mjs +148 -0
  148. package/dist/components/sign/Message.mjs.map +1 -0
  149. package/dist/components/user/ConnectWallet.d.ts +8 -0
  150. package/dist/components/user/ConnectWallet.d.ts.map +1 -0
  151. package/dist/components/user/ConnectWallet.js +114 -0
  152. package/dist/components/user/ConnectWallet.js.map +1 -0
  153. package/dist/components/user/ConnectWallet.mjs +194 -0
  154. package/dist/components/user/ConnectWallet.mjs.map +1 -0
  155. package/dist/components/user/RemoveEmail.d.ts +12 -0
  156. package/dist/components/user/RemoveEmail.d.ts.map +1 -0
  157. package/dist/components/user/RemoveEmail.js +105 -0
  158. package/dist/components/user/RemoveEmail.js.map +1 -0
  159. package/dist/components/user/RemoveEmail.mjs +124 -0
  160. package/dist/components/user/RemoveEmail.mjs.map +1 -0
  161. package/dist/components/user/RemoveOAuthProvider.d.ts +12 -0
  162. package/dist/components/user/RemoveOAuthProvider.d.ts.map +1 -0
  163. package/dist/components/user/RemoveOAuthProvider.js +110 -0
  164. package/dist/components/user/RemoveOAuthProvider.js.map +1 -0
  165. package/dist/components/user/RemoveOAuthProvider.mjs +131 -0
  166. package/dist/components/user/RemoveOAuthProvider.mjs.map +1 -0
  167. package/dist/components/user/RemovePasskey.d.ts +12 -0
  168. package/dist/components/user/RemovePasskey.d.ts.map +1 -0
  169. package/dist/components/user/RemovePasskey.js +114 -0
  170. package/dist/components/user/RemovePasskey.js.map +1 -0
  171. package/dist/components/user/RemovePasskey.mjs +135 -0
  172. package/dist/components/user/RemovePasskey.mjs.map +1 -0
  173. package/dist/components/user/RemovePhoneNumber.d.ts +12 -0
  174. package/dist/components/user/RemovePhoneNumber.d.ts.map +1 -0
  175. package/dist/components/user/RemovePhoneNumber.js +105 -0
  176. package/dist/components/user/RemovePhoneNumber.js.map +1 -0
  177. package/dist/components/user/RemovePhoneNumber.mjs +124 -0
  178. package/dist/components/user/RemovePhoneNumber.mjs.map +1 -0
  179. package/dist/components/user/UpdateEmail.d.ts +12 -0
  180. package/dist/components/user/UpdateEmail.d.ts.map +1 -0
  181. package/dist/components/user/UpdateEmail.js +154 -0
  182. package/dist/components/user/UpdateEmail.js.map +1 -0
  183. package/dist/components/user/UpdateEmail.mjs +197 -0
  184. package/dist/components/user/UpdateEmail.mjs.map +1 -0
  185. package/dist/components/user/UpdatePhoneNumber.d.ts +12 -0
  186. package/dist/components/user/UpdatePhoneNumber.d.ts.map +1 -0
  187. package/dist/components/user/UpdatePhoneNumber.js +151 -0
  188. package/dist/components/user/UpdatePhoneNumber.js.map +1 -0
  189. package/dist/components/user/UpdatePhoneNumber.mjs +198 -0
  190. package/dist/components/user/UpdatePhoneNumber.mjs.map +1 -0
  191. package/dist/components/user/UpdateUserName.d.ts +13 -0
  192. package/dist/components/user/UpdateUserName.d.ts.map +1 -0
  193. package/dist/components/user/UpdateUserName.js +113 -0
  194. package/dist/components/user/UpdateUserName.js.map +1 -0
  195. package/dist/components/user/UpdateUserName.mjs +139 -0
  196. package/dist/components/user/UpdateUserName.mjs.map +1 -0
  197. package/dist/components/verify/Verify.d.ts +9 -0
  198. package/dist/components/verify/Verify.d.ts.map +1 -0
  199. package/dist/components/verify/Verify.js +121 -0
  200. package/dist/components/verify/Verify.js.map +1 -0
  201. package/dist/components/verify/Verify.mjs +149 -0
  202. package/dist/components/verify/Verify.mjs.map +1 -0
  203. package/dist/index.d.ts +25 -0
  204. package/dist/index.d.ts.map +1 -0
  205. package/dist/index.js +74 -0
  206. package/dist/index.js.map +1 -0
  207. package/dist/index.mjs +8 -0
  208. package/dist/index.mjs.map +1 -0
  209. package/dist/providers/ZeroXKeyProvider.d.ts +9 -0
  210. package/dist/providers/ZeroXKeyProvider.d.ts.map +1 -0
  211. package/dist/providers/ZeroXKeyProvider.js +36 -0
  212. package/dist/providers/ZeroXKeyProvider.js.map +1 -0
  213. package/dist/providers/ZeroXKeyProvider.mjs +34 -0
  214. package/dist/providers/ZeroXKeyProvider.mjs.map +1 -0
  215. package/dist/providers/client/Hook.d.ts +4 -0
  216. package/dist/providers/client/Hook.d.ts.map +1 -0
  217. package/dist/providers/client/Hook.js +15 -0
  218. package/dist/providers/client/Hook.js.map +1 -0
  219. package/dist/providers/client/Hook.mjs +13 -0
  220. package/dist/providers/client/Hook.mjs.map +1 -0
  221. package/dist/providers/client/Provider.d.ts +39 -0
  222. package/dist/providers/client/Provider.d.ts.map +1 -0
  223. package/dist/providers/client/Provider.js +3934 -0
  224. package/dist/providers/client/Provider.js.map +1 -0
  225. package/dist/providers/client/Provider.mjs +6895 -0
  226. package/dist/providers/client/Provider.mjs.map +1 -0
  227. package/dist/providers/client/Types.d.ts +711 -0
  228. package/dist/providers/client/Types.d.ts.map +1 -0
  229. package/dist/providers/client/Types.js +10 -0
  230. package/dist/providers/client/Types.js.map +1 -0
  231. package/dist/providers/client/Types.mjs +8 -0
  232. package/dist/providers/client/Types.mjs.map +1 -0
  233. package/dist/providers/index.d.ts +5 -0
  234. package/dist/providers/index.d.ts.map +1 -0
  235. package/dist/providers/modal/Hook.d.ts +4 -0
  236. package/dist/providers/modal/Hook.d.ts.map +1 -0
  237. package/dist/providers/modal/Hook.js +15 -0
  238. package/dist/providers/modal/Hook.js.map +1 -0
  239. package/dist/providers/modal/Hook.mjs +13 -0
  240. package/dist/providers/modal/Hook.mjs.map +1 -0
  241. package/dist/providers/modal/Provider.d.ts +27 -0
  242. package/dist/providers/modal/Provider.d.ts.map +1 -0
  243. package/dist/providers/modal/Provider.js +48 -0
  244. package/dist/providers/modal/Provider.js.map +1 -0
  245. package/dist/providers/modal/Provider.mjs +68 -0
  246. package/dist/providers/modal/Provider.mjs.map +1 -0
  247. package/dist/providers/modal/Root.d.ts +7 -0
  248. package/dist/providers/modal/Root.d.ts.map +1 -0
  249. package/dist/providers/modal/Root.js +345 -0
  250. package/dist/providers/modal/Root.js.map +1 -0
  251. package/dist/providers/modal/Root.mjs +352 -0
  252. package/dist/providers/modal/Root.mjs.map +1 -0
  253. package/dist/providers/theme/Overrides.d.ts +18 -0
  254. package/dist/providers/theme/Overrides.d.ts.map +1 -0
  255. package/dist/providers/theme/Overrides.js +35 -0
  256. package/dist/providers/theme/Overrides.js.map +1 -0
  257. package/dist/providers/theme/Overrides.mjs +37 -0
  258. package/dist/providers/theme/Overrides.mjs.map +1 -0
  259. package/dist/styles.css +1 -0
  260. package/dist/tests/oauth-test.d.ts +2 -0
  261. package/dist/tests/oauth-test.d.ts.map +1 -0
  262. package/dist/tests/timers-test.d.ts +2 -0
  263. package/dist/tests/timers-test.d.ts.map +1 -0
  264. package/dist/tests/utils-test.d.ts +2 -0
  265. package/dist/tests/utils-test.d.ts.map +1 -0
  266. package/dist/typedoc-entry/index.d.ts +5 -0
  267. package/dist/typedoc-entry/index.d.ts.map +1 -0
  268. package/dist/types/base.d.ts +178 -0
  269. package/dist/types/base.d.ts.map +1 -0
  270. package/dist/types/base.js +55 -0
  271. package/dist/types/base.js.map +1 -0
  272. package/dist/types/base.mjs +50 -0
  273. package/dist/types/base.mjs.map +1 -0
  274. package/dist/types/method-types.d.ts +258 -0
  275. package/dist/types/method-types.d.ts.map +1 -0
  276. package/dist/utils/oauth/completion.d.ts +132 -0
  277. package/dist/utils/oauth/completion.d.ts.map +1 -0
  278. package/dist/utils/oauth/completion.js +136 -0
  279. package/dist/utils/oauth/completion.js.map +1 -0
  280. package/dist/utils/oauth/completion.mjs +176 -0
  281. package/dist/utils/oauth/completion.mjs.map +1 -0
  282. package/dist/utils/oauth/config.d.ts +34 -0
  283. package/dist/utils/oauth/config.d.ts.map +1 -0
  284. package/dist/utils/oauth/config.js +69 -0
  285. package/dist/utils/oauth/config.js.map +1 -0
  286. package/dist/utils/oauth/config.mjs +54 -0
  287. package/dist/utils/oauth/config.mjs.map +1 -0
  288. package/dist/utils/oauth/helpers.d.ts +13 -0
  289. package/dist/utils/oauth/helpers.d.ts.map +1 -0
  290. package/dist/utils/oauth/helpers.js +38 -0
  291. package/dist/utils/oauth/helpers.js.map +1 -0
  292. package/dist/utils/oauth/helpers.mjs +35 -0
  293. package/dist/utils/oauth/helpers.mjs.map +1 -0
  294. package/dist/utils/oauth/index.d.ts +7 -0
  295. package/dist/utils/oauth/index.d.ts.map +1 -0
  296. package/dist/utils/oauth/pkce.d.ts +14 -0
  297. package/dist/utils/oauth/pkce.d.ts.map +1 -0
  298. package/dist/utils/oauth/pkce.js +48 -0
  299. package/dist/utils/oauth/pkce.js.map +1 -0
  300. package/dist/utils/oauth/pkce.mjs +85 -0
  301. package/dist/utils/oauth/pkce.mjs.map +1 -0
  302. package/dist/utils/oauth/storage.d.ts +48 -0
  303. package/dist/utils/oauth/storage.d.ts.map +1 -0
  304. package/dist/utils/oauth/storage.js +87 -0
  305. package/dist/utils/oauth/storage.js.map +1 -0
  306. package/dist/utils/oauth/storage.mjs +78 -0
  307. package/dist/utils/oauth/storage.mjs.map +1 -0
  308. package/dist/utils/oauth/url.d.ts +94 -0
  309. package/dist/utils/oauth/url.d.ts.map +1 -0
  310. package/dist/utils/oauth/url.js +224 -0
  311. package/dist/utils/oauth/url.js.map +1 -0
  312. package/dist/utils/oauth/url.mjs +230 -0
  313. package/dist/utils/oauth/url.mjs.map +1 -0
  314. package/dist/utils/timers.d.ts +73 -0
  315. package/dist/utils/timers.d.ts.map +1 -0
  316. package/dist/utils/timers.js +133 -0
  317. package/dist/utils/timers.js.map +1 -0
  318. package/dist/utils/timers.mjs +142 -0
  319. package/dist/utils/timers.mjs.map +1 -0
  320. package/dist/utils/utils.d.ts +40 -0
  321. package/dist/utils/utils.d.ts.map +1 -0
  322. package/dist/utils/utils.js +116 -0
  323. package/dist/utils/utils.js.map +1 -0
  324. package/dist/utils/utils.mjs +164 -0
  325. package/dist/utils/utils.mjs.map +1 -0
  326. package/package.json +91 -0
@@ -0,0 +1,3934 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var sha2 = require('@noble/hashes/sha2');
6
+ var utils$1 = require('@noble/hashes/utils');
7
+ var storage = require('../../utils/oauth/storage.js');
8
+ require('../../utils/oauth/config.js');
9
+ var url = require('../../utils/oauth/url.js');
10
+ var completion = require('../../utils/oauth/completion.js');
11
+ var pkce = require('../../utils/oauth/pkce.js');
12
+ var helpers = require('../../utils/oauth/helpers.js');
13
+ var utils = require('../../utils/utils.js');
14
+ var timers = require('../../utils/timers.js');
15
+ var core = require('@0xkey-io/core');
16
+ var react = require('react');
17
+ var sdkTypes = require('@0xkey-io/sdk-types');
18
+ var Hook = require('../modal/Hook.js');
19
+ var base = require('../../types/base.js');
20
+ var index = require('../../components/auth/index.js');
21
+ var reactFontawesome = require('@fortawesome/react-fontawesome');
22
+ var Action = require('../../components/auth/Action.js');
23
+ var Message = require('../../components/sign/Message.js');
24
+ var Export = require('../../components/export/Export.js');
25
+ var Import = require('../../components/import/Import.js');
26
+ var Success = require('../../components/design/Success.js');
27
+ var UpdateEmail = require('../../components/user/UpdateEmail.js');
28
+ var UpdatePhoneNumber = require('../../components/user/UpdatePhoneNumber.js');
29
+ var UpdateUserName = require('../../components/user/UpdateUserName.js');
30
+ var RemoveOAuthProvider = require('../../components/user/RemoveOAuthProvider.js');
31
+ var RemovePasskey = require('../../components/user/RemovePasskey.js');
32
+ var ConnectWallet = require('../../components/user/ConnectWallet.js');
33
+ var Types = require('./Types.js');
34
+ var OTP = require('../../components/auth/OTP.js');
35
+ var RemoveEmail = require('../../components/user/RemoveEmail.js');
36
+ var RemovePhoneNumber = require('../../components/user/RemovePhoneNumber.js');
37
+ var Verify = require('../../components/verify/Verify.js');
38
+ var OnRamp = require('../../components/onramp/OnRamp.js');
39
+ var Svg = require('../../components/design/Svg.js');
40
+ var SendTransaction = require('../../components/send-transaction/SendTransaction.js');
41
+ var helpers$1 = require('../../components/send-transaction/helpers.js');
42
+
43
+ /**
44
+ * Provides ZeroXKey client authentication, session management, wallet operations, and user profile management
45
+ * for the React Wallet Kit SDK. This context provider encapsulates all core authentication flows (Passkey, Wallet, OTP, OAuth),
46
+ * session lifecycle (creation, expiration, refresh), wallet connecting/import/export, and user profile updates (email, phone, name).
47
+ *
48
+ * The provider automatically initializes the ZeroXKey client, fetches configuration (including proxy auth config if needed),
49
+ * and synchronizes session and authentication state. It exposes a comprehensive set of methods for authentication flows,
50
+ * wallet management, and user profile operations, as well as UI handlers for modal-driven flows.
51
+ *
52
+ * Features:
53
+ * - Passkey, Wallet, OTP (Email/SMS), and OAuth (Google, Apple, Facebook, X, Discord) authentication and sign-up flows.
54
+ * - Session management: creation, expiration scheduling, refresh, and clearing.
55
+ * - Wallet management: fetch, connect, import, export, account management.
56
+ * - User profile management: email, phone, name, OAuth provider, and passkey linking/removal.
57
+ * - Modal-driven UI flows for authentication, wallet connecting, and profile updates.
58
+ * - Error handling and callback integration for custom error and event responses.
59
+ *
60
+ * Usage:
61
+ * Wrap your application with `ZeroXKeyProvider` to enable authentication and wallet features via context.
62
+ *
63
+ * @param config - The ZeroXKey provider configuration object.
64
+ * @param children - React children to be rendered within the provider.
65
+ * @param callbacks - Optional callbacks for error handling and session events.
66
+ *
67
+ * @returns A React context provider exposing authentication, wallet, and user management methods and state.
68
+ */
69
+ const ClientProvider = ({
70
+ config,
71
+ children,
72
+ callbacks
73
+ }) => {
74
+ const [client, setClient] = react.useState(undefined);
75
+ const [session, setSession] = react.useState(undefined);
76
+ const [masterConfig, setMasterConfig] = react.useState(undefined);
77
+ const [wallets, setWallets] = react.useState([]);
78
+ const [user, setUser] = react.useState(undefined);
79
+ const [clientState, setClientState] = react.useState();
80
+ const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
81
+ // if there is no authProxyConfigId or if autoFetchWalletKitConfig is specifically
82
+ // set to false, we don't need to fetch the config
83
+ const shouldFetchWalletKitConfig = !!config.authProxyConfigId && (config.autoFetchWalletKitConfig ?? true);
84
+ // we use this custom hook to only update the state if the value is different
85
+ // this is so our useEffect that calls `initializeWalletProviderListeners()` only runs when it needs to
86
+ const [walletProviders, setWalletProviders] = utils.useWalletProviderState();
87
+ const expiryTimeoutsRef = react.useRef({});
88
+ const proxyAuthConfigRef = react.useRef(null);
89
+ const [allSessions, setAllSessions] = react.useState(undefined);
90
+ const {
91
+ isMobile,
92
+ pushPage,
93
+ popPage,
94
+ closeModal
95
+ } = Hook.useModal();
96
+ const completeRedirectOauth = async () => {
97
+ // Since we use localStorage (see storage.ts), we always clean up OAuth data
98
+ // when this runs — even if there are no OAuth params in the URL (e.g. the
99
+ // user canceled at the provider and came back manually)
100
+ try {
101
+ // Check for either hash or search parameters that could indicate an OAuth redirect
102
+ if (!window.location.hash && !window.location.search) {
103
+ // No OAuth redirect parameters found, nothing to do
104
+ return;
105
+ }
106
+ /**
107
+ * Wraps an OAuth completion action with optional modal UI.
108
+ * This is the key difference between redirect and popup flows:
109
+ * - Popup: No modal needed (the popup window itself is the UI)
110
+ * - Redirect: Optional modal to show loading/success states on return
111
+ */
112
+ const withModalWrapper = async params => {
113
+ const {
114
+ provider,
115
+ isAddProvider,
116
+ metadata,
117
+ openModal,
118
+ action
119
+ } = params;
120
+ const providerDisplayName = helpers.capitalizeProviderName(provider);
121
+ const icon = helpers.getProviderIcon(provider);
122
+ if (openModal === "true") {
123
+ // Show modal UI for the completion
124
+ await new Promise((resolve, reject) => {
125
+ pushPage({
126
+ key: `${providerDisplayName} OAuth`,
127
+ content: jsxRuntime.jsx(Action.ActionPage, {
128
+ closeOnComplete: isAddProvider ? false : true,
129
+ title: isAddProvider ? `Adding ${providerDisplayName} provider...` : `Authenticating with ${providerDisplayName}...`,
130
+ action: async () => {
131
+ try {
132
+ await action();
133
+ if (isAddProvider && metadata) {
134
+ // Don't show success for auth. Not needed
135
+ pushPage({
136
+ key: "OAuth Provider Added",
137
+ content: jsxRuntime.jsx(Success.SuccessPage, {
138
+ text: `Successfully added ${providerDisplayName} OAuth provider!`,
139
+ duration: metadata.successPageDuration ?? 2000,
140
+ onComplete: () => {
141
+ closeModal();
142
+ }
143
+ }),
144
+ preventBack: true,
145
+ showTitle: false
146
+ });
147
+ }
148
+ resolve();
149
+ } catch (err) {
150
+ reject(err);
151
+ popPage();
152
+ }
153
+ },
154
+ icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, {
155
+ icon: icon,
156
+ size: "3x"
157
+ })
158
+ }),
159
+ showTitle: false,
160
+ onClose: () => {
161
+ reject(new sdkTypes.ZeroXKeyError(isAddProvider ? `User canceled the ${providerDisplayName} add provider process.` : `User canceled the ${providerDisplayName} authentication process.`, sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED));
162
+ }
163
+ });
164
+ });
165
+ } else {
166
+ // No modal - execute directly
167
+ await action();
168
+ }
169
+ };
170
+ // Handle PKCE-based OAuth redirects (Facebook, Discord, X) with code in search parameters
171
+ if (window.location.search && window.location.search.includes("code=") && window.location.search.includes("state=")) {
172
+ // Parse the URL using our unified helper
173
+ const result = url.parseOAuthResponse(window.location.href);
174
+ if (!result || !result.authCode || !result.publicKey) {
175
+ return;
176
+ }
177
+ if (result.flow !== "redirect") {
178
+ // To complete OAuth we need redirect flow
179
+ return;
180
+ }
181
+ const {
182
+ authCode: code,
183
+ provider,
184
+ publicKey,
185
+ oauthIntent,
186
+ sessionKey,
187
+ nonce,
188
+ openModal
189
+ } = result;
190
+ const isAddProvider = oauthIntent === storage.OAUTH_INTENT_ADD_PROVIDER;
191
+ const metadata = isAddProvider ? storage.getOAuthAddProviderMetadata() : null;
192
+ /**
193
+ * Helper to complete PKCE redirect flow with optional modal wrapper.
194
+ * Uses completePKCEFlow from oauth utils for the core logic.
195
+ * We put this in a separate function to avoid duplicating for each provider.
196
+ */
197
+ const completePKCERedirect = async (providerName, exchangeCodeFn) => {
198
+ const action = async () => {
199
+ try {
200
+ await completion.completePKCEFlow({
201
+ publicKey,
202
+ providerName,
203
+ sessionKey: sessionKey ?? undefined,
204
+ callbacks,
205
+ completeOauth,
206
+ onAddProvider:
207
+ // Only set onAddProvider if we are adding a provider and have metadata
208
+ isAddProvider && metadata ? async oidcToken => {
209
+ await addOauthProvider({
210
+ providerName: provider,
211
+ oidcToken,
212
+ organizationId: metadata.organizationId,
213
+ userId: metadata.userId,
214
+ ...(metadata.stampWith && {
215
+ stampWith: metadata.stampWith
216
+ })
217
+ });
218
+ } : undefined,
219
+ exchangeCodeForToken: exchangeCodeFn
220
+ });
221
+ } catch (err) {
222
+ if (callbacks?.onError) {
223
+ const providerDisplayName = helpers.capitalizeProviderName(providerName);
224
+ callbacks.onError(err instanceof sdkTypes.ZeroXKeyError ? err : new sdkTypes.ZeroXKeyError(`${providerDisplayName} authentication failed`, sdkTypes.ZeroXKeyErrorCodes.OAUTH_SIGNUP_ERROR, err));
225
+ }
226
+ throw err;
227
+ }
228
+ };
229
+ await withModalWrapper({
230
+ provider: providerName,
231
+ isAddProvider,
232
+ metadata,
233
+ openModal,
234
+ action
235
+ });
236
+ // Clean up URL after successful completion
237
+ url.cleanupOAuthUrl();
238
+ };
239
+ // FACEBOOK
240
+ if (provider === sdkTypes.OAuthProviders.FACEBOOK) {
241
+ const clientId = masterConfig?.auth?.oauthConfig?.facebookClientId;
242
+ const redirectURI = masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
243
+ const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.FACEBOOK);
244
+ if (clientId && redirectURI && hasVerifier) {
245
+ await completePKCERedirect(sdkTypes.OAuthProviders.FACEBOOK, async codeVerifier => {
246
+ const tokenResponse = await pkce.exchangeFacebookCodeForToken(clientId, redirectURI, code, codeVerifier);
247
+ const oidcToken = tokenResponse?.id_token;
248
+ if (!oidcToken) {
249
+ throw new sdkTypes.ZeroXKeyError("Missing OIDC token", sdkTypes.ZeroXKeyErrorCodes.OAUTH_LOGIN_ERROR);
250
+ }
251
+ return oidcToken;
252
+ });
253
+ }
254
+ return;
255
+ }
256
+ // DISCORD
257
+ if (provider === sdkTypes.OAuthProviders.DISCORD) {
258
+ const clientId = masterConfig?.auth?.oauthConfig?.discordClientId;
259
+ const redirectURI = result.redirectUri ?? masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
260
+ const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.DISCORD);
261
+ if (clientId && redirectURI && hasVerifier && nonce) {
262
+ await completePKCERedirect(sdkTypes.OAuthProviders.DISCORD, async codeVerifier => {
263
+ const resp = await client?.httpClient.proxyOAuth2Authenticate({
264
+ provider: "OAUTH2_PROVIDER_DISCORD",
265
+ authCode: code,
266
+ redirectUri: redirectURI,
267
+ codeVerifier,
268
+ clientId,
269
+ nonce
270
+ });
271
+ const oidcToken = resp?.oidcToken;
272
+ if (!oidcToken) {
273
+ throw new sdkTypes.ZeroXKeyError("Missing OIDC token", sdkTypes.ZeroXKeyErrorCodes.OAUTH_LOGIN_ERROR);
274
+ }
275
+ return oidcToken;
276
+ });
277
+ }
278
+ return;
279
+ }
280
+ // X (Twitter)
281
+ if (provider === sdkTypes.OAuthProviders.X) {
282
+ const clientId = masterConfig?.auth?.oauthConfig?.xClientId;
283
+ const redirectURI = result.redirectUri ?? masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
284
+ const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.X);
285
+ if (clientId && redirectURI && hasVerifier && nonce) {
286
+ await completePKCERedirect(sdkTypes.OAuthProviders.X, async codeVerifier => {
287
+ const resp = await client?.httpClient.proxyOAuth2Authenticate({
288
+ provider: "OAUTH2_PROVIDER_X",
289
+ authCode: code,
290
+ redirectUri: redirectURI,
291
+ codeVerifier,
292
+ clientId,
293
+ nonce
294
+ });
295
+ const oidcToken = resp?.oidcToken;
296
+ if (!oidcToken) {
297
+ throw new sdkTypes.ZeroXKeyError("Missing OIDC token", sdkTypes.ZeroXKeyErrorCodes.OAUTH_LOGIN_ERROR);
298
+ }
299
+ return oidcToken;
300
+ });
301
+ }
302
+ return;
303
+ }
304
+ }
305
+ // Handle Google/Apple redirects (uses hash with idToken - non-PKCE)
306
+ if (window.location.hash) {
307
+ // Parse the URL using our unified helper
308
+ const result = url.parseOAuthResponse(window.location.href);
309
+ if (!result || !result.idToken || result.flow !== "redirect" || !result.publicKey) {
310
+ // idToken and publicKey are required to complete OAuth. These are both in the hash for non-PKCE providers
311
+ return;
312
+ }
313
+ const {
314
+ idToken,
315
+ provider,
316
+ publicKey,
317
+ openModal,
318
+ sessionKey,
319
+ oauthIntent
320
+ } = result;
321
+ const isAddProvider = oauthIntent === storage.OAUTH_INTENT_ADD_PROVIDER;
322
+ const metadata = isAddProvider ? storage.getOAuthAddProviderMetadata() : null;
323
+ const resolvedProvider = provider || sdkTypes.OAuthProviders.GOOGLE;
324
+ // Use completeOAuthFlow from utils for the core completion logic
325
+ const action = async () => {
326
+ await completion.completeOAuthFlow({
327
+ provider: resolvedProvider,
328
+ publicKey,
329
+ oidcToken: idToken,
330
+ sessionKey: sessionKey ?? undefined,
331
+ callbacks,
332
+ completeOauth,
333
+ onAddProvider: isAddProvider && metadata ? async oidcToken => {
334
+ await addOauthProvider({
335
+ providerName: resolvedProvider,
336
+ oidcToken,
337
+ organizationId: metadata.organizationId,
338
+ userId: metadata.userId,
339
+ ...(metadata.stampWith && {
340
+ stampWith: metadata.stampWith
341
+ })
342
+ });
343
+ } : undefined
344
+ });
345
+ };
346
+ await withModalWrapper({
347
+ provider: resolvedProvider,
348
+ isAddProvider,
349
+ metadata,
350
+ openModal: openModal ?? undefined,
351
+ action
352
+ });
353
+ // Clean up the URL after processing
354
+ url.cleanupOAuthUrlPreserveSearch();
355
+ }
356
+ } finally {
357
+ storage.clearAllOAuthData();
358
+ }
359
+ };
360
+ const buildConfig = proxyAuthConfig => {
361
+ // Juggle the local overrides with the values set in the dashboard (proxyAuthConfig).
362
+ const resolvedMethods = {
363
+ emailOtpAuthEnabled: config.auth?.methods?.emailOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("email"),
364
+ smsOtpAuthEnabled: config.auth?.methods?.smsOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("sms"),
365
+ passkeyAuthEnabled: config.auth?.methods?.passkeyAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("passkey"),
366
+ walletAuthEnabled: config.auth?.methods?.walletAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("wallet"),
367
+ googleOauthEnabled: config.auth?.methods?.googleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("google"),
368
+ xOauthEnabled: config.auth?.methods?.xOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("x"),
369
+ discordOauthEnabled: config.auth?.methods?.discordOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("discord"),
370
+ appleOauthEnabled: config.auth?.methods?.appleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("apple"),
371
+ facebookOauthEnabled: config.auth?.methods?.facebookOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("facebook")
372
+ };
373
+ const resolvedClientIds = {
374
+ googleClientId: config.auth?.oauthConfig?.googleClientId ?? proxyAuthConfig?.oauthClientIds?.google,
375
+ appleClientId: config.auth?.oauthConfig?.appleClientId ?? proxyAuthConfig?.oauthClientIds?.apple,
376
+ facebookClientId: config.auth?.oauthConfig?.facebookClientId ?? proxyAuthConfig?.oauthClientIds?.facebook,
377
+ xClientId: config.auth?.oauthConfig?.xClientId ?? proxyAuthConfig?.oauthClientIds?.x,
378
+ discordClientId: config.auth?.oauthConfig?.discordClientId ?? proxyAuthConfig?.oauthClientIds?.discord
379
+ };
380
+ const redirectUrl = config.auth?.oauthConfig?.oauthRedirectUri ?? proxyAuthConfig?.oauthRedirectUrl;
381
+ // Set a default ordering for the oAuth methods
382
+ const oauthOrder = config.auth?.oauthOrder ?? ["google", "apple", "x", "discord", "facebook"].filter(provider => resolvedMethods[`${provider}OauthEnabled`]);
383
+ // Set a default ordering for the overall auth methods
384
+ const methodOrder = config.auth?.methodOrder ?? [oauthOrder.length > 0 ? "socials" : null, resolvedMethods.emailOtpAuthEnabled ? "email" : null, resolvedMethods.smsOtpAuthEnabled ? "sms" : null, resolvedMethods.passkeyAuthEnabled ? "passkey" : null, resolvedMethods.walletAuthEnabled ? "wallet" : null].filter(Boolean);
385
+ // Warn if they are trying to set auth proxy only settings directly
386
+ if (proxyAuthConfig) {
387
+ if (config.auth?.sessionExpirationSeconds) {
388
+ console.warn("ZeroXKey SDK warning. You have set sessionExpirationSeconds directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure session expiration in the ZeroXKey dashboard.");
389
+ }
390
+ if (config.auth?.otpAlphanumeric !== undefined) {
391
+ console.warn("ZeroXKey SDK warning. You have set otpAlphanumeric directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the ZeroXKey dashboard.");
392
+ }
393
+ if (config.auth?.otpLength) {
394
+ console.warn("ZeroXKey SDK warning. You have set otpLength directly in the ZeroXKeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the ZeroXKey dashboard.");
395
+ }
396
+ }
397
+ // These are settings that, if using the auth proxy, must be set in the dashboard. They override any local settings unless they are not using auth proxy or are not fetching the auth proxy config.
398
+ const authProxyPrioSettings = {
399
+ sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds ?? config.auth?.sessionExpirationSeconds,
400
+ otpAlphanumeric: proxyAuthConfig?.otpAlphanumeric ?? config.auth?.otpAlphanumeric ?? true,
401
+ otpLength: proxyAuthConfig?.otpLength ?? config.auth?.otpLength ?? "6"
402
+ };
403
+ return {
404
+ ...config,
405
+ // Overrides:
406
+ auth: {
407
+ ...config.auth,
408
+ ...authProxyPrioSettings,
409
+ methods: resolvedMethods,
410
+ oauthConfig: {
411
+ ...config.auth?.oauthConfig,
412
+ ...resolvedClientIds,
413
+ oauthRedirectUri: redirectUrl,
414
+ // on mobile we default to true since many mobile browsers
415
+ // (e.g. Safari) block popups
416
+ openOauthInPage: isMobile ? true : config.auth?.oauthConfig?.openOauthInPage
417
+ },
418
+ methodOrder,
419
+ oauthOrder,
420
+ autoRefreshSession: config.auth?.autoRefreshSession ?? true
421
+ },
422
+ autoRefreshManagedState: config.autoRefreshManagedState ?? true,
423
+ walletConfig: {
424
+ ...config.walletConfig,
425
+ features: {
426
+ ...config.walletConfig?.features,
427
+ auth:
428
+ // If walletAuthEnabled is not set, default to true. Wallet auth can be enabled/disabled in the dashboard or by explicitly changing the walletAuthEnabled / walletConfig auth feature.
429
+ resolvedMethods.walletAuthEnabled ?? config.walletConfig?.features?.auth ?? true,
430
+ connecting: config.walletConfig?.features?.connecting ?? true // Default connecting to true if not set. We don't care about auth settings here.
431
+ },
432
+ chains: {
433
+ ...config.walletConfig?.chains,
434
+ ethereum: {
435
+ ...config.walletConfig?.chains?.ethereum,
436
+ // keep user's value if provided; default only when undefined
437
+ native: config.walletConfig?.chains?.ethereum?.native ?? true
438
+ },
439
+ solana: {
440
+ ...config.walletConfig?.chains?.solana,
441
+ // keep user's value if provided; default only when undefined
442
+ native: config.walletConfig?.chains?.solana?.native ?? true
443
+ }
444
+ }
445
+ },
446
+ importIframeUrl: config.importIframeUrl ?? "https://import.0xkey.com",
447
+ exportIframeUrl: config.exportIframeUrl ?? "https://export.0xkey.com"
448
+ };
449
+ };
450
+ /**
451
+ * Initializes the ZeroXKey client with the provided configuration.
452
+ * This function sets up the client, fetches the proxy auth config if needed,
453
+ * and prepares the client for use in authentication and wallet operations.
454
+ *
455
+ * @internal
456
+ */
457
+ const initializeClient = async () => {
458
+ if (!masterConfig || client || clientState == base.ClientState.Loading) return;
459
+ try {
460
+ setClientState(base.ClientState.Loading);
461
+ const zeroXKeyClient = new core.ZeroXKeyClient({
462
+ apiBaseUrl: masterConfig.apiBaseUrl,
463
+ authProxyUrl: masterConfig.authProxyUrl,
464
+ authProxyConfigId: masterConfig.authProxyConfigId,
465
+ organizationId: masterConfig.organizationId,
466
+ // Define passkey and wallet config here. If we don't pass it into the client, Mr. Client will assume that we don't want to use passkeys/wallets and not create the stamper!
467
+ passkeyConfig: {
468
+ rpId: masterConfig.passkeyConfig?.rpId,
469
+ timeout: masterConfig.passkeyConfig?.timeout || 60000,
470
+ // 60 seconds
471
+ userVerification: masterConfig.passkeyConfig?.userVerification || "preferred",
472
+ allowCredentials: masterConfig.passkeyConfig?.allowCredentials || []
473
+ },
474
+ walletConfig: {
475
+ features: {
476
+ ...masterConfig.walletConfig?.features
477
+ },
478
+ chains: {
479
+ ...masterConfig.walletConfig?.chains
480
+ },
481
+ ...(masterConfig.walletConfig?.walletConnect && {
482
+ walletConnect: masterConfig.walletConfig.walletConnect
483
+ })
484
+ },
485
+ defaultStamperType: masterConfig.defaultStamperType
486
+ });
487
+ await zeroXKeyClient.init();
488
+ setClient(zeroXKeyClient);
489
+ // Don't set clientState to ready until we fetch the proxy auth config (See other fetchProxyAuthConfig useEffect)
490
+ } catch (error) {
491
+ setClientState(base.ClientState.Error);
492
+ if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
493
+ callbacks?.onError?.(error);
494
+ } else {
495
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize ZeroXKey client`, sdkTypes.ZeroXKeyErrorCodes.INITIALIZE_CLIENT_ERROR, error));
496
+ }
497
+ }
498
+ };
499
+ /**
500
+ * Initializes the user sessions by fetching all active sessions and setting up their state.
501
+ * @internal
502
+ */
503
+ const initializeSessions = async () => {
504
+ setSession(undefined);
505
+ setAllSessions(undefined);
506
+ try {
507
+ const allLocalStorageSessions = await getAllSessions();
508
+ if (!allLocalStorageSessions) return;
509
+ await Promise.all(Object.keys(allLocalStorageSessions).map(async sessionKey => {
510
+ const session = allLocalStorageSessions?.[sessionKey];
511
+ if (!utils.isValidSession(session)) {
512
+ await clearSession({
513
+ sessionKey
514
+ });
515
+ if (sessionKey === (await getActiveSessionKey())) {
516
+ setSession(undefined);
517
+ }
518
+ delete allLocalStorageSessions[sessionKey];
519
+ return;
520
+ }
521
+ scheduleSessionExpiration({
522
+ sessionKey,
523
+ expiry: session.expiry
524
+ });
525
+ }));
526
+ setAllSessions(allLocalStorageSessions || undefined);
527
+ const activeSessionKey = await client?.getActiveSessionKey();
528
+ if (activeSessionKey) {
529
+ // If we have an active session key, set
530
+ if (!allLocalStorageSessions[activeSessionKey]) {
531
+ return;
532
+ }
533
+ setSession(allLocalStorageSessions[activeSessionKey]);
534
+ // we use `maybeFetchWallets()` instead of `maybeRefreshWallets()` here to avoid a race condition
535
+ // specifically, if WalletConnect finishes initializing before this promise resolves,
536
+ // `maybeRefreshWallets()` could overwrite the WalletConnect wallet state with an outdated
537
+ // list of wallets that doesn’t yet include the WalletConnect wallets
538
+ const [, wallets] = await Promise.all([maybeRefreshUser(), (() => {
539
+ if (!masterConfig?.autoRefreshManagedState) return [];
540
+ return fetchWallets();
541
+ })()]);
542
+ // the prev wallets should only ever be WalletConnect wallets
543
+ if (wallets) {
544
+ setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wallets));
545
+ }
546
+ return;
547
+ }
548
+ } catch (error) {
549
+ if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
550
+ callbacks?.onError?.(error);
551
+ } else {
552
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize sessions`, sdkTypes.ZeroXKeyErrorCodes.INITIALIZE_SESSION_ERROR, error));
553
+ }
554
+ }
555
+ };
556
+ /**
557
+ * @internal
558
+ * Attach listeners for connected wallet providers so we can refresh state on changes.
559
+ *
560
+ * - Ethereum: listens for disconnect and chain/account changes to trigger a refresh.
561
+ * - Solana: listens for disconnect via Wallet Standard `change` events to trigger a refresh.
562
+ * - WalletConnect:
563
+ * - listens for disconnect and other state changes via its unified `change` event
564
+ * - additionally listens for `pairingExpired` events (proposal expiration), in which
565
+ * case we re-fetch providers to refresh the pairing URI for the UI.
566
+ *
567
+ * Notes:
568
+ * - Only connected providers are bound, except WalletConnect which must always register
569
+ * to handle proposal expiration even if no active session exists.
570
+ * - Since all WalletConnect providers share the same session, we only attach to one.
571
+ *
572
+ * @param walletProviders - Discovered providers; only connected ones are bound.
573
+ * @param onUpdateState - Invoked when a relevant provider event occurs.
574
+ * @returns Cleanup function that removes all listeners registered by this call.
575
+ */
576
+ async function initializeWalletProviderListeners(walletProviders, onUpdateState) {
577
+ if (walletProviders.length === 0) return () => {};
578
+ const cleanups = [];
579
+ // we only want to initialize these listeners for connected walletProviders
580
+ const nativeOnly = provider => provider.interfaceType !== core.WalletInterfaceType.WalletConnect;
581
+ const ethProviders = masterConfig?.walletConfig?.chains.ethereum?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Ethereum && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
582
+ const solProviders = masterConfig?.walletConfig?.chains.solana?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Solana && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
583
+ // WalletConnect is excluded from native event wiring. Instead,
584
+ // it uses a unified `change` event exposed by our custom wrapper
585
+ //
586
+ // unlike native providers, we register listeners for WalletConnect
587
+ // even if it’s not currently “connected”. This is required so we
588
+ // can detect proposal expiration events and display the new regenerated
589
+ // URI for the UI
590
+ const wcProviders = walletProviders.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
591
+ // since all WalletConnect providers share the same underlying session
592
+ // and emit identical events, we only attach listeners to a single provider
593
+ const wcProvider = wcProviders.find(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
594
+ function attachEthereumListeners(provider, onUpdateState) {
595
+ if (typeof provider.on !== "function") return;
596
+ const handleChainChanged = async _chainId => onUpdateState();
597
+ const handleAccountsChanged = async accounts => {
598
+ if (accounts.length === 0) onUpdateState();
599
+ };
600
+ const handleDisconnect = () => onUpdateState();
601
+ provider.on("chainChanged", handleChainChanged);
602
+ provider.on("accountsChanged", handleAccountsChanged);
603
+ provider.on("disconnect", handleDisconnect);
604
+ return () => {
605
+ provider.removeListener("chainChanged", handleChainChanged);
606
+ provider.removeListener("accountsChanged", handleAccountsChanged);
607
+ provider.removeListener("disconnect", handleDisconnect);
608
+ };
609
+ }
610
+ function attachSolanaListeners(provider, onUpdateState) {
611
+ const cleanups = [];
612
+ const walletEvents = provider?.features?.["standard:events"];
613
+ if (walletEvents?.on) {
614
+ const offChange = walletEvents.on("change", async _evt => {
615
+ await onUpdateState();
616
+ });
617
+ cleanups.push(offChange);
618
+ }
619
+ return () => cleanups.forEach(fn => fn());
620
+ }
621
+ ethProviders.forEach(p => {
622
+ const cleanup = attachEthereumListeners(p.provider, onUpdateState);
623
+ if (cleanup) cleanups.push(cleanup);
624
+ });
625
+ solProviders.forEach(p => {
626
+ const cleanup = attachSolanaListeners(p.provider, onUpdateState);
627
+ if (cleanup) cleanups.push(cleanup);
628
+ });
629
+ if (wcProvider) {
630
+ const standardEvents = wcProvider.provider?.features?.["standard:events"];
631
+ if (standardEvents?.on) {
632
+ if (standardEvents?.on) {
633
+ const unsubscribe = standardEvents.on("change", async evt => {
634
+ // if the event is a proposalExpired, we want to re-fetch the providers
635
+ // to refresh the uri, there is no need to refresh the wallets state
636
+ if (evt?.type === "pairingExpired") {
637
+ debouncedFetchWalletProviders();
638
+ return;
639
+ }
640
+ // if WalletConnect initialization failed, refresh providers
641
+ // (the failed provider will be removed from the list)
642
+ if (evt?.type === "failed") {
643
+ debouncedFetchWalletProviders();
644
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`WalletConnect initialization failed: ${evt.error || "Unknown error"}`, sdkTypes.ZeroXKeyErrorCodes.WALLET_CONNECT_INITIALIZATION_ERROR, evt.error));
645
+ return;
646
+ }
647
+ if (evt?.type === "initialized") {
648
+ // this updates our walletProvider state
649
+ const providers = await debouncedFetchWalletProviders();
650
+ // if we have an active session, we need to restore any possibly connected
651
+ // WalletConnect wallets since its now initialized
652
+ const currentSession = await getSession();
653
+ if (currentSession) {
654
+ const wcProviders = providers?.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
655
+ const wcWallets = await fetchWallets({
656
+ walletProviders: wcProviders,
657
+ connectedOnly: true
658
+ });
659
+ if (wcWallets.length > 0) {
660
+ setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wcWallets));
661
+ }
662
+ }
663
+ return;
664
+ }
665
+ // any other event (disconnect, chain switch, accounts changed)
666
+ // we refresh the wallets state
667
+ await onUpdateState();
668
+ });
669
+ cleanups.push(unsubscribe);
670
+ }
671
+ }
672
+ }
673
+ return () => {
674
+ cleanups.forEach(remove => remove());
675
+ };
676
+ }
677
+ /**
678
+ * Clears all scheduled session timers (warning + expiry).
679
+ *
680
+ * - Removes all active timers managed by this client.
681
+ * - Useful on re-init or logout to avoid stale timers.
682
+ *
683
+ * @throws {ZeroXKeyError} If an error occurs while clearing the timers.
684
+ */
685
+ function clearSessionTimeouts(sessionKeys) {
686
+ try {
687
+ if (sessionKeys) {
688
+ timers.clearKeys(expiryTimeoutsRef.current, sessionKeys);
689
+ } else {
690
+ timers.clearAll(expiryTimeoutsRef.current); // clears & deletes everything
691
+ }
692
+ } catch (error) {
693
+ if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
694
+ callbacks?.onError?.(error);
695
+ } else {
696
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError("Failed to clear session timeouts", sdkTypes.ZeroXKeyErrorCodes.CLEAR_SESSION_TIMEOUTS_ERROR, error));
697
+ }
698
+ }
699
+ }
700
+ /**
701
+ * @internal
702
+ * Handles the post-authentication flow.
703
+ *
704
+ * - This function is called after a successful authentication (login or sign-up) via any supported method (Passkey, Wallet, OTP, OAuth).
705
+ * - It fetches the active session and all sessions, updates the session state, and schedules session expiration and warning timeouts.
706
+ * - It also refreshes the user's wallets and profile information to ensure the provider state is up to date.
707
+ * - This function is used internally after all authentication flows to synchronize state and trigger any necessary callbacks.
708
+ *
709
+ * @returns A void promise.
710
+ * @throws {ZeroXKeyError} If the client is not initialized or if there is an error during the process.
711
+ */
712
+ const handlePostAuth = async params => {
713
+ const {
714
+ method,
715
+ action,
716
+ identifier,
717
+ appProofs
718
+ } = params;
719
+ try {
720
+ const sessionKey = await getActiveSessionKey();
721
+ const session = await getSession({
722
+ ...(sessionKey && {
723
+ sessionKey
724
+ })
725
+ });
726
+ if (session && sessionKey) await scheduleSessionExpiration({
727
+ sessionKey,
728
+ expiry: session.expiry
729
+ });
730
+ const allSessions = await client.getAllSessions();
731
+ setSession(session);
732
+ setAllSessions(allSessions);
733
+ await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
734
+ if (masterConfig?.auth?.verifyWalletOnSignup === true && appProofs && appProofs.length > 0 && action === sdkTypes.AuthAction.SIGNUP) {
735
+ // On signup, if we have appProofs, verify them
736
+ await handleVerifyAppProofs({
737
+ appProofs
738
+ });
739
+ }
740
+ callbacks?.onAuthenticationSuccess?.({
741
+ session,
742
+ method,
743
+ action,
744
+ identifier
745
+ });
746
+ } catch (error) {
747
+ if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
748
+ callbacks?.onError?.(error);
749
+ } else {
750
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to handle post-authentication`, sdkTypes.ZeroXKeyErrorCodes.HANDLE_POST_AUTH_ERROR, error));
751
+ }
752
+ }
753
+ };
754
+ /**
755
+ * @internal
756
+ * Handles the post-logout flow.
757
+ *
758
+ * - This function is called after a successful logout or session clear.
759
+ * - It clears all scheduled session expiration and warning timeouts associated to the session key to prevent memory leaks.
760
+ * - It resets the session state, removes user data from memory, the logged out session from all sessions state, and clears the wallets list.
761
+ * - This ensures that all sensitive information is removed from the provider state after logout.
762
+ * - Called internally after logout or when all sessions are cleared.
763
+ *
764
+ * @returns void
765
+ * @throws {ZeroXKeyError} If there is an error during the post-logout process.
766
+ */
767
+ const handlePostLogout = sessionKey => {
768
+ try {
769
+ clearSessionTimeouts(sessionKey ? [sessionKey, `${sessionKey}-warning`] : undefined);
770
+ setAllSessions(prev => {
771
+ if (!prev) return prev;
772
+ if (sessionKey) {
773
+ const next = {
774
+ ...prev
775
+ };
776
+ delete next[sessionKey];
777
+ return next;
778
+ }
779
+ return {};
780
+ });
781
+ setSession(undefined);
782
+ setUser(undefined);
783
+ setWallets([]);
784
+ } catch (error) {
785
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to initialize sessions`, sdkTypes.ZeroXKeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
786
+ }
787
+ };
788
+ const createHttpClient = react.useCallback(params => {
789
+ if (!client) {
790
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
791
+ }
792
+ return client.createHttpClient(params);
793
+ }, [client]);
794
+ const getActiveSessionKey = react.useCallback(async () => {
795
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
796
+ return utils.withZeroXKeyErrorHandling(() => client.getActiveSessionKey(), undefined, callbacks, "Failed to get active session key");
797
+ }, [client, callbacks]);
798
+ const logout = react.useCallback(async params => {
799
+ if (!client) {
800
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
801
+ }
802
+ await utils.withZeroXKeyErrorHandling(async () => {
803
+ // If no sessionKey is provided, we try to get the active one.
804
+ let sessionKey = params?.sessionKey;
805
+ if (!sessionKey) sessionKey = await getActiveSessionKey();
806
+ await client.logout(params);
807
+ // We only handle post logout if the sessionKey is defined since that means we actually logged out of a session.
808
+ if (sessionKey) handlePostLogout(sessionKey);
809
+ }, undefined, callbacks, "Failed to logout");
810
+ return;
811
+ }, [client, callbacks, getActiveSessionKey]);
812
+ const getSession = react.useCallback(async params => {
813
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
814
+ return utils.withZeroXKeyErrorHandling(() => client.getSession(params), undefined, callbacks, "Failed to get session");
815
+ }, [client, callbacks]);
816
+ const getAllSessions = react.useCallback(async () => {
817
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
818
+ return utils.withZeroXKeyErrorHandling(() => client.getAllSessions(), undefined, callbacks, "Failed to get all sessions");
819
+ }, [client, callbacks]);
820
+ const createPasskey = react.useCallback(async params => {
821
+ if (!client) {
822
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
823
+ }
824
+ return utils.withZeroXKeyErrorHandling(() => client.createPasskey({
825
+ ...params
826
+ }), undefined, callbacks, "Failed to create passkey");
827
+ }, [client, callbacks]);
828
+ const fetchUser = react.useCallback(async params => {
829
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
830
+ return utils.withZeroXKeyErrorHandling(() => client.fetchUser(params), () => logout(), callbacks, "Failed to fetch user");
831
+ }, [client, callbacks, logout]);
832
+ const fetchWalletProviders = react.useCallback(async chain => {
833
+ if (!client) {
834
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
835
+ }
836
+ return utils.withZeroXKeyErrorHandling(async () => {
837
+ const newProviders = await client.fetchWalletProviders(chain);
838
+ // we update state with the latest providers
839
+ // we keep this state so that initializeWalletProviderListeners() re-runs
840
+ // whenever the list of connected providers changes
841
+ // this ensures we attach disconnect listeners for each connected provider
842
+ setWalletProviders(newProviders);
843
+ return newProviders;
844
+ }, undefined, callbacks, "Failed to fetch wallet providers");
845
+ }, [client, callbacks]);
846
+ const fetchWallets = react.useCallback(async params => {
847
+ if (!client) {
848
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
849
+ }
850
+ return utils.withZeroXKeyErrorHandling(() => client.fetchWallets(params), () => logout(), callbacks, "Failed to fetch wallets");
851
+ }, [client, callbacks, logout]);
852
+ const refreshUser = react.useCallback(async params => {
853
+ const {
854
+ stampWith,
855
+ organizationId,
856
+ userId
857
+ } = params || {};
858
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
859
+ const user = await utils.withZeroXKeyErrorHandling(() => fetchUser({
860
+ stampWith,
861
+ ...(organizationId && {
862
+ organizationId
863
+ }),
864
+ ...(userId && {
865
+ userId
866
+ })
867
+ }), () => logout(), callbacks, "Failed to refresh user");
868
+ if (user) {
869
+ setUser(user);
870
+ }
871
+ }, [client, callbacks, fetchUser, logout]);
872
+ /**
873
+ * @internal
874
+ * Auto-refresh user only if enabled in config. This is only used internally.
875
+ *
876
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
877
+ * @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
878
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
879
+ * @returns A promise that resolves when the user is refreshed, or does nothing if auto-refresh is disabled
880
+ */
881
+ const maybeRefreshUser = react.useCallback(async params => {
882
+ if (!masterConfig?.autoRefreshManagedState) return;
883
+ return refreshUser(params);
884
+ }, [masterConfig, refreshUser]);
885
+ const refreshWallets = react.useCallback(async params => {
886
+ const {
887
+ stampWith,
888
+ organizationId,
889
+ userId
890
+ } = params || {};
891
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
892
+ const walletProviders = await utils.withZeroXKeyErrorHandling(() => fetchWalletProviders(), undefined, callbacks, "Failed to refresh wallets");
893
+ const wallets = await utils.withZeroXKeyErrorHandling(() => fetchWallets({
894
+ stampWith,
895
+ walletProviders,
896
+ ...(organizationId && {
897
+ organizationId
898
+ }),
899
+ ...(userId && {
900
+ userId
901
+ })
902
+ }), () => logout(), callbacks, "Failed to refresh wallets");
903
+ if (wallets) {
904
+ setWallets(wallets);
905
+ }
906
+ return wallets;
907
+ }, [client, callbacks, fetchWalletProviders, fetchWallets, logout]);
908
+ /**
909
+ * @internal
910
+ * Auto-refresh wallets only if enabled in config. This is only used internally.
911
+ *
912
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
913
+ * @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
914
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
915
+ * @returns A promise that resolves to an array of wallets, or an empty array if auto-refresh is disabled
916
+ */
917
+ const maybeRefreshWallets = react.useCallback(async params => {
918
+ if (!masterConfig?.autoRefreshManagedState) return [];
919
+ return refreshWallets(params);
920
+ }, [masterConfig, refreshWallets]);
921
+ const clearSession = react.useCallback(async params => {
922
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
923
+ await utils.withZeroXKeyErrorHandling(async () => client.clearSession(params), undefined, callbacks, "Failed to clear session");
924
+ const sessionKey = params?.sessionKey ?? (await getActiveSessionKey());
925
+ if (!sessionKey) return;
926
+ if (!params?.sessionKey) {
927
+ setSession(undefined);
928
+ }
929
+ clearSessionTimeouts([sessionKey]);
930
+ // clear only the cleared session from allSessions
931
+ const newAllSessions = {
932
+ ...allSessions
933
+ };
934
+ if (newAllSessions) {
935
+ delete newAllSessions[sessionKey];
936
+ }
937
+ setAllSessions(newAllSessions);
938
+ return;
939
+ }, [client, callbacks, getActiveSessionKey, allSessions]);
940
+ /**
941
+ * @internal
942
+ * Schedules a session expiration and warning timer for the given session key.
943
+ *
944
+ * - Sets up two timers: one for warning before expiry and one for actual expiry.
945
+ * - Uses capped timeouts under the hood so delays > 24.8 days are safe (see utils/timers.ts).
946
+ *
947
+ * @param params.sessionKey - The key of the session to schedule expiration for.
948
+ * @param params.expiry - The expiration time in seconds since epoch.
949
+ * @throws {ZeroXKeyError} If an error occurs while scheduling the session expiration.
950
+ */
951
+ const scheduleSessionExpiration = react.useCallback(async params => {
952
+ const {
953
+ sessionKey,
954
+ expiry
955
+ } = params;
956
+ try {
957
+ const warnKey = `${sessionKey}-warning`;
958
+ // Replace any prior timers for this session
959
+ timers.clearKey(expiryTimeoutsRef.current, sessionKey);
960
+ timers.clearKey(expiryTimeoutsRef.current, warnKey);
961
+ const now = Date.now();
962
+ const expiryMs = expiry * 1000;
963
+ const timeUntilExpiry = expiryMs - now;
964
+ const runRefresh = async () => {
965
+ const activeSession = await getSession();
966
+ if (!activeSession && expiryTimeoutsRef.current[warnKey]) {
967
+ // Keep nudging until session materializes (short 10s timer is fine)
968
+ timers.setTimeoutInMap(expiryTimeoutsRef.current, warnKey, runRefresh, 10_000);
969
+ return;
970
+ }
971
+ const session = await getSession({
972
+ sessionKey
973
+ });
974
+ if (!session) return;
975
+ callbacks?.beforeSessionExpiry?.({
976
+ sessionKey
977
+ });
978
+ if (masterConfig?.auth?.autoRefreshSession) {
979
+ await refreshSession({
980
+ expirationSeconds: session.expirationSeconds,
981
+ sessionKey
982
+ });
983
+ }
984
+ };
985
+ const expireSession = async () => {
986
+ const expiredSession = await getSession({
987
+ sessionKey
988
+ });
989
+ if (!expiredSession) return;
990
+ callbacks?.onSessionExpired?.({
991
+ sessionKey
992
+ });
993
+ if ((await getActiveSessionKey()) === sessionKey) {
994
+ setSession(undefined);
995
+ }
996
+ setAllSessions(prev => {
997
+ if (!prev) return prev;
998
+ const next = {
999
+ ...prev
1000
+ };
1001
+ delete next[sessionKey];
1002
+ return next;
1003
+ });
1004
+ await clearSession({
1005
+ sessionKey
1006
+ });
1007
+ // Remove timers for this session
1008
+ timers.clearKey(expiryTimeoutsRef.current, sessionKey);
1009
+ timers.clearKey(expiryTimeoutsRef.current, warnKey);
1010
+ await logout();
1011
+ };
1012
+ // Already expired → expire immediately
1013
+ if (timeUntilExpiry <= 0) {
1014
+ await expireSession();
1015
+ return;
1016
+ }
1017
+ // Warning timer (if threshold is in the future)
1018
+ const warnAt = expiryMs - utils.SESSION_WARNING_THRESHOLD_MS;
1019
+ if (warnAt <= now) {
1020
+ void runRefresh(); // fire-and-forget is fine
1021
+ } else {
1022
+ timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, warnKey, runRefresh, warnAt - now);
1023
+ }
1024
+ // Actual expiry timer (safe for long delays)
1025
+ timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, sessionKey, expireSession, timeUntilExpiry);
1026
+ } catch (error) {
1027
+ if (error instanceof sdkTypes.ZeroXKeyError || error instanceof sdkTypes.ZeroXKeyNetworkError) {
1028
+ callbacks?.onError?.(error);
1029
+ } else {
1030
+ callbacks?.onError?.(new sdkTypes.ZeroXKeyError(`Failed to schedule session expiration for ${sessionKey}`, sdkTypes.ZeroXKeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, error));
1031
+ }
1032
+ }
1033
+ },
1034
+ // Note: `refreshSession()` is intentionally NOT in the dependency array even though
1035
+ // it's called in runRefresh. This is because: `refreshSession()` itself calls `scheduleSessionExpiration()`,
1036
+ // creating a circular dependency that would cause infinite re-renders
1037
+ //
1038
+ // this is fine because `refreshSession()` reference is stable enough for this use case (session
1039
+ // expiration timers are long-lived and don't need to re-subscribe on every `refreshSession()` change)
1040
+ [callbacks, masterConfig, getSession, getActiveSessionKey, clearSession, logout]);
1041
+ const refreshSession = react.useCallback(async params => {
1042
+ if (!client) {
1043
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1044
+ }
1045
+ const activeSessionKey = await client.getActiveSessionKey();
1046
+ if (!activeSessionKey) {
1047
+ throw new sdkTypes.ZeroXKeyError("No active session found.", sdkTypes.ZeroXKeyErrorCodes.NO_SESSION_FOUND);
1048
+ }
1049
+ const sessionKey = params?.sessionKey ?? activeSessionKey;
1050
+ const res = await utils.withZeroXKeyErrorHandling(() => client.refreshSession({
1051
+ ...params
1052
+ }), () => logout(), callbacks, "Failed to refresh session");
1053
+ const session = await getSession({
1054
+ sessionKey
1055
+ });
1056
+ if (session && sessionKey) {
1057
+ await scheduleSessionExpiration({
1058
+ sessionKey,
1059
+ expiry: session.expiry
1060
+ });
1061
+ }
1062
+ const allSessions = await getAllSessions();
1063
+ setSession(session);
1064
+ setAllSessions(allSessions);
1065
+ return res;
1066
+ }, [client, callbacks, logout, getSession, scheduleSessionExpiration, getAllSessions]);
1067
+ const loginWithPasskey = react.useCallback(async params => {
1068
+ if (!client) {
1069
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1070
+ }
1071
+ const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
1072
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithPasskey({
1073
+ ...params,
1074
+ expirationSeconds
1075
+ }), () => logout(), callbacks, "Failed to login with passkey");
1076
+ if (res) {
1077
+ await handlePostAuth({
1078
+ method: base.AuthMethod.Passkey,
1079
+ action: sdkTypes.AuthAction.LOGIN,
1080
+ identifier: res.credentialId,
1081
+ appProofs: res.appProofs
1082
+ });
1083
+ }
1084
+ return res;
1085
+ }, [client, callbacks, masterConfig, logout, handlePostAuth]);
1086
+ const signUpWithPasskey = react.useCallback(async params => {
1087
+ if (!client) {
1088
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1089
+ }
1090
+ if (!masterConfig) {
1091
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1092
+ }
1093
+ // If createSubOrgParams is not provided, use the default from masterConfig
1094
+ let createSubOrgParams = params?.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.passkeyAuth;
1095
+ params = createSubOrgParams !== undefined ? {
1096
+ ...params,
1097
+ createSubOrgParams
1098
+ } : {
1099
+ ...params
1100
+ };
1101
+ const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
1102
+ const websiteName = window.location.hostname;
1103
+ const timestamp = new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString([], {
1104
+ hour: "2-digit",
1105
+ minute: "2-digit"
1106
+ });
1107
+ // We allow passkeyName to be passed in thru the provider or thru the params of this function directly.
1108
+ // This is because signUpWithPasskey will create a new passkey using that name.
1109
+ // Any extra authenticators will be created after the first one. (see core implementation)
1110
+ const passkeyName = params?.passkeyDisplayName ?? masterConfig.auth?.createSuborgParams?.passkeyAuth?.passkeyName ?? `${websiteName}-${timestamp}`;
1111
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithPasskey({
1112
+ ...params,
1113
+ passkeyDisplayName: passkeyName,
1114
+ expirationSeconds
1115
+ }), () => logout(), callbacks, "Failed to sign up with passkey");
1116
+ if (res) {
1117
+ await handlePostAuth({
1118
+ method: base.AuthMethod.Passkey,
1119
+ action: sdkTypes.AuthAction.SIGNUP,
1120
+ identifier: res.credentialId,
1121
+ appProofs: res.appProofs
1122
+ });
1123
+ }
1124
+ return res;
1125
+ }, [client, callbacks, logout, handlePostAuth, masterConfig]);
1126
+ const connectWalletAccount = react.useCallback(async walletProvider => {
1127
+ if (!client) {
1128
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1129
+ }
1130
+ return utils.withZeroXKeyErrorHandling(async () => {
1131
+ const address = await client.connectWalletAccount(walletProvider);
1132
+ let wallets;
1133
+ const s = await getSession();
1134
+ if (s) {
1135
+ // this will update our walletProvider state
1136
+ wallets = await maybeRefreshWallets();
1137
+ } else {
1138
+ wallets = await fetchWallets({
1139
+ connectedOnly: true
1140
+ });
1141
+ }
1142
+ // we narrow to only connected wallets
1143
+ // because we know the account must come from one of them
1144
+ const connectedWallets = wallets.filter(w => w.source === core.WalletSource.Connected);
1145
+ // find the matching account
1146
+ const matchedAccount = connectedWallets.flatMap(w => w.accounts).find(a => a.address === address);
1147
+ if (!matchedAccount) {
1148
+ throw new sdkTypes.ZeroXKeyError(`No connected wallet account found for address: ${address}`, sdkTypes.ZeroXKeyErrorCodes.NO_WALLET_FOUND);
1149
+ }
1150
+ return matchedAccount;
1151
+ }, () => logout(), callbacks, "Failed to connect wallet account");
1152
+ }, [client, callbacks, getSession, logout, maybeRefreshWallets, fetchWallets]);
1153
+ const disconnectWalletAccount = react.useCallback(async walletProvider => {
1154
+ if (!client) {
1155
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1156
+ }
1157
+ await utils.withZeroXKeyErrorHandling(async () => {
1158
+ await client.disconnectWalletAccount(walletProvider);
1159
+ // no need here to call `maybeRefreshWallets()` because the provider emits a disconnect event which
1160
+ // will trigger a refresh via the listener we set up in `initializeWalletProviderListeners()`
1161
+ }, undefined, callbacks, "Failed to disconnect wallet account");
1162
+ }, [client, callbacks]);
1163
+ const switchWalletAccountChain = react.useCallback(async params => {
1164
+ if (!client) {
1165
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1166
+ }
1167
+ await utils.withZeroXKeyErrorHandling(async () => {
1168
+ await client.switchWalletAccountChain({
1169
+ ...params,
1170
+ walletProviders
1171
+ });
1172
+ }, undefined, callbacks, "Failed to switch wallet account chain");
1173
+ }, [client, walletProviders, callbacks]);
1174
+ const buildWalletLoginRequest = react.useCallback(async params => {
1175
+ if (!client) {
1176
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1177
+ }
1178
+ const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
1179
+ return await utils.withZeroXKeyErrorHandling(() => client.buildWalletLoginRequest({
1180
+ ...params,
1181
+ expirationSeconds
1182
+ }), undefined, callbacks, "Failed to login with wallet");
1183
+ }, [client, callbacks, masterConfig]);
1184
+ const loginWithWallet = react.useCallback(async params => {
1185
+ if (!client) {
1186
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1187
+ }
1188
+ const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
1189
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithWallet({
1190
+ ...params,
1191
+ expirationSeconds
1192
+ }), undefined, callbacks, "Failed to login with wallet");
1193
+ if (res) {
1194
+ await handlePostAuth({
1195
+ method: base.AuthMethod.Wallet,
1196
+ action: sdkTypes.AuthAction.LOGIN,
1197
+ identifier: res.address,
1198
+ appProofs: res.appProofs
1199
+ });
1200
+ }
1201
+ return res;
1202
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1203
+ const signUpWithWallet = react.useCallback(async params => {
1204
+ if (!client) {
1205
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1206
+ }
1207
+ if (!masterConfig) {
1208
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1209
+ }
1210
+ // If createSubOrgParams is not provided, use the default from masterConfig
1211
+ let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.walletAuth;
1212
+ params = createSubOrgParams !== undefined ? {
1213
+ ...params,
1214
+ createSubOrgParams
1215
+ } : {
1216
+ ...params
1217
+ };
1218
+ const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
1219
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithWallet({
1220
+ ...params,
1221
+ expirationSeconds
1222
+ }), undefined, callbacks, "Failed to sign up with wallet");
1223
+ if (res) {
1224
+ await handlePostAuth({
1225
+ method: base.AuthMethod.Wallet,
1226
+ action: sdkTypes.AuthAction.SIGNUP,
1227
+ identifier: res.address,
1228
+ appProofs: res.appProofs
1229
+ });
1230
+ }
1231
+ return res;
1232
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1233
+ const loginOrSignupWithWallet = react.useCallback(async params => {
1234
+ if (!client) {
1235
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1236
+ }
1237
+ if (!masterConfig) {
1238
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1239
+ }
1240
+ // If createSubOrgParams is not provided, use the default from masterConfig
1241
+ let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.walletAuth;
1242
+ params = createSubOrgParams !== undefined ? {
1243
+ ...params,
1244
+ createSubOrgParams
1245
+ } : {
1246
+ ...params
1247
+ };
1248
+ const expirationSeconds = params?.expirationSeconds ?? masterConfig?.auth?.sessionExpirationSeconds ?? core.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
1249
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginOrSignupWithWallet({
1250
+ ...params,
1251
+ expirationSeconds
1252
+ }), undefined, callbacks, "Failed to login or sign up with wallet");
1253
+ if (res) {
1254
+ await handlePostAuth({
1255
+ method: base.AuthMethod.Wallet,
1256
+ action: res.action,
1257
+ identifier: res.address,
1258
+ appProofs: res.appProofs
1259
+ });
1260
+ }
1261
+ return res;
1262
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1263
+ const initOtp = react.useCallback(async params => {
1264
+ if (!client) {
1265
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1266
+ }
1267
+ return utils.withZeroXKeyErrorHandling(() => client.initOtp(params), undefined, callbacks, "Failed to initialize OTP");
1268
+ }, [client, callbacks]);
1269
+ const verifyOtp = react.useCallback(async params => {
1270
+ if (!client) {
1271
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1272
+ }
1273
+ return utils.withZeroXKeyErrorHandling(() => client.verifyOtp(params), undefined, callbacks, "Failed to verify OTP");
1274
+ }, [client, callbacks]);
1275
+ const loginWithOtp = react.useCallback(async params => {
1276
+ if (!client) {
1277
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1278
+ }
1279
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithOtp(params), undefined, callbacks, "Failed to login with OTP");
1280
+ if (res) {
1281
+ await handlePostAuth({
1282
+ method: base.AuthMethod.Otp,
1283
+ action: sdkTypes.AuthAction.LOGIN,
1284
+ identifier: params.verificationToken,
1285
+ appProofs: res.appProofs
1286
+ });
1287
+ }
1288
+ return res;
1289
+ }, [client, callbacks, handlePostAuth]);
1290
+ const signUpWithOtp = react.useCallback(async params => {
1291
+ if (!client) {
1292
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1293
+ }
1294
+ if (!masterConfig) {
1295
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1296
+ }
1297
+ // If createSubOrgParams is not provided, use the default from masterConfig
1298
+ let createSubOrgParams = params.createSubOrgParams;
1299
+ if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
1300
+ if (params.otpType === core.OtpType.Email) {
1301
+ createSubOrgParams = masterConfig.auth.createSuborgParams.emailOtpAuth;
1302
+ } else if (params.otpType === core.OtpType.Sms) {
1303
+ createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
1304
+ }
1305
+ }
1306
+ params = createSubOrgParams !== undefined ? {
1307
+ ...params,
1308
+ createSubOrgParams
1309
+ } : {
1310
+ ...params
1311
+ };
1312
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithOtp(params), undefined, callbacks, "Failed to sign up with OTP");
1313
+ if (res) {
1314
+ await handlePostAuth({
1315
+ method: base.AuthMethod.Otp,
1316
+ action: sdkTypes.AuthAction.SIGNUP,
1317
+ identifier: params.verificationToken,
1318
+ appProofs: res.appProofs
1319
+ });
1320
+ }
1321
+ return res;
1322
+ }, [client, callbacks, masterConfig, handlePostAuth]);
1323
+ const completeOtp = react.useCallback(async params => {
1324
+ if (!client) {
1325
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1326
+ }
1327
+ if (!masterConfig) {
1328
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1329
+ }
1330
+ // If createSubOrgParams is not provided, use the default from masterConfig
1331
+ let createSubOrgParams = params.createSubOrgParams;
1332
+ if (!createSubOrgParams && masterConfig?.auth?.createSuborgParams) {
1333
+ if (params.otpType === core.OtpType.Email) {
1334
+ createSubOrgParams = masterConfig.auth.createSuborgParams.emailOtpAuth;
1335
+ } else if (params.otpType === core.OtpType.Sms) {
1336
+ createSubOrgParams = masterConfig.auth.createSuborgParams.smsOtpAuth;
1337
+ }
1338
+ }
1339
+ params = createSubOrgParams !== undefined ? {
1340
+ ...params,
1341
+ createSubOrgParams
1342
+ } : {
1343
+ ...params
1344
+ };
1345
+ const res = await utils.withZeroXKeyErrorHandling(() => client.completeOtp(params), undefined, callbacks, "Failed to complete OTP");
1346
+ if (res) {
1347
+ await handlePostAuth({
1348
+ method: base.AuthMethod.Otp,
1349
+ action: res.action,
1350
+ identifier: res.verificationToken,
1351
+ appProofs: res.appProofs
1352
+ });
1353
+ }
1354
+ return res;
1355
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1356
+ const loginWithOauth = react.useCallback(async params => {
1357
+ if (!client) {
1358
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1359
+ }
1360
+ const res = await utils.withZeroXKeyErrorHandling(() => client.loginWithOauth(params), undefined, callbacks, "Failed to login with OAuth");
1361
+ if (res) {
1362
+ await handlePostAuth({
1363
+ method: base.AuthMethod.Oauth,
1364
+ action: sdkTypes.AuthAction.LOGIN,
1365
+ identifier: params.oidcToken,
1366
+ appProofs: res.appProofs
1367
+ });
1368
+ }
1369
+ return res;
1370
+ }, [client, callbacks, handlePostAuth]);
1371
+ const signUpWithOauth = react.useCallback(async params => {
1372
+ if (!client) {
1373
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1374
+ }
1375
+ if (!masterConfig) {
1376
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1377
+ }
1378
+ // If createSubOrgParams is not provided, use the default from masterConfig
1379
+ let createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.oauth;
1380
+ params = createSubOrgParams !== undefined ? {
1381
+ ...params,
1382
+ createSubOrgParams
1383
+ } : {
1384
+ ...params
1385
+ };
1386
+ const res = await utils.withZeroXKeyErrorHandling(() => client.signUpWithOauth(params), undefined, callbacks, "Failed to sign up with OAuth");
1387
+ if (res) {
1388
+ await handlePostAuth({
1389
+ method: base.AuthMethod.Oauth,
1390
+ action: sdkTypes.AuthAction.SIGNUP,
1391
+ identifier: params.oidcToken,
1392
+ appProofs: res.appProofs
1393
+ });
1394
+ }
1395
+ return res;
1396
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1397
+ const completeOauth = react.useCallback(async params => {
1398
+ if (!client) {
1399
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1400
+ }
1401
+ if (!masterConfig) {
1402
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1403
+ }
1404
+ // If createSubOrgParams is not provided, use the default from masterConfig
1405
+ const createSubOrgParams = params.createSubOrgParams ?? masterConfig.auth?.createSuborgParams?.oauth;
1406
+ params = createSubOrgParams !== undefined ? {
1407
+ ...params,
1408
+ createSubOrgParams
1409
+ } : {
1410
+ ...params
1411
+ };
1412
+ const res = await utils.withZeroXKeyErrorHandling(() => client.completeOauth(params), undefined, callbacks, "Failed to complete OAuth");
1413
+ if (res) {
1414
+ await handlePostAuth({
1415
+ method: base.AuthMethod.Oauth,
1416
+ action: res.action,
1417
+ identifier: params.oidcToken,
1418
+ appProofs: res.appProofs
1419
+ });
1420
+ }
1421
+ return res;
1422
+ }, [client, callbacks, masterConfig, handlePostAuth]);
1423
+ const fetchWalletAccounts = react.useCallback(async params => {
1424
+ if (!client) {
1425
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1426
+ }
1427
+ return utils.withZeroXKeyErrorHandling(() => client.fetchWalletAccounts(params), () => logout(), callbacks, "Failed to fetch wallet accounts");
1428
+ }, [client, callbacks, logout]);
1429
+ const fetchPrivateKeys = react.useCallback(async params => {
1430
+ if (!client) {
1431
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1432
+ }
1433
+ return utils.withZeroXKeyErrorHandling(() => client.fetchPrivateKeys(params), () => logout(), callbacks, "Failed to fetch private keys");
1434
+ }, [client, callbacks, logout]);
1435
+ const signMessage = react.useCallback(async params => {
1436
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1437
+ return utils.withZeroXKeyErrorHandling(() => client.signMessage(params), () => logout(), callbacks, "Failed to sign message");
1438
+ }, [client, callbacks, logout]);
1439
+ const handleSignMessage = react.useCallback(async params => {
1440
+ const {
1441
+ successPageDuration = 2000
1442
+ } = params;
1443
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1444
+ return new Promise((resolve, reject) => {
1445
+ pushPage({
1446
+ key: "Sign message",
1447
+ content: jsxRuntime.jsx(Message.SignMessageModal, {
1448
+ message: params.message,
1449
+ subText: params?.subText,
1450
+ walletAccount: params.walletAccount,
1451
+ stampWith: params.stampWith,
1452
+ successPageDuration: successPageDuration,
1453
+ onSuccess: result => {
1454
+ resolve(result);
1455
+ },
1456
+ onError: error => {
1457
+ reject(error);
1458
+ },
1459
+ ...(params?.encoding && {
1460
+ encoding: params.encoding
1461
+ }),
1462
+ ...(params?.hashFunction && {
1463
+ hashFunction: params.hashFunction
1464
+ }),
1465
+ ...(params?.addEthereumPrefix && {
1466
+ addEthereumPrefix: params.addEthereumPrefix
1467
+ }),
1468
+ ...(params?.organizationId && {
1469
+ organizationId: params.organizationId
1470
+ })
1471
+ }),
1472
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the signing process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
1473
+ });
1474
+ });
1475
+ }, [client, callbacks, pushPage]);
1476
+ const signTransaction = react.useCallback(async params => {
1477
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1478
+ return utils.withZeroXKeyErrorHandling(() => client.signTransaction(params), () => logout(), callbacks, "Failed to sign transaction");
1479
+ }, [client, callbacks, logout]);
1480
+ const ethSendTransaction = react.useCallback(async params => {
1481
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1482
+ return utils.withZeroXKeyErrorHandling(() => client.ethSendTransaction(params), () => logout(), callbacks, "Failed to send eth transaction");
1483
+ }, [client, callbacks, logout]);
1484
+ const ethSendErc20Transfer = react.useCallback(async params => {
1485
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1486
+ return utils.withZeroXKeyErrorHandling(() => client.ethSendErc20Transfer(params), () => logout(), callbacks, "Failed to send ERC20 transfer");
1487
+ }, [client, callbacks, logout]);
1488
+ const solSendTransaction = react.useCallback(async params => {
1489
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1490
+ return utils.withZeroXKeyErrorHandling(() => client.solSendTransaction(params), () => logout(), callbacks, "Failed to send sol transaction");
1491
+ }, [client, callbacks, logout]);
1492
+ const signAndSendTransaction = react.useCallback(async params => {
1493
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1494
+ return utils.withZeroXKeyErrorHandling(() => client.signAndSendTransaction(params), () => logout(), callbacks, "Failed to sign and send transaction");
1495
+ }, [client, callbacks, logout]);
1496
+ const pollTransactionStatus = react.useCallback(async params => {
1497
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1498
+ return utils.withZeroXKeyErrorHandling(() => client.pollTransactionStatus(params), () => logout(), callbacks, "Failed to poll transaction status");
1499
+ }, [client, callbacks]);
1500
+ const fetchOrCreateP256ApiKeyUser = react.useCallback(async params => {
1501
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1502
+ return utils.withZeroXKeyErrorHandling(() => client.fetchOrCreateP256ApiKeyUser(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
1503
+ }, [client, callbacks, logout]);
1504
+ const fetchOrCreatePolicies = react.useCallback(async params => {
1505
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1506
+ return utils.withZeroXKeyErrorHandling(() => client.fetchOrCreatePolicies(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
1507
+ }, [client, callbacks, logout]);
1508
+ const updateUserEmail = react.useCallback(async params => {
1509
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1510
+ const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserEmail(params), () => logout(), callbacks, "Failed to update user email");
1511
+ if (res) await maybeRefreshUser({
1512
+ stampWith: params?.stampWith,
1513
+ ...(params?.organizationId && {
1514
+ organizationId: params.organizationId
1515
+ }),
1516
+ ...(params?.userId && {
1517
+ userId: params.userId
1518
+ })
1519
+ });
1520
+ return res;
1521
+ }, [client, callbacks, logout, maybeRefreshUser]);
1522
+ const removeUserEmail = react.useCallback(async params => {
1523
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1524
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removeUserEmail(params), () => logout(), callbacks, "Failed to remove user email");
1525
+ if (res) await maybeRefreshUser({
1526
+ stampWith: params?.stampWith,
1527
+ ...(params?.organizationId && {
1528
+ organizationId: params.organizationId
1529
+ }),
1530
+ ...(params?.userId && {
1531
+ userId: params.userId
1532
+ })
1533
+ });
1534
+ return res;
1535
+ }, [client, callbacks, logout, maybeRefreshUser]);
1536
+ const updateUserPhoneNumber = react.useCallback(async params => {
1537
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1538
+ const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserPhoneNumber(params), () => logout(), callbacks, "Failed to update user phone number");
1539
+ if (res) await maybeRefreshUser({
1540
+ stampWith: params?.stampWith,
1541
+ ...(params?.organizationId && {
1542
+ organizationId: params.organizationId
1543
+ }),
1544
+ ...(params?.userId && {
1545
+ userId: params.userId
1546
+ })
1547
+ });
1548
+ return res;
1549
+ }, [client, callbacks, logout, maybeRefreshUser]);
1550
+ const removeUserPhoneNumber = react.useCallback(async params => {
1551
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1552
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removeUserPhoneNumber(params), () => logout(), callbacks, "Failed to remove user phone number");
1553
+ if (res) await maybeRefreshUser({
1554
+ stampWith: params?.stampWith,
1555
+ ...(params?.organizationId && {
1556
+ organizationId: params.organizationId
1557
+ }),
1558
+ ...(params?.userId && {
1559
+ userId: params.userId
1560
+ })
1561
+ });
1562
+ return res;
1563
+ }, [client, callbacks, logout, maybeRefreshUser]);
1564
+ const updateUserName = react.useCallback(async params => {
1565
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1566
+ const res = await utils.withZeroXKeyErrorHandling(() => client.updateUserName(params), () => logout(), callbacks, "Failed to update user name");
1567
+ if (res) await maybeRefreshUser({
1568
+ stampWith: params?.stampWith,
1569
+ ...(params?.organizationId && {
1570
+ organizationId: params.organizationId
1571
+ }),
1572
+ ...(params?.userId && {
1573
+ userId: params.userId
1574
+ })
1575
+ });
1576
+ return res;
1577
+ }, [client, callbacks, logout, maybeRefreshUser]);
1578
+ const addOauthProvider = react.useCallback(async params => {
1579
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1580
+ const res = await utils.withZeroXKeyErrorHandling(() => client.addOauthProvider(params), () => logout(), callbacks, "Failed to add OAuth provider");
1581
+ if (res) await maybeRefreshUser({
1582
+ stampWith: params?.stampWith,
1583
+ ...(params?.organizationId && {
1584
+ organizationId: params.organizationId
1585
+ }),
1586
+ ...(params?.userId && {
1587
+ userId: params.userId
1588
+ })
1589
+ });
1590
+ return res;
1591
+ }, [client, callbacks, logout, maybeRefreshUser]);
1592
+ const removeOauthProviders = react.useCallback(async params => {
1593
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1594
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removeOauthProviders(params), () => logout(), callbacks, "Failed to remove OAuth providers");
1595
+ if (res) await maybeRefreshUser({
1596
+ stampWith: params?.stampWith,
1597
+ ...(params?.organizationId && {
1598
+ organizationId: params.organizationId
1599
+ }),
1600
+ ...(params?.userId && {
1601
+ userId: params.userId
1602
+ })
1603
+ });
1604
+ return res;
1605
+ }, [client, callbacks, logout, maybeRefreshUser]);
1606
+ const addPasskey = react.useCallback(async params => {
1607
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1608
+ const res = await utils.withZeroXKeyErrorHandling(() => client.addPasskey(params), () => logout(), callbacks, "Failed to add passkey");
1609
+ if (res) await maybeRefreshUser({
1610
+ stampWith: params?.stampWith,
1611
+ ...(params?.organizationId && {
1612
+ organizationId: params.organizationId
1613
+ }),
1614
+ ...(params?.userId && {
1615
+ userId: params.userId
1616
+ })
1617
+ });
1618
+ return res;
1619
+ }, [client, callbacks, logout, maybeRefreshUser]);
1620
+ const removePasskeys = react.useCallback(async params => {
1621
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1622
+ const res = await utils.withZeroXKeyErrorHandling(() => client.removePasskeys(params), () => logout(), callbacks, "Failed to remove passkeys");
1623
+ if (res) await maybeRefreshUser({
1624
+ stampWith: params?.stampWith,
1625
+ ...(params?.organizationId && {
1626
+ organizationId: params.organizationId
1627
+ }),
1628
+ ...(params?.userId && {
1629
+ userId: params.userId
1630
+ })
1631
+ });
1632
+ return res;
1633
+ }, [client, callbacks, logout, maybeRefreshUser]);
1634
+ const createWallet = react.useCallback(async params => {
1635
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1636
+ const res = await utils.withZeroXKeyErrorHandling(() => client.createWallet(params), () => logout(), callbacks, "Failed to create wallet");
1637
+ const s = await getSession();
1638
+ if (res && s) await maybeRefreshWallets({
1639
+ stampWith: params?.stampWith,
1640
+ ...(params?.organizationId && {
1641
+ organizationId: params.organizationId
1642
+ })
1643
+ });
1644
+ return res;
1645
+ }, [client, session, callbacks, logout, maybeRefreshWallets, getSession]);
1646
+ const createWalletAccounts = react.useCallback(async params => {
1647
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1648
+ const res = await utils.withZeroXKeyErrorHandling(() => client.createWalletAccounts(params), () => logout(), callbacks, "Failed to create wallet accounts");
1649
+ const s = await getSession();
1650
+ if (res && s) await maybeRefreshWallets({
1651
+ stampWith: params?.stampWith,
1652
+ ...(params?.organizationId && {
1653
+ organizationId: params.organizationId
1654
+ })
1655
+ });
1656
+ return res;
1657
+ }, [client, session, callbacks, logout, getSession, maybeRefreshWallets]);
1658
+ const exportWallet = react.useCallback(async params => {
1659
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1660
+ const res = await utils.withZeroXKeyErrorHandling(() => client.exportWallet(params), () => logout(), callbacks, "Failed to export wallet");
1661
+ const s = await getSession();
1662
+ if (res && s) await maybeRefreshWallets({
1663
+ stampWith: params?.stampWith,
1664
+ ...(params?.organizationId && {
1665
+ organizationId: params.organizationId
1666
+ })
1667
+ });
1668
+ return res;
1669
+ }, [client, session, callbacks, logout, getSession, maybeRefreshWallets]);
1670
+ const exportPrivateKey = react.useCallback(async params => {
1671
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1672
+ const res = await utils.withZeroXKeyErrorHandling(() => client.exportPrivateKey(params), () => logout(), callbacks, "Failed to export private key");
1673
+ return res;
1674
+ }, [client, callbacks, logout]);
1675
+ const exportWalletAccount = react.useCallback(async params => {
1676
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1677
+ const res = await utils.withZeroXKeyErrorHandling(() => client.exportWalletAccount(params), () => logout(), callbacks, "Failed to export wallet accounts");
1678
+ const s = await getSession();
1679
+ if (res && s) await maybeRefreshWallets({
1680
+ stampWith: params?.stampWith,
1681
+ ...(params?.organizationId && {
1682
+ organizationId: params.organizationId
1683
+ })
1684
+ });
1685
+ return res;
1686
+ }, [client, callbacks, logout, getSession, maybeRefreshWallets]);
1687
+ const importWallet = react.useCallback(async params => {
1688
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1689
+ const res = await utils.withZeroXKeyErrorHandling(() => client.importWallet(params), () => logout(), callbacks, "Failed to import wallet");
1690
+ const s = await getSession();
1691
+ if (res && s) await maybeRefreshWallets({
1692
+ stampWith: params?.stampWith,
1693
+ ...(params?.organizationId && {
1694
+ organizationId: params.organizationId
1695
+ }),
1696
+ ...(params?.userId && {
1697
+ userId: params.userId
1698
+ })
1699
+ });
1700
+ return res;
1701
+ }, [client, callbacks, logout, getSession, maybeRefreshWallets]);
1702
+ const importPrivateKey = react.useCallback(async params => {
1703
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1704
+ const res = await utils.withZeroXKeyErrorHandling(() => client.importPrivateKey(params), () => logout(), callbacks, "Failed to import private key");
1705
+ return res;
1706
+ }, [client, callbacks, logout]);
1707
+ const deleteSubOrganization = react.useCallback(async params => {
1708
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1709
+ return utils.withZeroXKeyErrorHandling(() => client.deleteSubOrganization(params), () => logout(), callbacks, "Failed to delete sub-organization");
1710
+ }, [client, callbacks, logout]);
1711
+ const storeSession = react.useCallback(async params => {
1712
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1713
+ await utils.withZeroXKeyErrorHandling(() => client.storeSession(params), () => logout(), callbacks, "Failed to store session");
1714
+ const sessionKey = await getActiveSessionKey();
1715
+ const session = await getSession({
1716
+ ...(sessionKey && {
1717
+ sessionKey
1718
+ })
1719
+ });
1720
+ if (session && sessionKey) await scheduleSessionExpiration({
1721
+ sessionKey,
1722
+ expiry: session.expiry
1723
+ });
1724
+ const allSessions = await getAllSessions();
1725
+ setSession(session);
1726
+ setAllSessions(allSessions);
1727
+ await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
1728
+ }, [client, callbacks, logout, getActiveSessionKey, getSession, scheduleSessionExpiration, getAllSessions, maybeRefreshWallets, maybeRefreshUser]);
1729
+ const clearAllSessions = react.useCallback(async () => {
1730
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1731
+ setSession(undefined);
1732
+ setAllSessions(undefined);
1733
+ clearSessionTimeouts();
1734
+ return await utils.withZeroXKeyErrorHandling(() => client.clearAllSessions(), () => logout(), callbacks, "Failed to clear all sessions");
1735
+ }, [client, callbacks, logout, clearSessionTimeouts]);
1736
+ const setActiveSession = react.useCallback(async params => {
1737
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1738
+ const session = await utils.withZeroXKeyErrorHandling(() => client.getSession({
1739
+ sessionKey: params.sessionKey
1740
+ }), () => logout(), callbacks, "Failed to get session");
1741
+ const s = await getSession();
1742
+ if (!s) {
1743
+ throw new sdkTypes.ZeroXKeyError("Session not found.", sdkTypes.ZeroXKeyErrorCodes.NOT_FOUND);
1744
+ }
1745
+ await utils.withZeroXKeyErrorHandling(() => client.setActiveSession(params), () => logout(), callbacks, "Failed to set active session");
1746
+ setSession(session);
1747
+ await utils.withZeroXKeyErrorHandling(async () => {
1748
+ await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
1749
+ }, () => logout(), callbacks, "Failed to refresh data after setting active session");
1750
+ return;
1751
+ }, [client, callbacks, logout, getSession, maybeRefreshWallets, maybeRefreshUser]);
1752
+ const clearUnusedKeyPairs = react.useCallback(async () => {
1753
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1754
+ return utils.withZeroXKeyErrorHandling(() => client.clearUnusedKeyPairs(), undefined, callbacks, "Failed to clear unused key pairs");
1755
+ }, [client, callbacks]);
1756
+ const createApiKeyPair = react.useCallback(async params => {
1757
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1758
+ return utils.withZeroXKeyErrorHandling(() => client.createApiKeyPair(params), undefined, callbacks, "Failed to create API key pair");
1759
+ }, [client, callbacks]);
1760
+ const getProxyAuthConfig = react.useCallback(async () => {
1761
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1762
+ return utils.withZeroXKeyErrorHandling(() => client.getProxyAuthConfig(), undefined, callbacks, "Failed to get proxy auth config");
1763
+ }, [client, callbacks]);
1764
+ const fetchBootProofForAppProof = react.useCallback(async params => {
1765
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1766
+ return utils.withZeroXKeyErrorHandling(() => client.fetchBootProofForAppProof(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
1767
+ }, [client, callbacks, logout]);
1768
+ const verifyAppProofs = react.useCallback(async params => {
1769
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
1770
+ return utils.withZeroXKeyErrorHandling(() => client.verifyAppProofs(params), () => logout(), callbacks, "Failed to verify app proofs");
1771
+ }, [client, callbacks, logout]);
1772
+ const handleDiscordOauth = react.useCallback(async params => {
1773
+ const {
1774
+ clientId = masterConfig?.auth?.oauthConfig?.discordClientId,
1775
+ openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
1776
+ additionalState: additionalParameters
1777
+ } = params || {};
1778
+ const provider = sdkTypes.OAuthProviders.DISCORD;
1779
+ if (!masterConfig) {
1780
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1781
+ }
1782
+ if (!clientId) {
1783
+ throw new sdkTypes.ZeroXKeyError("Discord Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1784
+ }
1785
+ if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
1786
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1787
+ }
1788
+ const flow = openInPage ? "redirect" : "popup";
1789
+ const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
1790
+ // Create key pair and generate nonce
1791
+ const publicKey = await createApiKeyPair();
1792
+ if (!publicKey) {
1793
+ throw new Error("Failed to create public key for OAuth.");
1794
+ }
1795
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1796
+ // Generate PKCE challenge pair and store verifier
1797
+ const {
1798
+ verifier,
1799
+ codeChallenge
1800
+ } = await pkce.generateChallengePair();
1801
+ storage.storePKCEVerifier(provider, verifier);
1802
+ // Build OAuth URL
1803
+ const authUrl = url.buildOAuthUrl({
1804
+ provider,
1805
+ clientId,
1806
+ redirectUri,
1807
+ publicKey,
1808
+ nonce,
1809
+ flow,
1810
+ codeChallenge,
1811
+ additionalState: additionalParameters
1812
+ });
1813
+ if (openInPage) {
1814
+ // Remainder of logic will occur in completeRedirectOauth
1815
+ return url.redirectToOAuthProvider(authUrl);
1816
+ }
1817
+ // Popup flow
1818
+ const authWindow = url.openOAuthPopup();
1819
+ if (!authWindow) {
1820
+ throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
1821
+ }
1822
+ authWindow.location.href = authUrl;
1823
+ return new Promise((resolve, reject) => {
1824
+ const interval = setInterval(() => {
1825
+ try {
1826
+ if (authWindow.closed) {
1827
+ clearInterval(interval);
1828
+ reject(new Error("Authentication window was closed."));
1829
+ return;
1830
+ }
1831
+ const url$1 = authWindow.location.href || "";
1832
+ if (url$1.startsWith(window.location.origin)) {
1833
+ const result = url.parseOAuthResponse(url$1, provider);
1834
+ if (result) {
1835
+ authWindow.close();
1836
+ clearInterval(interval);
1837
+ completion.completeOAuthPopup({
1838
+ provider,
1839
+ publicKey,
1840
+ result,
1841
+ callbacks,
1842
+ completeOauth,
1843
+ onOauthSuccess: params?.onOauthSuccess,
1844
+ exchangeCodeForToken: async codeVerifier => {
1845
+ const resp = await client?.httpClient.proxyOAuth2Authenticate({
1846
+ provider: "OAUTH2_PROVIDER_DISCORD",
1847
+ authCode: result.authCode,
1848
+ redirectUri,
1849
+ codeVerifier,
1850
+ clientId,
1851
+ nonce
1852
+ });
1853
+ return resp?.oidcToken ?? "";
1854
+ }
1855
+ }).then(() => resolve()).catch(reject);
1856
+ }
1857
+ }
1858
+ } catch {
1859
+ // ignore cross-origin
1860
+ }
1861
+ }, 500);
1862
+ if (authWindow.closed) {
1863
+ clearInterval(interval);
1864
+ }
1865
+ });
1866
+ }, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
1867
+ const handleXOauth = react.useCallback(async params => {
1868
+ const {
1869
+ clientId = masterConfig?.auth?.oauthConfig?.xClientId,
1870
+ openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
1871
+ additionalState: additionalParameters
1872
+ } = params || {};
1873
+ const provider = sdkTypes.OAuthProviders.X;
1874
+ if (!masterConfig) {
1875
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1876
+ }
1877
+ if (!clientId) {
1878
+ throw new sdkTypes.ZeroXKeyError("Twitter Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1879
+ }
1880
+ if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
1881
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1882
+ }
1883
+ const flow = openInPage ? "redirect" : "popup";
1884
+ const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
1885
+ // Create key pair and generate nonce
1886
+ const publicKey = await createApiKeyPair();
1887
+ if (!publicKey) {
1888
+ throw new Error("Failed to create public key for OAuth.");
1889
+ }
1890
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1891
+ // Generate PKCE challenge pair and store verifier
1892
+ const {
1893
+ verifier,
1894
+ codeChallenge
1895
+ } = await pkce.generateChallengePair();
1896
+ storage.storePKCEVerifier(provider, verifier);
1897
+ // Build OAuth URL
1898
+ const authUrl = url.buildOAuthUrl({
1899
+ provider,
1900
+ clientId,
1901
+ redirectUri,
1902
+ publicKey,
1903
+ nonce,
1904
+ flow,
1905
+ codeChallenge,
1906
+ additionalState: additionalParameters
1907
+ });
1908
+ if (openInPage) {
1909
+ // Remainder of logic will occur in completeRedirectOauth
1910
+ return url.redirectToOAuthProvider(authUrl);
1911
+ }
1912
+ // Popup flow
1913
+ const authWindow = url.openOAuthPopup();
1914
+ if (!authWindow) {
1915
+ throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
1916
+ }
1917
+ authWindow.location.href = authUrl;
1918
+ return new Promise((resolve, reject) => {
1919
+ const interval = setInterval(() => {
1920
+ try {
1921
+ if (authWindow.closed) {
1922
+ clearInterval(interval);
1923
+ reject(new Error("Authentication window was closed."));
1924
+ return;
1925
+ }
1926
+ const url$1 = authWindow.location.href || "";
1927
+ if (url$1.startsWith(window.location.origin)) {
1928
+ const result = url.parseOAuthResponse(url$1, provider);
1929
+ if (result) {
1930
+ authWindow.close();
1931
+ clearInterval(interval);
1932
+ completion.completeOAuthPopup({
1933
+ provider,
1934
+ publicKey,
1935
+ result,
1936
+ callbacks,
1937
+ completeOauth,
1938
+ onOauthSuccess: params?.onOauthSuccess,
1939
+ exchangeCodeForToken: async codeVerifier => {
1940
+ const resp = await client?.httpClient.proxyOAuth2Authenticate({
1941
+ provider: "OAUTH2_PROVIDER_X",
1942
+ authCode: result.authCode,
1943
+ redirectUri,
1944
+ codeVerifier,
1945
+ clientId,
1946
+ nonce
1947
+ });
1948
+ return resp?.oidcToken ?? "";
1949
+ }
1950
+ }).then(() => resolve()).catch(reject);
1951
+ }
1952
+ }
1953
+ } catch {
1954
+ // ignore cross-origin
1955
+ }
1956
+ }, 500);
1957
+ if (authWindow.closed) {
1958
+ clearInterval(interval);
1959
+ }
1960
+ });
1961
+ }, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
1962
+ const handleGoogleOauth = react.useCallback(async params => {
1963
+ const {
1964
+ clientId = masterConfig?.auth?.oauthConfig?.googleClientId,
1965
+ openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
1966
+ additionalState: additionalParameters
1967
+ } = params || {};
1968
+ const provider = sdkTypes.OAuthProviders.GOOGLE;
1969
+ if (!masterConfig) {
1970
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1971
+ }
1972
+ if (!clientId) {
1973
+ throw new sdkTypes.ZeroXKeyError("Google Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1974
+ }
1975
+ if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
1976
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
1977
+ }
1978
+ const flow = openInPage ? "redirect" : "popup";
1979
+ // Google requires no trailing slash
1980
+ const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri.replace(/\/$/, "");
1981
+ // Create key pair and generate nonce
1982
+ const publicKey = await createApiKeyPair();
1983
+ if (!publicKey) {
1984
+ throw new Error("Failed to create public key for OAuth.");
1985
+ }
1986
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
1987
+ // Build OAuth URL
1988
+ const authUrl = url.buildOAuthUrl({
1989
+ provider,
1990
+ clientId,
1991
+ redirectUri,
1992
+ publicKey,
1993
+ nonce,
1994
+ flow,
1995
+ additionalState: additionalParameters
1996
+ });
1997
+ if (openInPage) {
1998
+ // Remainder of logic will occur in completeRedirectOauth
1999
+ return url.redirectToOAuthProvider(authUrl);
2000
+ }
2001
+ // Popup flow
2002
+ const authWindow = url.openOAuthPopup();
2003
+ if (!authWindow) {
2004
+ throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
2005
+ }
2006
+ authWindow.location.href = authUrl;
2007
+ return new Promise((resolve, reject) => {
2008
+ const interval = setInterval(() => {
2009
+ try {
2010
+ if (authWindow.closed) {
2011
+ clearInterval(interval);
2012
+ reject(new Error("Authentication window was closed."));
2013
+ return;
2014
+ }
2015
+ const url$1 = authWindow.location.href || "";
2016
+ if (url$1.startsWith(window.location.origin)) {
2017
+ const result = url.parseOAuthResponse(url$1, provider);
2018
+ if (result) {
2019
+ authWindow.close();
2020
+ clearInterval(interval);
2021
+ completion.completeOAuthPopup({
2022
+ provider,
2023
+ publicKey,
2024
+ result,
2025
+ callbacks,
2026
+ completeOauth,
2027
+ onOauthSuccess: params?.onOauthSuccess
2028
+ }).then(() => resolve()).catch(reject);
2029
+ }
2030
+ }
2031
+ } catch {
2032
+ // Ignore cross-origin errors
2033
+ }
2034
+ }, 500);
2035
+ if (authWindow.closed) {
2036
+ clearInterval(interval);
2037
+ }
2038
+ });
2039
+ }, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
2040
+ const handleAppleOauth = react.useCallback(async params => {
2041
+ const {
2042
+ clientId = masterConfig?.auth?.oauthConfig?.appleClientId,
2043
+ openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
2044
+ additionalState: additionalParameters
2045
+ } = params || {};
2046
+ const provider = sdkTypes.OAuthProviders.APPLE;
2047
+ if (!masterConfig) {
2048
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
2049
+ }
2050
+ if (!clientId) {
2051
+ throw new sdkTypes.ZeroXKeyError("Apple Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
2052
+ }
2053
+ if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
2054
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
2055
+ }
2056
+ const flow = openInPage ? "redirect" : "popup";
2057
+ // TODO (Amir): Apple needs the '/' at the end. Maybe we should add it if not there?
2058
+ const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
2059
+ // Create key pair and generate nonce
2060
+ const publicKey = await createApiKeyPair();
2061
+ if (!publicKey) {
2062
+ throw new Error("Failed to create public key for OAuth.");
2063
+ }
2064
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
2065
+ // Build OAuth URL
2066
+ const authUrl = url.buildOAuthUrl({
2067
+ provider,
2068
+ clientId,
2069
+ redirectUri,
2070
+ publicKey,
2071
+ nonce,
2072
+ flow,
2073
+ additionalState: additionalParameters
2074
+ });
2075
+ if (openInPage) {
2076
+ // Remainder of logic will occur in completeRedirectOauth
2077
+ return url.redirectToOAuthProvider(authUrl);
2078
+ }
2079
+ // Popup flow
2080
+ const authWindow = url.openOAuthPopup();
2081
+ if (!authWindow) {
2082
+ throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
2083
+ }
2084
+ authWindow.location.href = authUrl;
2085
+ return new Promise((resolve, reject) => {
2086
+ const interval = setInterval(() => {
2087
+ try {
2088
+ if (authWindow.closed) {
2089
+ clearInterval(interval);
2090
+ reject(new Error("Authentication window was closed."));
2091
+ return;
2092
+ }
2093
+ const url$1 = authWindow.location.href || "";
2094
+ if (url$1.startsWith(window.location.origin)) {
2095
+ const result = url.parseOAuthResponse(url$1, provider);
2096
+ if (result) {
2097
+ authWindow.close();
2098
+ clearInterval(interval);
2099
+ completion.completeOAuthPopup({
2100
+ provider,
2101
+ publicKey,
2102
+ result,
2103
+ callbacks,
2104
+ completeOauth,
2105
+ onOauthSuccess: params?.onOauthSuccess
2106
+ }).then(() => resolve()).catch(reject);
2107
+ }
2108
+ }
2109
+ } catch {
2110
+ // Ignore cross-origin errors
2111
+ }
2112
+ }, 500);
2113
+ if (authWindow.closed) {
2114
+ clearInterval(interval);
2115
+ }
2116
+ });
2117
+ }, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
2118
+ const handleFacebookOauth = react.useCallback(async params => {
2119
+ const {
2120
+ clientId = masterConfig?.auth?.oauthConfig?.facebookClientId,
2121
+ openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
2122
+ additionalState: additionalParameters
2123
+ } = params || {};
2124
+ const provider = sdkTypes.OAuthProviders.FACEBOOK;
2125
+ if (!masterConfig) {
2126
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
2127
+ }
2128
+ if (!clientId) {
2129
+ throw new sdkTypes.ZeroXKeyError("Facebook Client ID is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
2130
+ }
2131
+ if (!masterConfig.auth?.oauthConfig?.oauthRedirectUri) {
2132
+ throw new sdkTypes.ZeroXKeyError("OAuth Redirect URI is not configured.", sdkTypes.ZeroXKeyErrorCodes.INVALID_CONFIGURATION);
2133
+ }
2134
+ const flow = openInPage ? "redirect" : "popup";
2135
+ const redirectUri = masterConfig.auth?.oauthConfig.oauthRedirectUri;
2136
+ // Create key pair and generate nonce
2137
+ const publicKey = await createApiKeyPair();
2138
+ if (!publicKey) {
2139
+ throw new Error("Failed to create public key for OAuth.");
2140
+ }
2141
+ const nonce = utils$1.bytesToHex(sha2.sha256(publicKey));
2142
+ // Generate PKCE challenge pair and store verifier
2143
+ const {
2144
+ verifier,
2145
+ codeChallenge
2146
+ } = await pkce.generateChallengePair();
2147
+ storage.storePKCEVerifier(provider, verifier);
2148
+ // Build OAuth URL
2149
+ const authUrl = url.buildOAuthUrl({
2150
+ provider,
2151
+ clientId,
2152
+ redirectUri,
2153
+ publicKey,
2154
+ nonce,
2155
+ flow,
2156
+ codeChallenge,
2157
+ additionalState: additionalParameters
2158
+ });
2159
+ if (openInPage) {
2160
+ // Remainder of logic will occur in completeRedirectOauth
2161
+ return url.redirectToOAuthProvider(authUrl);
2162
+ }
2163
+ // Popup flow
2164
+ const authWindow = url.openOAuthPopup();
2165
+ if (!authWindow) {
2166
+ throw new Error(`Failed to open ${helpers.capitalizeProviderName(provider)} login window.`);
2167
+ }
2168
+ authWindow.location.href = authUrl;
2169
+ return new Promise((resolve, reject) => {
2170
+ const interval = setInterval(() => {
2171
+ try {
2172
+ if (authWindow.closed) {
2173
+ clearInterval(interval);
2174
+ reject(new Error("Authentication window was closed."));
2175
+ return;
2176
+ }
2177
+ const url$1 = authWindow.location.href || "";
2178
+ if (url$1.startsWith(window.location.origin)) {
2179
+ const result = url.parseOAuthResponse(url$1, provider);
2180
+ if (result) {
2181
+ authWindow.close();
2182
+ clearInterval(interval);
2183
+ completion.completeOAuthPopup({
2184
+ provider,
2185
+ publicKey,
2186
+ result,
2187
+ callbacks,
2188
+ completeOauth,
2189
+ onOauthSuccess: params?.onOauthSuccess,
2190
+ exchangeCodeForToken: async codeVerifier => {
2191
+ const tokenData = await pkce.exchangeFacebookCodeForToken(clientId, redirectUri, result.authCode, codeVerifier);
2192
+ return tokenData.id_token;
2193
+ }
2194
+ }).then(() => resolve()).catch(reject);
2195
+ }
2196
+ }
2197
+ } catch {
2198
+ // Ignore cross-origin errors
2199
+ }
2200
+ }, 500);
2201
+ if (authWindow.closed) {
2202
+ clearInterval(interval);
2203
+ }
2204
+ });
2205
+ }, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
2206
+ const handleLogin = react.useCallback(async params => {
2207
+ const logo = masterConfig?.ui?.darkMode ? params?.logoDark ?? masterConfig?.ui?.logoDark : params?.logoLight ?? masterConfig?.ui?.logoLight;
2208
+ pushPage({
2209
+ key: params?.title ?? "Log in or sign up",
2210
+ content: jsxRuntime.jsx(index.AuthComponent, {
2211
+ sessionKey: params?.sessionKey,
2212
+ logo: logo,
2213
+ logoClassName: params?.logoClassName,
2214
+ title: params?.title
2215
+ }),
2216
+ showTitle: false,
2217
+ preventClose: true
2218
+ });
2219
+ }, [pushPage, masterConfig]);
2220
+ const handleExportWallet = react.useCallback(async params => {
2221
+ const {
2222
+ walletId,
2223
+ targetPublicKey,
2224
+ stampWith,
2225
+ organizationId
2226
+ } = params;
2227
+ return new Promise((resolve, reject) => pushPage({
2228
+ key: "Export wallet",
2229
+ content: jsxRuntime.jsx(Export.ExportComponent, {
2230
+ target: walletId,
2231
+ exportType: base.ExportType.Wallet,
2232
+ ...(targetPublicKey !== undefined && {
2233
+ targetPublicKey
2234
+ }),
2235
+ ...(stampWith !== undefined && {
2236
+ stampWith
2237
+ }),
2238
+ ...(organizationId !== undefined && {
2239
+ organizationId
2240
+ }),
2241
+ onSuccess: () => resolve(),
2242
+ onError: error => reject(error)
2243
+ }),
2244
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the export wallet process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
2245
+ }));
2246
+ }, [pushPage]);
2247
+ const handleExportPrivateKey = react.useCallback(async params => {
2248
+ const {
2249
+ privateKeyId,
2250
+ targetPublicKey,
2251
+ keyFormat,
2252
+ stampWith,
2253
+ organizationId
2254
+ } = params;
2255
+ return new Promise((resolve, reject) => pushPage({
2256
+ key: "Export private key",
2257
+ content: jsxRuntime.jsx(Export.ExportComponent, {
2258
+ target: privateKeyId,
2259
+ exportType: base.ExportType.PrivateKey,
2260
+ ...(keyFormat !== undefined && {
2261
+ keyFormat
2262
+ }),
2263
+ ...(targetPublicKey !== undefined && {
2264
+ targetPublicKey
2265
+ }),
2266
+ ...(stampWith !== undefined && {
2267
+ stampWith
2268
+ }),
2269
+ ...(organizationId !== undefined && {
2270
+ organizationId
2271
+ }),
2272
+ onSuccess: () => resolve(),
2273
+ onError: error => reject(error)
2274
+ }),
2275
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the export private key process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
2276
+ }));
2277
+ }, [pushPage]);
2278
+ const handleExportWalletAccount = react.useCallback(async params => {
2279
+ const {
2280
+ address,
2281
+ targetPublicKey,
2282
+ keyFormat,
2283
+ stampWith,
2284
+ organizationId
2285
+ } = params;
2286
+ return new Promise((resolve, reject) => pushPage({
2287
+ key: "Export wallet account",
2288
+ content: jsxRuntime.jsx(Export.ExportComponent, {
2289
+ target: address,
2290
+ exportType: base.ExportType.WalletAccount,
2291
+ ...(keyFormat !== undefined && {
2292
+ keyFormat
2293
+ }),
2294
+ ...(targetPublicKey !== undefined && {
2295
+ targetPublicKey
2296
+ }),
2297
+ ...(stampWith !== undefined && {
2298
+ stampWith
2299
+ }),
2300
+ ...(organizationId !== undefined && {
2301
+ organizationId
2302
+ }),
2303
+ onSuccess: () => resolve(),
2304
+ onError: error => reject(error)
2305
+ }),
2306
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the export wallet account process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
2307
+ }));
2308
+ }, [pushPage]);
2309
+ const handleImportWallet = react.useCallback(async params => {
2310
+ const {
2311
+ defaultWalletAccounts,
2312
+ successPageDuration = 2000,
2313
+ stampWith,
2314
+ walletName,
2315
+ clearClipboardOnPaste,
2316
+ organizationId,
2317
+ userId
2318
+ } = params || {};
2319
+ try {
2320
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => pushPage({
2321
+ key: "Import wallet",
2322
+ content: jsxRuntime.jsx(Import.ImportComponent, {
2323
+ importType: base.ImportType.Wallet,
2324
+ onError: error => {
2325
+ reject(error);
2326
+ },
2327
+ onSuccess: walletId => resolve(walletId),
2328
+ ...(defaultWalletAccounts !== undefined && {
2329
+ defaultWalletAccounts
2330
+ }),
2331
+ ...(successPageDuration !== undefined && {
2332
+ successPageDuration
2333
+ }),
2334
+ ...(clearClipboardOnPaste !== undefined && {
2335
+ clearClipboardOnPaste // Note: This is defaulted to true in the IframeStamper
2336
+ }),
2337
+ ...(stampWith !== undefined && {
2338
+ stampWith
2339
+ }),
2340
+ ...(walletName !== undefined && {
2341
+ name: walletName
2342
+ }),
2343
+ ...(organizationId !== undefined && {
2344
+ organizationId
2345
+ }),
2346
+ ...(userId !== undefined && {
2347
+ userId
2348
+ })
2349
+ })
2350
+ })), () => logout());
2351
+ } catch (error) {
2352
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2353
+ throw error;
2354
+ }
2355
+ throw new sdkTypes.ZeroXKeyError("Failed to import wallet.", sdkTypes.ZeroXKeyErrorCodes.IMPORT_WALLET_ERROR, error);
2356
+ }
2357
+ }, [pushPage, logout]);
2358
+ const handleImportPrivateKey = react.useCallback(async params => {
2359
+ const {
2360
+ curve,
2361
+ addressFormats,
2362
+ successPageDuration = 2000,
2363
+ stampWith,
2364
+ keyName,
2365
+ keyFormat,
2366
+ clearClipboardOnPaste,
2367
+ organizationId
2368
+ } = params || {};
2369
+ try {
2370
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => pushPage({
2371
+ key: "Import private key",
2372
+ content: jsxRuntime.jsx(Import.ImportComponent, {
2373
+ importType: base.ImportType.PrivateKey,
2374
+ curve: curve,
2375
+ addressFormats: addressFormats,
2376
+ keyFormat: keyFormat,
2377
+ onError: error => {
2378
+ reject(error);
2379
+ },
2380
+ onSuccess: privateKeyId => resolve(privateKeyId),
2381
+ ...(successPageDuration !== undefined && {
2382
+ successPageDuration
2383
+ }),
2384
+ ...(clearClipboardOnPaste !== undefined && {
2385
+ clearClipboardOnPaste // Note: This is defaulted to true in the IframeStamper
2386
+ }),
2387
+ ...(stampWith !== undefined && {
2388
+ stampWith
2389
+ }),
2390
+ ...(keyName !== undefined && {
2391
+ name: keyName
2392
+ }),
2393
+ ...(organizationId !== undefined && {
2394
+ organizationId
2395
+ })
2396
+ })
2397
+ })), () => logout());
2398
+ } catch (error) {
2399
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2400
+ throw error;
2401
+ }
2402
+ throw new sdkTypes.ZeroXKeyError("Failed to import private key.", sdkTypes.ZeroXKeyErrorCodes.IMPORT_WALLET_ERROR, error);
2403
+ }
2404
+ }, [pushPage, logout]);
2405
+ const handleUpdateUserName = react.useCallback(async params => {
2406
+ const {
2407
+ successPageDuration = 2000,
2408
+ subTitle,
2409
+ title,
2410
+ stampWith
2411
+ } = params || {};
2412
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
2413
+ const s = await getSession();
2414
+ const organizationId = params?.organizationId || s?.organizationId;
2415
+ if (!organizationId) {
2416
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2417
+ }
2418
+ const userId = params?.userId || user?.userId;
2419
+ if (!userId) {
2420
+ throw new sdkTypes.ZeroXKeyError("A user ID is required to update a user name.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2421
+ }
2422
+ const onSuccess = () => {
2423
+ if (!successPageDuration) return;
2424
+ pushPage({
2425
+ key: "success",
2426
+ content: jsxRuntime.jsx(Success.SuccessPage, {
2427
+ text: "User name changed successfully!",
2428
+ duration: successPageDuration,
2429
+ onComplete: () => {
2430
+ closeModal();
2431
+ }
2432
+ }),
2433
+ preventBack: true,
2434
+ showTitle: false
2435
+ });
2436
+ };
2437
+ try {
2438
+ if (!params?.userName && params?.userName !== "") {
2439
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2440
+ pushPage({
2441
+ key: "Update User Name",
2442
+ content: jsxRuntime.jsx(UpdateUserName.UpdateUserName, {
2443
+ onSuccess: userId => {
2444
+ resolve(userId);
2445
+ },
2446
+ onError: error => {
2447
+ reject(error);
2448
+ },
2449
+ successPageDuration: successPageDuration,
2450
+ stampWith: stampWith,
2451
+ ...(title !== undefined && {
2452
+ title
2453
+ }),
2454
+ ...(subTitle !== undefined && {
2455
+ subTitle
2456
+ }),
2457
+ organizationId: organizationId,
2458
+ userId: userId
2459
+ }),
2460
+ showTitle: false
2461
+ });
2462
+ }), () => logout());
2463
+ } else {
2464
+ const res = await updateUserName({
2465
+ userName: params.userName,
2466
+ userId: params.userId ?? user.userId,
2467
+ stampWith,
2468
+ ...(organizationId !== undefined && {
2469
+ organizationId
2470
+ })
2471
+ });
2472
+ onSuccess();
2473
+ return res;
2474
+ }
2475
+ } catch (error) {
2476
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2477
+ throw error;
2478
+ }
2479
+ throw new sdkTypes.ZeroXKeyError("Failed to update user name.", sdkTypes.ZeroXKeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
2480
+ }
2481
+ }, [client, getSession, user, pushPage, closeModal, updateUserName, logout]);
2482
+ const handleUpdateUserPhoneNumber = react.useCallback(async params => {
2483
+ const {
2484
+ successPageDuration = 2000,
2485
+ subTitle,
2486
+ title,
2487
+ stampWith
2488
+ } = params || {};
2489
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
2490
+ if (!masterConfig) {
2491
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.CONFIG_NOT_INITIALIZED);
2492
+ }
2493
+ if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
2494
+ throw new sdkTypes.ZeroXKeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.ZeroXKeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
2495
+ }
2496
+ const s = await getSession();
2497
+ const organizationId = params?.organizationId || s?.organizationId;
2498
+ if (!organizationId) {
2499
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2500
+ }
2501
+ const userId = params?.userId || s?.userId;
2502
+ if (!userId) {
2503
+ throw new sdkTypes.ZeroXKeyError("A user ID is required to update a phone number.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2504
+ }
2505
+ const onSuccess = () => {
2506
+ if (!successPageDuration) return;
2507
+ pushPage({
2508
+ key: "success",
2509
+ content: jsxRuntime.jsx(Success.SuccessPage, {
2510
+ text: "Phone number changed successfully!",
2511
+ duration: successPageDuration,
2512
+ onComplete: () => {
2513
+ closeModal();
2514
+ }
2515
+ }),
2516
+ preventBack: true,
2517
+ showTitle: false
2518
+ });
2519
+ };
2520
+ try {
2521
+ if (!params?.phoneNumber && params?.phoneNumber !== "") {
2522
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2523
+ pushPage({
2524
+ key: "Update Phone Number",
2525
+ content: jsxRuntime.jsx(UpdatePhoneNumber.UpdatePhoneNumber, {
2526
+ successPageDuration: successPageDuration,
2527
+ onSuccess: userId => resolve(userId),
2528
+ onError: error => reject(error),
2529
+ organizationId: organizationId,
2530
+ userId: userId,
2531
+ ...(title !== undefined && {
2532
+ title
2533
+ }),
2534
+ ...(subTitle !== undefined && {
2535
+ subTitle
2536
+ }),
2537
+ ...(stampWith !== undefined && {
2538
+ stampWith
2539
+ })
2540
+ }),
2541
+ showTitle: false
2542
+ });
2543
+ }), () => logout());
2544
+ } else {
2545
+ const {
2546
+ otpId,
2547
+ otpEncryptionTargetBundle
2548
+ } = await initOtp({
2549
+ otpType: core.OtpType.Sms,
2550
+ contact: params.phoneNumber
2551
+ });
2552
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2553
+ pushPage({
2554
+ key: "Update Phone Number",
2555
+ content: jsxRuntime.jsx(OTP.OtpVerification, {
2556
+ otpType: core.OtpType.Sms,
2557
+ contact: params.phoneNumber,
2558
+ otpId: otpId,
2559
+ otpEncryptionTargetBundle: otpEncryptionTargetBundle,
2560
+ otpLength: masterConfig.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
2561
+ alphanumeric: masterConfig.auth?.otpAlphanumeric,
2562
+ onContinue: async otpCode => {
2563
+ try {
2564
+ const {
2565
+ verificationToken
2566
+ } = await verifyOtp({
2567
+ otpId,
2568
+ otpCode,
2569
+ otpEncryptionTargetBundle,
2570
+ contact: params.phoneNumber,
2571
+ otpType: core.OtpType.Sms
2572
+ });
2573
+ const res = await updateUserPhoneNumber({
2574
+ phoneNumber: params.phoneNumber,
2575
+ verificationToken,
2576
+ userId,
2577
+ organizationId,
2578
+ ...(stampWith !== undefined && {
2579
+ stampWith
2580
+ })
2581
+ });
2582
+ onSuccess();
2583
+ resolve(res);
2584
+ } catch (error) {
2585
+ reject(error);
2586
+ }
2587
+ },
2588
+ ...(!user?.userPhoneNumber && {
2589
+ title: title ?? "Connect a phone number"
2590
+ }),
2591
+ ...(subTitle !== undefined && {
2592
+ subTitle
2593
+ }),
2594
+ ...(params.formattedPhone && {
2595
+ formattedPhone: params.formattedPhone
2596
+ })
2597
+ }),
2598
+ showTitle: false
2599
+ });
2600
+ }), () => logout(), callbacks, "Failed to update phone number");
2601
+ }
2602
+ } catch (error) {
2603
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2604
+ throw error;
2605
+ }
2606
+ throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for sms verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
2607
+ }
2608
+ }, [client, masterConfig, getSession, pushPage, closeModal, logout, initOtp, verifyOtp, updateUserPhoneNumber, user, callbacks]);
2609
+ const handleUpdateUserEmail = react.useCallback(async params => {
2610
+ const {
2611
+ successPageDuration = 2000,
2612
+ subTitle,
2613
+ title,
2614
+ stampWith
2615
+ } = params || {};
2616
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
2617
+ const s = await getSession();
2618
+ const organizationId = params?.organizationId || s?.organizationId;
2619
+ if (!organizationId) {
2620
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2621
+ }
2622
+ const userId = params?.userId || s?.userId;
2623
+ if (!userId) {
2624
+ throw new sdkTypes.ZeroXKeyError("A user ID is required to update an email.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2625
+ }
2626
+ const onSuccess = () => {
2627
+ if (!successPageDuration) return;
2628
+ pushPage({
2629
+ key: "success",
2630
+ content: jsxRuntime.jsx(Success.SuccessPage, {
2631
+ text: "Email changed successfully!",
2632
+ duration: successPageDuration,
2633
+ onComplete: () => {
2634
+ closeModal();
2635
+ }
2636
+ }),
2637
+ preventBack: true,
2638
+ showTitle: false
2639
+ });
2640
+ };
2641
+ try {
2642
+ if (!params?.email && params?.email !== "") {
2643
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2644
+ pushPage({
2645
+ key: "Update Email",
2646
+ content: jsxRuntime.jsx(UpdateEmail.UpdateEmail, {
2647
+ successPageDuration: successPageDuration,
2648
+ onSuccess: userId => {
2649
+ resolve(userId);
2650
+ },
2651
+ onError: error => reject(error),
2652
+ organizationId: organizationId,
2653
+ userId: userId,
2654
+ ...(title !== undefined && {
2655
+ title
2656
+ }),
2657
+ ...(subTitle !== undefined && {
2658
+ subTitle
2659
+ }),
2660
+ ...(stampWith !== undefined && {
2661
+ stampWith
2662
+ })
2663
+ }),
2664
+ showTitle: false
2665
+ });
2666
+ }), () => logout());
2667
+ } else {
2668
+ const {
2669
+ otpId,
2670
+ otpEncryptionTargetBundle
2671
+ } = await initOtp({
2672
+ otpType: core.OtpType.Email,
2673
+ contact: params.email
2674
+ });
2675
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2676
+ pushPage({
2677
+ key: "Update Email",
2678
+ content: jsxRuntime.jsx(OTP.OtpVerification, {
2679
+ otpType: core.OtpType.Email,
2680
+ contact: params.email,
2681
+ otpId: otpId,
2682
+ otpEncryptionTargetBundle: otpEncryptionTargetBundle,
2683
+ otpLength: masterConfig?.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
2684
+ alphanumeric: masterConfig?.auth?.otpAlphanumeric,
2685
+ onContinue: async otpCode => {
2686
+ try {
2687
+ const {
2688
+ verificationToken
2689
+ } = await verifyOtp({
2690
+ otpId,
2691
+ otpCode,
2692
+ otpEncryptionTargetBundle,
2693
+ contact: params.email,
2694
+ otpType: core.OtpType.Email
2695
+ });
2696
+ const res = await updateUserEmail({
2697
+ email: params.email,
2698
+ verificationToken,
2699
+ userId,
2700
+ organizationId,
2701
+ ...(stampWith !== undefined && {
2702
+ stampWith
2703
+ })
2704
+ });
2705
+ onSuccess();
2706
+ resolve(res);
2707
+ } catch (error) {
2708
+ reject(error);
2709
+ }
2710
+ },
2711
+ ...(!user?.userEmail && {
2712
+ title: title ?? "Connect an email"
2713
+ }),
2714
+ ...(subTitle !== undefined && {
2715
+ subTitle
2716
+ })
2717
+ }),
2718
+ showTitle: false
2719
+ });
2720
+ }), () => logout(), callbacks, "Failed to update email");
2721
+ }
2722
+ } catch (error) {
2723
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2724
+ throw error;
2725
+ }
2726
+ throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for email verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
2727
+ }
2728
+ }, [client, getSession, pushPage, closeModal, logout, initOtp, masterConfig, verifyOtp, updateUserEmail, user, callbacks]);
2729
+ const handleAddEmail = react.useCallback(async params => {
2730
+ const {
2731
+ successPageDuration = 2000,
2732
+ subTitle,
2733
+ title,
2734
+ stampWith
2735
+ } = params || {};
2736
+ if (!client) {
2737
+ throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
2738
+ }
2739
+ const s = await getSession();
2740
+ const organizationId = params?.organizationId || s?.organizationId;
2741
+ if (!organizationId) {
2742
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2743
+ }
2744
+ const userId = params?.userId || s?.userId;
2745
+ if (!userId) {
2746
+ throw new sdkTypes.ZeroXKeyError("A user ID is required to add an email.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2747
+ }
2748
+ const onSuccess = () => {
2749
+ if (!successPageDuration) return;
2750
+ pushPage({
2751
+ key: "success",
2752
+ content: jsxRuntime.jsx(Success.SuccessPage, {
2753
+ text: "Email added successfully!",
2754
+ duration: successPageDuration,
2755
+ onComplete: () => {
2756
+ closeModal();
2757
+ }
2758
+ }),
2759
+ preventBack: true,
2760
+ showTitle: false
2761
+ });
2762
+ };
2763
+ try {
2764
+ if (!params?.email && params?.email !== "") {
2765
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2766
+ pushPage({
2767
+ key: "Add Email",
2768
+ content: jsxRuntime.jsx(UpdateEmail.UpdateEmail, {
2769
+ successPageDuration: successPageDuration,
2770
+ onSuccess: userId => {
2771
+ resolve(userId);
2772
+ },
2773
+ onError: error => reject(error),
2774
+ ...(!user?.userEmail ? {
2775
+ title: title ?? "Connect an email"
2776
+ } : {}),
2777
+ ...(subTitle !== undefined ? {
2778
+ subTitle
2779
+ } : {}),
2780
+ organizationId: organizationId,
2781
+ userId: userId,
2782
+ stampWith: stampWith
2783
+ }),
2784
+ showTitle: false
2785
+ });
2786
+ }), () => logout());
2787
+ } else {
2788
+ const {
2789
+ otpId,
2790
+ otpEncryptionTargetBundle
2791
+ } = await initOtp({
2792
+ otpType: core.OtpType.Email,
2793
+ contact: params.email
2794
+ });
2795
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2796
+ pushPage({
2797
+ key: "Add Email",
2798
+ content: jsxRuntime.jsx(OTP.OtpVerification, {
2799
+ otpType: core.OtpType.Email,
2800
+ contact: params.email,
2801
+ otpId: otpId,
2802
+ otpEncryptionTargetBundle: otpEncryptionTargetBundle,
2803
+ otpLength: masterConfig?.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
2804
+ alphanumeric: masterConfig?.auth?.otpAlphanumeric,
2805
+ onContinue: async otpCode => {
2806
+ try {
2807
+ const {
2808
+ verificationToken
2809
+ } = await verifyOtp({
2810
+ otpId,
2811
+ otpCode,
2812
+ otpEncryptionTargetBundle,
2813
+ contact: params.email,
2814
+ otpType: core.OtpType.Email
2815
+ });
2816
+ const res = await updateUserEmail({
2817
+ email: params.email,
2818
+ verificationToken,
2819
+ userId,
2820
+ organizationId,
2821
+ stampWith
2822
+ });
2823
+ onSuccess();
2824
+ resolve(res);
2825
+ } catch (error) {
2826
+ reject(error);
2827
+ }
2828
+ },
2829
+ ...(!user?.userEmail && {
2830
+ title: title ?? "Connect an email"
2831
+ }),
2832
+ ...(subTitle !== undefined && {
2833
+ subTitle
2834
+ })
2835
+ }),
2836
+ showTitle: false
2837
+ });
2838
+ }), () => logout(), callbacks, "Failed to add email");
2839
+ }
2840
+ } catch (error) {
2841
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2842
+ throw error;
2843
+ }
2844
+ throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for email verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
2845
+ }
2846
+ }, [client, getSession, pushPage, closeModal, user, logout, initOtp, masterConfig, verifyOtp, updateUserEmail, callbacks]);
2847
+ const handleAddPhoneNumber = react.useCallback(async params => {
2848
+ const {
2849
+ successPageDuration = 2000,
2850
+ subTitle,
2851
+ title,
2852
+ stampWith
2853
+ } = params || {};
2854
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
2855
+ if (!masterConfig) {
2856
+ throw new sdkTypes.ZeroXKeyError("Config is not ready yet!", sdkTypes.ZeroXKeyErrorCodes.CONFIG_NOT_INITIALIZED);
2857
+ }
2858
+ if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
2859
+ throw new sdkTypes.ZeroXKeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.ZeroXKeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
2860
+ }
2861
+ const s = await getSession();
2862
+ const organizationId = params?.organizationId || s?.organizationId;
2863
+ if (!organizationId) {
2864
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2865
+ }
2866
+ const userId = params?.userId || s?.userId;
2867
+ if (!userId) {
2868
+ throw new sdkTypes.ZeroXKeyError("A user ID is required to add a phone number.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2869
+ }
2870
+ const onSuccess = () => {
2871
+ if (!successPageDuration) return;
2872
+ pushPage({
2873
+ key: "success",
2874
+ content: jsxRuntime.jsx(Success.SuccessPage, {
2875
+ text: "Phone number updated successfully!",
2876
+ duration: successPageDuration,
2877
+ onComplete: () => {
2878
+ closeModal();
2879
+ }
2880
+ }),
2881
+ preventBack: true,
2882
+ showTitle: false
2883
+ });
2884
+ };
2885
+ try {
2886
+ if (!params?.phoneNumber && params?.phoneNumber !== "") {
2887
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2888
+ pushPage({
2889
+ key: "Add Phone Number",
2890
+ content: jsxRuntime.jsx(UpdatePhoneNumber.UpdatePhoneNumber, {
2891
+ successPageDuration: successPageDuration,
2892
+ onSuccess: userId => {
2893
+ resolve(userId);
2894
+ },
2895
+ onError: error => {
2896
+ reject(error);
2897
+ },
2898
+ ...(!user?.userPhoneNumber && {
2899
+ title: title ?? "Connect a phone number"
2900
+ }),
2901
+ ...(subTitle !== undefined && {
2902
+ subTitle
2903
+ }),
2904
+ organizationId: organizationId,
2905
+ userId: userId,
2906
+ stampWith: stampWith
2907
+ }),
2908
+ showTitle: false
2909
+ });
2910
+ }), () => logout(), callbacks, "Failed to add phone number");
2911
+ } else {
2912
+ const {
2913
+ otpId,
2914
+ otpEncryptionTargetBundle
2915
+ } = await initOtp({
2916
+ otpType: core.OtpType.Sms,
2917
+ contact: params.phoneNumber
2918
+ });
2919
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2920
+ pushPage({
2921
+ key: "Add Phone Number",
2922
+ content: jsxRuntime.jsx(OTP.OtpVerification, {
2923
+ otpType: core.OtpType.Sms,
2924
+ contact: params.phoneNumber,
2925
+ otpId: otpId,
2926
+ otpEncryptionTargetBundle: otpEncryptionTargetBundle,
2927
+ otpLength: masterConfig.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
2928
+ alphanumeric: masterConfig?.auth?.otpAlphanumeric,
2929
+ onContinue: async otpCode => {
2930
+ try {
2931
+ const {
2932
+ verificationToken
2933
+ } = await verifyOtp({
2934
+ otpId,
2935
+ otpCode,
2936
+ otpEncryptionTargetBundle,
2937
+ contact: params.phoneNumber,
2938
+ otpType: core.OtpType.Sms
2939
+ });
2940
+ const res = await updateUserPhoneNumber({
2941
+ phoneNumber: params.phoneNumber,
2942
+ verificationToken,
2943
+ userId,
2944
+ organizationId,
2945
+ stampWith
2946
+ });
2947
+ onSuccess();
2948
+ resolve(res);
2949
+ } catch (error) {
2950
+ reject(error);
2951
+ }
2952
+ },
2953
+ ...(!user?.userPhoneNumber && {
2954
+ title: title ?? "Connect a phone number"
2955
+ }),
2956
+ ...(subTitle !== undefined && {
2957
+ subTitle
2958
+ }),
2959
+ ...(params.formattedPhone && {
2960
+ formattedPhone: params.formattedPhone
2961
+ })
2962
+ }),
2963
+ showTitle: false
2964
+ });
2965
+ }), () => logout(), callbacks, "Failed to add phone number");
2966
+ }
2967
+ } catch (error) {
2968
+ if (error instanceof sdkTypes.ZeroXKeyError) {
2969
+ throw error;
2970
+ }
2971
+ throw new sdkTypes.ZeroXKeyError("Failed to initialize OTP for sms verification.", sdkTypes.ZeroXKeyErrorCodes.INIT_OTP_ERROR, error);
2972
+ }
2973
+ }, [client, masterConfig, getSession, pushPage, closeModal, user, logout, callbacks, initOtp, verifyOtp, updateUserPhoneNumber]);
2974
+ const handleRemovePasskey = react.useCallback(async params => {
2975
+ const {
2976
+ authenticatorId,
2977
+ successPageDuration = 2000,
2978
+ subTitle,
2979
+ title,
2980
+ stampWith,
2981
+ userId
2982
+ } = params;
2983
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
2984
+ const s = await getSession();
2985
+ const organizationId = params?.organizationId || s?.organizationId;
2986
+ if (!organizationId) {
2987
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
2988
+ }
2989
+ return utils.withZeroXKeyErrorHandling(() => new Promise((resolve, reject) => {
2990
+ pushPage({
2991
+ key: "Remove Passkey",
2992
+ content: jsxRuntime.jsx(RemovePasskey.RemovePasskey, {
2993
+ authenticatorId: authenticatorId,
2994
+ successPageDuration: successPageDuration,
2995
+ onSuccess: authenticatorIds => {
2996
+ resolve(authenticatorIds);
2997
+ },
2998
+ onError: error => {
2999
+ reject(error);
3000
+ },
3001
+ stampWith: stampWith,
3002
+ ...(userId && {
3003
+ userId
3004
+ }),
3005
+ ...(title !== undefined && {
3006
+ title
3007
+ }),
3008
+ ...(subTitle !== undefined && {
3009
+ subTitle
3010
+ }),
3011
+ ...(organizationId !== undefined && {
3012
+ organizationId
3013
+ })
3014
+ }),
3015
+ showTitle: false,
3016
+ preventBack: true
3017
+ });
3018
+ }), () => logout(), callbacks, "Failed to remove passkey");
3019
+ }, [client, getSession, pushPage, logout, callbacks]);
3020
+ const handleAddPasskey = react.useCallback(async params => {
3021
+ const {
3022
+ name,
3023
+ displayName,
3024
+ successPageDuration = 2000,
3025
+ stampWith
3026
+ } = params || {};
3027
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
3028
+ const s = await getSession();
3029
+ const organizationId = params?.organizationId || s?.organizationId;
3030
+ if (!organizationId) {
3031
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3032
+ }
3033
+ const userId = params?.userId || s?.userId;
3034
+ if (!userId) {
3035
+ throw new sdkTypes.ZeroXKeyError("A user ID or a valid session is required to add a passkey.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3036
+ }
3037
+ try {
3038
+ const resPromise = addPasskey({
3039
+ ...(name && {
3040
+ name
3041
+ }),
3042
+ ...(displayName && {
3043
+ displayName
3044
+ }),
3045
+ userId,
3046
+ stampWith,
3047
+ ...(organizationId && {
3048
+ organizationId
3049
+ })
3050
+ });
3051
+ resPromise.then(() => {
3052
+ pushPage({
3053
+ key: "Passkey Added",
3054
+ content: jsxRuntime.jsx(Success.SuccessPage, {
3055
+ text: "Successfully added passkey!",
3056
+ duration: successPageDuration,
3057
+ onComplete: () => {
3058
+ closeModal();
3059
+ }
3060
+ }),
3061
+ preventBack: true,
3062
+ showTitle: false
3063
+ });
3064
+ });
3065
+ return await resPromise;
3066
+ } catch (error) {
3067
+ if (error instanceof sdkTypes.ZeroXKeyError) {
3068
+ throw error;
3069
+ }
3070
+ throw new sdkTypes.ZeroXKeyError("Failed to add passkey in handler.", sdkTypes.ZeroXKeyErrorCodes.ADD_PASSKEY_ERROR, error);
3071
+ }
3072
+ }, [client, getSession, addPasskey, pushPage, closeModal]);
3073
+ const handleRemoveOauthProvider = react.useCallback(async params => {
3074
+ const {
3075
+ providerId,
3076
+ successPageDuration = 2000,
3077
+ subTitle,
3078
+ title,
3079
+ stampWith
3080
+ } = params;
3081
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
3082
+ const s = await getSession();
3083
+ const organizationId = params?.organizationId || s?.organizationId;
3084
+ if (!organizationId) {
3085
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3086
+ }
3087
+ try {
3088
+ return new Promise((resolve, reject) => {
3089
+ pushPage({
3090
+ key: "Remove OAuth Provider",
3091
+ content: jsxRuntime.jsx(RemoveOAuthProvider.RemoveOAuthProvider, {
3092
+ providerId: providerId,
3093
+ stampWith: stampWith,
3094
+ successPageDuration: successPageDuration,
3095
+ onSuccess: providerIds => {
3096
+ resolve(providerIds);
3097
+ },
3098
+ onError: error => {
3099
+ reject(error);
3100
+ },
3101
+ ...(title !== undefined && {
3102
+ title
3103
+ }),
3104
+ ...(subTitle !== undefined && {
3105
+ subTitle
3106
+ }),
3107
+ ...(organizationId !== undefined && {
3108
+ organizationId
3109
+ })
3110
+ }),
3111
+ showTitle: false,
3112
+ preventBack: true,
3113
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the remove OAuth provider process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
3114
+ });
3115
+ });
3116
+ } catch (error) {
3117
+ if (error instanceof sdkTypes.ZeroXKeyError) {
3118
+ throw error;
3119
+ }
3120
+ throw new sdkTypes.ZeroXKeyError("Failed to remove OAuth provider in handler.", sdkTypes.ZeroXKeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR, error);
3121
+ }
3122
+ }, [client, getSession, pushPage]);
3123
+ const handleAddOauthProvider = react.useCallback(async params => {
3124
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
3125
+ const {
3126
+ providerName,
3127
+ stampWith,
3128
+ successPageDuration = 2000,
3129
+ openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false
3130
+ } = params;
3131
+ const s = await getSession();
3132
+ const organizationId = params?.organizationId || s?.organizationId;
3133
+ if (!organizationId) {
3134
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3135
+ }
3136
+ const userId = params?.userId || s?.userId;
3137
+ if (!userId) {
3138
+ throw new sdkTypes.ZeroXKeyError("A user ID is required to add an OAuth provider.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3139
+ }
3140
+ return new Promise(async (resolve, reject) => {
3141
+ try {
3142
+ const onOauthSuccess = async params => {
3143
+ await addOauthProvider({
3144
+ providerName: params.providerName,
3145
+ oidcToken: params.oidcToken,
3146
+ stampWith,
3147
+ organizationId,
3148
+ userId
3149
+ });
3150
+ resolve();
3151
+ pushPage({
3152
+ key: "OAuth Provider Added",
3153
+ content: jsxRuntime.jsx(Success.SuccessPage, {
3154
+ text: `Successfully added ${params.providerName} OAuth provider!`,
3155
+ duration: successPageDuration,
3156
+ onComplete: () => {
3157
+ closeModal();
3158
+ }
3159
+ }),
3160
+ preventBack: true,
3161
+ showTitle: false
3162
+ });
3163
+ };
3164
+ if (openInPage) {
3165
+ storage.storeOAuthAddProviderMetadata({
3166
+ organizationId,
3167
+ userId,
3168
+ ...(stampWith && {
3169
+ stampWith: stampWith
3170
+ }),
3171
+ successPageDuration
3172
+ });
3173
+ }
3174
+ const additionalState = openInPage ? {
3175
+ oauthIntent: storage.OAUTH_INTENT_ADD_PROVIDER,
3176
+ ...(successPageDuration > 0 && {
3177
+ openModal: "true"
3178
+ })
3179
+ } : undefined;
3180
+ switch (providerName) {
3181
+ case sdkTypes.OAuthProviders.DISCORD:
3182
+ {
3183
+ return await handleDiscordOauth({
3184
+ openInPage,
3185
+ ...(additionalState && {
3186
+ additionalState
3187
+ }),
3188
+ ...(!openInPage && {
3189
+ onOauthSuccess
3190
+ })
3191
+ });
3192
+ }
3193
+ case sdkTypes.OAuthProviders.X:
3194
+ {
3195
+ return await handleXOauth({
3196
+ openInPage,
3197
+ ...(additionalState && {
3198
+ additionalState
3199
+ }),
3200
+ ...(!openInPage && {
3201
+ onOauthSuccess
3202
+ })
3203
+ });
3204
+ }
3205
+ case sdkTypes.OAuthProviders.GOOGLE:
3206
+ {
3207
+ return await handleGoogleOauth({
3208
+ openInPage,
3209
+ ...(additionalState && {
3210
+ additionalState
3211
+ }),
3212
+ ...(!openInPage && {
3213
+ onOauthSuccess
3214
+ })
3215
+ });
3216
+ }
3217
+ case sdkTypes.OAuthProviders.APPLE:
3218
+ {
3219
+ return await handleAppleOauth({
3220
+ openInPage,
3221
+ ...(additionalState && {
3222
+ additionalState
3223
+ }),
3224
+ ...(!openInPage && {
3225
+ onOauthSuccess
3226
+ })
3227
+ });
3228
+ }
3229
+ case sdkTypes.OAuthProviders.FACEBOOK:
3230
+ {
3231
+ return await handleFacebookOauth({
3232
+ openInPage,
3233
+ ...(additionalState && {
3234
+ additionalState
3235
+ }),
3236
+ ...(!openInPage && {
3237
+ onOauthSuccess
3238
+ })
3239
+ });
3240
+ }
3241
+ default:
3242
+ {
3243
+ throw new sdkTypes.ZeroXKeyError(`Unsupported OAuth provider: ${providerName}`, sdkTypes.ZeroXKeyErrorCodes.NOT_FOUND);
3244
+ }
3245
+ }
3246
+ } catch (error) {
3247
+ reject(error);
3248
+ }
3249
+ });
3250
+ }, [client, getSession, addOauthProvider, pushPage, closeModal, handleDiscordOauth, handleXOauth, handleGoogleOauth, handleAppleOauth, handleFacebookOauth]);
3251
+ const handleConnectExternalWallet = react.useCallback(async params => {
3252
+ const {
3253
+ successPageDuration = 2000
3254
+ } = params || {};
3255
+ if (!client) throw new sdkTypes.ZeroXKeyError("Client is not initialized.", sdkTypes.ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
3256
+ if (!masterConfig?.walletConfig?.features?.connecting) {
3257
+ throw new sdkTypes.ZeroXKeyError("Wallet connecting is not enabled.", sdkTypes.ZeroXKeyErrorCodes.FEATURE_NOT_ENABLED);
3258
+ }
3259
+ return new Promise((resolve, reject) => {
3260
+ pushPage({
3261
+ key: "Connect wallet",
3262
+ content: jsxRuntime.jsx(ConnectWallet.ConnectWalletModal, {
3263
+ successPageDuration: successPageDuration,
3264
+ onSuccess: (type, account) => {
3265
+ resolve({
3266
+ type,
3267
+ account
3268
+ });
3269
+ }
3270
+ }),
3271
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the connect wallet process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
3272
+ });
3273
+ });
3274
+ }, [client, masterConfig, fetchWalletProviders, pushPage]);
3275
+ const handleRemoveUserEmail = react.useCallback(async params => {
3276
+ const {
3277
+ successPageDuration = 2000,
3278
+ stampWith,
3279
+ userId
3280
+ } = params || {};
3281
+ const s = await getSession();
3282
+ const organizationId = params?.organizationId || s?.organizationId;
3283
+ if (!organizationId) {
3284
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3285
+ }
3286
+ try {
3287
+ return new Promise((resolve, reject) => {
3288
+ pushPage({
3289
+ key: "Remove Email",
3290
+ content: jsxRuntime.jsx(RemoveEmail.RemoveEmail, {
3291
+ successPageDuration: successPageDuration,
3292
+ ...(userId && {
3293
+ userId
3294
+ }),
3295
+ ...(stampWith && {
3296
+ stampWith
3297
+ }),
3298
+ onSuccess: userId => {
3299
+ resolve(userId);
3300
+ },
3301
+ onError: error => {
3302
+ reject(error);
3303
+ },
3304
+ ...(organizationId !== undefined && {
3305
+ organizationId
3306
+ })
3307
+ }),
3308
+ showTitle: false,
3309
+ preventBack: true,
3310
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the remove email process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
3311
+ });
3312
+ });
3313
+ } catch (error) {
3314
+ if (error instanceof sdkTypes.ZeroXKeyError) {
3315
+ throw error;
3316
+ }
3317
+ throw new sdkTypes.ZeroXKeyError("Failed to remove user email.", sdkTypes.ZeroXKeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
3318
+ }
3319
+ }, [getSession, pushPage]);
3320
+ const handleRemoveUserPhoneNumber = react.useCallback(async params => {
3321
+ const {
3322
+ successPageDuration = 2000,
3323
+ stampWith,
3324
+ userId
3325
+ } = params || {};
3326
+ const s = await getSession();
3327
+ const organizationId = params?.organizationId || s?.organizationId;
3328
+ if (!organizationId) {
3329
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3330
+ }
3331
+ try {
3332
+ return new Promise((resolve, reject) => {
3333
+ pushPage({
3334
+ key: "Remove Phone Number",
3335
+ content: jsxRuntime.jsx(RemovePhoneNumber.RemovePhoneNumber, {
3336
+ successPageDuration: successPageDuration,
3337
+ ...(userId && {
3338
+ userId
3339
+ }),
3340
+ ...(stampWith && {
3341
+ stampWith
3342
+ }),
3343
+ onSuccess: userId => {
3344
+ resolve(userId);
3345
+ },
3346
+ onError: error => {
3347
+ reject(error);
3348
+ },
3349
+ ...(organizationId !== undefined && {
3350
+ organizationId
3351
+ })
3352
+ }),
3353
+ showTitle: false,
3354
+ preventBack: true,
3355
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the remove phone number process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
3356
+ });
3357
+ });
3358
+ } catch (error) {
3359
+ if (error instanceof sdkTypes.ZeroXKeyError) {
3360
+ throw error;
3361
+ }
3362
+ throw new sdkTypes.ZeroXKeyError("Failed to remove user phone number.", sdkTypes.ZeroXKeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
3363
+ }
3364
+ }, [getSession, pushPage]);
3365
+ const handleSendTransaction = react.useCallback(async params => {
3366
+ const session = await getSession();
3367
+ const organizationId = params.organizationId || session?.organizationId;
3368
+ if (!organizationId) {
3369
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3370
+ }
3371
+ const {
3372
+ transaction,
3373
+ icon,
3374
+ stampWith,
3375
+ successPageDuration = 2000
3376
+ } = params;
3377
+ const {
3378
+ caip2
3379
+ } = transaction;
3380
+ const isSolanaTransaction = caip2.startsWith("solana:");
3381
+ return new Promise((resolve, reject) => {
3382
+ const action = async () => {
3383
+ const sendTransactionStatusId = isSolanaTransaction ? await solSendTransaction({
3384
+ organizationId,
3385
+ transaction: transaction,
3386
+ stampWith
3387
+ }) : await (async () => {
3388
+ const {
3389
+ from,
3390
+ to,
3391
+ value,
3392
+ data,
3393
+ nonce,
3394
+ gasLimit,
3395
+ maxFeePerGas,
3396
+ maxPriorityFeePerGas,
3397
+ sponsor
3398
+ } = transaction;
3399
+ const cleanedData = data && data !== "0x" && data !== "" ? data : undefined;
3400
+ const tx = {
3401
+ from,
3402
+ to,
3403
+ caip2,
3404
+ sponsor: sponsor ?? false,
3405
+ ...(value ? {
3406
+ value
3407
+ } : {}),
3408
+ ...(cleanedData ? {
3409
+ data: cleanedData
3410
+ } : {}),
3411
+ ...(nonce ? {
3412
+ nonce
3413
+ } : {}),
3414
+ ...(gasLimit ? {
3415
+ gasLimit
3416
+ } : {}),
3417
+ ...(maxFeePerGas ? {
3418
+ maxFeePerGas
3419
+ } : {}),
3420
+ ...(maxPriorityFeePerGas ? {
3421
+ maxPriorityFeePerGas
3422
+ } : {})
3423
+ };
3424
+ return ethSendTransaction({
3425
+ organizationId,
3426
+ transaction: tx,
3427
+ stampWith
3428
+ });
3429
+ })();
3430
+ if (!sendTransactionStatusId) {
3431
+ throw new sdkTypes.ZeroXKeyError("Missing sendTransactionStatusId", sdkTypes.ZeroXKeyErrorCodes.BAD_RESPONSE);
3432
+ }
3433
+ const pollResult = await pollTransactionStatus({
3434
+ organizationId,
3435
+ sendTransactionStatusId
3436
+ });
3437
+ const txDetails = pollResult;
3438
+ const txHash = txDetails.eth?.txHash ?? txDetails.solana?.signature ?? txDetails.txHash;
3439
+ return txHash ? {
3440
+ txHash
3441
+ } : {};
3442
+ };
3443
+ pushPage({
3444
+ key: "Send Transaction",
3445
+ showTitle: false,
3446
+ preventBack: true,
3447
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the transaction.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED)),
3448
+ content: jsxRuntime.jsx(SendTransaction.SendTransactionPage, {
3449
+ icon: icon ?? helpers$1.getChainLogo(caip2),
3450
+ action: action,
3451
+ caip2: caip2,
3452
+ successPageDuration: successPageDuration,
3453
+ onSuccess: () => resolve(),
3454
+ onError: err => reject(err)
3455
+ })
3456
+ });
3457
+ });
3458
+ }, [ethSendTransaction, getSession, pollTransactionStatus, pushPage, solSendTransaction]);
3459
+ const handleSendErc20Transfer = react.useCallback(async params => {
3460
+ const session = await getSession();
3461
+ const organizationId = params.organizationId || session?.organizationId;
3462
+ if (!organizationId) {
3463
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3464
+ }
3465
+ const {
3466
+ transfer,
3467
+ icon,
3468
+ stampWith,
3469
+ successPageDuration = 2000
3470
+ } = params;
3471
+ const {
3472
+ caip2
3473
+ } = transfer;
3474
+ return new Promise((resolve, reject) => {
3475
+ const action = async () => {
3476
+ const sendTransactionStatusId = await ethSendErc20Transfer({
3477
+ organizationId,
3478
+ transfer,
3479
+ stampWith
3480
+ });
3481
+ if (!sendTransactionStatusId) {
3482
+ throw new sdkTypes.ZeroXKeyError("Missing sendTransactionStatusId", sdkTypes.ZeroXKeyErrorCodes.BAD_RESPONSE);
3483
+ }
3484
+ const pollResult = await pollTransactionStatus({
3485
+ organizationId,
3486
+ sendTransactionStatusId
3487
+ });
3488
+ const txHash = pollResult?.eth?.txHash ?? pollResult?.txHash;
3489
+ return txHash ? {
3490
+ txHash
3491
+ } : {};
3492
+ };
3493
+ pushPage({
3494
+ key: "Send ERC20 Transfer",
3495
+ showTitle: false,
3496
+ preventBack: true,
3497
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the transaction.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED)),
3498
+ content: jsxRuntime.jsx(SendTransaction.SendTransactionPage, {
3499
+ icon: icon ?? helpers$1.getChainLogo(caip2),
3500
+ action: action,
3501
+ caip2: caip2,
3502
+ successPageDuration: successPageDuration,
3503
+ onSuccess: () => resolve(),
3504
+ onError: err => reject(err)
3505
+ })
3506
+ });
3507
+ });
3508
+ }, [ethSendErc20Transfer, getSession, pollTransactionStatus, pushPage]);
3509
+ const handleOnRamp = react.useCallback(async params => {
3510
+ const {
3511
+ walletAccount,
3512
+ fiatCurrencyAmount,
3513
+ fiatCurrencyCode,
3514
+ paymentMethod,
3515
+ countrySubdivisionCode,
3516
+ urlForSignature,
3517
+ countryCode,
3518
+ onrampProvider = "FIAT_ON_RAMP_PROVIDER_MOONPAY",
3519
+ sandboxMode = true,
3520
+ successPageDuration = 2000,
3521
+ openInNewTab = false
3522
+ } = params;
3523
+ const s = await getSession();
3524
+ const organizationId = params?.organizationId || s?.organizationId;
3525
+ if (!organizationId) {
3526
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3527
+ }
3528
+ let cryptoCurrencyCode;
3529
+ let network;
3530
+ switch (true) {
3531
+ case walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM":
3532
+ cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.ETHEREUM;
3533
+ network = sdkTypes.FiatOnRampBlockchainNetwork.ETHEREUM;
3534
+ break;
3535
+ case walletAccount.addressFormat?.includes("ADDRESS_FORMAT_BITCOIN"):
3536
+ cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.BITCOIN;
3537
+ network = sdkTypes.FiatOnRampBlockchainNetwork.BITCOIN;
3538
+ break;
3539
+ case walletAccount.addressFormat === "ADDRESS_FORMAT_SOLANA":
3540
+ cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.SOLANA;
3541
+ network = sdkTypes.FiatOnRampBlockchainNetwork.SOLANA;
3542
+ break;
3543
+ default:
3544
+ cryptoCurrencyCode = sdkTypes.FiatOnRampCryptoCurrency.ETHEREUM;
3545
+ network = sdkTypes.FiatOnRampBlockchainNetwork.ETHEREUM;
3546
+ break;
3547
+ }
3548
+ const openNewTab = openInNewTab || isMobile;
3549
+ cryptoCurrencyCode = params.cryptoCurrencyCode || cryptoCurrencyCode;
3550
+ network = params.network || network;
3551
+ return new Promise((resolve, reject) => {
3552
+ const OnRampContainer = () => {
3553
+ const [completed, setCompleted] = react.useState(false);
3554
+ const pollingRef = react.useRef(null);
3555
+ const cleanup = () => {
3556
+ if (pollingRef.current) {
3557
+ clearInterval(pollingRef.current);
3558
+ pollingRef.current = null;
3559
+ }
3560
+ };
3561
+ react.useEffect(() => {
3562
+ return () => {
3563
+ cleanup();
3564
+ };
3565
+ }, []);
3566
+ const action = async () => {
3567
+ try {
3568
+ let onRampWindow = null;
3569
+ if (openNewTab) {
3570
+ onRampWindow = window.open("", "_blank");
3571
+ if (!onRampWindow) throw new Error("Failed to open On Ramp tab.");
3572
+ }
3573
+ const result = await client?.httpClient?.initFiatOnRamp({
3574
+ onrampProvider,
3575
+ walletAddress: walletAccount.address,
3576
+ network,
3577
+ cryptoCurrencyCode,
3578
+ sandboxMode,
3579
+ organizationId,
3580
+ ...(fiatCurrencyCode ? {
3581
+ fiatCurrencyCode
3582
+ } : {}),
3583
+ ...(fiatCurrencyAmount ? {
3584
+ fiatCurrencyAmount
3585
+ } : {}),
3586
+ ...(paymentMethod ? {
3587
+ paymentMethod
3588
+ } : {}),
3589
+ ...(countryCode ? {
3590
+ countryCode
3591
+ } : {}),
3592
+ ...(countrySubdivisionCode ? {
3593
+ countrySubdivisionCode
3594
+ } : {}),
3595
+ ...(sandboxMode !== undefined ? {
3596
+ sandboxMode
3597
+ } : {}),
3598
+ ...(urlForSignature ? {
3599
+ urlForSignature
3600
+ } : {})
3601
+ });
3602
+ if (!result?.onRampUrl) throw new Error("Missing onRampUrl");
3603
+ if (openNewTab && onRampWindow) {
3604
+ onRampWindow.location.href = result.onRampUrl.toString();
3605
+ } else {
3606
+ const popupWidth = 500;
3607
+ const popupHeight = 600;
3608
+ const left = window.screenX + (window.innerWidth - popupWidth) / 2;
3609
+ const top = window.screenY + (window.innerHeight - popupHeight) / 2;
3610
+ onRampWindow = window.open(result.onRampUrl.toString(), "_blank", `width=${popupWidth},height=${popupHeight},top=${top},left=${left},scrollbars=yes,resizable=yes`);
3611
+ if (!onRampWindow) throw new Error("Failed to open On Ramp window.");
3612
+ }
3613
+ const onRampTransactionId = result.onRampTransactionId;
3614
+ if (!onRampTransactionId) throw new Error("No onRampTransactionId returned");
3615
+ return new Promise((resolveAction, rejectAction) => {
3616
+ pollingRef.current = setInterval(async () => {
3617
+ try {
3618
+ if (onrampProvider === "FIAT_ON_RAMP_PROVIDER_COINBASE" && onRampWindow?.closed) {
3619
+ cleanup();
3620
+ rejectAction(new Error("On-ramp popup closed by user"));
3621
+ return;
3622
+ }
3623
+ let currentUrl = "";
3624
+ try {
3625
+ currentUrl = onRampWindow?.location.href || "";
3626
+ } catch {}
3627
+ if (currentUrl && currentUrl.startsWith(window.location.origin)) {
3628
+ cleanup();
3629
+ onRampWindow?.close();
3630
+ setCompleted(true);
3631
+ resolveAction();
3632
+ return;
3633
+ }
3634
+ const resp = await client?.httpClient?.getOnRampTransactionStatus({
3635
+ transactionId: onRampTransactionId,
3636
+ refresh: true
3637
+ });
3638
+ const status = resp?.transactionStatus;
3639
+ if (["COMPLETED", "FAILED", "CANCELLED"].includes(status ?? "")) {
3640
+ cleanup();
3641
+ try {
3642
+ onRampWindow?.close();
3643
+ } catch {}
3644
+ setCompleted(true);
3645
+ resolveAction();
3646
+ }
3647
+ } catch (error) {
3648
+ console.warn("Polling error (ignored):", error);
3649
+ }
3650
+ }, 3000);
3651
+ });
3652
+ } catch (err) {
3653
+ cleanup();
3654
+ throw err;
3655
+ }
3656
+ };
3657
+ return jsxRuntime.jsx(OnRamp.OnRampPage, {
3658
+ icon: onrampProvider === "FIAT_ON_RAMP_PROVIDER_COINBASE" ? jsxRuntime.jsx(Svg.CoinbaseLogo, {
3659
+ className: "w-12 h-12"
3660
+ }) : jsxRuntime.jsx(Svg.MoonPayLogo, {
3661
+ className: "w-12 h-12"
3662
+ }),
3663
+ onrampProvider: onrampProvider,
3664
+ action: action,
3665
+ sandboxMode: sandboxMode,
3666
+ completed: completed,
3667
+ successPageDuration: successPageDuration,
3668
+ onSuccess: () => resolve(),
3669
+ onError: err => reject(err)
3670
+ });
3671
+ };
3672
+ pushPage({
3673
+ key: "Fiat OnRamp",
3674
+ content: jsxRuntime.jsx(OnRampContainer, {}),
3675
+ showTitle: false,
3676
+ preventBack: true,
3677
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the onramp process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
3678
+ });
3679
+ });
3680
+ }, [getSession, client, pushPage]);
3681
+ const handleVerifyAppProofs = react.useCallback(async params => {
3682
+ const {
3683
+ appProofs,
3684
+ successPageDuration = 3000,
3685
+ stampWith
3686
+ } = params || {};
3687
+ const s = await getSession();
3688
+ const organizationId = params?.organizationId || s?.organizationId;
3689
+ if (!organizationId) {
3690
+ throw new sdkTypes.ZeroXKeyError("A session or passed in organization ID is required.", sdkTypes.ZeroXKeyErrorCodes.INVALID_REQUEST);
3691
+ }
3692
+ try {
3693
+ return new Promise((resolve, reject) => {
3694
+ pushPage({
3695
+ key: "Verify app proofs",
3696
+ content: jsxRuntime.jsx(Verify.VerifyPage, {
3697
+ appProofs: appProofs,
3698
+ onSuccess: () => {
3699
+ resolve();
3700
+ },
3701
+ onError: error => {
3702
+ reject(error);
3703
+ },
3704
+ successPageDuration: successPageDuration,
3705
+ ...(stampWith && {
3706
+ stampWith
3707
+ }),
3708
+ ...(organizationId !== undefined && {
3709
+ organizationId
3710
+ })
3711
+ }),
3712
+ showTitle: false,
3713
+ preventBack: true,
3714
+ onClose: () => reject(new sdkTypes.ZeroXKeyError("User canceled the verify app proofs process.", sdkTypes.ZeroXKeyErrorCodes.USER_CANCELED))
3715
+ });
3716
+ });
3717
+ } catch (error) {
3718
+ if (error instanceof sdkTypes.ZeroXKeyError) {
3719
+ throw error;
3720
+ }
3721
+ throw new sdkTypes.ZeroXKeyError("Failed to verify app proofs.", sdkTypes.ZeroXKeyErrorCodes.VERIFY_APP_PROOFS_ERROR, error);
3722
+ }
3723
+ }, [getSession, pushPage]);
3724
+ react.useEffect(() => {
3725
+ if (proxyAuthConfigRef.current) return;
3726
+ // Only fetch the proxy auth config once. Use that to build the master config.
3727
+ const fetchProxyAuthConfig = async () => {
3728
+ try {
3729
+ let proxyAuthConfig;
3730
+ if (shouldFetchWalletKitConfig) {
3731
+ // Only fetch the proxy auth config if we have an authProxyId and the autoFetchWalletKitConfig param is enabled or not passed in.
3732
+ proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId,
3733
+ // Can assert safely. See shouldFetchWalletKitConfig definition.
3734
+ config.authProxyUrl);
3735
+ proxyAuthConfigRef.current = proxyAuthConfig;
3736
+ }
3737
+ setMasterConfig(buildConfig(proxyAuthConfig));
3738
+ } catch {
3739
+ setClientState(base.ClientState.Error);
3740
+ }
3741
+ };
3742
+ fetchProxyAuthConfig();
3743
+ }, []);
3744
+ react.useEffect(() => {
3745
+ // Start the client initialization process once we have the master config.
3746
+ if (!masterConfig) return;
3747
+ initializeClient();
3748
+ }, [masterConfig]);
3749
+ react.useEffect(() => {
3750
+ // Handle changes to the passed in config prop -- update the master config
3751
+ // Rebuild the master config with the updated config and stored proxyAuthConfig
3752
+ // If we don't have a stored proxyAuthConfig and we need to fetch it, we wait until that fetch is done in the other useEffect.
3753
+ // If shouldFetchWalletKitConfig is false, we'll never have a proxyAuthConfig to build the master config with, so this useEffect should always run.
3754
+ if (!proxyAuthConfigRef.current && shouldFetchWalletKitConfig) return;
3755
+ setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
3756
+ }, [config, proxyAuthConfigRef.current]);
3757
+ /**
3758
+ * @internal
3759
+ * We create `debouncedRefreshWallets()` so that multiple rapid wallet events
3760
+ * (for example, on Solana a single disconnect can emit several events we listen for)
3761
+ * only trigger `maybeRefreshWallets()` once.
3762
+ *
3763
+ * Defining the debounced function outside of the `useEffect` ensures all event
3764
+ * listeners in `initializeWalletProviderListeners` share the same instance, instead of creating
3765
+ * a new one on every render.
3766
+ */
3767
+ const debouncedRefreshWallets = utils.useDebouncedCallback(maybeRefreshWallets, 100);
3768
+ const debouncedFetchWalletProviders = utils.useDebouncedCallback(fetchWalletProviders, 100);
3769
+ react.useEffect(() => {
3770
+ const handleUpdateState = async () => {
3771
+ // we only refresh the wallets if there is an active session
3772
+ // this is needed because a disconnect event can occur
3773
+ // while the user is unauthenticated
3774
+ //
3775
+ // WalletProviders state is updated regardless of session state
3776
+ const currentSession = await getSession();
3777
+ if (currentSession) {
3778
+ // this updates both the wallets and walletProviders state
3779
+ await debouncedRefreshWallets();
3780
+ } else {
3781
+ // this updates only the walletProviders state
3782
+ await debouncedFetchWalletProviders();
3783
+ }
3784
+ };
3785
+ let cleanup = () => {};
3786
+ initializeWalletProviderListeners(walletProviders, handleUpdateState).then(fn => {
3787
+ cleanup = fn;
3788
+ }).catch(err => {
3789
+ console.error("Failed to init providers:", err);
3790
+ });
3791
+ return () => {
3792
+ cleanup();
3793
+ };
3794
+ }, [walletProviders, getSession, debouncedRefreshWallets, debouncedFetchWalletProviders]);
3795
+ react.useEffect(() => {
3796
+ // authState must be consistent with session state. We found during testing that there are cases where the session and authState can be out of sync in very rare edge cases.
3797
+ // This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
3798
+ if (session && utils.isValidSession(session)) {
3799
+ setAuthState(base.AuthState.Authenticated);
3800
+ } else {
3801
+ setAuthState(base.AuthState.Unauthenticated);
3802
+ }
3803
+ }, [session]);
3804
+ react.useEffect(() => {
3805
+ // This will handle any redirect based oAuth. It then initializes the session. This is the last step before client is considered "ready"
3806
+ if (!client || !masterConfig) return;
3807
+ completeRedirectOauth().finally(() => {
3808
+ clearSessionTimeouts();
3809
+ // if auth or wallet connecting features are enabled, we want to fetch
3810
+ // the wallet providers to set the state
3811
+ if (masterConfig.walletConfig?.features?.auth || masterConfig.walletConfig?.features?.connecting) {
3812
+ fetchWalletProviders();
3813
+ }
3814
+ initializeSessions().finally(() => {
3815
+ // Set the client state to ready only after all initializations are done.
3816
+ setClientState(base.ClientState.Ready);
3817
+ });
3818
+ });
3819
+ return () => {
3820
+ clearSessionTimeouts();
3821
+ };
3822
+ }, [client]);
3823
+ return jsxRuntime.jsx(Types.ClientContext.Provider, {
3824
+ value: {
3825
+ session,
3826
+ allSessions,
3827
+ clientState,
3828
+ authState,
3829
+ user,
3830
+ wallets,
3831
+ walletProviders,
3832
+ config: masterConfig,
3833
+ httpClient: client?.httpClient,
3834
+ createHttpClient,
3835
+ createPasskey,
3836
+ logout,
3837
+ loginWithPasskey,
3838
+ signUpWithPasskey,
3839
+ fetchWalletProviders,
3840
+ connectWalletAccount,
3841
+ disconnectWalletAccount,
3842
+ switchWalletAccountChain,
3843
+ buildWalletLoginRequest,
3844
+ loginWithWallet,
3845
+ signUpWithWallet,
3846
+ loginOrSignupWithWallet,
3847
+ initOtp,
3848
+ verifyOtp,
3849
+ loginWithOtp,
3850
+ signUpWithOtp,
3851
+ completeOtp,
3852
+ loginWithOauth,
3853
+ signUpWithOauth,
3854
+ completeOauth,
3855
+ fetchWallets,
3856
+ fetchWalletAccounts,
3857
+ fetchPrivateKeys,
3858
+ refreshWallets,
3859
+ signMessage,
3860
+ signTransaction,
3861
+ ethSendTransaction,
3862
+ ethSendErc20Transfer,
3863
+ solSendTransaction,
3864
+ signAndSendTransaction,
3865
+ pollTransactionStatus,
3866
+ fetchUser,
3867
+ fetchOrCreateP256ApiKeyUser,
3868
+ fetchOrCreatePolicies,
3869
+ refreshUser,
3870
+ updateUserEmail,
3871
+ removeUserEmail,
3872
+ updateUserPhoneNumber,
3873
+ removeUserPhoneNumber,
3874
+ updateUserName,
3875
+ addOauthProvider,
3876
+ removeOauthProviders,
3877
+ addPasskey,
3878
+ removePasskeys,
3879
+ createWallet,
3880
+ createWalletAccounts,
3881
+ exportWallet,
3882
+ exportPrivateKey,
3883
+ exportWalletAccount,
3884
+ importWallet,
3885
+ importPrivateKey,
3886
+ deleteSubOrganization,
3887
+ storeSession,
3888
+ clearSession,
3889
+ clearAllSessions,
3890
+ refreshSession,
3891
+ getSession,
3892
+ getAllSessions,
3893
+ setActiveSession,
3894
+ clearUnusedKeyPairs,
3895
+ getActiveSessionKey,
3896
+ createApiKeyPair,
3897
+ getProxyAuthConfig,
3898
+ fetchBootProofForAppProof,
3899
+ verifyAppProofs,
3900
+ handleLogin,
3901
+ handleGoogleOauth,
3902
+ handleXOauth,
3903
+ handleDiscordOauth,
3904
+ handleAppleOauth,
3905
+ handleFacebookOauth,
3906
+ handleExportWallet,
3907
+ handleExportPrivateKey,
3908
+ handleExportWalletAccount,
3909
+ handleImportWallet,
3910
+ handleImportPrivateKey,
3911
+ handleUpdateUserEmail,
3912
+ handleUpdateUserPhoneNumber,
3913
+ handleUpdateUserName,
3914
+ handleAddOauthProvider,
3915
+ handleRemoveOauthProvider,
3916
+ handleAddPasskey,
3917
+ handleRemovePasskey,
3918
+ handleAddEmail,
3919
+ handleAddPhoneNumber,
3920
+ handleSignMessage,
3921
+ handleConnectExternalWallet,
3922
+ handleRemoveUserEmail,
3923
+ handleRemoveUserPhoneNumber,
3924
+ handleVerifyAppProofs,
3925
+ handleOnRamp,
3926
+ handleSendTransaction,
3927
+ handleSendErc20Transfer
3928
+ },
3929
+ children: children
3930
+ });
3931
+ };
3932
+
3933
+ exports.ClientProvider = ClientProvider;
3934
+ //# sourceMappingURL=Provider.js.map