@tatchi-xyz/sdk 0.19.0 → 0.21.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 (243) hide show
  1. package/dist/cjs/core/EmailRecovery/index.js +25 -0
  2. package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
  3. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +135 -77
  4. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  5. package/dist/cjs/core/TatchiPasskey/index.js +2 -1
  6. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  7. package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -1
  8. package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
  9. package/dist/cjs/core/TatchiPasskey/scanDevice.js +5 -3
  10. package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
  11. package/dist/cjs/core/WalletIframe/client/router.js +1 -1
  12. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  13. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +3 -4
  14. package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  15. package/dist/cjs/core/defaultConfigs.js +3 -7
  16. package/dist/cjs/core/defaultConfigs.js.map +1 -1
  17. package/dist/cjs/core/nearCrypto.js +29 -5
  18. package/dist/cjs/core/nearCrypto.js.map +1 -1
  19. package/dist/cjs/core/rpcCalls.js +56 -26
  20. package/dist/cjs/core/rpcCalls.js.map +1 -1
  21. package/dist/cjs/core/types/emailRecovery.js +33 -0
  22. package/dist/cjs/core/types/emailRecovery.js.map +1 -0
  23. package/dist/cjs/index.js +4 -0
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-CSSowiHP.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
  26. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
  27. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-CEPMZ1gY.css → ProfileDropdown-BG_6hcim.css} +1 -1
  28. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
  29. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
  30. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
  31. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css → TouchIcon-C-RcGfr5.css} +1 -1
  32. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
  33. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
  34. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.css.map → PasskeyAuthMenu-DKMiLeT9.css.map} +1 -1
  35. package/dist/cjs/react/components/PasskeyAuthMenu/adapters/tatchi.js +1 -0
  36. package/dist/cjs/react/components/PasskeyAuthMenu/adapters/tatchi.js.map +1 -1
  37. package/dist/cjs/react/components/PasskeyAuthMenu/client.js +30 -8
  38. package/dist/cjs/react/components/PasskeyAuthMenu/client.js.map +1 -1
  39. package/dist/cjs/react/components/PasskeyAuthMenu/controller/useSDKEvents.js +22 -0
  40. package/dist/cjs/react/components/PasskeyAuthMenu/controller/useSDKEvents.js.map +1 -0
  41. package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +17 -4
  42. package/dist/cjs/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
  43. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +354 -154
  44. package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  45. package/dist/cjs/react/components/{ShowQRCode-CCN4h6Uv.css → ShowQRCode-CB0UCQ_h.css} +1 -1
  46. package/dist/cjs/react/components/{ShowQRCode-CCN4h6Uv.css.map → ShowQRCode-CB0UCQ_h.css.map} +1 -1
  47. package/dist/cjs/react/context/useSDKFlowRuntime.js +183 -0
  48. package/dist/cjs/react/context/useSDKFlowRuntime.js.map +1 -0
  49. package/dist/cjs/react/context/useTatchiContextValue.js +24 -15
  50. package/dist/cjs/react/context/useTatchiContextValue.js.map +1 -1
  51. package/dist/cjs/react/context/useTatchiWithSdkFlow.js +96 -0
  52. package/dist/cjs/react/context/useTatchiWithSdkFlow.js.map +1 -0
  53. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +26 -0
  54. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  55. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +135 -77
  56. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  57. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +2 -1
  58. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  59. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -1
  60. package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  61. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +5 -3
  62. package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  63. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +1 -1
  64. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  65. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +3 -4
  66. package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  67. package/dist/cjs/react/sdk/src/core/defaultConfigs.js +3 -7
  68. package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
  69. package/dist/cjs/react/sdk/src/core/nearCrypto.js +29 -5
  70. package/dist/cjs/react/sdk/src/core/nearCrypto.js.map +1 -1
  71. package/dist/cjs/react/sdk/src/core/rpcCalls.js +56 -26
  72. package/dist/cjs/react/sdk/src/core/rpcCalls.js.map +1 -1
  73. package/dist/cjs/react/sdk/src/core/types/emailRecovery.js +33 -0
  74. package/dist/cjs/react/sdk/src/core/types/emailRecovery.js.map +1 -0
  75. package/dist/cjs/server/email-recovery/emailParsers.js +2 -1
  76. package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
  77. package/dist/cjs/server/email-recovery/index.js +6 -6
  78. package/dist/cjs/server/email-recovery/index.js.map +1 -1
  79. package/dist/cjs/server/email-recovery/rpcCalls.js +22 -3
  80. package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
  81. package/dist/cjs/server/router/cloudflare.js +8 -3
  82. package/dist/cjs/server/router/cloudflare.js.map +1 -1
  83. package/dist/cjs/server/router/express.js.map +1 -1
  84. package/dist/cjs/server/sdk/src/core/defaultConfigs.js +2 -4
  85. package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
  86. package/dist/cjs/server/sdk/src/core/nearCrypto.js +26 -7
  87. package/dist/cjs/server/sdk/src/core/nearCrypto.js.map +1 -1
  88. package/dist/esm/core/EmailRecovery/index.js +25 -1
  89. package/dist/esm/core/EmailRecovery/index.js.map +1 -1
  90. package/dist/esm/core/TatchiPasskey/emailRecovery.js +136 -78
  91. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  92. package/dist/esm/core/TatchiPasskey/index.js +2 -1
  93. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  94. package/dist/esm/core/TatchiPasskey/linkDevice.js +2 -1
  95. package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
  96. package/dist/esm/core/TatchiPasskey/scanDevice.js +5 -3
  97. package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
  98. package/dist/esm/core/WalletIframe/client/router.js +1 -1
  99. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  100. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -3
  101. package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  102. package/dist/esm/core/defaultConfigs.js +3 -7
  103. package/dist/esm/core/defaultConfigs.js.map +1 -1
  104. package/dist/esm/core/nearCrypto.js +24 -6
  105. package/dist/esm/core/nearCrypto.js.map +1 -1
  106. package/dist/esm/core/rpcCalls.js +56 -26
  107. package/dist/esm/core/rpcCalls.js.map +1 -1
  108. package/dist/esm/core/types/emailRecovery.js +26 -0
  109. package/dist/esm/core/types/emailRecovery.js.map +1 -0
  110. package/dist/esm/index.js +3 -1
  111. package/dist/esm/index.js.map +1 -1
  112. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-CSSowiHP.css → LinkedDevicesModal-BRtht0XI.css} +1 -1
  113. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-BRtht0XI.css.map} +1 -1
  114. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-CEPMZ1gY.css → ProfileDropdown-BG_6hcim.css} +1 -1
  115. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-BG_6hcim.css.map} +1 -1
  116. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css → Web3AuthProfileButton-k8_FAYFq.css} +1 -1
  117. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-DopOg7Xc.css.map → Web3AuthProfileButton-k8_FAYFq.css.map} +1 -1
  118. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css → TouchIcon-C-RcGfr5.css} +1 -1
  119. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BQWentvJ.css.map → TouchIcon-C-RcGfr5.css.map} +1 -1
  120. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.css → PasskeyAuthMenu-DKMiLeT9.css} +59 -4
  121. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-DwrzWMYx.css.map → PasskeyAuthMenu-DKMiLeT9.css.map} +1 -1
  122. package/dist/esm/react/components/PasskeyAuthMenu/adapters/tatchi.js +1 -0
  123. package/dist/esm/react/components/PasskeyAuthMenu/adapters/tatchi.js.map +1 -1
  124. package/dist/esm/react/components/PasskeyAuthMenu/client.js +30 -8
  125. package/dist/esm/react/components/PasskeyAuthMenu/client.js.map +1 -1
  126. package/dist/esm/react/components/PasskeyAuthMenu/controller/useSDKEvents.js +20 -0
  127. package/dist/esm/react/components/PasskeyAuthMenu/controller/useSDKEvents.js.map +1 -0
  128. package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js +17 -4
  129. package/dist/esm/react/components/PasskeyAuthMenu/ui/ContentSwitcher.js.map +1 -1
  130. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +354 -154
  131. package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
  132. package/dist/esm/react/components/{ShowQRCode-CCN4h6Uv.css → ShowQRCode-CB0UCQ_h.css} +1 -1
  133. package/dist/esm/react/components/{ShowQRCode-CCN4h6Uv.css.map → ShowQRCode-CB0UCQ_h.css.map} +1 -1
  134. package/dist/esm/react/context/useSDKFlowRuntime.js +181 -0
  135. package/dist/esm/react/context/useSDKFlowRuntime.js.map +1 -0
  136. package/dist/esm/react/context/useTatchiContextValue.js +25 -16
  137. package/dist/esm/react/context/useTatchiContextValue.js.map +1 -1
  138. package/dist/esm/react/context/useTatchiWithSdkFlow.js +94 -0
  139. package/dist/esm/react/context/useTatchiWithSdkFlow.js.map +1 -0
  140. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +25 -1
  141. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  142. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +136 -78
  143. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  144. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +2 -1
  145. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  146. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -1
  147. package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
  148. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +5 -3
  149. package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
  150. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +1 -1
  151. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  152. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -3
  153. package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
  154. package/dist/esm/react/sdk/src/core/defaultConfigs.js +3 -7
  155. package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
  156. package/dist/esm/react/sdk/src/core/nearCrypto.js +24 -6
  157. package/dist/esm/react/sdk/src/core/nearCrypto.js.map +1 -1
  158. package/dist/esm/react/sdk/src/core/rpcCalls.js +56 -26
  159. package/dist/esm/react/sdk/src/core/rpcCalls.js.map +1 -1
  160. package/dist/esm/react/sdk/src/core/types/emailRecovery.js +26 -0
  161. package/dist/esm/react/sdk/src/core/types/emailRecovery.js.map +1 -0
  162. package/dist/esm/react/styles/styles.css +58 -3
  163. package/dist/esm/sdk/{defaultConfigs-DpslkAQd.js → defaultConfigs-CfQDV-ya.js} +3 -7
  164. package/dist/esm/sdk/{getDeviceNumber-fXizNGQl.js → getDeviceNumber-BpernPnM.js} +4 -8
  165. package/dist/esm/sdk/getDeviceNumber-BpernPnM.js.map +1 -0
  166. package/dist/esm/sdk/offline-export-app.js +23 -6
  167. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  168. package/dist/esm/sdk/{router-DuGYOd3G.js → router-BWtacLJg.js} +1 -1
  169. package/dist/esm/sdk/{rpcCalls-BQrJMTdg.js → rpcCalls-CYGJSCgm.js} +3 -3
  170. package/dist/esm/sdk/{rpcCalls-YVeUVMk2.js → rpcCalls-DZZSa-sk.js} +57 -27
  171. package/dist/esm/sdk/{transactions-bqaAwL4k.js → transactions-Cn9xTWlK.js} +2 -2
  172. package/dist/esm/sdk/{transactions-bqaAwL4k.js.map → transactions-Cn9xTWlK.js.map} +1 -1
  173. package/dist/esm/sdk/{transactions-BalIhtJ9.js → transactions-DfdwDQCn.js} +1 -1
  174. package/dist/esm/sdk/wallet-iframe-host.js +660 -590
  175. package/dist/esm/server/email-recovery/emailParsers.js +3 -1
  176. package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
  177. package/dist/esm/server/email-recovery/index.js +6 -6
  178. package/dist/esm/server/email-recovery/index.js.map +1 -1
  179. package/dist/esm/server/email-recovery/rpcCalls.js +22 -3
  180. package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
  181. package/dist/esm/server/router/cloudflare.js +8 -3
  182. package/dist/esm/server/router/cloudflare.js.map +1 -1
  183. package/dist/esm/server/router/express.js.map +1 -1
  184. package/dist/esm/server/sdk/src/core/defaultConfigs.js +2 -4
  185. package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
  186. package/dist/esm/server/sdk/src/core/nearCrypto.js +26 -8
  187. package/dist/esm/server/sdk/src/core/nearCrypto.js.map +1 -1
  188. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  189. package/dist/types/src/core/EmailRecovery/index.d.ts +8 -0
  190. package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
  191. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +8 -5
  192. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  193. package/dist/types/src/core/TatchiPasskey/index.d.ts +1 -1
  194. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  195. package/dist/types/src/core/TatchiPasskey/scanDevice.d.ts.map +1 -1
  196. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +1 -1
  197. package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
  198. package/dist/types/src/core/WalletIframe/client/router.d.ts +1 -1
  199. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  200. package/dist/types/src/core/WalletIframe/shared/messages.d.ts +1 -1
  201. package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
  202. package/dist/types/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.d.ts +2 -1
  203. package/dist/types/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.d.ts.map +1 -1
  204. package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
  205. package/dist/types/src/core/nearCrypto.d.ts +14 -0
  206. package/dist/types/src/core/nearCrypto.d.ts.map +1 -1
  207. package/dist/types/src/core/rpcCalls.d.ts +11 -8
  208. package/dist/types/src/core/rpcCalls.d.ts.map +1 -1
  209. package/dist/types/src/core/types/emailRecovery.d.ts +10 -0
  210. package/dist/types/src/core/types/emailRecovery.d.ts.map +1 -0
  211. package/dist/types/src/core/types/index.d.ts +1 -0
  212. package/dist/types/src/core/types/index.d.ts.map +1 -1
  213. package/dist/types/src/core/types/tatchi.d.ts +0 -4
  214. package/dist/types/src/core/types/tatchi.d.ts.map +1 -1
  215. package/dist/types/src/index.d.ts +1 -0
  216. package/dist/types/src/index.d.ts.map +1 -1
  217. package/dist/types/src/react/components/PasskeyAuthMenu/adapters/tatchi.d.ts +2 -0
  218. package/dist/types/src/react/components/PasskeyAuthMenu/adapters/tatchi.d.ts.map +1 -1
  219. package/dist/types/src/react/components/PasskeyAuthMenu/client.d.ts.map +1 -1
  220. package/dist/types/src/react/components/PasskeyAuthMenu/controller/useSDKEvents.d.ts +10 -0
  221. package/dist/types/src/react/components/PasskeyAuthMenu/controller/useSDKEvents.d.ts.map +1 -0
  222. package/dist/types/src/react/components/PasskeyAuthMenu/types.d.ts +8 -3
  223. package/dist/types/src/react/components/PasskeyAuthMenu/types.d.ts.map +1 -1
  224. package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts +2 -0
  225. package/dist/types/src/react/components/PasskeyAuthMenu/ui/ContentSwitcher.d.ts.map +1 -1
  226. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts +1 -1
  227. package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
  228. package/dist/types/src/react/context/useSDKFlowRuntime.d.ts +10 -0
  229. package/dist/types/src/react/context/useSDKFlowRuntime.d.ts.map +1 -0
  230. package/dist/types/src/react/context/useTatchiContextValue.d.ts.map +1 -1
  231. package/dist/types/src/react/context/useTatchiWithSdkFlow.d.ts +9 -0
  232. package/dist/types/src/react/context/useTatchiWithSdkFlow.d.ts.map +1 -0
  233. package/dist/types/src/react/types.d.ts +31 -0
  234. package/dist/types/src/react/types.d.ts.map +1 -1
  235. package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
  236. package/dist/types/src/server/email-recovery/index.d.ts +5 -6
  237. package/dist/types/src/server/email-recovery/index.d.ts.map +1 -1
  238. package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -0
  239. package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
  240. package/dist/types/src/server/router/cloudflare-adaptor.d.ts.map +1 -1
  241. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  242. package/package.json +1 -1
  243. package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"nearCrypto.js","names":[],"sources":["../../../../../../src/core/nearCrypto.ts"],"sourcesContent":["import * as ed25519 from '@noble/ed25519';\nimport bs58 from 'bs58';\n\n// NEAR key prefix\nconst NEAR_KEY_PREFIX = 'ed25519:';\n\nfunction ensurePrefix(str: string): string {\n return str.startsWith(NEAR_KEY_PREFIX) ? str : `${NEAR_KEY_PREFIX}${str}`;\n}\n\nfunction stripPrefix(str: string): string {\n return str.startsWith(NEAR_KEY_PREFIX) ? str.slice(NEAR_KEY_PREFIX.length) : str;\n}\n\n/**\n * Creates a NEAR-compatible Ed25519 keypair formatted as strings:\n * - publicKey: 'ed25519:' + base58(pub)\n * - privateKey: 'ed25519:' + base58(seed(32) | pub(32))\n */\nexport async function createNearKeypair(): Promise<{ publicKey: string; privateKey: string }> {\n const seed = ed25519.utils.randomPrivateKey(); // 32 bytes\n const pub = await ed25519.getPublicKeyAsync(seed); // 32 bytes\n\n const secret = new Uint8Array(64);\n secret.set(seed, 0);\n secret.set(pub, 32);\n\n const publicKey = ensurePrefix(bs58.encode(pub));\n const privateKey = ensurePrefix(bs58.encode(secret));\n return { publicKey, privateKey };\n}\n\n/** Parse NEAR public key string ('ed25519:...') into 32-byte Uint8Array */\nexport function parseNearPublicKey(str: string): Uint8Array {\n const b58 = stripPrefix(str);\n const bytes = bs58.decode(b58);\n if (bytes.length !== 32) {\n throw new Error(`Invalid NEAR public key length: ${bytes.length}`);\n }\n return new Uint8Array(bytes);\n}\n\n/**\n * Parse NEAR secret key string ('ed25519:...') into its components.\n * NEAR secrets are 64 bytes: seed(32) | pub(32)\n */\nexport function parseNearSecretKey(str: string): { seed: Uint8Array; pub: Uint8Array } {\n const b58 = stripPrefix(str);\n const bytes = bs58.decode(b58);\n if (bytes.length !== 64) {\n throw new Error(`Invalid NEAR secret key length: ${bytes.length}`);\n }\n const all = new Uint8Array(bytes);\n const seed = all.slice(0, 32);\n const pub = all.slice(32, 64);\n return { seed, pub };\n}\n\n/** Convert raw 32-byte public key to NEAR string ('ed25519:...') */\nexport function toPublicKeyString(pub: Uint8Array): string {\n if (!(pub?.length === 32)) {\n throw new Error('Public key must be 32 bytes');\n }\n return ensurePrefix(bs58.encode(pub));\n}\n\n/** Convert raw seed(32) + pub(32) to NEAR secret string ('ed25519:...') */\nexport function toSecretKeyString(seed: Uint8Array, pub: Uint8Array): string {\n if (!(seed?.length === 32)) {\n throw new Error('Seed must be 32 bytes');\n }\n if (!(pub?.length === 32)) {\n throw new Error('Public key must be 32 bytes');\n }\n const secret = new Uint8Array(64);\n secret.set(seed, 0);\n secret.set(pub, 32);\n return ensurePrefix(bs58.encode(secret));\n}\n\n"],"mappings":";;;;AAIA,MAAM,kBAAkB;AAExB,SAAS,aAAa,KAAqB;AACzC,QAAO,IAAI,WAAW,mBAAmB,MAAM,GAAG,kBAAkB;;;;;;;AAYtE,eAAsB,oBAAwE;CAC5F,MAAM,OAAO,QAAQ,MAAM;CAC3B,MAAM,MAAM,MAAM,QAAQ,kBAAkB;CAE5C,MAAM,SAAS,IAAI,WAAW;AAC9B,QAAO,IAAI,MAAM;AACjB,QAAO,IAAI,KAAK;CAEhB,MAAM,YAAY,aAAa,KAAK,OAAO;CAC3C,MAAM,aAAa,aAAa,KAAK,OAAO;AAC5C,QAAO;EAAE;EAAW"}
