@tatchi-xyz/sdk 0.16.0 → 0.18.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.
- package/dist/cjs/core/EmailRecovery/emailRecoveryPendingStore.js +69 -0
- package/dist/cjs/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
- package/dist/cjs/core/EmailRecovery/index.js +32 -13
- package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
- package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js +35 -36
- package/dist/cjs/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
- package/dist/cjs/core/NearClient.js +2 -1
- package/dist/cjs/core/NearClient.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js +557 -377
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
- package/dist/cjs/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/index.js +26 -0
- package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/linkDevice.js +2 -0
- package/dist/cjs/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/login.js +15 -4
- package/dist/cjs/core/TatchiPasskey/login.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/recoverAccount.js +1 -0
- package/dist/cjs/core/TatchiPasskey/recoverAccount.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/relay.js +23 -1
- package/dist/cjs/core/TatchiPasskey/relay.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/scanDevice.js +1 -0
- package/dist/cjs/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/cjs/core/WalletIframe/client/IframeTransport.js +3 -0
- package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
- package/dist/cjs/core/WalletIframe/client/router.js +15 -2
- package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
- package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
- package/dist/cjs/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
- package/dist/cjs/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
- package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
- package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
- package/dist/cjs/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js +12 -2
- package/dist/cjs/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/index.js +6 -1
- package/dist/cjs/core/WebAuthnManager/index.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js +209 -201
- package/dist/cjs/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/userHandle.js +2 -1
- package/dist/cjs/core/WebAuthnManager/userHandle.js.map +1 -1
- package/dist/cjs/core/defaultConfigs.js +1 -1
- package/dist/cjs/core/defaultConfigs.js.map +1 -1
- package/dist/cjs/core/rpcCalls.js +8 -0
- package/dist/cjs/core/rpcCalls.js.map +1 -1
- package/dist/cjs/core/types/vrf-worker.js +10 -1
- package/dist/cjs/core/types/vrf-worker.js.map +1 -1
- package/dist/cjs/index.js +6 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-BQWentvJ.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-DwrzWMYx.css} +14 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +122 -53
- package/dist/cjs/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
- package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-CCN4h6Uv.css} +1 -1
- package/dist/cjs/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
- package/dist/cjs/react/deviceDetection.js +75 -92
- package/dist/cjs/react/deviceDetection.js.map +1 -1
- package/dist/cjs/react/hooks/useQRCamera.js +1 -0
- package/dist/cjs/react/hooks/useQRCamera.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js +69 -0
- package/dist/cjs/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
- package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +32 -13
- package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
- package/dist/cjs/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/NearClient.js +2 -1
- package/dist/cjs/react/sdk/src/core/NearClient.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +557 -377
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +1 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +26 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js +2 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js +15 -4
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js +1 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/relay.js +23 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/relay.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js +1 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js +3 -0
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +15 -2
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +10 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +2 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +6 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +4 -15
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +17 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +64 -54
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +12 -2
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js +6 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +209 -201
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/defaultConfigs.js +1 -1
- package/dist/cjs/react/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/rpcCalls.js +8 -0
- package/dist/cjs/react/sdk/src/core/rpcCalls.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/types/vrf-worker.js +10 -1
- package/dist/cjs/react/sdk/src/core/types/vrf-worker.js.map +1 -1
- package/dist/cjs/react/sdk/src/utils/index.js +13 -3
- package/dist/cjs/server/email-recovery/emailEncryptor.js +11 -0
- package/dist/cjs/server/email-recovery/emailEncryptor.js.map +1 -1
- package/dist/cjs/server/email-recovery/emailParsers.js +57 -0
- package/dist/cjs/server/email-recovery/emailParsers.js.map +1 -1
- package/dist/cjs/server/email-recovery/index.js +1 -1
- package/dist/cjs/server/email-recovery/index.js.map +1 -1
- package/dist/cjs/server/email-recovery/rpcCalls.js +14 -1
- package/dist/cjs/server/email-recovery/rpcCalls.js.map +1 -1
- package/dist/cjs/server/index.js +1 -0
- package/dist/cjs/server/router/cloudflare.js.map +1 -1
- package/dist/cjs/server/router/express.js.map +1 -1
- package/dist/cjs/server/sdk/src/core/defaultConfigs.js +1 -1
- package/dist/cjs/server/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/cjs/utils/index.js +13 -3
- package/dist/esm/core/EmailRecovery/emailRecoveryPendingStore.js +63 -0
- package/dist/esm/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
- package/dist/esm/core/EmailRecovery/index.js +28 -14
- package/dist/esm/core/EmailRecovery/index.js.map +1 -1
- package/dist/esm/core/IndexedDBManager/passkeyClientDB.js +35 -36
- package/dist/esm/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
- package/dist/esm/core/NearClient.js +2 -1
- package/dist/esm/core/NearClient.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/emailRecovery.js +557 -377
- package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
- package/dist/esm/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/index.js +28 -2
- package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/linkDevice.js +4 -2
- package/dist/esm/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/login.js +13 -7
- package/dist/esm/core/TatchiPasskey/login.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/recoverAccount.js +2 -1
- package/dist/esm/core/TatchiPasskey/recoverAccount.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/relay.js +23 -1
- package/dist/esm/core/TatchiPasskey/relay.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/scanDevice.js +2 -1
- package/dist/esm/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/esm/core/WalletIframe/client/IframeTransport.js +4 -1
- package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
- package/dist/esm/core/WalletIframe/client/router.js +16 -3
- package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
- package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
- package/dist/esm/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
- package/dist/esm/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
- package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
- package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
- package/dist/esm/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/credentialsHelpers.js +8 -3
- package/dist/esm/core/WebAuthnManager/index.js +8 -3
- package/dist/esm/core/WebAuthnManager/index.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/touchIdPrompt.js +207 -204
- package/dist/esm/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/userHandle.js +2 -1
- package/dist/esm/core/WebAuthnManager/userHandle.js.map +1 -1
- package/dist/esm/core/defaultConfigs.js +1 -1
- package/dist/esm/core/defaultConfigs.js.map +1 -1
- package/dist/esm/core/rpcCalls.js +8 -1
- package/dist/esm/core/rpcCalls.js.map +1 -1
- package/dist/esm/core/types/vrf-worker.js +6 -2
- package/dist/esm/index.js +4 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-STvIsylA.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-STvIsylA.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-iARgUwK1.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-iARgUwK1.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-Db3NeoAC.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css → TouchIcon-BQWentvJ.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-BXM5NR4A.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css → PasskeyAuthMenu-DwrzWMYx.css} +14 -1
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-De1qTSmU.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js +123 -54
- package/dist/esm/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.js.map +1 -1
- package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css → ShowQRCode-CCN4h6Uv.css} +1 -1
- package/dist/esm/react/components/{ShowQRCode-DCnR__fx.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
- package/dist/esm/react/deviceDetection.js +72 -93
- package/dist/esm/react/deviceDetection.js.map +1 -1
- package/dist/esm/react/hooks/useQRCamera.js +2 -1
- package/dist/esm/react/hooks/useQRCamera.js.map +1 -1
- package/dist/esm/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js +63 -0
- package/dist/esm/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
- package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +28 -14
- package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js +35 -36
- package/dist/esm/react/sdk/src/core/IndexedDBManager/passkeyClientDB.js.map +1 -1
- package/dist/esm/react/sdk/src/core/NearClient.js +2 -1
- package/dist/esm/react/sdk/src/core/NearClient.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +557 -377
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js +2 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/faucets/createAccountRelayServer.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +28 -2
- package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js +4 -2
- package/dist/esm/react/sdk/src/core/TatchiPasskey/linkDevice.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js +13 -7
- package/dist/esm/react/sdk/src/core/TatchiPasskey/login.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js +2 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/recoverAccount.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/relay.js +23 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/relay.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js +2 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/scanDevice.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js +4 -1
- package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +16 -3
- package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js +52 -52
- package/dist/esm/react/sdk/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/getDeviceNumber.js +6 -2
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/checkCanRegisterUser.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/decryptPrivateKeyWithPrf.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/deriveNearKeypairAndEncryptFromSerialized.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/exportNearKeypairUi.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/registerDevice2WithDerivedKey.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signDelegateAction.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signNep413Message.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js +4 -2
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js +1 -0
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +8 -2
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js +5 -16
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/deriveVrfKeypairFromPrf.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfChallenge.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/handlers/generateVrfKeypairBootstrap.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js +12 -0
- package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/index.js.map +1 -0
- package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js +61 -55
- package/dist/esm/react/sdk/src/core/WebAuthnManager/WebAuthnFallbacks/safari-fallbacks.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/credentialsHelpers.js +8 -3
- package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js +8 -3
- package/dist/esm/react/sdk/src/core/WebAuthnManager/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js +207 -204
- package/dist/esm/react/sdk/src/core/WebAuthnManager/touchIdPrompt.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js +2 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/userHandle.js.map +1 -1
- package/dist/esm/react/sdk/src/core/defaultConfigs.js +1 -1
- package/dist/esm/react/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/esm/react/sdk/src/core/rpcCalls.js +8 -1
- package/dist/esm/react/sdk/src/core/rpcCalls.js.map +1 -1
- package/dist/esm/react/sdk/src/core/types/vrf-worker.js +6 -2
- package/dist/esm/react/sdk/src/utils/index.js +10 -4
- package/dist/esm/react/styles/styles.css +13 -0
- package/dist/esm/sdk/{safari-fallbacks-oQKu9xUs.js → WebAuthnFallbacks-Bl4BTsNt.js} +131 -135
- package/dist/esm/sdk/{createAdapters-pNiL2KNq.js → createAdapters-BumKM2ft.js} +59 -54
- package/dist/esm/sdk/createAdapters-BumKM2ft.js.map +1 -0
- package/dist/esm/sdk/{createAdapters-BWLe9Ddo.js → createAdapters-qVGD6i0g.js} +10 -3
- package/dist/esm/sdk/{defaultConfigs-VzvDejmy.js → defaultConfigs-DpslkAQd.js} +1 -1
- package/dist/esm/sdk/{getDeviceNumber-CkWRT17I.js → getDeviceNumber-fXizNGQl.js} +2 -2
- package/dist/esm/sdk/getDeviceNumber-fXizNGQl.js.map +1 -0
- package/dist/esm/sdk/{getDeviceNumber-CfmlgfMX.js → getDeviceNumber-zsOHT_Um.js} +6 -3
- package/dist/esm/sdk/{localOnly-DnpSyDaF.js → localOnly-Byi3AK7A.js} +2 -2
- package/dist/esm/sdk/{localOnly-DnpSyDaF.js.map → localOnly-Byi3AK7A.js.map} +1 -1
- package/dist/esm/sdk/{localOnly-BdumO2st.js → localOnly-pXMTqh1m.js} +5 -4
- package/dist/esm/sdk/offline-export-app.js +46 -44
- package/dist/esm/sdk/offline-export-app.js.map +1 -1
- package/dist/esm/sdk/{overlay-BTqPGG-o.js → overlay-ZGbucXIa.js} +2 -0
- package/dist/esm/sdk/{registration-C633u6x8.js → registration-CBiS4Ua_.js} +2 -2
- package/dist/esm/sdk/{registration-C633u6x8.js.map → registration-CBiS4Ua_.js.map} +1 -1
- package/dist/esm/sdk/{registration-xyYUFRqk.js → registration-DLPLsGCz.js} +5 -4
- package/dist/esm/sdk/{requestHelpers-DLBGBHMw.js → requestHelpers-Dh1hEYL9.js} +206 -204
- package/dist/esm/sdk/{router-BG6KC_p7.js → router-DuGYOd3G.js} +19 -4
- package/dist/esm/sdk/{rpcCalls-fLObBbbz.js → rpcCalls-BQrJMTdg.js} +3 -3
- package/dist/esm/sdk/{rpcCalls-CAU5XYEF.js → rpcCalls-YVeUVMk2.js} +9 -2
- package/dist/esm/sdk/{transactions-jH38BZ-Q.js → transactions-BIqKZeR0.js} +6 -18
- package/dist/esm/sdk/transactions-BIqKZeR0.js.map +1 -0
- package/dist/esm/sdk/{transactions-CzZAt1Yn.js → transactions-Bk-VavcV.js} +10 -21
- package/dist/esm/sdk/tx-confirm-ui.js +53 -53
- package/dist/esm/sdk/{tx-confirmer-wrapper-CqfVBUaA.js → tx-confirmer-wrapper-lHNgz9i4.js} +53 -53
- package/dist/esm/sdk/tx-confirmer.css +6 -4
- package/dist/esm/sdk/w3a-tx-confirmer.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host.js +782 -447
- package/dist/esm/server/email-recovery/emailEncryptor.js +11 -1
- package/dist/esm/server/email-recovery/emailEncryptor.js.map +1 -1
- package/dist/esm/server/email-recovery/emailParsers.js +55 -1
- package/dist/esm/server/email-recovery/emailParsers.js.map +1 -1
- package/dist/esm/server/email-recovery/index.js +2 -2
- package/dist/esm/server/email-recovery/index.js.map +1 -1
- package/dist/esm/server/email-recovery/rpcCalls.js +14 -1
- package/dist/esm/server/email-recovery/rpcCalls.js.map +1 -1
- package/dist/esm/server/index.js +2 -2
- package/dist/esm/server/router/cloudflare.js.map +1 -1
- package/dist/esm/server/router/express.js.map +1 -1
- package/dist/esm/server/sdk/src/core/defaultConfigs.js +1 -1
- package/dist/esm/server/sdk/src/core/defaultConfigs.js.map +1 -1
- package/dist/esm/utils/index.js +10 -4
- package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker.js +3 -0
- package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
- package/dist/types/src/core/EmailRecovery/emailRecoveryPendingStore.d.ts +25 -0
- package/dist/types/src/core/EmailRecovery/emailRecoveryPendingStore.d.ts.map +1 -0
- package/dist/types/src/core/EmailRecovery/index.d.ts +1 -0
- package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
- package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts +11 -21
- package/dist/types/src/core/IndexedDBManager/passkeyClientDB.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +45 -5
- package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/index.d.ts +10 -2
- package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/relay.d.ts +2 -1
- package/dist/types/src/core/TatchiPasskey/relay.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts +4 -0
- package/dist/types/src/core/WalletIframe/TatchiPasskeyIframe.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/client/router.d.ts +7 -3
- package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/host/wallet-iframe-handlers.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/shared/messages.d.ts +6 -2
- package/dist/types/src/core/WalletIframe/shared/messages.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-drawer.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/LitComponents/IframeTxConfirmer/viewer-modal.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.d.ts.map +1 -1
- package/dist/types/src/core/WebAuthnManager/index.d.ts.map +1 -1
- package/dist/types/src/core/defaultConfigs.d.ts.map +1 -1
- package/dist/types/src/core/rpcCalls.d.ts +9 -0
- package/dist/types/src/core/rpcCalls.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/react/components/PasskeyAuthMenu/ui/EmailRecoverySlide.d.ts.map +1 -1
- package/dist/types/src/server/email-recovery/emailEncryptor.d.ts +4 -0
- package/dist/types/src/server/email-recovery/emailEncryptor.d.ts.map +1 -1
- package/dist/types/src/server/email-recovery/emailParsers.d.ts +7 -0
- package/dist/types/src/server/email-recovery/emailParsers.d.ts.map +1 -1
- package/dist/types/src/server/email-recovery/index.d.ts +1 -1
- package/dist/types/src/server/email-recovery/rpcCalls.d.ts +1 -1
- package/dist/types/src/server/email-recovery/rpcCalls.d.ts.map +1 -1
- package/dist/types/src/wasm_vrf_worker/pkg/wasm_vrf_worker.d.ts.map +1 -1
- package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
- package/dist/workers/web3authn-vrf.worker.js +3 -0
- package/package.json +1 -1
- package/dist/esm/sdk/createAdapters-pNiL2KNq.js.map +0 -1
- package/dist/esm/sdk/getDeviceNumber-CkWRT17I.js.map +0 -1
- package/dist/esm/sdk/transactions-jH38BZ-Q.js.map +0 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
|
|
2
|
+
const require_index = require('../IndexedDBManager/index.js');
|
|
3
|
+
|
|
4
|
+
//#region src/core/EmailRecovery/emailRecoveryPendingStore.ts
|
|
5
|
+
var EmailRecoveryPendingStore;
|
|
6
|
+
var init_emailRecoveryPendingStore = require_rolldown_runtime.__esm({ "src/core/EmailRecovery/emailRecoveryPendingStore.ts": (() => {
|
|
7
|
+
require_index.init_IndexedDBManager();
|
|
8
|
+
EmailRecoveryPendingStore = class {
|
|
9
|
+
getPendingTtlMs;
|
|
10
|
+
now;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.getPendingTtlMs = options.getPendingTtlMs;
|
|
13
|
+
this.now = options.now ?? Date.now;
|
|
14
|
+
}
|
|
15
|
+
getPendingIndexKey(accountId) {
|
|
16
|
+
return `pendingEmailRecovery:${accountId}`;
|
|
17
|
+
}
|
|
18
|
+
getPendingRecordKey(accountId, nearPublicKey) {
|
|
19
|
+
return `${this.getPendingIndexKey(accountId)}:${nearPublicKey}`;
|
|
20
|
+
}
|
|
21
|
+
async get(accountId, nearPublicKey) {
|
|
22
|
+
const pendingTtlMs = this.getPendingTtlMs();
|
|
23
|
+
const indexKey = this.getPendingIndexKey(accountId);
|
|
24
|
+
const indexedNearPublicKey = await require_index.IndexedDBManager.clientDB.getAppState(indexKey);
|
|
25
|
+
const resolvedNearPublicKey = nearPublicKey ?? indexedNearPublicKey;
|
|
26
|
+
if (!resolvedNearPublicKey) return null;
|
|
27
|
+
const recordKey = this.getPendingRecordKey(accountId, resolvedNearPublicKey);
|
|
28
|
+
const record = await require_index.IndexedDBManager.clientDB.getAppState(recordKey);
|
|
29
|
+
const shouldClearIndex = indexedNearPublicKey === resolvedNearPublicKey;
|
|
30
|
+
if (!record) {
|
|
31
|
+
if (shouldClearIndex) await require_index.IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (this.now() - record.createdAt > pendingTtlMs) {
|
|
35
|
+
await require_index.IndexedDBManager.clientDB.setAppState(recordKey, void 0).catch(() => {});
|
|
36
|
+
if (shouldClearIndex) await require_index.IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
await this.touchIndex(accountId, record.nearPublicKey);
|
|
40
|
+
return record;
|
|
41
|
+
}
|
|
42
|
+
async set(record) {
|
|
43
|
+
const key = this.getPendingRecordKey(record.accountId, record.nearPublicKey);
|
|
44
|
+
await require_index.IndexedDBManager.clientDB.setAppState(key, record);
|
|
45
|
+
await this.touchIndex(record.accountId, record.nearPublicKey);
|
|
46
|
+
}
|
|
47
|
+
async clear(accountId, nearPublicKey) {
|
|
48
|
+
const indexKey = this.getPendingIndexKey(accountId);
|
|
49
|
+
const idx = await require_index.IndexedDBManager.clientDB.getAppState(indexKey).catch(() => void 0);
|
|
50
|
+
const resolvedNearPublicKey = nearPublicKey || idx || "";
|
|
51
|
+
if (resolvedNearPublicKey) await require_index.IndexedDBManager.clientDB.setAppState(this.getPendingRecordKey(accountId, resolvedNearPublicKey), void 0).catch(() => {});
|
|
52
|
+
if (!nearPublicKey || idx === nearPublicKey) await require_index.IndexedDBManager.clientDB.setAppState(indexKey, void 0).catch(() => {});
|
|
53
|
+
}
|
|
54
|
+
async touchIndex(accountId, nearPublicKey) {
|
|
55
|
+
await require_index.IndexedDBManager.clientDB.setAppState(this.getPendingIndexKey(accountId), nearPublicKey).catch(() => {});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}) });
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
init_emailRecoveryPendingStore();
|
|
62
|
+
exports.EmailRecoveryPendingStore = EmailRecoveryPendingStore;
|
|
63
|
+
Object.defineProperty(exports, 'init_emailRecoveryPendingStore', {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
get: function () {
|
|
66
|
+
return init_emailRecoveryPendingStore;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=emailRecoveryPendingStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailRecoveryPendingStore.js","names":["IndexedDBManager"],"sources":["../../../../src/core/EmailRecovery/emailRecoveryPendingStore.ts"],"sourcesContent":["import { IndexedDBManager } from '../IndexedDBManager';\nimport type { AccountId } from '../types/accountIds';\nimport type { PendingEmailRecovery } from '../TatchiPasskey/emailRecovery';\n\nexport interface PendingStore {\n get(accountId: AccountId, nearPublicKey?: string): Promise<PendingEmailRecovery | null>;\n set(record: PendingEmailRecovery): Promise<void>;\n clear(accountId: AccountId, nearPublicKey?: string): Promise<void>;\n touchIndex(accountId: AccountId, nearPublicKey: string): Promise<void>;\n}\n\ntype EmailRecoveryPendingStoreOptions = {\n getPendingTtlMs: () => number;\n now?: () => number;\n};\n\nexport class EmailRecoveryPendingStore implements PendingStore {\n private getPendingTtlMs: () => number;\n private now: () => number;\n\n constructor(options: EmailRecoveryPendingStoreOptions) {\n this.getPendingTtlMs = options.getPendingTtlMs;\n this.now = options.now ?? Date.now;\n }\n\n private getPendingIndexKey(accountId: AccountId): string {\n return `pendingEmailRecovery:${accountId}`;\n }\n\n private getPendingRecordKey(accountId: AccountId, nearPublicKey: string): string {\n return `${this.getPendingIndexKey(accountId)}:${nearPublicKey}`;\n }\n\n async get(accountId: AccountId, nearPublicKey?: string): Promise<PendingEmailRecovery | null> {\n const pendingTtlMs = this.getPendingTtlMs();\n const indexKey = this.getPendingIndexKey(accountId);\n const indexedNearPublicKey = await IndexedDBManager.clientDB.getAppState<string>(indexKey);\n const resolvedNearPublicKey = nearPublicKey ?? indexedNearPublicKey;\n if (!resolvedNearPublicKey) {\n return null;\n }\n\n const recordKey = this.getPendingRecordKey(accountId, resolvedNearPublicKey);\n const record = await IndexedDBManager.clientDB.getAppState<PendingEmailRecovery>(recordKey);\n const shouldClearIndex = indexedNearPublicKey === resolvedNearPublicKey;\n if (!record) {\n if (shouldClearIndex) {\n await IndexedDBManager.clientDB.setAppState(indexKey, undefined as any).catch(() => { });\n }\n return null;\n }\n\n if (this.now() - record.createdAt > pendingTtlMs) {\n await IndexedDBManager.clientDB.setAppState(recordKey, undefined as any).catch(() => { });\n if (shouldClearIndex) {\n await IndexedDBManager.clientDB.setAppState(indexKey, undefined as any).catch(() => { });\n }\n return null;\n }\n\n await this.touchIndex(accountId, record.nearPublicKey);\n return record;\n }\n\n async set(record: PendingEmailRecovery): Promise<void> {\n const key = this.getPendingRecordKey(record.accountId, record.nearPublicKey);\n await IndexedDBManager.clientDB.setAppState(key, record);\n await this.touchIndex(record.accountId, record.nearPublicKey);\n }\n\n async clear(accountId: AccountId, nearPublicKey?: string): Promise<void> {\n const indexKey = this.getPendingIndexKey(accountId);\n const idx = await IndexedDBManager.clientDB.getAppState<string>(indexKey).catch(() => undefined);\n\n const resolvedNearPublicKey = nearPublicKey || idx || '';\n if (resolvedNearPublicKey) {\n await IndexedDBManager.clientDB\n .setAppState(this.getPendingRecordKey(accountId, resolvedNearPublicKey), undefined as any)\n .catch(() => { });\n }\n\n if (!nearPublicKey || idx === nearPublicKey) {\n await IndexedDBManager.clientDB.setAppState(indexKey, undefined as any).catch(() => { });\n }\n }\n\n async touchIndex(accountId: AccountId, nearPublicKey: string): Promise<void> {\n await IndexedDBManager.clientDB.setAppState(this.getPendingIndexKey(accountId), nearPublicKey).catch(() => { });\n }\n}\n"],"mappings":";;;;;;;CAgBa,4BAAb,MAA+D;EAC7D,AAAQ;EACR,AAAQ;EAER,YAAY,SAA2C;AACrD,QAAK,kBAAkB,QAAQ;AAC/B,QAAK,MAAM,QAAQ,OAAO,KAAK;;EAGjC,AAAQ,mBAAmB,WAA8B;AACvD,UAAO,wBAAwB;;EAGjC,AAAQ,oBAAoB,WAAsB,eAA+B;AAC/E,UAAO,GAAG,KAAK,mBAAmB,WAAW,GAAG;;EAGlD,MAAM,IAAI,WAAsB,eAA8D;GAC5F,MAAM,eAAe,KAAK;GAC1B,MAAM,WAAW,KAAK,mBAAmB;GACzC,MAAM,uBAAuB,MAAMA,+BAAiB,SAAS,YAAoB;GACjF,MAAM,wBAAwB,iBAAiB;AAC/C,OAAI,CAAC,sBACH,QAAO;GAGT,MAAM,YAAY,KAAK,oBAAoB,WAAW;GACtD,MAAM,SAAS,MAAMA,+BAAiB,SAAS,YAAkC;GACjF,MAAM,mBAAmB,yBAAyB;AAClD,OAAI,CAAC,QAAQ;AACX,QAAI,iBACF,OAAMA,+BAAiB,SAAS,YAAY,UAAU,QAAkB,YAAY;AAEtF,WAAO;;AAGT,OAAI,KAAK,QAAQ,OAAO,YAAY,cAAc;AAChD,UAAMA,+BAAiB,SAAS,YAAY,WAAW,QAAkB,YAAY;AACrF,QAAI,iBACF,OAAMA,+BAAiB,SAAS,YAAY,UAAU,QAAkB,YAAY;AAEtF,WAAO;;AAGT,SAAM,KAAK,WAAW,WAAW,OAAO;AACxC,UAAO;;EAGT,MAAM,IAAI,QAA6C;GACrD,MAAM,MAAM,KAAK,oBAAoB,OAAO,WAAW,OAAO;AAC9D,SAAMA,+BAAiB,SAAS,YAAY,KAAK;AACjD,SAAM,KAAK,WAAW,OAAO,WAAW,OAAO;;EAGjD,MAAM,MAAM,WAAsB,eAAuC;GACvE,MAAM,WAAW,KAAK,mBAAmB;GACzC,MAAM,MAAM,MAAMA,+BAAiB,SAAS,YAAoB,UAAU,YAAY;GAEtF,MAAM,wBAAwB,iBAAiB,OAAO;AACtD,OAAI,sBACF,OAAMA,+BAAiB,SACpB,YAAY,KAAK,oBAAoB,WAAW,wBAAwB,QACxE,YAAY;AAGjB,OAAI,CAAC,iBAAiB,QAAQ,cAC5B,OAAMA,+BAAiB,SAAS,YAAY,UAAU,QAAkB,YAAY;;EAIxF,MAAM,WAAW,WAAsB,eAAsC;AAC3E,SAAMA,+BAAiB,SAAS,YAAY,KAAK,mBAAmB,YAAY,eAAe,YAAY"}
|
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
|
|
2
2
|
const require_accountIds = require('../types/accountIds.js');
|
|
3
3
|
const require_index = require('../IndexedDBManager/index.js');
|
|
4
|
+
const require_emailRecoveryPendingStore = require('./emailRecoveryPendingStore.js');
|
|
4
5
|
|
|
5
6
|
//#region src/core/EmailRecovery/index.ts
|
|
6
|
-
require_accountIds.init_accountIds();
|
|
7
|
-
require_index.init_IndexedDBManager();
|
|
8
|
-
const canonicalizeEmail = (email) => {
|
|
9
|
-
let addr = email;
|
|
10
|
-
const angleStart = email.indexOf("<");
|
|
11
|
-
const angleEnd = email.indexOf(">");
|
|
12
|
-
if (angleStart !== -1 && angleEnd > angleStart) addr = email.slice(angleStart + 1, angleEnd);
|
|
13
|
-
return addr.trim().toLowerCase();
|
|
14
|
-
};
|
|
15
|
-
const bytesToHex = (bytes) => {
|
|
16
|
-
const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);
|
|
17
|
-
return `0x${Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
18
|
-
};
|
|
19
7
|
async function hashRecoveryEmails(emails, accountId) {
|
|
20
8
|
const encoder = new TextEncoder();
|
|
21
9
|
const salt = (accountId || "").trim().toLowerCase();
|
|
@@ -62,9 +50,40 @@ async function prepareRecoveryEmails(nearAccountId, recoveryEmails) {
|
|
|
62
50
|
async function getLocalRecoveryEmails(nearAccountId) {
|
|
63
51
|
return require_index.IndexedDBManager.getRecoveryEmails(nearAccountId);
|
|
64
52
|
}
|
|
53
|
+
var canonicalizeEmail, bytesToHex;
|
|
54
|
+
var init_EmailRecovery = require_rolldown_runtime.__esm({ "src/core/EmailRecovery/index.ts": (() => {
|
|
55
|
+
require_accountIds.init_accountIds();
|
|
56
|
+
require_index.init_IndexedDBManager();
|
|
57
|
+
require_emailRecoveryPendingStore.init_emailRecoveryPendingStore();
|
|
58
|
+
canonicalizeEmail = (email) => {
|
|
59
|
+
const raw = String(email || "").trim();
|
|
60
|
+
if (!raw) return "";
|
|
61
|
+
const withoutHeaderName = raw.replace(/^[a-z0-9-]+\s*:\s*/i, "").trim();
|
|
62
|
+
const emailRegex = /([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*)/;
|
|
63
|
+
const angleMatch = withoutHeaderName.match(/<([^>]+)>/);
|
|
64
|
+
const candidates = [angleMatch?.[1], withoutHeaderName].filter((v) => typeof v === "string" && v.length > 0);
|
|
65
|
+
for (const candidate of candidates) {
|
|
66
|
+
const cleaned = candidate.replace(/^mailto:\s*/i, "");
|
|
67
|
+
const match = cleaned.match(emailRegex);
|
|
68
|
+
if (match?.[1]) return match[1].trim().toLowerCase();
|
|
69
|
+
}
|
|
70
|
+
return withoutHeaderName.toLowerCase();
|
|
71
|
+
};
|
|
72
|
+
bytesToHex = (bytes) => {
|
|
73
|
+
const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);
|
|
74
|
+
return `0x${Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
75
|
+
};
|
|
76
|
+
}) });
|
|
65
77
|
|
|
66
78
|
//#endregion
|
|
79
|
+
init_EmailRecovery();
|
|
67
80
|
exports.bytesToHex = bytesToHex;
|
|
68
81
|
exports.getLocalRecoveryEmails = getLocalRecoveryEmails;
|
|
82
|
+
Object.defineProperty(exports, 'init_EmailRecovery', {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
get: function () {
|
|
85
|
+
return init_EmailRecovery;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
69
88
|
exports.prepareRecoveryEmails = prepareRecoveryEmails;
|
|
70
89
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["hashed: number[][]","toAccountId","pairs: RecoveryEmailEntry[]","IndexedDBManager"],"sources":["../../../../src/core/EmailRecovery/index.ts"],"sourcesContent":["import type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { IndexedDBManager, type RecoveryEmailRecord } from '../IndexedDBManager';\n\nexport type RecoveryEmailEntry = {\n hashHex: string;\n email: string;\n};\n\nexport { type RecoveryEmailRecord };\n\nexport const canonicalizeEmail = (email: string): string => {\n
|
|
1
|
+
{"version":3,"file":"index.js","names":["hashed: number[][]","toAccountId","pairs: RecoveryEmailEntry[]","IndexedDBManager"],"sources":["../../../../src/core/EmailRecovery/index.ts"],"sourcesContent":["import type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { IndexedDBManager, type RecoveryEmailRecord } from '../IndexedDBManager';\nexport { EmailRecoveryPendingStore, type PendingStore } from './emailRecoveryPendingStore';\n\nexport type RecoveryEmailEntry = {\n hashHex: string;\n email: string;\n};\n\nexport { type RecoveryEmailRecord };\n\nexport const canonicalizeEmail = (email: string): string => {\n const raw = String(email || '').trim();\n if (!raw) return '';\n\n // Handle cases where a full header line is passed in (e.g. \"From: ...\").\n const withoutHeaderName = raw.replace(/^[a-z0-9-]+\\s*:\\s*/i, '').trim();\n\n const emailRegex =\n /([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)/;\n\n // Prefer the common \"Name <email@domain>\" format when present, but still\n // validate/extract the actual address via regex.\n const angleMatch = withoutHeaderName.match(/<([^>]+)>/);\n const candidates = [\n angleMatch?.[1],\n withoutHeaderName,\n ].filter((v): v is string => typeof v === 'string' && v.length > 0);\n\n for (const candidate of candidates) {\n const cleaned = candidate.replace(/^mailto:\\s*/i, '');\n const match = cleaned.match(emailRegex);\n if (match?.[1]) {\n return match[1].trim().toLowerCase();\n }\n }\n\n return withoutHeaderName.toLowerCase();\n};\n\nexport const bytesToHex = (bytes: number[] | Uint8Array): string => {\n const arr = bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes);\n return `0x${Array.from(arr)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')}`;\n};\n\nasync function hashRecoveryEmails(emails: string[], accountId: AccountId): Promise<number[][]> {\n const encoder = new TextEncoder();\n const salt = (accountId || '').trim().toLowerCase();\n const normalized = (emails || [])\n .map(e => e.trim())\n .filter(e => e.length > 0);\n\n const hashed: number[][] = [];\n\n for (const email of normalized) {\n try {\n const canonicalEmail = canonicalizeEmail(email);\n const input = `${canonicalEmail}|${salt}`;\n const data = encoder.encode(input);\n const digest = await crypto.subtle.digest('SHA-256', data);\n const bytes = new Uint8Array(digest);\n hashed.push(Array.from(bytes));\n } catch {\n const bytes = encoder.encode(email.toLowerCase());\n hashed.push(Array.from(bytes));\n }\n }\n\n return hashed;\n}\n\n/**\n * Canonicalize and hash recovery emails for an account, and persist the mapping\n * (hashHex → canonical email) in IndexedDB on a best-effort basis.\n */\nexport async function prepareRecoveryEmails(nearAccountId: AccountId, recoveryEmails: string[]): Promise<{\n hashes: number[][];\n pairs: RecoveryEmailEntry[];\n}> {\n const accountId = toAccountId(nearAccountId);\n\n const trimmedEmails = (recoveryEmails || []).map(e => e.trim()).filter(e => e.length > 0);\n const canonicalEmails = trimmedEmails.map(canonicalizeEmail);\n const recoveryEmailHashes = await hashRecoveryEmails(recoveryEmails, accountId);\n\n const pairs: RecoveryEmailEntry[] = recoveryEmailHashes.map((hashBytes, idx) => ({\n hashHex: bytesToHex(hashBytes),\n email: canonicalEmails[idx],\n }));\n\n void (async () => {\n try {\n await IndexedDBManager.upsertRecoveryEmails(accountId, pairs);\n } catch (error) {\n console.warn('[EmailRecovery] Failed to persist local recovery emails', error);\n }\n })();\n\n return { hashes: recoveryEmailHashes, pairs };\n}\n\nexport async function getLocalRecoveryEmails(nearAccountId: AccountId): Promise<RecoveryEmailRecord[]> {\n return IndexedDBManager.getRecoveryEmails(nearAccountId);\n}\n"],"mappings":";;;;;;AAgDA,eAAe,mBAAmB,QAAkB,WAA2C;CAC7F,MAAM,UAAU,IAAI;CACpB,MAAM,QAAQ,aAAa,IAAI,OAAO;CACtC,MAAM,cAAc,UAAU,IAC3B,KAAI,MAAK,EAAE,QACX,QAAO,MAAK,EAAE,SAAS;CAE1B,MAAMA,SAAqB;AAE3B,MAAK,MAAM,SAAS,WAClB,KAAI;EACF,MAAM,iBAAiB,kBAAkB;EACzC,MAAM,QAAQ,GAAG,eAAe,GAAG;EACnC,MAAM,OAAO,QAAQ,OAAO;EAC5B,MAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW;EACrD,MAAM,QAAQ,IAAI,WAAW;AAC7B,SAAO,KAAK,MAAM,KAAK;SACjB;EACN,MAAM,QAAQ,QAAQ,OAAO,MAAM;AACnC,SAAO,KAAK,MAAM,KAAK;;AAI3B,QAAO;;;;;;AAOT,eAAsB,sBAAsB,eAA0B,gBAGnE;CACD,MAAM,YAAYC,+BAAY;CAE9B,MAAM,iBAAiB,kBAAkB,IAAI,KAAI,MAAK,EAAE,QAAQ,QAAO,MAAK,EAAE,SAAS;CACvF,MAAM,kBAAkB,cAAc,IAAI;CAC1C,MAAM,sBAAsB,MAAM,mBAAmB,gBAAgB;CAErE,MAAMC,QAA8B,oBAAoB,KAAK,WAAW,SAAS;EAC/E,SAAS,WAAW;EACpB,OAAO,gBAAgB;;AAGzB,EAAM,YAAY;AAChB,MAAI;AACF,SAAMC,+BAAiB,qBAAqB,WAAW;WAChD,OAAO;AACd,WAAQ,KAAK,2DAA2D;;;AAI5E,QAAO;EAAE,QAAQ;EAAqB;;;AAGxC,eAAsB,uBAAuB,eAA0D;AACrG,QAAOA,+BAAiB,kBAAkB;;;;;;;CA7F/B,qBAAqB,UAA0B;EAC1D,MAAM,MAAM,OAAO,SAAS,IAAI;AAChC,MAAI,CAAC,IAAK,QAAO;EAGjB,MAAM,oBAAoB,IAAI,QAAQ,uBAAuB,IAAI;EAEjE,MAAM,aACJ;EAIF,MAAM,aAAa,kBAAkB,MAAM;EAC3C,MAAM,aAAa,CACjB,aAAa,IACb,mBACA,QAAQ,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS;AAEjE,OAAK,MAAM,aAAa,YAAY;GAClC,MAAM,UAAU,UAAU,QAAQ,gBAAgB;GAClD,MAAM,QAAQ,QAAQ,MAAM;AAC5B,OAAI,QAAQ,GACV,QAAO,MAAM,GAAG,OAAO;;AAI3B,SAAO,kBAAkB;;CAGd,cAAc,UAAyC;EAClE,MAAM,MAAM,iBAAiB,aAAa,QAAQ,WAAW,KAAK;AAClE,SAAO,KAAK,MAAM,KAAK,KACpB,KAAI,MAAK,EAAE,SAAS,IAAI,SAAS,GAAG,MACpC,KAAK"}
|
|
@@ -260,22 +260,17 @@ var init_passkeyClientDB = require_rolldown_runtime.__esm({ "src/core/IndexedDBM
|
|
|
260
260
|
* @returns filtered authenticators for allowCredentials, plus optional wrongPasskeyError
|
|
261
261
|
*/
|
|
262
262
|
async ensureCurrentPasskey(nearAccountId, authenticators, selectedCredentialRawId) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const matched = authenticators.find((a) => a.credentialId === selectedCredentialRawId);
|
|
275
|
-
if (matched && matched.deviceNumber !== expectedDeviceNumber) wrongPasskeyError = `You have multiple passkeys (deviceNumbers) for account ${accountIdNormalized}, but used a passkey from a different device. Please use the passkey for the most recently logged-in device.`;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
263
|
+
if (authenticators.length <= 1) return { authenticatorsForPrompt: authenticators };
|
|
264
|
+
const accountIdNormalized = require_accountIds.toAccountId(nearAccountId);
|
|
265
|
+
const lastUser = await this.getLastUser().catch(() => null);
|
|
266
|
+
if (!lastUser || lastUser.nearAccountId !== accountIdNormalized) return { authenticatorsForPrompt: authenticators };
|
|
267
|
+
const expectedDeviceNumber = lastUser.deviceNumber;
|
|
268
|
+
const byDeviceNumber = authenticators.filter((a) => a.deviceNumber === expectedDeviceNumber);
|
|
269
|
+
let expectedCredentialId = lastUser.passkeyCredential.rawId;
|
|
270
|
+
if (byDeviceNumber.length > 0 && !byDeviceNumber.some((a) => a.credentialId === expectedCredentialId)) expectedCredentialId = byDeviceNumber[0].credentialId;
|
|
271
|
+
const byCredentialId = authenticators.filter((a) => a.credentialId === expectedCredentialId);
|
|
272
|
+
const authenticatorsForPrompt = byCredentialId.length > 0 ? byCredentialId : byDeviceNumber.length > 0 ? byDeviceNumber : authenticators;
|
|
273
|
+
const wrongPasskeyError = selectedCredentialRawId && selectedCredentialRawId !== expectedCredentialId ? `You have multiple passkeys (deviceNumbers) for account ${accountIdNormalized}, but used a different passkey than the most recently logged-in one. Please use the passkey for the most recently logged-in device.` : void 0;
|
|
279
274
|
return {
|
|
280
275
|
authenticatorsForPrompt,
|
|
281
276
|
wrongPasskeyError
|
|
@@ -386,30 +381,34 @@ var init_passkeyClientDB = require_rolldown_runtime.__esm({ "src/core/IndexedDBM
|
|
|
386
381
|
* @param userData - User data with nearAccountId as primary identifier
|
|
387
382
|
*/
|
|
388
383
|
async storeWebAuthnUserData(userData) {
|
|
389
|
-
if (userData.deviceNumber === void 0) console.warn("WARNING: deviceNumber is undefined in storeWebAuthnUserData, will default to 1");
|
|
390
384
|
const validation = this.validateNearAccountId(userData.nearAccountId);
|
|
391
385
|
if (!validation.valid) throw new Error(`Cannot store WebAuthn data for invalid account ID: ${validation.error}`);
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
clientNearPublicKey: userData.clientNearPublicKey,
|
|
399
|
-
passkeyCredential: userData.passkeyCredential,
|
|
400
|
-
encryptedVrfKeypair: userData.encryptedVrfKeypair,
|
|
401
|
-
version: userData.version || 2,
|
|
402
|
-
serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
const finalDeviceNumber = userData.deviceNumber || existingUser.deviceNumber;
|
|
406
|
-
await this.updateUser(userData.nearAccountId, {
|
|
386
|
+
const accountId = require_accountIds.toAccountId(userData.nearAccountId);
|
|
387
|
+
const deviceNumber = userData.deviceNumber;
|
|
388
|
+
let user = await this.getUser(accountId, deviceNumber);
|
|
389
|
+
if (!user) user = await this.registerUser({
|
|
390
|
+
nearAccountId: accountId,
|
|
391
|
+
deviceNumber,
|
|
407
392
|
clientNearPublicKey: userData.clientNearPublicKey,
|
|
393
|
+
passkeyCredential: userData.passkeyCredential,
|
|
408
394
|
encryptedVrfKeypair: userData.encryptedVrfKeypair,
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
395
|
+
version: userData.version || 2,
|
|
396
|
+
serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair
|
|
397
|
+
});
|
|
398
|
+
const updatedUser = {
|
|
399
|
+
...user,
|
|
400
|
+
clientNearPublicKey: userData.clientNearPublicKey,
|
|
401
|
+
passkeyCredential: userData.passkeyCredential,
|
|
402
|
+
encryptedVrfKeypair: userData.encryptedVrfKeypair,
|
|
403
|
+
serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair ?? user.serverEncryptedVrfKeypair,
|
|
404
|
+
version: userData.version ?? user.version,
|
|
405
|
+
lastUpdated: userData.lastUpdated ?? Date.now()
|
|
406
|
+
};
|
|
407
|
+
await this.storeUser(updatedUser);
|
|
408
|
+
this.emitEvent({
|
|
409
|
+
type: "user-updated",
|
|
410
|
+
accountId,
|
|
411
|
+
data: { updatedUser }
|
|
413
412
|
});
|
|
414
413
|
}
|
|
415
414
|
async getAllUsers() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passkeyClientDB.js","names":["DB_CONFIG: PasskeyClientDBConfig","err: any","entry: AppStateEntry<T>","validateNearAccountId","toAccountId","wrongPasskeyError: string | undefined","userData: ClientUserData","DEFAULT_CONFIRMATION_CONFIG","lastUserState: LastUserAccountIdState","fixed: ClientUserData","clientAuth: ClientAuthenticatorData","rec: DerivedAddressRecord","rec: RecoveryEmailRecord"],"sources":["../../../../src/core/IndexedDBManager/passkeyClientDB.ts"],"sourcesContent":["import { openDB, type IDBPDatabase } from 'idb';\nimport { type ValidationResult, validateNearAccountId } from '../../utils/validation';\nimport type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { ConfirmationConfig, DEFAULT_CONFIRMATION_CONFIG } from '../types/signer-worker'\n\n\nexport interface ClientUserData {\n // Primary key - now uses AccountId + deviceNumber for unique identification\n nearAccountId: AccountId;\n deviceNumber: number; // Device number for multi-device support (1-indexed)\n version?: number;\n\n // User metadata\n registeredAt?: number;\n lastLogin?: number;\n lastUpdated?: number;\n\n // WebAuthn/Passkey data (merged from WebAuthnManager)\n clientNearPublicKey: string;\n passkeyCredential: {\n id: string;\n rawId: string;\n };\n\n // VRF credentials for stateless authentication\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: string;\n chacha20NonceB64u: string;\n };\n // Server-assisted auto-login (VRF key session): Shamir 3-pass fields\n // Stores relayer-blinded KEK and the VRF ciphertext; server never sees plaintext VRF or KEK\n serverEncryptedVrfKeypair?: {\n ciphertextVrfB64u: string;\n kek_s_b64u: string;\n // Metadata for proactive refresh\n serverKeyId: string;\n updatedAt?: number;\n };\n\n // User preferences\n preferences?: UserPreferences;\n}\n\nexport type StoreUserDataInput = Omit<ClientUserData, 'deviceNumber' | 'lastLogin' | 'registeredAt'>\n & {\n deviceNumber?: number;\n serverEncryptedVrfKeypair?: ClientUserData['serverEncryptedVrfKeypair'];\n version?: number;\n };\n\nexport interface UserPreferences {\n useRelayer: boolean;\n useNetwork: 'testnet' | 'mainnet';\n confirmationConfig: ConfirmationConfig;\n // User preferences can be extended here as needed\n}\n\n// Authenticator cache\nexport interface ClientAuthenticatorData {\n credentialId: string;\n credentialPublicKey: Uint8Array;\n transports?: string[]; // AuthenticatorTransport[]\n name?: string;\n nearAccountId: AccountId; // FK reference using AccountId\n deviceNumber: number; // Device number for this authenticator (1-indexed)\n registered: string; // ISO date string\n syncedAt: string; // When this cache entry was last synced with contract\n vrfPublicKey: string; // Base64-encoded VRF public key (1:1 relationship on client)\n}\n\ninterface AppStateEntry<T = unknown> {\n key: string;\n value: T;\n}\n\n// Internal helper: legacy user records may be missing deviceNumber.\ntype ClientUserDataWithOptionalDevice =\n | ClientUserData\n | (Omit<ClientUserData, 'deviceNumber'> & { deviceNumber?: number });\n\n// Special type for lastUserAccountId app state entry\nexport interface LastUserAccountIdState {\n accountId: AccountId;\n deviceNumber: number;\n}\n\ninterface PasskeyClientDBConfig {\n dbName: string;\n dbVersion: number;\n userStore: string;\n appStateStore: string;\n authenticatorStore: string;\n derivedAddressStore: string;\n recoveryEmailStore: string;\n}\n\n// === CONSTANTS ===\nconst DB_CONFIG: PasskeyClientDBConfig = {\n dbName: 'PasskeyClientDB',\n dbVersion: 15, // v15: add recoveryEmails store\n userStore: 'users',\n appStateStore: 'appState',\n authenticatorStore: 'authenticators',\n derivedAddressStore: 'derivedAddresses',\n recoveryEmailStore: 'recoveryEmails'\n} as const;\n\nexport interface IndexedDBEvent {\n type: 'user-updated' | 'preferences-updated' | 'user-deleted';\n accountId: AccountId;\n data?: Record<string, unknown>;\n}\n\n// Persisted mapping of derived (e.g., EVM) addresses tied to an account\n/**\n * Persisted mapping of derived (e.g., EVM/Solana/Zcash) addresses tied to an account.\n *\n * Notes on multi-chain support:\n * - The composite primary key is [nearAccountId, contractId, path]. To support\n * different chains and chain IDs, encode them in the `path` string, e.g.:\n * - EVM: `evm:<chainId>:<derivationPath>` → `evm:84532:ethereum-1`\n * - Solana: `solana:<derivationPath>`\n * - Zcash: `zcash:<derivationPath>`\n * - Additional descriptive fields like `namespace` and `chainRef` are optional metadata\n * and are not part of the key.\n */\nexport interface DerivedAddressRecord {\n nearAccountId: AccountId;\n contractId: string; // MPC/Derivation contract on NEAR\n path: string; // Composite path (may include namespace/chainId); see docs above\n address: string; // Derived address (e.g., 0x...)\n updatedAt: number;\n // Optional metadata (not used in the key)\n namespace?: string; // e.g., 'evm', 'solana', 'zcash'\n chainRef?: string; // e.g., chainId '84532' or a named network slug\n}\n\n/**\n * Persisted mapping of recovery email hashes to canonical email addresses for an account.\n *\n * Notes:\n * - Composite primary key is [nearAccountId, hashHex].\n * - `hashHex` is the 0x-prefixed hex encoding of the 32-byte hash:\n * SHA256(canonical_email || \"|\" || account_id)\n * - `email` is the canonical form: \"local@domain\", lowercased.\n */\nexport interface RecoveryEmailRecord {\n nearAccountId: AccountId;\n hashHex: string;\n email: string;\n addedAt: number;\n}\n\nexport class PasskeyClientDBManager {\n private config: PasskeyClientDBConfig;\n private db: IDBPDatabase | null = null;\n private disabled = false;\n private eventListeners: Set<(event: IndexedDBEvent) => void> = new Set();\n\n constructor(config: PasskeyClientDBConfig = DB_CONFIG) {\n this.config = config;\n }\n\n getDbName(): string {\n return this.config.dbName;\n }\n\n setDbName(dbName: string): void {\n const next = String(dbName || '').trim();\n if (!next || next === this.config.dbName) return;\n try { (this.db as any)?.close?.(); } catch {}\n this.db = null;\n this.config = { ...this.config, dbName: next };\n }\n\n isDisabled(): boolean {\n return this.disabled;\n }\n\n setDisabled(disabled: boolean): void {\n const next = !!disabled;\n if (next === this.disabled) return;\n this.disabled = next;\n if (next) {\n try { (this.db as any)?.close?.(); } catch {}\n this.db = null;\n }\n }\n\n // === EVENT SYSTEM ===\n\n onChange(listener: (event: IndexedDBEvent) => void): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n private emitEvent(event: IndexedDBEvent): void {\n this.eventListeners.forEach(listener => {\n try {\n listener(event);\n } catch (error) {\n console.warn('[IndexedDBManager]: Error in event listener:', error);\n }\n });\n }\n\n private async getDB(): Promise<IDBPDatabase> {\n if (this.disabled) {\n throw new Error('[PasskeyClientDBManager] IndexedDB is disabled in this environment.');\n }\n if (this.db) {\n return this.db;\n }\n\n try {\n this.db = await openDB(this.config.dbName, this.config.dbVersion, {\n upgrade: (db, oldVersion, _newVersion, _transaction): void => {\n // Create stores if they don't exist\n if (!db.objectStoreNames.contains(DB_CONFIG.userStore)) {\n // Users table: composite key of [nearAccountId, deviceNumber]\n const userStore = db.createObjectStore(DB_CONFIG.userStore, { keyPath: ['nearAccountId', 'deviceNumber'] });\n userStore.createIndex('nearAccountId', 'nearAccountId', { unique: false });\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.appStateStore)) {\n db.createObjectStore(DB_CONFIG.appStateStore, { keyPath: 'key' });\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.authenticatorStore)) {\n // Authenticators table: composite key of [nearAccountId, deviceNumber, credentialId]\n const authStore = db.createObjectStore(DB_CONFIG.authenticatorStore, { keyPath: ['nearAccountId', 'deviceNumber', 'credentialId'] });\n authStore.createIndex('nearAccountId', 'nearAccountId', { unique: false });\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.derivedAddressStore)) {\n // Derived addresses: composite key of [nearAccountId, contractId, path]\n const dStore = db.createObjectStore(DB_CONFIG.derivedAddressStore, { keyPath: ['nearAccountId', 'contractId', 'path'] });\n try { dStore.createIndex('nearAccountId', 'nearAccountId', { unique: false }); } catch {}\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.recoveryEmailStore)) {\n // Recovery emails: composite key of [nearAccountId, hashHex]\n const rStore = db.createObjectStore(DB_CONFIG.recoveryEmailStore, { keyPath: ['nearAccountId', 'hashHex'] });\n try { rStore.createIndex('nearAccountId', 'nearAccountId', { unique: false }); } catch {}\n }\n },\n blocked() {\n console.warn('PasskeyClientDB connection is blocked.');\n },\n blocking() {\n console.warn('PasskeyClientDB connection is blocking another connection.');\n },\n terminated: () => {\n console.warn('PasskeyClientDB connection has been terminated.');\n this.db = null;\n },\n });\n\n // Post-open migrations (non-blocking)\n try { await this.runMigrationsIfNeeded(this.db); } catch {}\n\n } catch (err: any) {\n const msg = String(err?.message || '');\n if (err?.name === 'VersionError' || /less than the existing version/i.test(msg)) {\n // Mixed-version contexts (host/app) — open without version to adopt existing DB\n try {\n console.warn('PasskeyClientDB: opening existing DB without version due to VersionError');\n this.db = await openDB(this.config.dbName);\n } catch (e) {\n throw err;\n }\n } else {\n throw err;\n }\n }\n\n return this.db;\n }\n\n private async runMigrationsIfNeeded(_db: IDBPDatabase): Promise<void> {\n return;\n }\n\n // === APP STATE METHODS ===\n\n async getAppState<T = unknown>(key: string): Promise<T | undefined> {\n const db = await this.getDB();\n const result = await db.get(DB_CONFIG.appStateStore, key);\n return result?.value as T | undefined;\n }\n\n async setAppState<T = unknown>(key: string, value: T): Promise<void> {\n const db = await this.getDB();\n const entry: AppStateEntry<T> = { key, value };\n await db.put(DB_CONFIG.appStateStore, entry);\n }\n\n // === ACCOUNT ID VALIDATION AND UTILITIES ===\n\n /**\n * Validate that a NEAR account ID is in the expected format\n * Supports both <username>.<relayerAccountId> and <username>.testnet formats\n */\n validateNearAccountId(nearAccountId: AccountId): ValidationResult {\n return validateNearAccountId(nearAccountId);\n }\n\n /**\n * Extract username from NEAR account ID\n */\n extractUsername(nearAccountId: AccountId): string {\n const validation = validateNearAccountId(nearAccountId);\n if (!validation.valid) {\n throw new Error(`Invalid NEAR account ID: ${validation.error}`);\n }\n return nearAccountId.split('.')[0];\n }\n\n /**\n * Generate a NEAR account ID from a username and domain\n * @param username - The username to use for the account ID\n * @param domain - The domain to use for the account ID\n * @returns The generated NEAR account ID\n */\n generateNearAccountId(username: string, domain: string): string {\n const sanitizedName = username\n .toLowerCase()\n .replace(/[^a-z0-9_\\\\-]/g, '')\n .substring(0, 32);\n return `${sanitizedName}.${domain}`;\n }\n\n // === USER MANAGEMENT METHODS ===\n\n async getUser(nearAccountId: AccountId, deviceNumber?: number): Promise<ClientUserData | null> {\n if (!nearAccountId) return null;\n\n const validation = this.validateNearAccountId(nearAccountId);\n if (!validation.valid) {\n console.warn(`Invalid account ID format: ${nearAccountId}`);\n return null;\n }\n\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n\n if (typeof deviceNumber === 'number') {\n const rec = await db.get(DB_CONFIG.userStore, [accountId, deviceNumber]);\n if (!rec) return null;\n return await this.normalizeUserDeviceNumber(rec as ClientUserDataWithOptionalDevice, deviceNumber);\n }\n\n const index = db.transaction(DB_CONFIG.userStore).store.index('nearAccountId');\n const results = await index.getAll(accountId);\n if (results.length === 0) {\n return null;\n }\n\n if (results.length > 1) {\n console.warn(\n `Multiple passkeys found for account ${accountId}, deviceNumber not provided; ` +\n 'defaulting to last logged-in user.'\n );\n console.log('defaulting to last used user deviceNumber');\n const lastUserState = await this.getAppState<LastUserAccountIdState>('lastUserAccountId').catch(() => null);\n if (lastUserState && toAccountId(lastUserState.accountId) === accountId) {\n const keyed = await db.get(DB_CONFIG.userStore, [accountId, lastUserState.deviceNumber]);\n if (keyed) {\n return await this.normalizeUserDeviceNumber(\n keyed as ClientUserDataWithOptionalDevice,\n lastUserState.deviceNumber\n );\n }\n }\n }\n\n const first = results[0] as ClientUserDataWithOptionalDevice;\n if (!first) return null;\n return await this.normalizeUserDeviceNumber(first, 1);\n }\n\n /**\n * Get the current/last user\n * This is maintained via app state and updated whenever a user is stored or updated\n */\n async getLastUser(): Promise<ClientUserData | null> {\n const lastUserState = await this.getAppState<LastUserAccountIdState>('lastUserAccountId');\n if (!lastUserState) return null;\n const db = await this.getDB();\n const accountId = toAccountId(lastUserState.accountId);\n // Prefer exact device match using composite primary key\n const record = await db.get(DB_CONFIG.userStore, [accountId, lastUserState.deviceNumber]);\n if (record) return record as ClientUserData;\n // Fallback: return any user for account\n return this.getUser(accountId);\n }\n\n /** Get user record by composite key (nearAccountId, deviceNumber) */\n async getUserByDevice(nearAccountId: AccountId, deviceNumber: number): Promise<ClientUserData | null> {\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n const rec = await db.get(DB_CONFIG.userStore, [accountId, deviceNumber]);\n return rec as ClientUserData || null;\n }\n\n /**\n * Get the most recently updated user record for a given account.\n * Useful when deviceNumber is unknown but we need the freshest key for the account.\n */\n /**\n * Get the most recently updated user record for a given account.\n * Useful when deviceNumber is unknown but we need the freshest key for the account.\n */\n async getLastDBUpdatedUser(nearAccountId: AccountId): Promise<ClientUserData | null> {\n const db = await this.getDB();\n try {\n const idx = db.transaction(DB_CONFIG.userStore).store.index('nearAccountId');\n const all = await idx.getAll(toAccountId(nearAccountId));\n if (Array.isArray(all) && all.length > 0) {\n const latest = (all as ClientUserData[]).reduce((a, b) =>\n (a.lastUpdated ?? 0) >= (b.lastUpdated ?? 0) ? a : b\n );\n return latest;\n }\n } catch {\n // fall through\n }\n return null;\n }\n\n async hasPasskeyCredential(nearAccountId: AccountId): Promise<boolean> {\n const authenticators = await this.getAuthenticatorsByUser(nearAccountId);\n return !!authenticators[0]?.credentialId;\n }\n\n /**\n * Ensure the current passkey selection is aligned with the last logged-in device.\n *\n * - When multiple authenticators exist for an account and no deviceNumber is specified,\n * this helper prefers authenticators whose deviceNumber matches the last logged-in user.\n * - Optionally validates that a selected credential (by rawId) also matches the last-user device.\n *\n * @param nearAccountId - Account ID for which the operation is being performed\n * @param authenticators - All authenticators stored for the account\n * @param selectedCredentialRawId - Optional rawId of the credential chosen by WebAuthn\n * @returns filtered authenticators for allowCredentials, plus optional wrongPasskeyError\n */\n async ensureCurrentPasskey(\n nearAccountId: AccountId,\n authenticators: ClientAuthenticatorData[],\n selectedCredentialRawId?: string,\n ): Promise<{\n authenticatorsForPrompt: ClientAuthenticatorData[];\n wrongPasskeyError?: string;\n }> {\n let authenticatorsForPrompt = authenticators;\n let wrongPasskeyError: string | undefined;\n\n if (authenticators.length > 1) {\n const accountIdNormalized = toAccountId(nearAccountId);\n const lastUser = await this.getLastUser().catch(() => null);\n const expectedAccountId = lastUser?.nearAccountId;\n const expectedDeviceNumber = lastUser?.deviceNumber;\n\n if (\n expectedAccountId &&\n expectedDeviceNumber &&\n expectedAccountId === accountIdNormalized\n ) {\n // For the prompt, prefer authenticators that match the last-user deviceNumber.\n const filtered = authenticators.filter(a => a.deviceNumber === expectedDeviceNumber);\n if (filtered.length > 0) {\n authenticatorsForPrompt = filtered;\n }\n\n // If a credential was already chosen, verify it matches the last-user deviceNumber.\n if (selectedCredentialRawId) {\n const matched = authenticators.find(a => a.credentialId === selectedCredentialRawId);\n if (matched && matched.deviceNumber !== expectedDeviceNumber) {\n wrongPasskeyError =\n `You have multiple passkeys (deviceNumbers) for account ${accountIdNormalized}, ` +\n 'but used a passkey from a different device. Please use the passkey for the most recently logged-in device.';\n }\n }\n }\n }\n\n return { authenticatorsForPrompt, wrongPasskeyError };\n }\n\n /**\n * Register a new user with the given NEAR account ID\n * @param nearAccountId - Full NEAR account ID (e.g., \"username.testnet\" or \"username.relayer.testnet\")\n * @param additionalData - Additional user data to store\n */\n async registerUser(storeUserData: StoreUserDataInput): Promise<ClientUserData> {\n\n const validation = this.validateNearAccountId(storeUserData.nearAccountId);\n if (!validation.valid) {\n throw new Error(`Cannot register user with invalid account ID: ${validation.error}`);\n }\n\n const now = Date.now();\n\n const userData: ClientUserData = {\n nearAccountId: toAccountId(storeUserData.nearAccountId),\n deviceNumber: storeUserData.deviceNumber || 1, // Default to device 1 (1-indexed)\n version: storeUserData.version || 2,\n registeredAt: now,\n lastLogin: now,\n lastUpdated: now,\n clientNearPublicKey: storeUserData.clientNearPublicKey,\n passkeyCredential: storeUserData.passkeyCredential,\n preferences: {\n useRelayer: false,\n useNetwork: 'testnet',\n confirmationConfig: DEFAULT_CONFIRMATION_CONFIG,\n // Default preferences can be set here\n },\n encryptedVrfKeypair: storeUserData.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: storeUserData.serverEncryptedVrfKeypair,\n };\n\n await this.storeUser(userData);\n return userData;\n }\n\n async updateUser(nearAccountId: AccountId, updates: Partial<ClientUserData>): Promise<void> {\n const user = await this.getUser(nearAccountId);\n if (user) {\n const updatedUser = {\n ...user,\n ...updates,\n lastUpdated: Date.now()\n };\n await this.storeUser(updatedUser); // This will update the app state lastUserAccountId\n\n // Emit event for user updates\n this.emitEvent({\n type: 'user-updated',\n accountId: nearAccountId,\n data: { updates, updatedUser }\n });\n }\n }\n\n async updateLastLogin(nearAccountId: AccountId): Promise<void> {\n await this.updateUser(nearAccountId, { lastLogin: Date.now() });\n }\n\n /**\n * Set the last logged-in user\n * @param nearAccountId - The account ID of the user\n * @param deviceNumber - The device number (defaults to 1)\n */\n async setLastUser(nearAccountId: AccountId, deviceNumber: number = 1): Promise<void> {\n const lastUserState: LastUserAccountIdState = {\n accountId: nearAccountId,\n deviceNumber,\n };\n await this.setAppState('lastUserAccountId', lastUserState);\n }\n\n async updatePreferences(\n nearAccountId: AccountId,\n preferences: Partial<UserPreferences>\n ): Promise<void> {\n const user = await this.getUser(nearAccountId);\n if (user) {\n const updatedPreferences = {\n ...user.preferences,\n ...preferences\n } as UserPreferences;\n await this.updateUser(nearAccountId, { preferences: updatedPreferences });\n\n // Emit event for preference changes\n this.emitEvent({\n type: 'preferences-updated',\n accountId: nearAccountId,\n data: { preferences: updatedPreferences }\n });\n }\n }\n\n private async normalizeUserDeviceNumber(\n user: ClientUserDataWithOptionalDevice,\n defaultDeviceNumber: number\n ): Promise<ClientUserData> {\n const hasValidDevice =\n typeof user.deviceNumber === 'number' && Number.isFinite(user.deviceNumber);\n if (hasValidDevice) {\n return user as ClientUserData;\n }\n\n const deviceNumber = defaultDeviceNumber;\n const fixed: ClientUserData = {\n ...(user as Omit<ClientUserData, 'deviceNumber'>),\n deviceNumber,\n };\n await this.storeUser(fixed);\n return fixed;\n }\n\n private async storeUser(userData: ClientUserData): Promise<void> {\n const validation = this.validateNearAccountId(userData.nearAccountId);\n if (!validation.valid) {\n throw new Error(`Cannot store user with invalid account ID: ${validation.error}`);\n }\n\n const db = await this.getDB();\n await db.put(DB_CONFIG.userStore, userData);\n\n // Update lastUserAccountId with new format including device info\n const lastUserState: LastUserAccountIdState = {\n accountId: userData.nearAccountId,\n deviceNumber: userData.deviceNumber,\n };\n\n await this.setAppState('lastUserAccountId', lastUserState);\n }\n\n /**\n * Store WebAuthn user data (compatibility with WebAuthnManager)\n * @param userData - User data with nearAccountId as primary identifier\n */\n async storeWebAuthnUserData(userData: {\n nearAccountId: AccountId;\n deviceNumber?: number; // Device number for multi-device support (1-indexed)\n clientNearPublicKey: string;\n lastUpdated?: number;\n version?: number;\n passkeyCredential: {\n id: string;\n rawId: string;\n };\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: string;\n chacha20NonceB64u: string;\n };\n serverEncryptedVrfKeypair?: {\n ciphertextVrfB64u: string;\n kek_s_b64u: string;\n serverKeyId: string;\n updatedAt?: number;\n };\n }): Promise<void> {\n\n if (userData.deviceNumber === undefined) {\n console.warn(\"WARNING: deviceNumber is undefined in storeWebAuthnUserData, will default to 1\");\n }\n const validation = this.validateNearAccountId(userData.nearAccountId);\n if (!validation.valid) {\n throw new Error(`Cannot store WebAuthn data for invalid account ID: ${validation.error}`);\n }\n\n // Get existing user data or create new\n let existingUser = await this.getUser(userData.nearAccountId);\n if (!existingUser) {\n const deviceNumberToUse = userData.deviceNumber || 1;\n existingUser = await this.registerUser({\n nearAccountId: userData.nearAccountId,\n deviceNumber: deviceNumberToUse, // Use provided device number or default to 1\n clientNearPublicKey: userData.clientNearPublicKey,\n passkeyCredential: userData.passkeyCredential,\n encryptedVrfKeypair: userData.encryptedVrfKeypair,\n version: userData.version || 2,\n serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair,\n });\n }\n\n // Update with WebAuthn-specific data (including VRF credentials)\n const finalDeviceNumber = userData.deviceNumber || existingUser.deviceNumber;\n\n await this.updateUser(userData.nearAccountId, {\n clientNearPublicKey: userData.clientNearPublicKey,\n encryptedVrfKeypair: userData.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair,\n version: userData.version || existingUser.version,\n deviceNumber: finalDeviceNumber, // Use provided device number or keep existing\n lastUpdated: userData.lastUpdated || Date.now()\n });\n }\n\n async getAllUsers(): Promise<ClientUserData[]> {\n const db = await this.getDB();\n return db.getAll(DB_CONFIG.userStore);\n }\n\n async deleteUser(nearAccountId: AccountId): Promise<void> {\n const db = await this.getDB();\n await db.delete(DB_CONFIG.userStore, nearAccountId);\n // Also clean up related authenticators\n await this.clearAuthenticatorsForUser(nearAccountId);\n }\n\n async clearAllUsers(): Promise<void> {\n const db = await this.getDB();\n await db.clear(DB_CONFIG.userStore);\n }\n\n async clearAllAppState(): Promise<void> {\n const db = await this.getDB();\n await db.clear(DB_CONFIG.appStateStore);\n }\n\n /**\n * Store authenticator data for a user\n */\n async storeAuthenticator(authenticatorData: ClientAuthenticatorData): Promise<void> {\n const db = await this.getDB();\n await db.put(DB_CONFIG.authenticatorStore, authenticatorData);\n }\n\n /**\n * Get all authenticators for a user (optionally for a specific device)\n */\n async getAuthenticatorsByUser(nearAccountId: AccountId): Promise<ClientAuthenticatorData[]> {\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readonly');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n const accountId = toAccountId(nearAccountId);\n\n // Get all authenticators for this account across all devices\n const index = store.index('nearAccountId');\n return await index.getAll(accountId);\n }\n\n /**\n * Get a specific authenticator by credential ID\n */\n async getAuthenticatorByCredentialId(\n nearAccountId: AccountId,\n credentialId: string\n ): Promise<ClientAuthenticatorData | null> {\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readonly');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n const accountId = toAccountId(nearAccountId);\n\n // Primary key is [nearAccountId, deviceNumber, credentialId], so we cannot\n // look up by [nearAccountId, credentialId] directly. Use the nearAccountId\n // index and filter by credentialId.\n const index = store.index('nearAccountId');\n const all = await index.getAll(accountId);\n const match = all.find((auth: any) => auth.credentialId === credentialId) || null;\n return match;\n }\n\n /**\n * Clear all authenticators for a user\n */\n async clearAuthenticatorsForUser(nearAccountId: AccountId): Promise<void> {\n const authenticators = await this.getAuthenticatorsByUser(nearAccountId);\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readwrite');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n\n for (const auth of authenticators) {\n // Composite PK is [nearAccountId, deviceNumber, credentialId]\n await store.delete([nearAccountId, auth.deviceNumber, auth.credentialId]);\n }\n }\n\n /**\n * Sync authenticators from contract data\n */\n async syncAuthenticatorsFromContract(\n nearAccountId: AccountId,\n contractAuthenticators: Array<{\n credentialId: string;\n credentialPublicKey: Uint8Array;\n transports?: string[];\n name?: string;\n registered: string;\n vrfPublicKey: string;\n deviceNumber?: number; // Device number from contract\n }>\n ): Promise<void> {\n // Clear existing cache for this user\n await this.clearAuthenticatorsForUser(nearAccountId);\n\n // Add all contract authenticators to cache\n const syncedAt = new Date().toISOString();\n for (const auth of contractAuthenticators) {\n // Fix transport processing: filter out undefined values and provide fallback\n const rawTransports = auth.transports || [];\n const validTransports = rawTransports.filter((transport: any) =>\n transport !== undefined && transport !== null && typeof transport === 'string'\n );\n\n // If no valid transports, default to 'internal' for platform authenticators\n const transports = validTransports.length > 0 ? validTransports : ['internal'];\n\n const clientAuth: ClientAuthenticatorData = {\n credentialId: auth.credentialId,\n credentialPublicKey: auth.credentialPublicKey,\n transports,\n name: auth.name,\n nearAccountId: toAccountId(nearAccountId),\n deviceNumber: auth.deviceNumber || 1, // Default to device 1 (1-indexed)\n registered: auth.registered,\n syncedAt: syncedAt,\n vrfPublicKey: auth.vrfPublicKey,\n };\n await this.storeAuthenticator(clientAuth);\n }\n }\n\n // === ATOMIC OPERATIONS AND ROLLBACK METHODS ===\n\n /**\n * Delete all authenticators for a user\n */\n async deleteAllAuthenticatorsForUser(nearAccountId: AccountId): Promise<void> {\n const authenticators = await this.getAuthenticatorsByUser(nearAccountId);\n\n if (authenticators.length === 0) {\n console.warn(`No authenticators found for user ${nearAccountId}`);\n return;\n }\n\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readwrite');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n\n for (const auth of authenticators) {\n // Composite PK is [nearAccountId, deviceNumber, credentialId]\n await store.delete([nearAccountId, auth.deviceNumber, auth.credentialId]);\n }\n\n console.debug(`Deleted ${authenticators.length} authenticators for user ${nearAccountId}`);\n }\n\n /**\n * Get user's confirmation config from IndexedDB\n * @param nearAccountId - The user's account ID\n * @returns ConfirmationConfig or undefined\n */\n async getConfirmationConfig(nearAccountId: AccountId): Promise<ConfirmationConfig> {\n const user = await this.getUser(nearAccountId);\n return user?.preferences?.confirmationConfig || DEFAULT_CONFIRMATION_CONFIG;\n }\n\n /**\n * Get user's theme preference from IndexedDB\n * @param nearAccountId - The user's account ID\n * @returns 'dark' | 'light' | null\n */\n async getTheme(nearAccountId: AccountId): Promise<'dark' | 'light' | null> {\n const user = await this.getUser(nearAccountId);\n return user?.preferences?.confirmationConfig.theme || null;\n }\n\n /**\n * Set user's theme preference in IndexedDB\n * @param nearAccountId - The user's account ID\n * @param theme - The theme to set ('dark' | 'light')\n */\n async setTheme(nearAccountId: AccountId, theme: 'dark' | 'light'): Promise<void> {\n const existingConfig = await this.getConfirmationConfig(nearAccountId);\n const confirmationConfig = { ...existingConfig, theme };\n await this.updatePreferences(nearAccountId, { confirmationConfig });\n }\n\n /**\n * Get user's theme with fallback to 'dark'\n * @param nearAccountId - The user's account ID\n * @returns 'dark' | 'light'\n */\n async getThemeOrDefault(nearAccountId: AccountId): Promise<'dark' | 'light'> {\n const theme = await this.getTheme(nearAccountId);\n return theme || 'dark';\n }\n\n /**\n * Toggle between dark and light theme for a user\n * @param nearAccountId - The user's account ID\n * @returns The new theme that was set\n */\n async toggleTheme(nearAccountId: AccountId): Promise<'dark' | 'light'> {\n const currentTheme = await this.getThemeOrDefault(nearAccountId);\n const newTheme = currentTheme === 'dark' ? 'light' : 'dark';\n await this.setTheme(nearAccountId, newTheme);\n return newTheme;\n }\n\n // === DERIVED ADDRESS METHODS ===\n\n /**\n * Store a derived address for a given NEAR account + contract + path\n */\n async setDerivedAddress(nearAccountId: AccountId, args: { contractId: string; path: string; address: string }): Promise<void> {\n if (!nearAccountId || !args?.contractId || !args?.path || !args?.address) return;\n const validation = this.validateNearAccountId(nearAccountId);\n if (!validation.valid) return;\n const rec: DerivedAddressRecord = {\n nearAccountId: toAccountId(nearAccountId),\n contractId: String(args.contractId),\n path: String(args.path),\n address: String(args.address),\n updatedAt: Date.now(),\n };\n const db = await this.getDB();\n await db.put(DB_CONFIG.derivedAddressStore, rec);\n }\n\n /**\n * Fetch a derived address record; returns null if not found\n */\n async getDerivedAddressRecord(nearAccountId: AccountId, args: { contractId: string; path: string }): Promise<DerivedAddressRecord | null> {\n if (!nearAccountId || !args?.contractId || !args?.path) return null;\n const db = await this.getDB();\n const rec = await db.get(DB_CONFIG.derivedAddressStore, [toAccountId(nearAccountId), String(args.contractId), String(args.path)]);\n return (rec as DerivedAddressRecord) || null;\n }\n\n /**\n * Get only the derived address string; returns null if not set\n */\n async getDerivedAddress(nearAccountId: AccountId, args: { contractId: string; path: string }): Promise<string | null> {\n const rec = await this.getDerivedAddressRecord(nearAccountId, args);\n return rec?.address || null;\n }\n\n // === RECOVERY EMAIL METHODS ===\n\n /**\n * Upsert recovery email records for an account.\n * Merges by hashHex, preferring the most recent email.\n */\n async upsertRecoveryEmails(\n nearAccountId: AccountId,\n entries: Array<{ hashHex: string; email: string }>\n ): Promise<void> {\n if (!nearAccountId || !entries?.length) return;\n const validation = this.validateNearAccountId(nearAccountId);\n if (!validation.valid) return;\n\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n const now = Date.now();\n\n for (const entry of entries) {\n const hashHex = String(entry?.hashHex || '').trim();\n const email = String(entry?.email || '').trim();\n if (!hashHex || !email) continue;\n\n const rec: RecoveryEmailRecord = {\n nearAccountId: accountId,\n hashHex,\n email,\n addedAt: now,\n };\n await db.put(DB_CONFIG.recoveryEmailStore, rec);\n }\n }\n\n /**\n * Fetch all recovery email records for an account.\n */\n async getRecoveryEmails(nearAccountId: AccountId): Promise<RecoveryEmailRecord[]> {\n if (!nearAccountId) return [];\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n const tx = db.transaction(DB_CONFIG.recoveryEmailStore, 'readonly');\n const store = tx.objectStore(DB_CONFIG.recoveryEmailStore);\n const index = store.index('nearAccountId');\n const result = await index.getAll(accountId);\n return (result as RecoveryEmailRecord[]) || [];\n }\n\n /**\n * Atomic operation wrapper for multiple IndexedDB operations\n * Either all operations succeed or all are rolled back\n */\n async atomicOperation<T>(operation: (db: IDBPDatabase) => Promise<T>): Promise<T> {\n const db = await this.getDB();\n try {\n const result = await operation(db);\n return result;\n } catch (error) {\n console.error('Atomic operation failed:', error);\n throw error;\n }\n }\n\n /**\n * Complete rollback of user registration data\n * Deletes user, authenticators, and WebAuthn data atomically\n */\n async rollbackUserRegistration(nearAccountId: AccountId): Promise<void> {\n console.debug(`Rolling back registration data for ${nearAccountId}`);\n\n await this.atomicOperation(async (db) => {\n // Delete all authenticators for this user\n await this.deleteAllAuthenticatorsForUser(nearAccountId);\n\n // Delete user record\n await db.delete(DB_CONFIG.userStore, nearAccountId);\n\n // Clear from app state if this was the last user\n const lastUserAccount = await this.getAppState<string>('lastUserAccountId');\n if (lastUserAccount === nearAccountId) {\n await this.setAppState('lastUserAccountId', null);\n }\n\n console.debug(`Rolled back all registration data for ${nearAccountId}`);\n return true;\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"passkeyClientDB.js","names":["DB_CONFIG: PasskeyClientDBConfig","err: any","entry: AppStateEntry<T>","validateNearAccountId","toAccountId","userData: ClientUserData","DEFAULT_CONFIRMATION_CONFIG","lastUserState: LastUserAccountIdState","fixed: ClientUserData","updatedUser: ClientUserData","clientAuth: ClientAuthenticatorData","rec: DerivedAddressRecord","rec: RecoveryEmailRecord"],"sources":["../../../../src/core/IndexedDBManager/passkeyClientDB.ts"],"sourcesContent":["import { openDB, type IDBPDatabase } from 'idb';\nimport { type ValidationResult, validateNearAccountId } from '../../utils/validation';\nimport type { AccountId } from '../types/accountIds';\nimport { toAccountId } from '../types/accountIds';\nimport { ConfirmationConfig, DEFAULT_CONFIRMATION_CONFIG } from '../types/signer-worker'\n\n\nexport interface ClientUserData {\n // Primary key - now uses AccountId + deviceNumber for unique identification\n nearAccountId: AccountId;\n deviceNumber: number; // Device number for multi-device support (1-indexed)\n version?: number;\n\n // User metadata\n registeredAt?: number;\n lastLogin?: number;\n lastUpdated?: number;\n\n // WebAuthn/Passkey data (merged from WebAuthnManager)\n clientNearPublicKey: string;\n passkeyCredential: {\n id: string;\n rawId: string;\n };\n\n // VRF credentials for stateless authentication\n encryptedVrfKeypair: {\n encryptedVrfDataB64u: string;\n chacha20NonceB64u: string;\n };\n // Server-assisted auto-login (VRF key session): Shamir 3-pass fields\n // Stores relayer-blinded KEK and the VRF ciphertext; server never sees plaintext VRF or KEK\n serverEncryptedVrfKeypair?: {\n ciphertextVrfB64u: string;\n kek_s_b64u: string;\n // Metadata for proactive refresh\n serverKeyId: string;\n updatedAt?: number;\n };\n\n // User preferences\n preferences?: UserPreferences;\n}\n\nexport type StoreUserDataInput = Omit<ClientUserData, 'deviceNumber' | 'lastLogin' | 'registeredAt'>\n & {\n deviceNumber?: number;\n serverEncryptedVrfKeypair?: ClientUserData['serverEncryptedVrfKeypair'];\n version?: number;\n };\n\nexport type StoreWebAuthnUserDataInput = {\n nearAccountId: AccountId;\n deviceNumber: number;\n clientNearPublicKey: string;\n lastUpdated?: number;\n version?: number;\n passkeyCredential: ClientUserData['passkeyCredential'];\n encryptedVrfKeypair: ClientUserData['encryptedVrfKeypair'];\n serverEncryptedVrfKeypair?: ClientUserData['serverEncryptedVrfKeypair'];\n};\n\nexport interface UserPreferences {\n useRelayer: boolean;\n useNetwork: 'testnet' | 'mainnet';\n confirmationConfig: ConfirmationConfig;\n // User preferences can be extended here as needed\n}\n\n// Authenticator cache\nexport interface ClientAuthenticatorData {\n credentialId: string;\n credentialPublicKey: Uint8Array;\n transports?: string[]; // AuthenticatorTransport[]\n name?: string;\n nearAccountId: AccountId; // FK reference using AccountId\n deviceNumber: number; // Device number for this authenticator (1-indexed)\n registered: string; // ISO date string\n syncedAt: string; // When this cache entry was last synced with contract\n vrfPublicKey: string; // Base64-encoded VRF public key (1:1 relationship on client)\n}\n\ninterface AppStateEntry<T = unknown> {\n key: string;\n value: T;\n}\n\n// Internal helper: legacy user records may be missing deviceNumber.\ntype ClientUserDataWithOptionalDevice =\n | ClientUserData\n | (Omit<ClientUserData, 'deviceNumber'> & { deviceNumber?: number });\n\n// Special type for lastUserAccountId app state entry\nexport interface LastUserAccountIdState {\n accountId: AccountId;\n deviceNumber: number;\n}\n\ninterface PasskeyClientDBConfig {\n dbName: string;\n dbVersion: number;\n userStore: string;\n appStateStore: string;\n authenticatorStore: string;\n derivedAddressStore: string;\n recoveryEmailStore: string;\n}\n\n// === CONSTANTS ===\nconst DB_CONFIG: PasskeyClientDBConfig = {\n dbName: 'PasskeyClientDB',\n dbVersion: 15, // v15: add recoveryEmails store\n userStore: 'users',\n appStateStore: 'appState',\n authenticatorStore: 'authenticators',\n derivedAddressStore: 'derivedAddresses',\n recoveryEmailStore: 'recoveryEmails'\n} as const;\n\nexport interface IndexedDBEvent {\n type: 'user-updated' | 'preferences-updated' | 'user-deleted';\n accountId: AccountId;\n data?: Record<string, unknown>;\n}\n\n// Persisted mapping of derived (e.g., EVM) addresses tied to an account\n/**\n * Persisted mapping of derived (e.g., EVM/Solana/Zcash) addresses tied to an account.\n *\n * Notes on multi-chain support:\n * - The composite primary key is [nearAccountId, contractId, path]. To support\n * different chains and chain IDs, encode them in the `path` string, e.g.:\n * - EVM: `evm:<chainId>:<derivationPath>` → `evm:84532:ethereum-1`\n * - Solana: `solana:<derivationPath>`\n * - Zcash: `zcash:<derivationPath>`\n * - Additional descriptive fields like `namespace` and `chainRef` are optional metadata\n * and are not part of the key.\n */\nexport interface DerivedAddressRecord {\n nearAccountId: AccountId;\n contractId: string; // MPC/Derivation contract on NEAR\n path: string; // Composite path (may include namespace/chainId); see docs above\n address: string; // Derived address (e.g., 0x...)\n updatedAt: number;\n // Optional metadata (not used in the key)\n namespace?: string; // e.g., 'evm', 'solana', 'zcash'\n chainRef?: string; // e.g., chainId '84532' or a named network slug\n}\n\n/**\n * Persisted mapping of recovery email hashes to canonical email addresses for an account.\n *\n * Notes:\n * - Composite primary key is [nearAccountId, hashHex].\n * - `hashHex` is the 0x-prefixed hex encoding of the 32-byte hash:\n * SHA256(canonical_email || \"|\" || account_id)\n * - `email` is the canonical form: \"local@domain\", lowercased.\n */\nexport interface RecoveryEmailRecord {\n nearAccountId: AccountId;\n hashHex: string;\n email: string;\n addedAt: number;\n}\n\nexport class PasskeyClientDBManager {\n private config: PasskeyClientDBConfig;\n private db: IDBPDatabase | null = null;\n private disabled = false;\n private eventListeners: Set<(event: IndexedDBEvent) => void> = new Set();\n\n constructor(config: PasskeyClientDBConfig = DB_CONFIG) {\n this.config = config;\n }\n\n getDbName(): string {\n return this.config.dbName;\n }\n\n setDbName(dbName: string): void {\n const next = String(dbName || '').trim();\n if (!next || next === this.config.dbName) return;\n try { (this.db as any)?.close?.(); } catch {}\n this.db = null;\n this.config = { ...this.config, dbName: next };\n }\n\n isDisabled(): boolean {\n return this.disabled;\n }\n\n setDisabled(disabled: boolean): void {\n const next = !!disabled;\n if (next === this.disabled) return;\n this.disabled = next;\n if (next) {\n try { (this.db as any)?.close?.(); } catch {}\n this.db = null;\n }\n }\n\n // === EVENT SYSTEM ===\n\n onChange(listener: (event: IndexedDBEvent) => void): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n private emitEvent(event: IndexedDBEvent): void {\n this.eventListeners.forEach(listener => {\n try {\n listener(event);\n } catch (error) {\n console.warn('[IndexedDBManager]: Error in event listener:', error);\n }\n });\n }\n\n private async getDB(): Promise<IDBPDatabase> {\n if (this.disabled) {\n throw new Error('[PasskeyClientDBManager] IndexedDB is disabled in this environment.');\n }\n if (this.db) {\n return this.db;\n }\n\n try {\n this.db = await openDB(this.config.dbName, this.config.dbVersion, {\n upgrade: (db, oldVersion, _newVersion, _transaction): void => {\n // Create stores if they don't exist\n if (!db.objectStoreNames.contains(DB_CONFIG.userStore)) {\n // Users table: composite key of [nearAccountId, deviceNumber]\n const userStore = db.createObjectStore(DB_CONFIG.userStore, { keyPath: ['nearAccountId', 'deviceNumber'] });\n userStore.createIndex('nearAccountId', 'nearAccountId', { unique: false });\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.appStateStore)) {\n db.createObjectStore(DB_CONFIG.appStateStore, { keyPath: 'key' });\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.authenticatorStore)) {\n // Authenticators table: composite key of [nearAccountId, deviceNumber, credentialId]\n const authStore = db.createObjectStore(DB_CONFIG.authenticatorStore, { keyPath: ['nearAccountId', 'deviceNumber', 'credentialId'] });\n authStore.createIndex('nearAccountId', 'nearAccountId', { unique: false });\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.derivedAddressStore)) {\n // Derived addresses: composite key of [nearAccountId, contractId, path]\n const dStore = db.createObjectStore(DB_CONFIG.derivedAddressStore, { keyPath: ['nearAccountId', 'contractId', 'path'] });\n try { dStore.createIndex('nearAccountId', 'nearAccountId', { unique: false }); } catch {}\n }\n if (!db.objectStoreNames.contains(DB_CONFIG.recoveryEmailStore)) {\n // Recovery emails: composite key of [nearAccountId, hashHex]\n const rStore = db.createObjectStore(DB_CONFIG.recoveryEmailStore, { keyPath: ['nearAccountId', 'hashHex'] });\n try { rStore.createIndex('nearAccountId', 'nearAccountId', { unique: false }); } catch {}\n }\n },\n blocked() {\n console.warn('PasskeyClientDB connection is blocked.');\n },\n blocking() {\n console.warn('PasskeyClientDB connection is blocking another connection.');\n },\n terminated: () => {\n console.warn('PasskeyClientDB connection has been terminated.');\n this.db = null;\n },\n });\n\n // Post-open migrations (non-blocking)\n try { await this.runMigrationsIfNeeded(this.db); } catch {}\n\n } catch (err: any) {\n const msg = String(err?.message || '');\n if (err?.name === 'VersionError' || /less than the existing version/i.test(msg)) {\n // Mixed-version contexts (host/app) — open without version to adopt existing DB\n try {\n console.warn('PasskeyClientDB: opening existing DB without version due to VersionError');\n this.db = await openDB(this.config.dbName);\n } catch (e) {\n throw err;\n }\n } else {\n throw err;\n }\n }\n\n return this.db;\n }\n\n private async runMigrationsIfNeeded(_db: IDBPDatabase): Promise<void> {\n return;\n }\n\n // === APP STATE METHODS ===\n\n async getAppState<T = unknown>(key: string): Promise<T | undefined> {\n const db = await this.getDB();\n const result = await db.get(DB_CONFIG.appStateStore, key);\n return result?.value as T | undefined;\n }\n\n async setAppState<T = unknown>(key: string, value: T): Promise<void> {\n const db = await this.getDB();\n const entry: AppStateEntry<T> = { key, value };\n await db.put(DB_CONFIG.appStateStore, entry);\n }\n\n // === ACCOUNT ID VALIDATION AND UTILITIES ===\n\n /**\n * Validate that a NEAR account ID is in the expected format\n * Supports both <username>.<relayerAccountId> and <username>.testnet formats\n */\n validateNearAccountId(nearAccountId: AccountId): ValidationResult {\n return validateNearAccountId(nearAccountId);\n }\n\n /**\n * Extract username from NEAR account ID\n */\n extractUsername(nearAccountId: AccountId): string {\n const validation = validateNearAccountId(nearAccountId);\n if (!validation.valid) {\n throw new Error(`Invalid NEAR account ID: ${validation.error}`);\n }\n return nearAccountId.split('.')[0];\n }\n\n /**\n * Generate a NEAR account ID from a username and domain\n * @param username - The username to use for the account ID\n * @param domain - The domain to use for the account ID\n * @returns The generated NEAR account ID\n */\n generateNearAccountId(username: string, domain: string): string {\n const sanitizedName = username\n .toLowerCase()\n .replace(/[^a-z0-9_\\\\-]/g, '')\n .substring(0, 32);\n return `${sanitizedName}.${domain}`;\n }\n\n // === USER MANAGEMENT METHODS ===\n\n async getUser(nearAccountId: AccountId, deviceNumber?: number): Promise<ClientUserData | null> {\n if (!nearAccountId) return null;\n\n const validation = this.validateNearAccountId(nearAccountId);\n if (!validation.valid) {\n console.warn(`Invalid account ID format: ${nearAccountId}`);\n return null;\n }\n\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n\n if (typeof deviceNumber === 'number') {\n const rec = await db.get(DB_CONFIG.userStore, [accountId, deviceNumber]);\n if (!rec) return null;\n return await this.normalizeUserDeviceNumber(rec as ClientUserDataWithOptionalDevice, deviceNumber);\n }\n\n const index = db.transaction(DB_CONFIG.userStore).store.index('nearAccountId');\n const results = await index.getAll(accountId);\n if (results.length === 0) {\n return null;\n }\n\n if (results.length > 1) {\n console.warn(\n `Multiple passkeys found for account ${accountId}, deviceNumber not provided; ` +\n 'defaulting to last logged-in user.'\n );\n console.log('defaulting to last used user deviceNumber');\n const lastUserState = await this.getAppState<LastUserAccountIdState>('lastUserAccountId').catch(() => null);\n if (lastUserState && toAccountId(lastUserState.accountId) === accountId) {\n const keyed = await db.get(DB_CONFIG.userStore, [accountId, lastUserState.deviceNumber]);\n if (keyed) {\n return await this.normalizeUserDeviceNumber(\n keyed as ClientUserDataWithOptionalDevice,\n lastUserState.deviceNumber\n );\n }\n }\n }\n\n const first = results[0] as ClientUserDataWithOptionalDevice;\n if (!first) return null;\n return await this.normalizeUserDeviceNumber(first, 1);\n }\n\n /**\n * Get the current/last user\n * This is maintained via app state and updated whenever a user is stored or updated\n */\n async getLastUser(): Promise<ClientUserData | null> {\n const lastUserState = await this.getAppState<LastUserAccountIdState>('lastUserAccountId');\n if (!lastUserState) return null;\n const db = await this.getDB();\n const accountId = toAccountId(lastUserState.accountId);\n // Prefer exact device match using composite primary key\n const record = await db.get(DB_CONFIG.userStore, [accountId, lastUserState.deviceNumber]);\n if (record) return record as ClientUserData;\n // Fallback: return any user for account\n return this.getUser(accountId);\n }\n\n /** Get user record by composite key (nearAccountId, deviceNumber) */\n async getUserByDevice(nearAccountId: AccountId, deviceNumber: number): Promise<ClientUserData | null> {\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n const rec = await db.get(DB_CONFIG.userStore, [accountId, deviceNumber]);\n return rec as ClientUserData || null;\n }\n\n /**\n * Get the most recently updated user record for a given account.\n * Useful when deviceNumber is unknown but we need the freshest key for the account.\n */\n /**\n * Get the most recently updated user record for a given account.\n * Useful when deviceNumber is unknown but we need the freshest key for the account.\n */\n async getLastDBUpdatedUser(nearAccountId: AccountId): Promise<ClientUserData | null> {\n const db = await this.getDB();\n try {\n const idx = db.transaction(DB_CONFIG.userStore).store.index('nearAccountId');\n const all = await idx.getAll(toAccountId(nearAccountId));\n if (Array.isArray(all) && all.length > 0) {\n const latest = (all as ClientUserData[]).reduce((a, b) =>\n (a.lastUpdated ?? 0) >= (b.lastUpdated ?? 0) ? a : b\n );\n return latest;\n }\n } catch {\n // fall through\n }\n return null;\n }\n\n async hasPasskeyCredential(nearAccountId: AccountId): Promise<boolean> {\n const authenticators = await this.getAuthenticatorsByUser(nearAccountId);\n return !!authenticators[0]?.credentialId;\n }\n\n /**\n * Ensure the current passkey selection is aligned with the last logged-in device.\n *\n * - When multiple authenticators exist for an account and no deviceNumber is specified,\n * this helper prefers authenticators whose deviceNumber matches the last logged-in user.\n * - Optionally validates that a selected credential (by rawId) also matches the last-user device.\n *\n * @param nearAccountId - Account ID for which the operation is being performed\n * @param authenticators - All authenticators stored for the account\n * @param selectedCredentialRawId - Optional rawId of the credential chosen by WebAuthn\n * @returns filtered authenticators for allowCredentials, plus optional wrongPasskeyError\n */\n async ensureCurrentPasskey(\n nearAccountId: AccountId,\n authenticators: ClientAuthenticatorData[],\n selectedCredentialRawId?: string,\n ): Promise<{\n authenticatorsForPrompt: ClientAuthenticatorData[];\n wrongPasskeyError?: string;\n }> {\n if (authenticators.length <= 1) {\n return { authenticatorsForPrompt: authenticators };\n }\n\n const accountIdNormalized = toAccountId(nearAccountId);\n const lastUser = await this.getLastUser().catch(() => null);\n if (!lastUser || lastUser.nearAccountId !== accountIdNormalized) {\n return { authenticatorsForPrompt: authenticators };\n }\n\n const expectedDeviceNumber = lastUser.deviceNumber;\n const byDeviceNumber = authenticators.filter(a => a.deviceNumber === expectedDeviceNumber);\n\n // Prefer the credentialId for the last-user deviceNumber; use the stored last-user rawId\n // only when it matches an authenticator for that device (or when we have no device match).\n let expectedCredentialId = lastUser.passkeyCredential.rawId;\n if (byDeviceNumber.length > 0 && !byDeviceNumber.some(a => a.credentialId === expectedCredentialId)) {\n expectedCredentialId = byDeviceNumber[0].credentialId;\n }\n\n // Preference: restrict allowCredentials to the last-user credentialId.\n // Fallback: if the local authenticator cache is missing that entry, prefer the last-user deviceNumber.\n const byCredentialId = authenticators.filter(a => a.credentialId === expectedCredentialId);\n const authenticatorsForPrompt =\n byCredentialId.length > 0\n ? byCredentialId\n : (byDeviceNumber.length > 0 ? byDeviceNumber : authenticators);\n\n const wrongPasskeyError =\n selectedCredentialRawId && selectedCredentialRawId !== expectedCredentialId\n ? (\n `You have multiple passkeys (deviceNumbers) for account ${accountIdNormalized}, ` +\n 'but used a different passkey than the most recently logged-in one. Please use the passkey for the most recently logged-in device.'\n )\n : undefined;\n\n return { authenticatorsForPrompt, wrongPasskeyError };\n }\n\n /**\n * Register a new user with the given NEAR account ID\n * @param nearAccountId - Full NEAR account ID (e.g., \"username.testnet\" or \"username.relayer.testnet\")\n * @param additionalData - Additional user data to store\n */\n async registerUser(storeUserData: StoreUserDataInput): Promise<ClientUserData> {\n\n const validation = this.validateNearAccountId(storeUserData.nearAccountId);\n if (!validation.valid) {\n throw new Error(`Cannot register user with invalid account ID: ${validation.error}`);\n }\n\n const now = Date.now();\n\n const userData: ClientUserData = {\n nearAccountId: toAccountId(storeUserData.nearAccountId),\n deviceNumber: storeUserData.deviceNumber || 1, // Default to device 1 (1-indexed)\n version: storeUserData.version || 2,\n registeredAt: now,\n lastLogin: now,\n lastUpdated: now,\n clientNearPublicKey: storeUserData.clientNearPublicKey,\n passkeyCredential: storeUserData.passkeyCredential,\n preferences: {\n useRelayer: false,\n useNetwork: 'testnet',\n confirmationConfig: DEFAULT_CONFIRMATION_CONFIG,\n // Default preferences can be set here\n },\n encryptedVrfKeypair: storeUserData.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: storeUserData.serverEncryptedVrfKeypair,\n };\n\n await this.storeUser(userData);\n return userData;\n }\n\n async updateUser(nearAccountId: AccountId, updates: Partial<ClientUserData>): Promise<void> {\n const user = await this.getUser(nearAccountId);\n if (user) {\n const updatedUser = {\n ...user,\n ...updates,\n lastUpdated: Date.now()\n };\n await this.storeUser(updatedUser); // This will update the app state lastUserAccountId\n\n // Emit event for user updates\n this.emitEvent({\n type: 'user-updated',\n accountId: nearAccountId,\n data: { updates, updatedUser }\n });\n }\n }\n\n async updateLastLogin(nearAccountId: AccountId): Promise<void> {\n await this.updateUser(nearAccountId, { lastLogin: Date.now() });\n }\n\n /**\n * Set the last logged-in user\n * @param nearAccountId - The account ID of the user\n * @param deviceNumber - The device number (defaults to 1)\n */\n async setLastUser(nearAccountId: AccountId, deviceNumber: number = 1): Promise<void> {\n const lastUserState: LastUserAccountIdState = {\n accountId: nearAccountId,\n deviceNumber,\n };\n await this.setAppState('lastUserAccountId', lastUserState);\n }\n\n async updatePreferences(\n nearAccountId: AccountId,\n preferences: Partial<UserPreferences>\n ): Promise<void> {\n const user = await this.getUser(nearAccountId);\n if (user) {\n const updatedPreferences = {\n ...user.preferences,\n ...preferences\n } as UserPreferences;\n await this.updateUser(nearAccountId, { preferences: updatedPreferences });\n\n // Emit event for preference changes\n this.emitEvent({\n type: 'preferences-updated',\n accountId: nearAccountId,\n data: { preferences: updatedPreferences }\n });\n }\n }\n\n private async normalizeUserDeviceNumber(\n user: ClientUserDataWithOptionalDevice,\n defaultDeviceNumber: number\n ): Promise<ClientUserData> {\n const hasValidDevice =\n typeof user.deviceNumber === 'number' && Number.isFinite(user.deviceNumber);\n if (hasValidDevice) {\n return user as ClientUserData;\n }\n\n const deviceNumber = defaultDeviceNumber;\n const fixed: ClientUserData = {\n ...(user as Omit<ClientUserData, 'deviceNumber'>),\n deviceNumber,\n };\n await this.storeUser(fixed);\n return fixed;\n }\n\n private async storeUser(userData: ClientUserData): Promise<void> {\n const validation = this.validateNearAccountId(userData.nearAccountId);\n if (!validation.valid) {\n throw new Error(`Cannot store user with invalid account ID: ${validation.error}`);\n }\n\n const db = await this.getDB();\n await db.put(DB_CONFIG.userStore, userData);\n\n // Update lastUserAccountId with new format including device info\n const lastUserState: LastUserAccountIdState = {\n accountId: userData.nearAccountId,\n deviceNumber: userData.deviceNumber,\n };\n\n await this.setAppState('lastUserAccountId', lastUserState);\n }\n\n /**\n * Store WebAuthn user data (compatibility with WebAuthnManager)\n * @param userData - User data with nearAccountId as primary identifier\n */\n async storeWebAuthnUserData(userData: StoreWebAuthnUserDataInput): Promise<void> {\n const validation = this.validateNearAccountId(userData.nearAccountId);\n if (!validation.valid) {\n throw new Error(`Cannot store WebAuthn data for invalid account ID: ${validation.error}`);\n }\n\n const accountId = toAccountId(userData.nearAccountId);\n const deviceNumber = userData.deviceNumber;\n let user = await this.getUser(accountId, deviceNumber);\n\n if (!user) {\n user = await this.registerUser({\n nearAccountId: accountId,\n deviceNumber,\n clientNearPublicKey: userData.clientNearPublicKey,\n passkeyCredential: userData.passkeyCredential,\n encryptedVrfKeypair: userData.encryptedVrfKeypair,\n version: userData.version || 2,\n serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair,\n });\n }\n\n const updatedUser: ClientUserData = {\n ...user,\n clientNearPublicKey: userData.clientNearPublicKey,\n passkeyCredential: userData.passkeyCredential,\n encryptedVrfKeypair: userData.encryptedVrfKeypair,\n serverEncryptedVrfKeypair: userData.serverEncryptedVrfKeypair ?? user.serverEncryptedVrfKeypair,\n version: userData.version ?? user.version,\n lastUpdated: userData.lastUpdated ?? Date.now(),\n };\n\n await this.storeUser(updatedUser);\n this.emitEvent({\n type: 'user-updated',\n accountId,\n data: { updatedUser }\n });\n }\n\n async getAllUsers(): Promise<ClientUserData[]> {\n const db = await this.getDB();\n return db.getAll(DB_CONFIG.userStore);\n }\n\n async deleteUser(nearAccountId: AccountId): Promise<void> {\n const db = await this.getDB();\n await db.delete(DB_CONFIG.userStore, nearAccountId);\n // Also clean up related authenticators\n await this.clearAuthenticatorsForUser(nearAccountId);\n }\n\n async clearAllUsers(): Promise<void> {\n const db = await this.getDB();\n await db.clear(DB_CONFIG.userStore);\n }\n\n async clearAllAppState(): Promise<void> {\n const db = await this.getDB();\n await db.clear(DB_CONFIG.appStateStore);\n }\n\n /**\n * Store authenticator data for a user\n */\n async storeAuthenticator(authenticatorData: ClientAuthenticatorData): Promise<void> {\n const db = await this.getDB();\n await db.put(DB_CONFIG.authenticatorStore, authenticatorData);\n }\n\n /**\n * Get all authenticators for a user (optionally for a specific device)\n */\n async getAuthenticatorsByUser(nearAccountId: AccountId): Promise<ClientAuthenticatorData[]> {\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readonly');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n const accountId = toAccountId(nearAccountId);\n\n // Get all authenticators for this account across all devices\n const index = store.index('nearAccountId');\n return await index.getAll(accountId);\n }\n\n /**\n * Get a specific authenticator by credential ID\n */\n async getAuthenticatorByCredentialId(\n nearAccountId: AccountId,\n credentialId: string\n ): Promise<ClientAuthenticatorData | null> {\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readonly');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n const accountId = toAccountId(nearAccountId);\n\n // Primary key is [nearAccountId, deviceNumber, credentialId], so we cannot\n // look up by [nearAccountId, credentialId] directly. Use the nearAccountId\n // index and filter by credentialId.\n const index = store.index('nearAccountId');\n const all = await index.getAll(accountId);\n const match = all.find((auth: any) => auth.credentialId === credentialId) || null;\n return match;\n }\n\n /**\n * Clear all authenticators for a user\n */\n async clearAuthenticatorsForUser(nearAccountId: AccountId): Promise<void> {\n const authenticators = await this.getAuthenticatorsByUser(nearAccountId);\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readwrite');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n\n for (const auth of authenticators) {\n // Composite PK is [nearAccountId, deviceNumber, credentialId]\n await store.delete([nearAccountId, auth.deviceNumber, auth.credentialId]);\n }\n }\n\n /**\n * Sync authenticators from contract data\n */\n async syncAuthenticatorsFromContract(\n nearAccountId: AccountId,\n contractAuthenticators: Array<{\n credentialId: string;\n credentialPublicKey: Uint8Array;\n transports?: string[];\n name?: string;\n registered: string;\n vrfPublicKey: string;\n deviceNumber?: number; // Device number from contract\n }>\n ): Promise<void> {\n // Clear existing cache for this user\n await this.clearAuthenticatorsForUser(nearAccountId);\n\n // Add all contract authenticators to cache\n const syncedAt = new Date().toISOString();\n for (const auth of contractAuthenticators) {\n // Fix transport processing: filter out undefined values and provide fallback\n const rawTransports = auth.transports || [];\n const validTransports = rawTransports.filter((transport: any) =>\n transport !== undefined && transport !== null && typeof transport === 'string'\n );\n\n // If no valid transports, default to 'internal' for platform authenticators\n const transports = validTransports.length > 0 ? validTransports : ['internal'];\n\n const clientAuth: ClientAuthenticatorData = {\n credentialId: auth.credentialId,\n credentialPublicKey: auth.credentialPublicKey,\n transports,\n name: auth.name,\n nearAccountId: toAccountId(nearAccountId),\n deviceNumber: auth.deviceNumber || 1, // Default to device 1 (1-indexed)\n registered: auth.registered,\n syncedAt: syncedAt,\n vrfPublicKey: auth.vrfPublicKey,\n };\n await this.storeAuthenticator(clientAuth);\n }\n }\n\n // === ATOMIC OPERATIONS AND ROLLBACK METHODS ===\n\n /**\n * Delete all authenticators for a user\n */\n async deleteAllAuthenticatorsForUser(nearAccountId: AccountId): Promise<void> {\n const authenticators = await this.getAuthenticatorsByUser(nearAccountId);\n\n if (authenticators.length === 0) {\n console.warn(`No authenticators found for user ${nearAccountId}`);\n return;\n }\n\n const db = await this.getDB();\n const tx = db.transaction(DB_CONFIG.authenticatorStore, 'readwrite');\n const store = tx.objectStore(DB_CONFIG.authenticatorStore);\n\n for (const auth of authenticators) {\n // Composite PK is [nearAccountId, deviceNumber, credentialId]\n await store.delete([nearAccountId, auth.deviceNumber, auth.credentialId]);\n }\n\n console.debug(`Deleted ${authenticators.length} authenticators for user ${nearAccountId}`);\n }\n\n /**\n * Get user's confirmation config from IndexedDB\n * @param nearAccountId - The user's account ID\n * @returns ConfirmationConfig or undefined\n */\n async getConfirmationConfig(nearAccountId: AccountId): Promise<ConfirmationConfig> {\n const user = await this.getUser(nearAccountId);\n return user?.preferences?.confirmationConfig || DEFAULT_CONFIRMATION_CONFIG;\n }\n\n /**\n * Get user's theme preference from IndexedDB\n * @param nearAccountId - The user's account ID\n * @returns 'dark' | 'light' | null\n */\n async getTheme(nearAccountId: AccountId): Promise<'dark' | 'light' | null> {\n const user = await this.getUser(nearAccountId);\n return user?.preferences?.confirmationConfig.theme || null;\n }\n\n /**\n * Set user's theme preference in IndexedDB\n * @param nearAccountId - The user's account ID\n * @param theme - The theme to set ('dark' | 'light')\n */\n async setTheme(nearAccountId: AccountId, theme: 'dark' | 'light'): Promise<void> {\n const existingConfig = await this.getConfirmationConfig(nearAccountId);\n const confirmationConfig = { ...existingConfig, theme };\n await this.updatePreferences(nearAccountId, { confirmationConfig });\n }\n\n /**\n * Get user's theme with fallback to 'dark'\n * @param nearAccountId - The user's account ID\n * @returns 'dark' | 'light'\n */\n async getThemeOrDefault(nearAccountId: AccountId): Promise<'dark' | 'light'> {\n const theme = await this.getTheme(nearAccountId);\n return theme || 'dark';\n }\n\n /**\n * Toggle between dark and light theme for a user\n * @param nearAccountId - The user's account ID\n * @returns The new theme that was set\n */\n async toggleTheme(nearAccountId: AccountId): Promise<'dark' | 'light'> {\n const currentTheme = await this.getThemeOrDefault(nearAccountId);\n const newTheme = currentTheme === 'dark' ? 'light' : 'dark';\n await this.setTheme(nearAccountId, newTheme);\n return newTheme;\n }\n\n // === DERIVED ADDRESS METHODS ===\n\n /**\n * Store a derived address for a given NEAR account + contract + path\n */\n async setDerivedAddress(nearAccountId: AccountId, args: { contractId: string; path: string; address: string }): Promise<void> {\n if (!nearAccountId || !args?.contractId || !args?.path || !args?.address) return;\n const validation = this.validateNearAccountId(nearAccountId);\n if (!validation.valid) return;\n const rec: DerivedAddressRecord = {\n nearAccountId: toAccountId(nearAccountId),\n contractId: String(args.contractId),\n path: String(args.path),\n address: String(args.address),\n updatedAt: Date.now(),\n };\n const db = await this.getDB();\n await db.put(DB_CONFIG.derivedAddressStore, rec);\n }\n\n /**\n * Fetch a derived address record; returns null if not found\n */\n async getDerivedAddressRecord(nearAccountId: AccountId, args: { contractId: string; path: string }): Promise<DerivedAddressRecord | null> {\n if (!nearAccountId || !args?.contractId || !args?.path) return null;\n const db = await this.getDB();\n const rec = await db.get(DB_CONFIG.derivedAddressStore, [toAccountId(nearAccountId), String(args.contractId), String(args.path)]);\n return (rec as DerivedAddressRecord) || null;\n }\n\n /**\n * Get only the derived address string; returns null if not set\n */\n async getDerivedAddress(nearAccountId: AccountId, args: { contractId: string; path: string }): Promise<string | null> {\n const rec = await this.getDerivedAddressRecord(nearAccountId, args);\n return rec?.address || null;\n }\n\n // === RECOVERY EMAIL METHODS ===\n\n /**\n * Upsert recovery email records for an account.\n * Merges by hashHex, preferring the most recent email.\n */\n async upsertRecoveryEmails(\n nearAccountId: AccountId,\n entries: Array<{ hashHex: string; email: string }>\n ): Promise<void> {\n if (!nearAccountId || !entries?.length) return;\n const validation = this.validateNearAccountId(nearAccountId);\n if (!validation.valid) return;\n\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n const now = Date.now();\n\n for (const entry of entries) {\n const hashHex = String(entry?.hashHex || '').trim();\n const email = String(entry?.email || '').trim();\n if (!hashHex || !email) continue;\n\n const rec: RecoveryEmailRecord = {\n nearAccountId: accountId,\n hashHex,\n email,\n addedAt: now,\n };\n await db.put(DB_CONFIG.recoveryEmailStore, rec);\n }\n }\n\n /**\n * Fetch all recovery email records for an account.\n */\n async getRecoveryEmails(nearAccountId: AccountId): Promise<RecoveryEmailRecord[]> {\n if (!nearAccountId) return [];\n const db = await this.getDB();\n const accountId = toAccountId(nearAccountId);\n const tx = db.transaction(DB_CONFIG.recoveryEmailStore, 'readonly');\n const store = tx.objectStore(DB_CONFIG.recoveryEmailStore);\n const index = store.index('nearAccountId');\n const result = await index.getAll(accountId);\n return (result as RecoveryEmailRecord[]) || [];\n }\n\n /**\n * Atomic operation wrapper for multiple IndexedDB operations\n * Either all operations succeed or all are rolled back\n */\n async atomicOperation<T>(operation: (db: IDBPDatabase) => Promise<T>): Promise<T> {\n const db = await this.getDB();\n try {\n const result = await operation(db);\n return result;\n } catch (error) {\n console.error('Atomic operation failed:', error);\n throw error;\n }\n }\n\n /**\n * Complete rollback of user registration data\n * Deletes user, authenticators, and WebAuthn data atomically\n */\n async rollbackUserRegistration(nearAccountId: AccountId): Promise<void> {\n console.debug(`Rolling back registration data for ${nearAccountId}`);\n\n await this.atomicOperation(async (db) => {\n // Delete all authenticators for this user\n await this.deleteAllAuthenticatorsForUser(nearAccountId);\n\n // Delete user record\n await db.delete(DB_CONFIG.userStore, nearAccountId);\n\n // Clear from app state if this was the last user\n const lastUserAccount = await this.getAppState<string>('lastUserAccountId');\n if (lastUserAccount === nearAccountId) {\n await this.setAppState('lastUserAccountId', null);\n }\n\n console.debug(`Rolled back all registration data for ${nearAccountId}`);\n return true;\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,11 +2,12 @@ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
|
|
|
2
2
|
const require_validation = require('./WalletIframe/validation.js');
|
|
3
3
|
const require_base64 = require('../utils/base64.js');
|
|
4
4
|
const require_errors = require('../utils/errors.js');
|
|
5
|
-
require('../utils/index.js');
|
|
5
|
+
const require_index = require('../utils/index.js');
|
|
6
6
|
const require_rpc = require('./types/rpc.js');
|
|
7
7
|
const require_NearRpcError = require('./NearRpcError.js');
|
|
8
8
|
|
|
9
9
|
//#region src/core/NearClient.ts
|
|
10
|
+
require_index.init_utils();
|
|
10
11
|
require_errors.init_errors();
|
|
11
12
|
require_rpc.init_rpc();
|
|
12
13
|
require_validation.init_validation();
|