1
+ {"version":3,"file":"nearCrypto.js","names":[],"sources":["../../../../../../src/core/nearCrypto.ts"],"sourcesContent":["import * as ed25519 from '@noble/ed25519';\nimport bs58 from 'bs58';\n\nexport const NEAR_ED25519_KEY_PREFIX = 'ed25519:' as const;\n\n/**\n * Ensure a key string has the NEAR Ed25519 prefix (`ed25519:`).\n *\n * - Accepts either `ed25519:<base58>` or a bare `<base58>` string.\n * - Canonicalizes `ED25519:` → `ed25519:`.\n * - If a different prefix is present (e.g. `secp256k1:`), returns the input unchanged.\n */\nexport function ensureEd25519Prefix(value: string): string {\n const raw = String(value || '').trim();\n if (!raw) return '';\n\n // If it already looks like \"<prefix>:...\", only normalize when the prefix is ed25519.\n if (/^[a-z0-9_]+:/i.test(raw)) {\n if (/^ed25519:/i.test(raw)) {\n return `${NEAR_ED25519_KEY_PREFIX}${raw.replace(/^ed25519:/i, '')}`;\n }\n return raw;\n }\n\n return `${NEAR_ED25519_KEY_PREFIX}${raw}`;\n}\n\n/**\n * Remove the NEAR Ed25519 prefix (`ed25519:`) if present.\n * Useful for comparing keys where one side may omit the prefix.\n */\nexport function stripEd25519Prefix(value: string): string {\n const raw = String(value || '').trim();\n return raw.replace(/^ed25519:/i, '');\n}\n\n/**\n * Creates a NEAR-compatible Ed25519 keypair formatted as strings:\n * - publicKey: 'ed25519:' + base58(pub)\n * - privateKey: 'ed25519:' + base58(seed(32) | pub(32))\n */\nexport async function createNearKeypair(): Promise<{ publicKey: string; privateKey: string }> {\n const seed = ed25519.utils.randomPrivateKey(); // 32 bytes\n const pub = await ed25519.getPublicKeyAsync(seed); // 32 bytes\n\n const secret = new Uint8Array(64);\n secret.set(seed, 0);\n secret.set(pub, 32);\n\n const publicKey = ensureEd25519Prefix(bs58.encode(pub));\n const privateKey = ensureEd25519Prefix(bs58.encode(secret));\n return { publicKey, privateKey };\n}\n\n/** Parse NEAR public key string ('ed25519:...') into 32-byte Uint8Array */\nexport function parseNearPublicKey(str: string): Uint8Array {\n const b58 = stripEd25519Prefix(str);\n const bytes = bs58.decode(b58);\n if (bytes.length !== 32) {\n throw new Error(`Invalid NEAR public key length: ${bytes.length}`);\n }\n return new Uint8Array(bytes);\n}\n\n/**\n * Parse NEAR secret key string ('ed25519:...') into its components.\n * NEAR secrets are 64 bytes: seed(32) | pub(32)\n */\nexport function parseNearSecretKey(str: string): { seed: Uint8Array; pub: Uint8Array } {\n const b58 = stripEd25519Prefix(str);\n const bytes = bs58.decode(b58);\n if (bytes.length !== 64) {\n throw new Error(`Invalid NEAR secret key length: ${bytes.length}`);\n }\n const all = new Uint8Array(bytes);\n const seed = all.slice(0, 32);\n const pub = all.slice(32, 64);\n return { seed, pub };\n}\n\n/** Convert raw 32-byte public key to NEAR string ('ed25519:...') */\nexport function toPublicKeyString(pub: Uint8Array): string {\n if (!(pub?.length === 32)) {\n throw new Error('Public key must be 32 bytes');\n }\n return ensureEd25519Prefix(bs58.encode(pub));\n}\n\n/** Convert raw seed(32) + pub(32) to NEAR secret string ('ed25519:...') */\nexport function toSecretKeyString(seed: Uint8Array, pub: Uint8Array): string {\n if (!(seed?.length === 32)) {\n throw new Error('Seed must be 32 bytes');\n }\n if (!(pub?.length === 32)) {\n throw new Error('Public key must be 32 bytes');\n }\n const secret = new Uint8Array(64);\n secret.set(seed, 0);\n secret.set(pub, 32);\n return ensureEd25519Prefix(bs58.encode(secret));\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,oBAAoB,OAAuB;CACzD,MAAM,MAAM,OAAO,SAAS,IAAI;AAChC,KAAI,CAAC,IAAK,QAAO;AAGjB,KAAI,gBAAgB,KAAK,MAAM;AAC7B,MAAI,aAAa,KAAK,KACpB,QAAO,GAAG,0BAA0B,IAAI,QAAQ,cAAc;AAEhE,SAAO;;AAGT,QAAO,GAAG,0BAA0B;;;;;;;AAiBtC,eAAsB,oBAAwE;CAC5F,MAAM,OAAO,QAAQ,MAAM;CAC3B,MAAM,MAAM,MAAM,QAAQ,kBAAkB;CAE5C,MAAM,SAAS,IAAI,WAAW;AAC9B,QAAO,IAAI,MAAM;AACjB,QAAO,IAAI,KAAK;CAEhB,MAAM,YAAY,oBAAoB,KAAK,OAAO;CAClD,MAAM,aAAa,oBAAoB,KAAK,OAAO;AACnD,QAAO;EAAE;EAAW;;;;;CAhDT,0BAA0B"}
@@ -8,12 +8,26 @@ import { ActionType, init_actions } from "./types/actions.js";
8
8
  import { DEFAULT_WAIT_STATUS, init_rpc } from "./types/rpc.js";
9
9
 
10
10
  //#region src/core/rpcCalls.ts
11
- async function getEmailRecoveryVerificationResult(nearClient, dkimVerifierAccountId, verificationViewMethod, requestId) {
12
- return await nearClient.view({
13
- account: dkimVerifierAccountId,
14
- method: verificationViewMethod,
11
+ async function getEmailRecoveryAttempt(nearClient, accountId, requestId) {
12
+ const raw = await nearClient.view({
13
+ account: accountId,
14
+ method: "get_recovery_attempt",
15
15
  args: { request_id: requestId }
16
16
  });
17
+ if (!raw) return null;
18
+ const statusRaw = raw.status;
19
+ const status = (() => {
20
+ if (typeof statusRaw === "string") return statusRaw.trim();
21
+ if (statusRaw && typeof statusRaw === "object") {
22
+ const keys = Object.keys(statusRaw);
23
+ if (keys.length === 1) return String(keys[0] || "").trim();
24
+ }
25
+ return "";
26
+ })();
27
+ return {
28
+ ...raw,
29
+ status
30
+ };
17
31
  }
18
32
  /**
19
33
  * Query the contract to get the account linked to a device public key
@@ -225,14 +239,26 @@ async function syncAuthenticatorsContractCall(nearClient, contractId, accountId)
225
239
  return [];
226
240
  }
227
241
  }
242
+ async function hasDeployedContractCode(nearClient, accountId) {
243
+ try {
244
+ const account = await nearClient.viewAccount(accountId);
245
+ const codeHash = account?.code_hash;
246
+ const globalContractHash = account?.global_contract_hash;
247
+ const globalContractAccountId = account?.global_contract_account_id;
248
+ const hasLocalCode = typeof codeHash === "string" && codeHash !== EMPTY_NEAR_CODE_HASH;
249
+ const hasGlobalCode = typeof globalContractHash === "string" && globalContractHash.trim().length > 0 || typeof globalContractAccountId === "string" && globalContractAccountId.trim().length > 0;
250
+ return hasLocalCode || hasGlobalCode;
251
+ } catch {
252
+ return false;
253
+ }
254
+ }
228
255
  /**
229
256
  * Fetch on-chain recovery email hashes from the per-account contract.
230
257
  * Returns [] when no contract is deployed or on failure.
231
258
  */
232
259
  async function getRecoveryEmailHashesContractCall(nearClient, accountId) {
233
260
  try {
234
- const code = await nearClient.viewCode(accountId);
235
- const hasContract = !!code && code.byteLength > 0;
261
+ const hasContract = await hasDeployedContractCode(nearClient, accountId);
236
262
  if (!hasContract) return [];
237
263
  const hashes = await nearClient.view({
238
264
  account: accountId,
@@ -241,7 +267,6 @@ async function getRecoveryEmailHashesContractCall(nearClient, accountId) {
241
267
  });
242
268
  return Array.isArray(hashes) ? hashes : [];
243
269
  } catch (error) {
244
- console.error("[rpcCalls] Failed to fetch recovery email hashes", error);
245
270
  return [];
246
271
  }
247
272
  }
@@ -250,27 +275,24 @@ async function getRecoveryEmailHashesContractCall(nearClient, accountId) {
250
275
  * If the per-account contract is missing, deploy/attach the global recoverer via `init_email_recovery`.
251
276
  */
252
277
  async function buildSetRecoveryEmailsActions(nearClient, accountId, recoveryEmailHashes, contracts = DEFAULT_EMAIL_RECOVERY_CONTRACTS) {
253
- let hasContract = false;
254
- try {
255
- const code = await nearClient.viewCode(accountId);
256
- hasContract = !!code && code.byteLength > 0;
257
- } catch {
258
- hasContract = false;
259
- }
278
+ const hasContract = await hasDeployedContractCode(nearClient, accountId);
260
279
  const { emailRecovererGlobalContract, zkEmailVerifierContract, emailDkimVerifierContract } = contracts;
261
- return hasContract ? [{
262
- type: ActionType.UseGlobalContract,
263
- accountId: emailRecovererGlobalContract
264
- }, {
265
- type: ActionType.FunctionCall,
266
- methodName: "set_recovery_emails",
267
- args: { recovery_emails: recoveryEmailHashes },
268
- gas: "80000000000000",
269
- deposit: "0"
270
- }] : [{
280
+ let shouldInit = !hasContract;
281
+ if (!shouldInit) try {
282
+ await nearClient.view({
283
+ account: accountId,
284
+ method: "get_recovery_emails",
285
+ args: {}
286
+ });
287
+ } catch (err) {
288
+ const msg = errorMessage(err);
289
+ if (/Cannot deserialize the contract state/i.test(msg) || /CodeDoesNotExist/i.test(msg) || /MethodNotFound/i.test(msg)) shouldInit = true;
290
+ }
291
+ const base = [{
271
292
  type: ActionType.UseGlobalContract,
272
293
  accountId: emailRecovererGlobalContract
273
- }, {
294
+ }];
295
+ return shouldInit ? [...base, {
274
296
  type: ActionType.FunctionCall,
275
297
  methodName: "init_email_recovery",
276
298
  args: {
@@ -281,6 +303,12 @@ async function buildSetRecoveryEmailsActions(nearClient, accountId, recoveryEmai
281
303
  },
282
304
  gas: "80000000000000",
283
305
  deposit: "0"
306
+ }] : [...base, {
307
+ type: ActionType.FunctionCall,
308
+ methodName: "set_recovery_emails",
309
+ args: { recovery_emails: recoveryEmailHashes },
310
+ gas: "80000000000000",
311
+ deposit: "0"
284
312
  }];
285
313
  }
286
314
  /**
@@ -386,6 +414,7 @@ async function verifyAuthenticationResponse(relayServerUrl, routePath, sessionKi
386
414
  };
387
415
  }
388
416
  }
417
+ var EMPTY_NEAR_CODE_HASH;
389
418
  var init_rpcCalls = __esm({ "src/core/rpcCalls.ts": (() => {
390
419
  init_sdkSentEvents();
391
420
  init_actions();
@@ -393,9 +422,10 @@ var init_rpcCalls = __esm({ "src/core/rpcCalls.ts": (() => {
393
422
  init_encoders();
394
423
  init_errors();
395
424
  init_defaultConfigs();
425
+ EMPTY_NEAR_CODE_HASH = "11111111111111111111111111111111";
396
426
  }) });
397
427
 
398
428
  //#endregion
399
429
  init_rpcCalls();
400
- export { buildSetRecoveryEmailsActions, checkCanRegisterUserContractCall, executeDeviceLinkingContractCalls, getAuthenticatorsByUser, getCredentialIdsContractCall, getDeviceLinkingAccountContractCall, getEmailRecoveryVerificationResult, getRecoveryEmailHashesContractCall, init_rpcCalls, syncAuthenticatorsContractCall, verifyAuthenticationResponse };
430
+ export { buildSetRecoveryEmailsActions, checkCanRegisterUserContractCall, executeDeviceLinkingContractCalls, getAuthenticatorsByUser, getCredentialIdsContractCall, getDeviceLinkingAccountContractCall, getEmailRecoveryAttempt, getRecoveryEmailHashesContractCall, init_rpcCalls, syncAuthenticatorsContractCall, verifyAuthenticationResponse };
401
431
  //# sourceMappingURL=rpcCalls.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpcCalls.js","names":["error: any","addKeyTxResult: FinalExecutionOutcome","storeDeviceLinkingTxResult: FinalExecutionOutcome","txError: any","err: unknown"],"sources":["../../../../../../src/core/rpcCalls.ts"],"sourcesContent":["/**\n * Consolidated NEAR Contract Calls\n *\n * This file contains all the NEAR contract calls made to the web3authn contract\n * throughout the passkey SDK. It provides a centralized location for all\n * contract interactions and makes it easier to maintain and update contract\n * call patterns.\n */\n\nimport type { FinalExecutionOutcome } from '@near-js/types';\nimport type { NearClient, SignedTransaction } from './NearClient';\nimport type { ContractStoredAuthenticator } from './TatchiPasskey/recoverAccount';\nimport type { PasskeyManagerContext } from './TatchiPasskey';\nimport type { AccountId } from './types/accountIds';\nimport type { DeviceLinkingSSEEvent } from './types/sdkSentEvents';\nimport type {\n StoredAuthenticator,\n WebAuthnRegistrationCredential,\n WebAuthnAuthenticationCredential\n} from './types/webauthn';\n\nimport { ActionPhase, DeviceLinkingPhase, DeviceLinkingStatus } from './types/sdkSentEvents';\nimport { ActionType, type ActionArgs } from './types/actions';\nimport { VRFChallenge } from './types/vrf-worker';\nimport { DEFAULT_WAIT_STATUS, TransactionContext } from './types/rpc';\nimport type { AuthenticatorOptions } from './types/authenticatorOptions';\nimport type { ConfirmationConfig } from './types/signer-worker';\nimport { base64UrlDecode, base64UrlEncode } from '../utils/encoders';\nimport { errorMessage } from '../utils/errors';\nimport type { EmailRecoveryContracts } from './types/tatchi';\nimport { DEFAULT_EMAIL_RECOVERY_CONTRACTS } from './defaultConfigs';\n\n// ===========================\n// CONTRACT CALL RESPONSES\n// ===========================\n\nexport interface DeviceLinkingResult {\n linkedAccountId: string;\n deviceNumber: number;\n}\n\nexport interface CredentialIdsResult {\n credentialIds: string[];\n}\n\nexport interface AuthenticatorsResult {\n authenticators: Array<[string, ContractStoredAuthenticator]>;\n}\n\nexport type EmailRecoveryVerificationResult = {\n verified: boolean;\n account_id?: string;\n new_public_key?: string;\n transaction_hash?: string;\n error_code?: string;\n error_message?: string;\n};\n\nexport async function getEmailRecoveryVerificationResult(\n nearClient: NearClient,\n dkimVerifierAccountId: string,\n verificationViewMethod: string,\n requestId: string\n): Promise<EmailRecoveryVerificationResult | null> {\n return await nearClient.view<{ request_id: string }, EmailRecoveryVerificationResult | null>({\n account: dkimVerifierAccountId,\n method: verificationViewMethod,\n args: { request_id: requestId },\n });\n}\n\n// ===========================\n// DEVICE LINKING CONTRACT CALLS\n// ===========================\n\n/**\n * Query the contract to get the account linked to a device public key\n * Used in device linking flow to check if a device key has been added\n *\n * NEAR does not provide a way to lookup the AccountID an access key has access to.\n * So we store a temporary mapping in the contract to lookup pubkey -> account ID.\n */\nexport async function getDeviceLinkingAccountContractCall(\n nearClient: NearClient,\n contractId: string,\n devicePublicKey: string\n): Promise<DeviceLinkingResult | null> {\n try {\n const result = await nearClient.callFunction<\n { device_public_key: string },\n [string, number | string]\n >(\n contractId,\n 'get_device_linking_account',\n { device_public_key: devicePublicKey }\n );\n\n // Handle different result formats\n if (result && Array.isArray(result) && result.length >= 2) {\n const [linkedAccountId, deviceNumberRaw] = result;\n const deviceNumber = Number(deviceNumberRaw);\n if (!Number.isSafeInteger(deviceNumber) || deviceNumber < 0) {\n console.warn(\n 'Invalid deviceNumber returned from get_device_linking_account:',\n deviceNumberRaw\n );\n return null;\n }\n return {\n linkedAccountId,\n deviceNumber\n };\n }\n\n return null;\n } catch (error: any) {\n console.warn('Failed to get device linking account:', error.message);\n return null;\n }\n}\n\n// ===========================\n// DEVICE LINKING TRANSACTION CALLS\n// ===========================\n\n/**\n * Execute device1's linking transactions (AddKey + Contract mapping)\n * This function signs and broadcasts both transactions required for device linking\n */\nexport async function executeDeviceLinkingContractCalls({\n context,\n device1AccountId,\n device2PublicKey,\n nextNonce,\n nextNextNonce,\n nextNextNextNonce,\n txBlockHash,\n vrfChallenge,\n onEvent,\n confirmationConfigOverride,\n confirmerText,\n}: {\n context: PasskeyManagerContext,\n device1AccountId: AccountId,\n device2PublicKey: string,\n nextNonce: string,\n nextNextNonce: string,\n nextNextNextNonce: string,\n txBlockHash: string,\n vrfChallenge: VRFChallenge,\n onEvent?: (event: DeviceLinkingSSEEvent) => void;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n confirmerText?: { title?: string; body?: string };\n}): Promise<{\n addKeyTxResult: FinalExecutionOutcome;\n storeDeviceLinkingTxResult: FinalExecutionOutcome;\n signedDeleteKeyTransaction: SignedTransaction\n}> {\n\n // Sign three transactions with one PRF authentication\n const signedTransactions = await context.webAuthnManager.signTransactionsWithActions({\n rpcCall: {\n contractId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n nearRpcUrl: context.webAuthnManager.tatchiPasskeyConfigs.nearRpcUrl,\n nearAccountId: device1AccountId\n },\n confirmationConfigOverride,\n title: confirmerText?.title,\n body: confirmerText?.body,\n transactions: [\n // Transaction 1: AddKey - Add Device2's key to Device1's account\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.AddKey,\n public_key: device2PublicKey,\n access_key: JSON.stringify({\n // NEAR-style AccessKey JSON shape, matching near-api-js:\n // { nonce: number, permission: { FullAccess: {} } }\n nonce: 0,\n permission: { FullAccess: {} },\n }),\n }],\n nonce: nextNonce,\n },\n // Transaction 2: Store temporary mapping in contract so Device2 can lookup Device1's accountID.\n {\n receiverId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n actions: [{\n action_type: ActionType.FunctionCall,\n method_name: 'store_device_linking_mapping',\n args: JSON.stringify({\n device_public_key: device2PublicKey,\n target_account_id: device1AccountId,\n }),\n gas: '30000000000000', // 30 TGas for device linking with yield promise automatic cleanup\n deposit: '0'\n }],\n nonce: nextNextNonce,\n },\n // Transaction 3: Remove Device2's temporary key if it fails to complete linking after a timeout\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.DeleteKey,\n public_key: device2PublicKey\n }],\n nonce: nextNextNextNonce,\n }\n ],\n onEvent: (progress) => {\n // Bridge all action progress events to the parent so the wallet iframe overlay\n // can expand during user confirmation in wallet-iframe mode.\n try { onEvent?.(progress as any); } catch { }\n // Keep existing mapping for device linking semantics; surface signing as a loading state\n if (progress.phase == ActionPhase.STEP_6_TRANSACTION_SIGNING_COMPLETE) {\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.PROGRESS,\n message: progress.message || 'Transaction signing in progress...'\n })\n }\n }\n });\n\n if (!signedTransactions[0].signedTransaction) {\n throw new Error('AddKey transaction signing failed');\n }\n if (!signedTransactions[1].signedTransaction) {\n throw new Error('Contract mapping transaction signing failed');\n }\n if (!signedTransactions[2].signedTransaction) {\n throw new Error('DeleteKey transaction signing failed');\n }\n\n // Broadcast just the first 2 transactions: addKey and store device linking mapping\n let addKeyTxResult: FinalExecutionOutcome;\n let storeDeviceLinkingTxResult: FinalExecutionOutcome;\n try {\n console.debug('LinkDeviceFlow: AddKey transaction details:', {\n receiverId: signedTransactions[0].signedTransaction.transaction.receiverId,\n actions: signedTransactions[0].signedTransaction.transaction.actions || [],\n transactionKeys: Object.keys(signedTransactions[0].signedTransaction.transaction),\n });\n\n addKeyTxResult = await context.nearClient.sendTransaction(\n signedTransactions[0].signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceAddKey\n );\n console.log('LinkDeviceFlow: AddKey transaction result:', addKeyTxResult?.transaction?.hash);\n\n // Send success events immediately after AddKey succeeds\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `AddKey transaction completed successfully!`\n });\n\n // Check if contract mapping transaction is valid before attempting to broadcast\n const contractTx = signedTransactions[1].signedTransaction;\n console.log('LinkDeviceFlow: Contract mapping transaction details:', {\n receiverId: contractTx.transaction.receiverId,\n actions: (contractTx.transaction.actions || []).length\n });\n\n // Standard timeout since nonce conflict should be resolved by the 2s delay\n storeDeviceLinkingTxResult = await context.nearClient.sendTransaction(\n contractTx,\n DEFAULT_WAIT_STATUS.linkDeviceAccountMapping\n );\n\n } catch (txError: any) {\n console.error('LinkDeviceFlow: Transaction broadcasting failed:', txError);\n throw new Error(`Transaction broadcasting failed: ${txError.message}`);\n }\n\n onEvent?.({\n step: 6,\n phase: DeviceLinkingPhase.STEP_6_REGISTRATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Device linking completed successfully!`\n });\n\n return {\n addKeyTxResult,\n storeDeviceLinkingTxResult,\n signedDeleteKeyTransaction: signedTransactions[2].signedTransaction\n };\n}\n\n// ===========================\n// ACCOUNT RECOVERY CONTRACT CALLS\n// ===========================\n\n/**\n * Get credential IDs associated with an account from the contract\n * Used in account recovery to discover available credentials\n */\nexport async function getCredentialIdsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<string[]> {\n try {\n const credentialIds = await nearClient.callFunction<{ account_id: AccountId }, string[]>(\n contractId,\n 'get_credential_ids_by_account',\n { account_id: accountId }\n );\n return credentialIds || [];\n } catch (error: any) {\n console.warn('Failed to fetch credential IDs from contract:', error.message);\n return [];\n }\n}\n\n/**\n * Get all authenticators stored for a user from the contract\n * Used in account recovery to sync authenticator data\n */\nexport async function getAuthenticatorsByUser(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<[string, ContractStoredAuthenticator][]> {\n try {\n const authenticatorsResult = await nearClient.view<{ user_id: AccountId }, [string, ContractStoredAuthenticator][]>({\n account: contractId,\n method: 'get_authenticators_by_user',\n args: { user_id: accountId }\n });\n\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult;\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\nexport async function syncAuthenticatorsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<Array<{ credentialId: string, authenticator: StoredAuthenticator }>> {\n try {\n const authenticatorsResult = await getAuthenticatorsByUser(nearClient, contractId, accountId);\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult.map(([credentialId, contractAuthenticator]) => {\n console.log(`Contract authenticator device_number for ${credentialId}:`, contractAuthenticator.device_number);\n\n const transports = Array.isArray(contractAuthenticator.transports)\n ? contractAuthenticator.transports\n : [];\n\n const registered = (() => {\n const raw = String((contractAuthenticator as any).registered ?? '');\n if (!raw) return new Date(0);\n if (/^\\d+$/.test(raw)) {\n const ts = Number(raw);\n return Number.isFinite(ts) ? new Date(ts) : new Date(0);\n }\n const d = new Date(raw);\n return Number.isFinite(d.getTime()) ? d : new Date(0);\n })();\n\n const vrfPublicKeys = (() => {\n const raw = (contractAuthenticator as any).vrf_public_keys;\n if (!raw) return undefined;\n if (Array.isArray(raw) && raw.length > 0 && typeof raw[0] === 'string') {\n return raw as string[];\n }\n if (Array.isArray(raw)) {\n return raw\n .map((entry: unknown) => {\n if (!entry) return null;\n if (entry instanceof Uint8Array) return base64UrlEncode(entry);\n if (Array.isArray(entry)) return base64UrlEncode(new Uint8Array(entry));\n return null;\n })\n .filter((x): x is string => typeof x === 'string' && x.length > 0);\n }\n return undefined;\n })();\n\n return {\n credentialId,\n authenticator: {\n credentialId,\n credentialPublicKey: new Uint8Array(contractAuthenticator.credential_public_key),\n transports,\n userId: accountId,\n name: `Device ${contractAuthenticator.device_number} Authenticator`,\n registered,\n // Store the actual device number from contract (no fallback)\n deviceNumber: contractAuthenticator.device_number,\n vrfPublicKeys\n }\n };\n });\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\n// ===========================\n// RECOVERY EMAIL CONTRACT CALLS\n// ===========================\n\n/**\n * Fetch on-chain recovery email hashes from the per-account contract.\n * Returns [] when no contract is deployed or on failure.\n */\nexport async function getRecoveryEmailHashesContractCall(\n nearClient: NearClient,\n accountId: AccountId\n): Promise<number[][]> {\n try {\n const code = await nearClient.viewCode(accountId);\n const hasContract = !!code && code.byteLength > 0;\n if (!hasContract) return [];\n\n const hashes = await nearClient.view<Record<string, never>, number[][]>({\n account: accountId,\n method: 'get_recovery_emails',\n args: {} as Record<string, never>,\n });\n\n return Array.isArray(hashes) ? (hashes as number[][]) : [];\n } catch (error) {\n console.error('[rpcCalls] Failed to fetch recovery email hashes', error);\n return [];\n }\n}\n\n/**\n * Build action args to update on-chain recovery emails for an account.\n * If the per-account contract is missing, deploy/attach the global recoverer via `init_email_recovery`.\n */\nexport async function buildSetRecoveryEmailsActions(\n nearClient: NearClient,\n accountId: AccountId,\n recoveryEmailHashes: number[][],\n contracts: EmailRecoveryContracts = DEFAULT_EMAIL_RECOVERY_CONTRACTS\n): Promise<ActionArgs[]> {\n let hasContract = false;\n try {\n const code = await nearClient.viewCode(accountId);\n hasContract = !!code && code.byteLength > 0;\n } catch {\n hasContract = false;\n }\n\n const {\n emailRecovererGlobalContract,\n zkEmailVerifierContract,\n emailDkimVerifierContract,\n } = contracts;\n\n return hasContract\n ? [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n {\n type: ActionType.FunctionCall,\n methodName: 'set_recovery_emails',\n args: {\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ]\n : [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n {\n type: ActionType.FunctionCall,\n methodName: 'init_email_recovery',\n args: {\n zk_email_verifier: zkEmailVerifierContract,\n email_dkim_verifier: emailDkimVerifierContract,\n policy: null,\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ];\n}\n\nexport async function fetchNonceBlockHashAndHeight({ nearClient, nearPublicKeyStr, nearAccountId }: {\n nearClient: NearClient,\n nearPublicKeyStr: string,\n nearAccountId: AccountId\n}): Promise<TransactionContext> {\n // Get access key and transaction block info concurrently\n const [accessKeyInfo, txBlockInfo] = await Promise.all([\n nearClient.viewAccessKey(nearAccountId, nearPublicKeyStr)\n .catch(e => { throw new Error(`Failed to fetch Access Key`) }),\n nearClient.viewBlock({ finality: 'final' })\n .catch(e => { throw new Error(`Failed to fetch Block Info`) })\n ]);\n if (!accessKeyInfo || accessKeyInfo.nonce === undefined) {\n throw new Error(`Access key not found or invalid for account ${nearAccountId} with public key ${nearPublicKeyStr}. Response: ${JSON.stringify(accessKeyInfo)}`);\n }\n const nextNonce = (BigInt(accessKeyInfo.nonce) + BigInt(1)).toString();\n const txBlockHeight = String(txBlockInfo.header.height);\n const txBlockHash = txBlockInfo.header.hash; // Keep original base58 string\n\n return {\n nearPublicKeyStr,\n accessKeyInfo,\n nextNonce,\n txBlockHeight,\n txBlockHash,\n };\n}\n\n// ===========================\n// REGISTRATION PRE-CHECK CALL\n// ===========================\n\nexport interface CheckCanRegisterUserResult {\n success: boolean;\n verified: boolean;\n logs: string[];\n error?: string;\n}\n\n/**\n * View-only registration pre-check.\n *\n * Calls the contract's `check_can_register_user` view method with VRF data\n * derived from the provided VRF challenge and a serialized WebAuthn\n * registration credential (typically with PRF outputs embedded).\n */\nexport async function checkCanRegisterUserContractCall({\n nearClient,\n contractId,\n vrfChallenge,\n credential,\n authenticatorOptions,\n}: {\n nearClient: NearClient;\n contractId: string;\n vrfChallenge: VRFChallenge;\n credential: WebAuthnRegistrationCredential;\n authenticatorOptions?: AuthenticatorOptions;\n}): Promise<CheckCanRegisterUserResult> {\n try {\n const vrfData = {\n vrf_input_data: Array.from(base64UrlDecode(vrfChallenge.vrfInput)),\n vrf_output: Array.from(base64UrlDecode(vrfChallenge.vrfOutput)),\n vrf_proof: Array.from(base64UrlDecode(vrfChallenge.vrfProof)),\n public_key: Array.from(base64UrlDecode(vrfChallenge.vrfPublicKey)),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight),\n block_hash: Array.from(base64UrlDecode(vrfChallenge.blockHash)),\n };\n\n const args = {\n vrf_data: vrfData,\n webauthn_registration: credential,\n authenticator_options: authenticatorOptions,\n };\n\n const response = await nearClient.callFunction<typeof args, any>(\n contractId,\n 'check_can_register_user',\n args,\n );\n\n const verified = !!response?.verified;\n return {\n success: true,\n verified,\n logs: [],\n error: verified ? undefined : 'Contract registration check failed',\n };\n } catch (err: unknown) {\n return {\n success: false,\n verified: false,\n logs: [],\n error: errorMessage(err) || 'Failed to call check_can_register_user',\n };\n }\n}\n\n\n/**\n * Verify authentication response through relay server\n * Routes the request to relay server which calls the web3authn contract for verification\n * and issues a JWT or session credential\n */\nexport async function verifyAuthenticationResponse(\n relayServerUrl: string,\n routePath: string,\n sessionKind: 'jwt' | 'cookie',\n vrfChallenge: VRFChallenge,\n webauthnAuthentication: WebAuthnAuthenticationCredential\n): Promise<{\n success: boolean;\n verified?: boolean;\n jwt?: string;\n sessionCredential?: any;\n error?: string;\n contractResponse?: any;\n}> {\n try {\n // Map VRFChallenge into server ContractVrfData shape (number arrays)\n const toBytes = (b64u: string | undefined): number[] => {\n if (!b64u) return [];\n return Array.from(base64UrlDecode(b64u));\n };\n const vrf_data = {\n vrf_input_data: toBytes(vrfChallenge.vrfInput),\n vrf_output: toBytes(vrfChallenge.vrfOutput),\n vrf_proof: toBytes(vrfChallenge.vrfProof),\n public_key: toBytes(vrfChallenge.vrfPublicKey),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight || 0),\n block_hash: toBytes(vrfChallenge.blockHash),\n };\n\n // Normalize authenticatorAttachment and userHandle to null for server schema\n const webauthn_authentication = {\n ...webauthnAuthentication,\n authenticatorAttachment: webauthnAuthentication.authenticatorAttachment ?? null,\n response: {\n ...webauthnAuthentication.response,\n userHandle: webauthnAuthentication.response.userHandle ?? null,\n }\n };\n\n const url = `${relayServerUrl.replace(/\\/$/, '')}${routePath.startsWith('/') ? routePath : `/${routePath}`}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: sessionKind === 'cookie' ? 'include' : 'omit',\n body: JSON.stringify({\n sessionKind: sessionKind,\n vrf_data,\n webauthn_authentication,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n error: `HTTP ${response.status}: ${errorText}`,\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n verified: result.verified,\n jwt: result.jwt,\n sessionCredential: result.sessionCredential,\n contractResponse: result.contractResponse,\n };\n } catch (error: any) {\n return {\n success: false,\n error: error.message || 'Failed to verify authentication response',\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rpcCalls.js","names":["error: any","addKeyTxResult: FinalExecutionOutcome","storeDeviceLinkingTxResult: FinalExecutionOutcome","txError: any","err: unknown","base: ActionArgs[]"],"sources":["../../../../../../src/core/rpcCalls.ts"],"sourcesContent":["/**\n * Consolidated NEAR Contract Calls\n *\n * This file contains all the NEAR contract calls made to the web3authn contract\n * throughout the passkey SDK. It provides a centralized location for all\n * contract interactions and makes it easier to maintain and update contract\n * call patterns.\n */\n\nimport type { FinalExecutionOutcome } from '@near-js/types';\nimport type { NearClient, SignedTransaction } from './NearClient';\nimport type { ContractStoredAuthenticator } from './TatchiPasskey/recoverAccount';\nimport type { PasskeyManagerContext } from './TatchiPasskey';\nimport type { AccountId } from './types/accountIds';\nimport type { DeviceLinkingSSEEvent } from './types/sdkSentEvents';\nimport type {\n StoredAuthenticator,\n WebAuthnRegistrationCredential,\n WebAuthnAuthenticationCredential\n} from './types/webauthn';\n\nimport { ActionPhase, DeviceLinkingPhase, DeviceLinkingStatus } from './types/sdkSentEvents';\nimport { ActionType, type ActionArgs } from './types/actions';\nimport { VRFChallenge } from './types/vrf-worker';\nimport { DEFAULT_WAIT_STATUS, TransactionContext } from './types/rpc';\nimport type { AuthenticatorOptions } from './types/authenticatorOptions';\nimport type { ConfirmationConfig } from './types/signer-worker';\nimport { base64UrlDecode, base64UrlEncode } from '../utils/encoders';\nimport { errorMessage } from '../utils/errors';\nimport type { EmailRecoveryContracts } from './types/tatchi';\nimport { DEFAULT_EMAIL_RECOVERY_CONTRACTS } from './defaultConfigs';\n\n// ===========================\n// CONTRACT CALL RESPONSES\n// ===========================\n\nexport interface DeviceLinkingResult {\n linkedAccountId: string;\n deviceNumber: number;\n}\n\nexport interface CredentialIdsResult {\n credentialIds: string[];\n}\n\nexport interface AuthenticatorsResult {\n authenticators: Array<[string, ContractStoredAuthenticator]>;\n}\n\nexport type RecoveryAttemptStatus =\n | \"Started\"\n | \"VerifyingDkim\"\n | \"VerifyingZkEmail\"\n | \"DkimFailed\"\n | \"ZkEmailFailed\"\n | \"PolicyFailed\"\n | \"Recovering\"\n | \"AwaitingMoreEmails\"\n | \"Complete\"\n | \"Failed\";\n\nexport type RecoveryAttempt = {\n request_id: string;\n status: RecoveryAttemptStatus | string;\n created_at_ms: number;\n updated_at_ms: number;\n error?: string | null;\n from_address?: string | null;\n email_timestamp_ms?: number | null;\n new_public_key?: string | null;\n};\n\nexport async function getEmailRecoveryAttempt(\n nearClient: NearClient,\n accountId: string,\n requestId: string\n): Promise<RecoveryAttempt | null> {\n const raw = await nearClient.view<{ request_id: string }, Omit<RecoveryAttempt, 'status'> & { status: any } | null>({\n account: accountId,\n method: 'get_recovery_attempt',\n args: { request_id: requestId },\n });\n\n if (!raw) return null;\n\n // Normalization logic for status (string or object enum)\n const statusRaw = raw.status;\n const status = (() => {\n if (typeof statusRaw === 'string') return statusRaw.trim();\n if (statusRaw && typeof statusRaw === 'object') {\n const keys = Object.keys(statusRaw as Record<string, unknown>);\n if (keys.length === 1) {\n return String(keys[0] || '').trim();\n }\n }\n return '';\n })();\n\n return {\n ...raw,\n status: status as RecoveryAttemptStatus,\n };\n}\n\n// ===========================\n// DEVICE LINKING CONTRACT CALLS\n// ===========================\n\n/**\n * Query the contract to get the account linked to a device public key\n * Used in device linking flow to check if a device key has been added\n *\n * NEAR does not provide a way to lookup the AccountID an access key has access to.\n * So we store a temporary mapping in the contract to lookup pubkey -> account ID.\n */\nexport async function getDeviceLinkingAccountContractCall(\n nearClient: NearClient,\n contractId: string,\n devicePublicKey: string\n): Promise<DeviceLinkingResult | null> {\n try {\n const result = await nearClient.callFunction<\n { device_public_key: string },\n [string, number | string]\n >(\n contractId,\n 'get_device_linking_account',\n { device_public_key: devicePublicKey }\n );\n\n // Handle different result formats\n if (result && Array.isArray(result) && result.length >= 2) {\n const [linkedAccountId, deviceNumberRaw] = result;\n const deviceNumber = Number(deviceNumberRaw);\n if (!Number.isSafeInteger(deviceNumber) || deviceNumber < 0) {\n console.warn(\n 'Invalid deviceNumber returned from get_device_linking_account:',\n deviceNumberRaw\n );\n return null;\n }\n return {\n linkedAccountId,\n deviceNumber\n };\n }\n\n return null;\n } catch (error: any) {\n console.warn('Failed to get device linking account:', error.message);\n return null;\n }\n}\n\n// ===========================\n// DEVICE LINKING TRANSACTION CALLS\n// ===========================\n\n/**\n * Execute device1's linking transactions (AddKey + Contract mapping)\n * This function signs and broadcasts both transactions required for device linking\n */\nexport async function executeDeviceLinkingContractCalls({\n context,\n device1AccountId,\n device2PublicKey,\n nextNonce,\n nextNextNonce,\n nextNextNextNonce,\n txBlockHash,\n vrfChallenge,\n onEvent,\n confirmationConfigOverride,\n confirmerText,\n}: {\n context: PasskeyManagerContext,\n device1AccountId: AccountId,\n device2PublicKey: string,\n nextNonce: string,\n nextNextNonce: string,\n nextNextNextNonce: string,\n txBlockHash: string,\n vrfChallenge: VRFChallenge,\n onEvent?: (event: DeviceLinkingSSEEvent) => void;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n confirmerText?: { title?: string; body?: string };\n}): Promise<{\n addKeyTxResult: FinalExecutionOutcome;\n storeDeviceLinkingTxResult: FinalExecutionOutcome;\n signedDeleteKeyTransaction: SignedTransaction\n}> {\n\n // Sign three transactions with one PRF authentication\n const signedTransactions = await context.webAuthnManager.signTransactionsWithActions({\n rpcCall: {\n contractId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n nearRpcUrl: context.webAuthnManager.tatchiPasskeyConfigs.nearRpcUrl,\n nearAccountId: device1AccountId\n },\n confirmationConfigOverride,\n title: confirmerText?.title,\n body: confirmerText?.body,\n transactions: [\n // Transaction 1: AddKey - Add Device2's key to Device1's account\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.AddKey,\n public_key: device2PublicKey,\n access_key: JSON.stringify({\n // NEAR-style AccessKey JSON shape, matching near-api-js:\n // { nonce: number, permission: { FullAccess: {} } }\n nonce: 0,\n permission: { FullAccess: {} },\n }),\n }],\n nonce: nextNonce,\n },\n // Transaction 2: Store temporary mapping in contract so Device2 can lookup Device1's accountID.\n {\n receiverId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n actions: [{\n action_type: ActionType.FunctionCall,\n method_name: 'store_device_linking_mapping',\n args: JSON.stringify({\n device_public_key: device2PublicKey,\n target_account_id: device1AccountId,\n }),\n gas: '30000000000000', // 30 TGas for device linking with yield promise automatic cleanup\n deposit: '0'\n }],\n nonce: nextNextNonce,\n },\n // Transaction 3: Remove Device2's temporary key if it fails to complete linking after a timeout\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.DeleteKey,\n public_key: device2PublicKey\n }],\n nonce: nextNextNextNonce,\n }\n ],\n onEvent: (progress) => {\n // Bridge all action progress events to the parent so the wallet iframe overlay\n // can expand during user confirmation in wallet-iframe mode.\n try { onEvent?.(progress as any); } catch { }\n // Keep existing mapping for device linking semantics; surface signing as a loading state\n if (progress.phase == ActionPhase.STEP_6_TRANSACTION_SIGNING_COMPLETE) {\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.PROGRESS,\n message: progress.message || 'Transaction signing in progress...'\n })\n }\n }\n });\n\n if (!signedTransactions[0].signedTransaction) {\n throw new Error('AddKey transaction signing failed');\n }\n if (!signedTransactions[1].signedTransaction) {\n throw new Error('Contract mapping transaction signing failed');\n }\n if (!signedTransactions[2].signedTransaction) {\n throw new Error('DeleteKey transaction signing failed');\n }\n\n // Broadcast just the first 2 transactions: addKey and store device linking mapping\n let addKeyTxResult: FinalExecutionOutcome;\n let storeDeviceLinkingTxResult: FinalExecutionOutcome;\n try {\n console.debug('LinkDeviceFlow: AddKey transaction details:', {\n receiverId: signedTransactions[0].signedTransaction.transaction.receiverId,\n actions: signedTransactions[0].signedTransaction.transaction.actions || [],\n transactionKeys: Object.keys(signedTransactions[0].signedTransaction.transaction),\n });\n\n addKeyTxResult = await context.nearClient.sendTransaction(\n signedTransactions[0].signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceAddKey\n );\n console.log('LinkDeviceFlow: AddKey transaction result:', addKeyTxResult?.transaction?.hash);\n\n // Send success events immediately after AddKey succeeds\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `AddKey transaction completed successfully!`\n });\n\n // Check if contract mapping transaction is valid before attempting to broadcast\n const contractTx = signedTransactions[1].signedTransaction;\n console.log('LinkDeviceFlow: Contract mapping transaction details:', {\n receiverId: contractTx.transaction.receiverId,\n actions: (contractTx.transaction.actions || []).length\n });\n\n // Standard timeout since nonce conflict should be resolved by the 2s delay\n storeDeviceLinkingTxResult = await context.nearClient.sendTransaction(\n contractTx,\n DEFAULT_WAIT_STATUS.linkDeviceAccountMapping\n );\n\n } catch (txError: any) {\n console.error('LinkDeviceFlow: Transaction broadcasting failed:', txError);\n throw new Error(`Transaction broadcasting failed: ${txError.message}`);\n }\n\n onEvent?.({\n step: 6,\n phase: DeviceLinkingPhase.STEP_6_REGISTRATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Device linking completed successfully!`\n });\n\n return {\n addKeyTxResult,\n storeDeviceLinkingTxResult,\n signedDeleteKeyTransaction: signedTransactions[2].signedTransaction\n };\n}\n\n// ===========================\n// ACCOUNT RECOVERY CONTRACT CALLS\n// ===========================\n\n/**\n * Get credential IDs associated with an account from the contract\n * Used in account recovery to discover available credentials\n */\nexport async function getCredentialIdsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<string[]> {\n try {\n const credentialIds = await nearClient.callFunction<{ account_id: AccountId }, string[]>(\n contractId,\n 'get_credential_ids_by_account',\n { account_id: accountId }\n );\n return credentialIds || [];\n } catch (error: any) {\n console.warn('Failed to fetch credential IDs from contract:', error.message);\n return [];\n }\n}\n\n/**\n * Get all authenticators stored for a user from the contract\n * Used in account recovery to sync authenticator data\n */\nexport async function getAuthenticatorsByUser(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<[string, ContractStoredAuthenticator][]> {\n try {\n const authenticatorsResult = await nearClient.view<{ user_id: AccountId }, [string, ContractStoredAuthenticator][]>({\n account: contractId,\n method: 'get_authenticators_by_user',\n args: { user_id: accountId }\n });\n\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult;\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\nexport async function syncAuthenticatorsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<Array<{ credentialId: string, authenticator: StoredAuthenticator }>> {\n try {\n const authenticatorsResult = await getAuthenticatorsByUser(nearClient, contractId, accountId);\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult.map(([credentialId, contractAuthenticator]) => {\n console.log(`Contract authenticator device_number for ${credentialId}:`, contractAuthenticator.device_number);\n\n const transports = Array.isArray(contractAuthenticator.transports)\n ? contractAuthenticator.transports\n : [];\n\n const registered = (() => {\n const raw = String((contractAuthenticator as any).registered ?? '');\n if (!raw) return new Date(0);\n if (/^\\d+$/.test(raw)) {\n const ts = Number(raw);\n return Number.isFinite(ts) ? new Date(ts) : new Date(0);\n }\n const d = new Date(raw);\n return Number.isFinite(d.getTime()) ? d : new Date(0);\n })();\n\n const vrfPublicKeys = (() => {\n const raw = (contractAuthenticator as any).vrf_public_keys;\n if (!raw) return undefined;\n if (Array.isArray(raw) && raw.length > 0 && typeof raw[0] === 'string') {\n return raw as string[];\n }\n if (Array.isArray(raw)) {\n return raw\n .map((entry: unknown) => {\n if (!entry) return null;\n if (entry instanceof Uint8Array) return base64UrlEncode(entry);\n if (Array.isArray(entry)) return base64UrlEncode(new Uint8Array(entry));\n return null;\n })\n .filter((x): x is string => typeof x === 'string' && x.length > 0);\n }\n return undefined;\n })();\n\n return {\n credentialId,\n authenticator: {\n credentialId,\n credentialPublicKey: new Uint8Array(contractAuthenticator.credential_public_key),\n transports,\n userId: accountId,\n name: `Device ${contractAuthenticator.device_number} Authenticator`,\n registered,\n // Store the actual device number from contract (no fallback)\n deviceNumber: contractAuthenticator.device_number,\n vrfPublicKeys\n }\n };\n });\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\n// ===========================\n// RECOVERY EMAIL CONTRACT CALLS\n// ===========================\n\nconst EMPTY_NEAR_CODE_HASH = '11111111111111111111111111111111';\n\nasync function hasDeployedContractCode(nearClient: NearClient, accountId: AccountId): Promise<boolean> {\n try {\n const account = await nearClient.viewAccount(accountId);\n const codeHash = (account as { code_hash?: unknown } | null)?.code_hash;\n const globalContractHash = (account as { global_contract_hash?: unknown } | null)?.global_contract_hash;\n const globalContractAccountId = (account as { global_contract_account_id?: unknown } | null)?.global_contract_account_id;\n\n const hasLocalCode = typeof codeHash === 'string' && codeHash !== EMPTY_NEAR_CODE_HASH;\n const hasGlobalCode =\n (typeof globalContractHash === 'string' && globalContractHash.trim().length > 0) ||\n (typeof globalContractAccountId === 'string' && globalContractAccountId.trim().length > 0);\n\n return hasLocalCode || hasGlobalCode;\n } catch {\n return false;\n }\n}\n\n/**\n * Fetch on-chain recovery email hashes from the per-account contract.\n * Returns [] when no contract is deployed or on failure.\n */\nexport async function getRecoveryEmailHashesContractCall(\n nearClient: NearClient,\n accountId: AccountId\n): Promise<number[][]> {\n try {\n // Prefer `view_account` over `view_code`:\n // - `view_code` is expected to fail for non-contract accounts and is noisy.\n // - `view_account` is lightweight and tells us whether the account uses local contract code\n // or a NEAR \"global contract\" (via `global_contract_*` fields).\n const hasContract = await hasDeployedContractCode(nearClient, accountId);\n if (!hasContract) return [];\n\n const hashes = await nearClient.view<Record<string, never>, number[][]>({\n account: accountId,\n method: 'get_recovery_emails',\n args: {} as Record<string, never>,\n });\n\n return Array.isArray(hashes) ? (hashes as number[][]) : [];\n } catch (error) {\n return [];\n }\n}\n\n/**\n * Build action args to update on-chain recovery emails for an account.\n * If the per-account contract is missing, deploy/attach the global recoverer via `init_email_recovery`.\n */\nexport async function buildSetRecoveryEmailsActions(\n nearClient: NearClient,\n accountId: AccountId,\n recoveryEmailHashes: number[][],\n contracts: EmailRecoveryContracts = DEFAULT_EMAIL_RECOVERY_CONTRACTS\n): Promise<ActionArgs[]> {\n const hasContract = await hasDeployedContractCode(nearClient, accountId);\n\n const {\n emailRecovererGlobalContract,\n zkEmailVerifierContract,\n emailDkimVerifierContract,\n } = contracts;\n\n // If the account already has a contract (local or global), it still might not be a readable\n // EmailRecoverer instance (e.g. stale state after upgrades). In that case, `set_recovery_emails`\n // would fail while `init_email_recovery` (#[init(ignore_state)]) can safely re-initialize.\n //\n // We keep this as a best-effort probe to avoid wiping state on transient RPC issues.\n let shouldInit = !hasContract;\n if (!shouldInit) {\n try {\n await nearClient.view<Record<string, never>, unknown>({\n account: accountId,\n method: 'get_recovery_emails',\n args: {} as Record<string, never>,\n });\n } catch (err: unknown) {\n const msg = errorMessage(err);\n // Common/expected cases where we should fall back to init:\n // - account has a global contract pointer but no EmailRecoverer-compatible state yet\n // - account has stale/incompatible state after a contract upgrade\n // - account has some other contract (method missing)\n if (/Cannot deserialize the contract state/i.test(msg)\n || /CodeDoesNotExist/i.test(msg)\n || /MethodNotFound/i.test(msg)) {\n shouldInit = true;\n }\n }\n }\n\n const base: ActionArgs[] = [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n ];\n\n return shouldInit\n ? [\n ...base,\n {\n type: ActionType.FunctionCall,\n methodName: 'init_email_recovery',\n args: {\n zk_email_verifier: zkEmailVerifierContract,\n email_dkim_verifier: emailDkimVerifierContract,\n policy: null,\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ]\n : [\n ...base,\n {\n type: ActionType.FunctionCall,\n methodName: 'set_recovery_emails',\n args: {\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ];\n}\n\nexport async function fetchNonceBlockHashAndHeight({ nearClient, nearPublicKeyStr, nearAccountId }: {\n nearClient: NearClient,\n nearPublicKeyStr: string,\n nearAccountId: AccountId\n}): Promise<TransactionContext> {\n // Get access key and transaction block info concurrently\n const [accessKeyInfo, txBlockInfo] = await Promise.all([\n nearClient.viewAccessKey(nearAccountId, nearPublicKeyStr)\n .catch(e => { throw new Error(`Failed to fetch Access Key`) }),\n nearClient.viewBlock({ finality: 'final' })\n .catch(e => { throw new Error(`Failed to fetch Block Info`) })\n ]);\n if (!accessKeyInfo || accessKeyInfo.nonce === undefined) {\n throw new Error(`Access key not found or invalid for account ${nearAccountId} with public key ${nearPublicKeyStr}. Response: ${JSON.stringify(accessKeyInfo)}`);\n }\n const nextNonce = (BigInt(accessKeyInfo.nonce) + BigInt(1)).toString();\n const txBlockHeight = String(txBlockInfo.header.height);\n const txBlockHash = txBlockInfo.header.hash; // Keep original base58 string\n\n return {\n nearPublicKeyStr,\n accessKeyInfo,\n nextNonce,\n txBlockHeight,\n txBlockHash,\n };\n}\n\n// ===========================\n// REGISTRATION PRE-CHECK CALL\n// ===========================\n\nexport interface CheckCanRegisterUserResult {\n success: boolean;\n verified: boolean;\n logs: string[];\n error?: string;\n}\n\n/**\n * View-only registration pre-check.\n *\n * Calls the contract's `check_can_register_user` view method with VRF data\n * derived from the provided VRF challenge and a serialized WebAuthn\n * registration credential (typically with PRF outputs embedded).\n */\nexport async function checkCanRegisterUserContractCall({\n nearClient,\n contractId,\n vrfChallenge,\n credential,\n authenticatorOptions,\n}: {\n nearClient: NearClient;\n contractId: string;\n vrfChallenge: VRFChallenge;\n credential: WebAuthnRegistrationCredential;\n authenticatorOptions?: AuthenticatorOptions;\n}): Promise<CheckCanRegisterUserResult> {\n try {\n const vrfData = {\n vrf_input_data: Array.from(base64UrlDecode(vrfChallenge.vrfInput)),\n vrf_output: Array.from(base64UrlDecode(vrfChallenge.vrfOutput)),\n vrf_proof: Array.from(base64UrlDecode(vrfChallenge.vrfProof)),\n public_key: Array.from(base64UrlDecode(vrfChallenge.vrfPublicKey)),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight),\n block_hash: Array.from(base64UrlDecode(vrfChallenge.blockHash)),\n };\n\n const args = {\n vrf_data: vrfData,\n webauthn_registration: credential,\n authenticator_options: authenticatorOptions,\n };\n\n const response = await nearClient.callFunction<typeof args, any>(\n contractId,\n 'check_can_register_user',\n args,\n );\n\n const verified = !!response?.verified;\n return {\n success: true,\n verified,\n logs: [],\n error: verified ? undefined : 'Contract registration check failed',\n };\n } catch (err: unknown) {\n return {\n success: false,\n verified: false,\n logs: [],\n error: errorMessage(err) || 'Failed to call check_can_register_user',\n };\n }\n}\n\n\n/**\n * Verify authentication response through relay server\n * Routes the request to relay server which calls the web3authn contract for verification\n * and issues a JWT or session credential\n */\nexport async function verifyAuthenticationResponse(\n relayServerUrl: string,\n routePath: string,\n sessionKind: 'jwt' | 'cookie',\n vrfChallenge: VRFChallenge,\n webauthnAuthentication: WebAuthnAuthenticationCredential\n): Promise<{\n success: boolean;\n verified?: boolean;\n jwt?: string;\n sessionCredential?: any;\n error?: string;\n contractResponse?: any;\n}> {\n try {\n // Map VRFChallenge into server ContractVrfData shape (number arrays)\n const toBytes = (b64u: string | undefined): number[] => {\n if (!b64u) return [];\n return Array.from(base64UrlDecode(b64u));\n };\n const vrf_data = {\n vrf_input_data: toBytes(vrfChallenge.vrfInput),\n vrf_output: toBytes(vrfChallenge.vrfOutput),\n vrf_proof: toBytes(vrfChallenge.vrfProof),\n public_key: toBytes(vrfChallenge.vrfPublicKey),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight || 0),\n block_hash: toBytes(vrfChallenge.blockHash),\n };\n\n // Normalize authenticatorAttachment and userHandle to null for server schema\n const webauthn_authentication = {\n ...webauthnAuthentication,\n authenticatorAttachment: webauthnAuthentication.authenticatorAttachment ?? null,\n response: {\n ...webauthnAuthentication.response,\n userHandle: webauthnAuthentication.response.userHandle ?? null,\n }\n };\n\n const url = `${relayServerUrl.replace(/\\/$/, '')}${routePath.startsWith('/') ? routePath : `/${routePath}`}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: sessionKind === 'cookie' ? 'include' : 'omit',\n body: JSON.stringify({\n sessionKind: sessionKind,\n vrf_data,\n webauthn_authentication,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n error: `HTTP ${response.status}: ${errorText}`,\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n verified: result.verified,\n jwt: result.jwt,\n sessionCredential: result.sessionCredential,\n contractResponse: result.contractResponse,\n };\n } catch (error: any) {\n return {\n success: false,\n error: error.message || 'Failed to verify authentication response',\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { __esm } from "../../../../_virtual/rolldown_runtime.js";
2
+
3
+ //#region src/core/types/emailRecovery.ts
4
+ var EmailRecoveryErrorCode, EmailRecoveryError;
5
+ var init_emailRecovery = __esm({ "src/core/types/emailRecovery.ts": (() => {
6
+ EmailRecoveryErrorCode = /* @__PURE__ */ function(EmailRecoveryErrorCode$1) {
7
+ EmailRecoveryErrorCode$1["REGISTRATION_NOT_VERIFIED"] = "EMAIL_RECOVERY_REGISTRATION_NOT_VERIFIED";
8
+ EmailRecoveryErrorCode$1["VRF_CHALLENGE_EXPIRED"] = "EMAIL_RECOVERY_VRF_CHALLENGE_EXPIRED";
9
+ return EmailRecoveryErrorCode$1;
10
+ }({});
11
+ EmailRecoveryError = class extends Error {
12
+ code;
13
+ context;
14
+ constructor(message, code, context) {
15
+ super(message);
16
+ this.name = "EmailRecoveryError";
17
+ this.code = code;
18
+ this.context = context;
19
+ }
20
+ };
21
+ }) });
22
+
23
+ //#endregion
24
+ init_emailRecovery();
25
+ export { EmailRecoveryError, EmailRecoveryErrorCode, init_emailRecovery };
26
+ //# sourceMappingURL=emailRecovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailRecovery.js","names":[],"sources":["../../../../../../../src/core/types/emailRecovery.ts"],"sourcesContent":["export enum EmailRecoveryErrorCode {\n REGISTRATION_NOT_VERIFIED = 'EMAIL_RECOVERY_REGISTRATION_NOT_VERIFIED',\n VRF_CHALLENGE_EXPIRED = 'EMAIL_RECOVERY_VRF_CHALLENGE_EXPIRED',\n}\n\nexport class EmailRecoveryError extends Error {\n public readonly code: EmailRecoveryErrorCode;\n public readonly context?: Record<string, unknown>;\n\n constructor(message: string, code: EmailRecoveryErrorCode, context?: Record<string, unknown>) {\n super(message);\n this.name = 'EmailRecoveryError';\n this.code = code;\n this.context = context;\n }\n}\n\n"],"mappings":";;;;;CAAY,4EAAL;AACL;AACA;;;CAGW,qBAAb,cAAwC,MAAM;EAC5C,AAAgB;EAChB,AAAgB;EAEhB,YAAY,SAAiB,MAA8B,SAAmC;AAC5F,SAAM;AACN,QAAK,OAAO;AACZ,QAAK,OAAO;AACZ,QAAK,UAAU"}
@@ -1652,7 +1652,26 @@ body[data-w3a-theme-pulse="1"] .w3a-profile-dropdown-menu {
1652
1652
  animation-delay: var(--w3a-waiting-delay, 0ms);
1653
1653
  animation-fill-mode: both;
1654
1654
  }
1655
+ .w3a-waiting-message {
1656
+ display: flex;
1657
+ flex-direction: column;
1658
+ align-items: center;
1659
+ gap: 6px;
1660
+ }
1655
1661
  .w3a-waiting-text { font-size: 18px; font-weight: 600; }
1662
+ .w3a-waiting-subtext {
1663
+ font-size: 12px;
1664
+ font-weight: 500;
1665
+ line-height: 1.35;
1666
+ color: color-mix(in srgb, var(--w3a-colors-textSecondary), var(--w3a-colors-textPrimary) 25%);
1667
+ }
1668
+ .w3a-waiting-sdk-events {
1669
+ font-size: 11px;
1670
+ font-weight: 500;
1671
+ line-height: 1.35;
1672
+ white-space: pre-wrap;
1673
+ color: color-mix(in srgb, var(--w3a-colors-textSecondary), var(--w3a-colors-textPrimary) 15%);
1674
+ }
1656
1675
  .w3a-spinner {
1657
1676
  width: 36px;
1658
1677
  height: 36px;
@@ -1786,6 +1805,24 @@ body[data-w3a-theme-pulse="1"] .w3a-profile-dropdown-menu {
1786
1805
  to { transform: rotate(360deg); }
1787
1806
  }
1788
1807
 
1808
+ @keyframes w3a-ellipsis-dot {
1809
+ 0%, 80%, 100% { opacity: 0; }
1810
+ 40% { opacity: 1; }
1811
+ }
1812
+
1813
+ .w3a-ellipsis {
1814
+ display: inline-block;
1815
+ }
1816
+
1817
+ .w3a-ellipsis-dot {
1818
+ display: inline-block;
1819
+ opacity: 0;
1820
+ animation: w3a-ellipsis-dot 1.2s infinite;
1821
+ }
1822
+
1823
+ .w3a-ellipsis-dot:nth-child(2) { animation-delay: 0.15s; }
1824
+ .w3a-ellipsis-dot:nth-child(3) { animation-delay: 0.3s; }
1825
+
1789
1826
  /* Pop/bounce-in animation (kept for legacy classes) */
1790
1827
  @keyframes w3a-input-msg-pop {
1791
1828
  0% { opacity: 0; transform: translateY(8px) scale(0.98); }
@@ -1795,6 +1832,7 @@ body[data-w3a-theme-pulse="1"] .w3a-profile-dropdown-menu {
1795
1832
 
1796
1833
  @media (prefers-reduced-motion: reduce) {
1797
1834
  .w3a-input-msg.is-error { animation: none; }
1835
+ .w3a-ellipsis-dot { animation: none; opacity: 1; }
1798
1836
  }
1799
1837
 
1800
1838
  /* Button System */
@@ -1952,11 +1990,24 @@ body[data-w3a-theme-pulse="1"] .w3a-profile-dropdown-menu {
1952
1990
  color: color-mix(in srgb, var(--w3a-colors-error), var(--w3a-colors-textPrimary) 30%);
1953
1991
  }
1954
1992
 
1993
+ .w3a-email-recovery-from-warning {
1994
+ margin-top: 1rem;
1995
+ font-weight: 600;
1996
+ }
1997
+
1998
+ [data-w3a-theme="light"] .w3a-email-recovery-from-warning {
1999
+ color: #d80;
2000
+ }
2001
+
2002
+ [data-w3a-theme="dark"] .w3a-email-recovery-from-warning {
2003
+ color: #ea5;
2004
+ }
2005
+
1955
2006
  .w3a-email-recovery-link {
1956
2007
  font-size: 0.875rem;
1957
2008
  color: var(--w3a-colors-primary, #3b82f6);
1958
2009
  text-decoration: none;
1959
- padding: 0 0.25rem;
2010
+ padding: 0;
1960
2011
  }
1961
2012
 
1962
2013
  .w3a-email-recovery-link:hover {
@@ -1968,9 +2019,9 @@ body[data-w3a-theme-pulse="1"] .w3a-profile-dropdown-menu {
1968
2019
  padding: 0.75rem 0.875rem;
1969
2020
  border-radius: 1rem;
1970
2021
  border: 1px solid var(--w3a-colors-borderPrimary);
1971
- background: var(--w3a-colors-surface);
2022
+ background: var(--w3a-colors-surface2);
1972
2023
  color: var(--w3a-colors-textPrimary);
1973
- margin-bottom: 0.5rem;
2024
+ margin-bottom: 4px;
1974
2025
  }
1975
2026
 
1976
2027
  .w3a-email-recovery-status.is-error {
@@ -2003,6 +2054,10 @@ body[data-w3a-theme-pulse="1"] .w3a-profile-dropdown-menu {
2003
2054
  white-space: nowrap;
2004
2055
  }
2005
2056
 
2057
+ .w3a-email-recovery-email-chip-static {
2058
+ cursor: default;
2059
+ }
2060
+
2006
2061
  .w3a-email-recovery-email-chip:hover:not(:disabled) {
2007
2062
  background: var(--w3a-colors-surface2);
2008
2063
  }
@@ -23,9 +23,7 @@ function buildConfigsFromEnv(overrides = {}) {
23
23
  pollingIntervalMs: overrides.relayer?.emailRecovery?.pollingIntervalMs ?? defaults.relayer?.emailRecovery?.pollingIntervalMs,
24
24
  maxPollingDurationMs: overrides.relayer?.emailRecovery?.maxPollingDurationMs ?? defaults.relayer?.emailRecovery?.maxPollingDurationMs,
25
25
  pendingTtlMs: overrides.relayer?.emailRecovery?.pendingTtlMs ?? defaults.relayer?.emailRecovery?.pendingTtlMs,
26
- mailtoAddress: overrides.relayer?.emailRecovery?.mailtoAddress ?? defaults.relayer?.emailRecovery?.mailtoAddress,
27
- dkimVerifierAccountId: overrides.relayer?.emailRecovery?.dkimVerifierAccountId ?? defaults.relayer?.emailRecovery?.dkimVerifierAccountId,
28
- verificationViewMethod: overrides.relayer?.emailRecovery?.verificationViewMethod ?? defaults.relayer?.emailRecovery?.verificationViewMethod
26
+ mailtoAddress: overrides.relayer?.emailRecovery?.mailtoAddress ?? defaults.relayer?.emailRecovery?.mailtoAddress
29
27
  }
30
28
  },
31
29
  authenticatorOptions: overrides.authenticatorOptions ?? defaults.authenticatorOptions,
@@ -70,9 +68,7 @@ var init_defaultConfigs = __esm({ "src/core/defaultConfigs.ts": (() => {
70
68
  pollingIntervalMs: 4e3,
71
69
  maxPollingDurationMs: 1800 * 1e3,
72
70
  pendingTtlMs: 1800 * 1e3,
73
- mailtoAddress: "recover@web3authn.org",
74
- dkimVerifierAccountId: "email-dkim-verifier-v1.testnet",
75
- verificationViewMethod: "get_verification_result"
71
+ mailtoAddress: "recover@web3authn.org"
76
72
  }
77
73
  },
78
74
  vrfWorkerConfigs: { shamir3pass: {
@@ -94,7 +90,7 @@ var init_defaultConfigs = __esm({ "src/core/defaultConfigs.ts": (() => {
94
90
  }
95
91
  };
96
92
  DEFAULT_EMAIL_RECOVERY_CONTRACTS = {
97
- emailRecovererGlobalContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailDkimVerifierContract,
93
+ emailRecovererGlobalContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailRecovererGlobalContract,
98
94
  zkEmailVerifierContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.zkEmailVerifierContract,
99
95
  emailDkimVerifierContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailDkimVerifierContract
100
96
  };
@@ -18,9 +18,7 @@ const PASSKEY_MANAGER_DEFAULT_CONFIGS = {
18
18
  pollingIntervalMs: 4e3,
19
19
  maxPollingDurationMs: 1800 * 1e3,
20
20
  pendingTtlMs: 1800 * 1e3,
21
- mailtoAddress: "recover@web3authn.org",
22
- dkimVerifierAccountId: "email-dkim-verifier-v1.testnet",
23
- verificationViewMethod: "get_verification_result"
21
+ mailtoAddress: "recover@web3authn.org"
24
22
  }
25
23
  },
26
24
  vrfWorkerConfigs: { shamir3pass: {
@@ -42,7 +40,7 @@ const PASSKEY_MANAGER_DEFAULT_CONFIGS = {
42
40
  }
43
41
  };
44
42
  const DEFAULT_EMAIL_RECOVERY_CONTRACTS = {
45
- emailRecovererGlobalContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailDkimVerifierContract,
43
+ emailRecovererGlobalContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailRecovererGlobalContract,
46
44
  zkEmailVerifierContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.zkEmailVerifierContract,
47
45
  emailDkimVerifierContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailDkimVerifierContract
48
46
  };
@@ -68,9 +66,7 @@ function buildConfigsFromEnv(overrides = {}) {
68
66
  pollingIntervalMs: overrides.relayer?.emailRecovery?.pollingIntervalMs ?? defaults.relayer?.emailRecovery?.pollingIntervalMs,
69
67
  maxPollingDurationMs: overrides.relayer?.emailRecovery?.maxPollingDurationMs ?? defaults.relayer?.emailRecovery?.maxPollingDurationMs,
70
68
  pendingTtlMs: overrides.relayer?.emailRecovery?.pendingTtlMs ?? defaults.relayer?.emailRecovery?.pendingTtlMs,
71
- mailtoAddress: overrides.relayer?.emailRecovery?.mailtoAddress ?? defaults.relayer?.emailRecovery?.mailtoAddress,
72
- dkimVerifierAccountId: overrides.relayer?.emailRecovery?.dkimVerifierAccountId ?? defaults.relayer?.emailRecovery?.dkimVerifierAccountId,
73
- verificationViewMethod: overrides.relayer?.emailRecovery?.verificationViewMethod ?? defaults.relayer?.emailRecovery?.verificationViewMethod
69
+ mailtoAddress: overrides.relayer?.emailRecovery?.mailtoAddress ?? defaults.relayer?.emailRecovery?.mailtoAddress
74
70
  }
75
71
  },
76
72
  authenticatorOptions: overrides.authenticatorOptions ?? defaults.authenticatorOptions,
@@ -122,4 +118,4 @@ async function getLastLoggedInDeviceNumber(nearAccountId, clientDB) {
122
118
 
123
119
  //#endregion
124
120
  export { PASSKEY_MANAGER_DEFAULT_CONFIGS, buildConfigsFromEnv, getLastLoggedInDeviceNumber };
125
- //# sourceMappingURL=getDeviceNumber-fXizNGQl.js.map
121
+ //# sourceMappingURL=getDeviceNumber-BpernPnM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDeviceNumber-BpernPnM.js","names":["PASSKEY_MANAGER_DEFAULT_CONFIGS: TatchiConfigs","DEFAULT_EMAIL_RECOVERY_CONTRACTS: EmailRecoveryContracts","merged: TatchiConfigs"],"sources":["../../../src/core/defaultConfigs.ts","../../../src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.ts"],"sourcesContent":["import type { EmailRecoveryContracts, TatchiConfigs, TatchiConfigsInput } from './types/tatchi';\n\n// Default SDK configs suitable for local dev.\n// Cross-origin wallet isolation is recommended; set iframeWallet in your app config when you have a dedicated origin.\n// Consumers can shallow-merge overrides by field.\n\nexport const PASSKEY_MANAGER_DEFAULT_CONFIGS: TatchiConfigs = {\n // You can provide a single URL or a comma-separated list for failover.\n // First URL is treated as primary, subsequent URLs are fallbacks.\n nearRpcUrl: 'https://test.rpc.fastnear.com, https://rpc.testnet.near.org',\n nearNetwork: 'testnet',\n contractId: 'w3a-v1.testnet',\n nearExplorerUrl: 'https://testnet.nearblocks.io',\n // Warm signing session defaults used by login/unlock flows.\n // Enforcement (TTL/uses) is owned by the VRF worker; signer workers remain one-shot.\n signingSessionDefaults: {\n ttlMs: 0, // 0 minutes\n remainingUses: 0, // default to requiring a touchID prompt for each transaction\n },\n relayer: {\n // accountId: 'w3a-v1.testnet',\n // No default relayer URL. Force apps to configure via env/overrides.\n // Using an empty string triggers early validation errors in code paths that require it.\n url: '',\n delegateActionRoute: '/signed-delegate',\n emailRecovery: {\n // Require at least 0.01 NEAR available to start email recovery.\n minBalanceYocto: '10000000000000000000000', // 0.01 NEAR\n // Poll every 4 seconds for verification status / access key.\n pollingIntervalMs: 4000,\n // Stop polling after 30 minutes.\n maxPollingDurationMs: 30 * 60 * 1000,\n // Expire pending recovery records after 30 minutes.\n pendingTtlMs: 30 * 60 * 1000,\n // Default recovery mailbox for examples / docs.\n mailtoAddress: 'recover@web3authn.org',\n },\n },\n vrfWorkerConfigs: {\n shamir3pass: {\n // default Shamir's P in vrf-wasm-worker, needs to match relay server's Shamir P\n p: '3N5w46AIGjGT2v5Vua_TMD5Ywfa9U2F7-WzW8SNDsIM',\n // No default relay server URL to avoid accidental localhost usage in non-dev envs\n // Defaults to relayer.url when undefined\n relayServerUrl: '',\n applyServerLockRoute: '/vrf/apply-server-lock',\n removeServerLockRoute: '/vrf/remove-server-lock',\n }\n },\n emailRecoveryContracts: {\n emailRecovererGlobalContract: 'w3a-email-recoverer-v1.testnet',\n zkEmailVerifierContract: 'zk-email-verifier-v1.testnet',\n emailDkimVerifierContract: 'email-dkim-verifier-v1.testnet',\n },\n // Configure iframeWallet in application code to point at your dedicated wallet origin when available.\n iframeWallet: {\n walletOrigin: 'https://wallet.example.localhost',\n walletServicePath: '/wallet-service',\n sdkBasePath: '/sdk',\n rpIdOverride: 'example.localhost',\n }\n};\n\nexport const DEFAULT_EMAIL_RECOVERY_CONTRACTS: EmailRecoveryContracts = {\n emailRecovererGlobalContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailRecovererGlobalContract,\n zkEmailVerifierContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.zkEmailVerifierContract,\n emailDkimVerifierContract: PASSKEY_MANAGER_DEFAULT_CONFIGS.emailRecoveryContracts.emailDkimVerifierContract,\n};\n\n// Merge defaults with overrides\nexport function buildConfigsFromEnv(overrides: TatchiConfigsInput = {}): TatchiConfigs {\n\n const defaults = PASSKEY_MANAGER_DEFAULT_CONFIGS;\n const relayerUrl = overrides.relayer?.url ?? defaults.relayer?.url ?? '';\n // Prefer explicit override for relayer URL; fall back to default preset.\n // Used below to default VRF relayServerUrl when it is undefined.\n const relayServerUrlDefault = relayerUrl;\n\n const merged: TatchiConfigs = {\n nearRpcUrl: overrides.nearRpcUrl ?? defaults.nearRpcUrl,\n nearNetwork: overrides.nearNetwork ?? defaults.nearNetwork,\n contractId: overrides.contractId ?? defaults.contractId,\n nearExplorerUrl: overrides.nearExplorerUrl ?? defaults.nearExplorerUrl,\n walletTheme: overrides.walletTheme ?? defaults.walletTheme,\n signingSessionDefaults: {\n ttlMs: overrides.signingSessionDefaults?.ttlMs\n ?? defaults.signingSessionDefaults?.ttlMs,\n remainingUses: overrides.signingSessionDefaults?.remainingUses\n ?? defaults.signingSessionDefaults?.remainingUses,\n },\n relayer: {\n url: relayerUrl,\n delegateActionRoute: overrides.relayer?.delegateActionRoute\n ?? defaults.relayer?.delegateActionRoute,\n emailRecovery: {\n minBalanceYocto: overrides.relayer?.emailRecovery?.minBalanceYocto\n ?? defaults.relayer?.emailRecovery?.minBalanceYocto,\n pollingIntervalMs: overrides.relayer?.emailRecovery?.pollingIntervalMs\n ?? defaults.relayer?.emailRecovery?.pollingIntervalMs,\n maxPollingDurationMs: overrides.relayer?.emailRecovery?.maxPollingDurationMs\n ?? defaults.relayer?.emailRecovery?.maxPollingDurationMs,\n pendingTtlMs: overrides.relayer?.emailRecovery?.pendingTtlMs\n ?? defaults.relayer?.emailRecovery?.pendingTtlMs,\n mailtoAddress: overrides.relayer?.emailRecovery?.mailtoAddress\n ?? defaults.relayer?.emailRecovery?.mailtoAddress,\n },\n },\n authenticatorOptions: overrides.authenticatorOptions ?? defaults.authenticatorOptions,\n vrfWorkerConfigs: {\n shamir3pass: {\n p: overrides.vrfWorkerConfigs?.shamir3pass?.p\n ?? defaults.vrfWorkerConfigs?.shamir3pass?.p,\n relayServerUrl: overrides.vrfWorkerConfigs?.shamir3pass?.relayServerUrl\n ?? defaults.vrfWorkerConfigs?.shamir3pass?.relayServerUrl\n ?? relayServerUrlDefault,\n applyServerLockRoute: overrides.vrfWorkerConfigs?.shamir3pass?.applyServerLockRoute\n ?? defaults.vrfWorkerConfigs?.shamir3pass?.applyServerLockRoute,\n removeServerLockRoute: overrides.vrfWorkerConfigs?.shamir3pass?.removeServerLockRoute\n ?? defaults.vrfWorkerConfigs?.shamir3pass?.removeServerLockRoute,\n },\n },\n emailRecoveryContracts: {\n emailRecovererGlobalContract: overrides.emailRecoveryContracts?.emailRecovererGlobalContract\n ?? defaults.emailRecoveryContracts?.emailRecovererGlobalContract,\n zkEmailVerifierContract: overrides.emailRecoveryContracts?.zkEmailVerifierContract\n ?? defaults.emailRecoveryContracts?.zkEmailVerifierContract,\n emailDkimVerifierContract: overrides.emailRecoveryContracts?.emailDkimVerifierContract\n ?? defaults.emailRecoveryContracts?.emailDkimVerifierContract,\n },\n iframeWallet: {\n walletOrigin: overrides.iframeWallet?.walletOrigin\n ?? defaults.iframeWallet?.walletOrigin,\n walletServicePath: overrides.iframeWallet?.walletServicePath\n ?? defaults.iframeWallet?.walletServicePath\n ?? '/wallet-service',\n sdkBasePath: overrides.iframeWallet?.sdkBasePath\n ?? defaults.iframeWallet?.sdkBasePath\n ?? '/sdk',\n rpIdOverride: overrides.iframeWallet?.rpIdOverride\n ?? defaults.iframeWallet?.rpIdOverride,\n }\n };\n if (!merged.contractId) {\n throw new Error('[configPresets] Missing required config: contractId');\n }\n if (!merged.relayer.url) {\n throw new Error('[configPresets] Missing required config: relayer.url');\n }\n return merged;\n}\n","import type { PasskeyClientDBManager } from '@/core/IndexedDBManager';\nimport { toAccountId, type AccountId } from '../../types/accountIds';\n\nexport function parseDeviceNumber(\n value: unknown,\n options: { min?: number } = {}\n): number | null {\n const deviceNumber = Number(value);\n const min = options.min ?? 1;\n if (!Number.isSafeInteger(deviceNumber) || deviceNumber < min) {\n return null;\n }\n return deviceNumber;\n}\n\n/**\n * Return the deviceNumber for the last logged-in user for the given account.\n * This uses the app-state \"last user\" pointer only; if it does not match the\n * requested account, an error is thrown instead of silently falling back.\n */\nexport async function getLastLoggedInDeviceNumber(\n nearAccountId: AccountId | string,\n clientDB: PasskeyClientDBManager\n): Promise<number> {\n const accountId = toAccountId(nearAccountId);\n const last = await clientDB.getLastUser();\n if (last && last.nearAccountId === accountId) {\n const deviceNumber = parseDeviceNumber((last as any).deviceNumber, { min: 1 });\n if (deviceNumber !== null) {\n return deviceNumber;\n }\n }\n throw new Error(`No last user session for account ${accountId}`);\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { ActionType, SecureConfirmMessageType, SecureConfirmationType, TouchIdPrompt, base64Decode, base64Encode, base64UrlDecode, computeUiIntentDigestFromTxs, createRandomVRFChallenge, errorMessage, getIntentDigest, normalizeRegistrationCredential, orderActionForDigest, parseTransactionSummary, removePrfOutputGuard, sanitizeForPostMessage, sendConfirmResponse, serializeRegistrationCredentialWithPRF, toAccountId, toActionArgsWasm, toError, validateActionArgsWasm, validateNearAccountId, validateVRFChallenge } from "./requestHelpers-aUKhXiEl.js";
2
2
  import { assertString, isFunction, isNumber, isObject, isString } from "./validation-DhPPUba7.js";
3
3
  import { onEmbeddedBaseChange } from "./base-Qt2P7SNn.js";
4
- import { PASSKEY_MANAGER_DEFAULT_CONFIGS, buildConfigsFromEnv, getLastLoggedInDeviceNumber } from "./getDeviceNumber-fXizNGQl.js";
4
+ import { PASSKEY_MANAGER_DEFAULT_CONFIGS, buildConfigsFromEnv, getLastLoggedInDeviceNumber } from "./getDeviceNumber-BpernPnM.js";
5
5
 
6
6
  //#region ../node_modules/.pnpm/idb@8.0.3/node_modules/idb/build/index.js
7
7
  const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
@@ -2671,6 +2671,26 @@ async function signTransactionsWithActions({ ctx, transactions, rpcCall, onEvent
2671
2671
  }
2672
2672
  }
2673
2673
 
2674
+ //#endregion
2675
+ //#region src/core/nearCrypto.ts
2676
+ const NEAR_ED25519_KEY_PREFIX = "ed25519:";
2677
+ /**
2678
+ * Ensure a key string has the NEAR Ed25519 prefix (`ed25519:`).
2679
+ *
2680
+ * - Accepts either `ed25519:<base58>` or a bare `<base58>` string.
2681
+ * - Canonicalizes `ED25519:` → `ed25519:`.
2682
+ * - If a different prefix is present (e.g. `secp256k1:`), returns the input unchanged.
2683
+ */
2684
+ function ensureEd25519Prefix(value) {
2685
+ const raw = String(value || "").trim();
2686
+ if (!raw) return "";
2687
+ if (/^[a-z0-9_]+:/i.test(raw)) {
2688
+ if (/^ed25519:/i.test(raw)) return `${NEAR_ED25519_KEY_PREFIX}${raw.replace(/^ed25519:/i, "")}`;
2689
+ return raw;
2690
+ }
2691
+ return `${NEAR_ED25519_KEY_PREFIX}${raw}`;
2692
+ }
2693
+
2674
2694
  //#endregion
2675
2695
  //#region src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.ts
2676
2696
  function validateTransactionContextMaybe(input) {
@@ -2733,9 +2753,6 @@ function parseAndValidateRegistrationCredentialConfirmationPayload(payload) {
2733
2753
  error: normalizedError
2734
2754
  };
2735
2755
  }
2736
- const ensureEd25519Prefix = (value) => {
2737
- return value.startsWith("ed25519:") ? value : `ed25519:${value}`;
2738
- };
2739
2756
  const toPublicKeyString = (pk) => {
2740
2757
  if (typeof pk === "string") return pk;
2741
2758
  return ensureEd25519Prefix(base58Encode(pk.keyData));
@@ -3286,14 +3303,14 @@ const HANDLERS = {
3286
3303
  });
3287
3304
  },
3288
3305
  [SecureConfirmationType.SIGN_TRANSACTION]: async ({ ctx, request, worker, confirmationConfig, transactionSummary }) => {
3289
- const { handleTransactionSigningFlow } = await importFlow("transactions", () => import("./transactions-bqaAwL4k.js"));
3306
+ const { handleTransactionSigningFlow } = await importFlow("transactions", () => import("./transactions-Cn9xTWlK.js"));
3290
3307
  await handleTransactionSigningFlow(ctx, request, worker, {
3291
3308
  confirmationConfig,
3292
3309
  transactionSummary
3293
3310
  });
3294
3311
  },
3295
3312
  [SecureConfirmationType.SIGN_NEP413_MESSAGE]: async ({ ctx, request, worker, confirmationConfig, transactionSummary }) => {
3296
- const { handleTransactionSigningFlow } = await importFlow("transactions", () => import("./transactions-bqaAwL4k.js"));
3313
+ const { handleTransactionSigningFlow } = await importFlow("transactions", () => import("./transactions-Cn9xTWlK.js"));
3297
3314
  await handleTransactionSigningFlow(ctx, request, worker, {
3298
3315
  confirmationConfig,
3299
3316
  transactionSummary