@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signTransactionsWithActions.js","names":["txSigningRequests: TransactionPayload[]","error: unknown"],"sources":["../../../../../../../../../src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.ts"],"sourcesContent":["\nimport { SignedTransaction } from '../../../NearClient';\nimport { TransactionInputWasm, validateActionArgsWasm } from '../../../types/actions';\nimport { type onProgressEvents } from '../../../types/sdkSentEvents';\nimport type { ConfirmationConfig } from '../../../types/signer-worker';\nimport {\n WorkerRequestType,\n TransactionPayload,\n isSignTransactionsWithActionsSuccess,\n} from '../../../types/signer-worker';\nimport { AccountId } from \"../../../types/accountIds\";\nimport { SignerWorkerManagerContext } from '..';\nimport { RpcCallPayload } from '../../../types/signer-worker';\nimport { PASSKEY_MANAGER_DEFAULT_CONFIGS } from '../../../defaultConfigs';\nimport { toAccountId } from '../../../types/accountIds';\nimport { getLastLoggedInDeviceNumber } from '../getDeviceNumber';\nimport { isObject } from '../../../WalletIframe/validation';\nimport { generateSessionId } from '../sessionHandshake.js';\n\n/**\n * Sign multiple transactions with shared VRF challenge and credential\n * Efficiently processes multiple transactions with one PRF authentication\n */\nexport async function signTransactionsWithActions({\n ctx,\n transactions,\n rpcCall,\n onEvent,\n confirmationConfigOverride,\n title,\n body,\n sessionId: providedSessionId,\n}: {\n ctx: SignerWorkerManagerContext,\n transactions: TransactionInputWasm[],\n rpcCall: RpcCallPayload;\n onEvent?: (update: onProgressEvents) => void;\n // Allow callers to pass a partial override (e.g., { uiMode: 'drawer' })\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n title?: string;\n body?: string;\n sessionId?: string;\n}): Promise<Array<{\n signedTransaction: SignedTransaction;\n nearAccountId: AccountId;\n logs?: string[]\n}>> {\n try {\n if (transactions.length === 0) {\n throw new Error('No transactions provided for batch signing');\n }\n\n const sessionId = providedSessionId ?? generateSessionId();\n const nearAccountId = rpcCall.nearAccountId;\n\n // Validate all actions in all payloads\n transactions.forEach((txPayload, txIndex) => {\n txPayload.actions.forEach((action, actionIndex) => {\n try {\n validateActionArgsWasm(action);\n } catch (error) {\n throw new Error(`Transaction ${txIndex}, Action ${actionIndex} validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n });\n });\n\n // Retrieve encrypted key data from IndexedDB in main thread\n console.debug('WebAuthnManager: Retrieving encrypted key from IndexedDB for account:', nearAccountId);\n const deviceNumber = await getLastLoggedInDeviceNumber(nearAccountId, ctx.indexedDB.clientDB);\n const encryptedKeyData = await ctx.indexedDB.nearKeysDB.getEncryptedKey(nearAccountId, deviceNumber);\n\n if (!encryptedKeyData) {\n throw new Error(`No encrypted key found for account: ${nearAccountId}`);\n }\n\n // Normalize rpcCall to ensure required fields are present\n const resolvedRpcCall = {\n contractId: rpcCall.contractId || PASSKEY_MANAGER_DEFAULT_CONFIGS.contractId,\n nearRpcUrl: rpcCall.nearRpcUrl || (PASSKEY_MANAGER_DEFAULT_CONFIGS.nearRpcUrl.split(',')[0] || PASSKEY_MANAGER_DEFAULT_CONFIGS.nearRpcUrl),\n nearAccountId: rpcCall.nearAccountId,\n } as RpcCallPayload;\n\n // Confirm via VRF-driven flow before sending anything to the signer worker.\n // WrapKeySeed derivation is handled inside confirmTxFlow (handleTransactionSigningFlow),\n // which uses the same sessionId/requestId and delivers WrapKeySeed over the reserved port.\n if (!ctx.vrfWorkerManager) {\n throw new Error('VrfWorkerManager not available for signing');\n }\n const confirmation = await ctx.vrfWorkerManager.confirmAndPrepareSigningSession({\n ctx,\n sessionId,\n kind: 'transaction',\n txSigningRequests: transactions,\n rpcCall: resolvedRpcCall,\n confirmationConfigOverride,\n title,\n body,\n });\n\n const intentDigest = confirmation.intentDigest;\n const transactionContext = confirmation.transactionContext;\n const credential = confirmation.credential ? JSON.stringify(confirmation.credential) : undefined;\n\n // Create transaction signing requests\n // NOTE: nonce and blockHash are computed in confirmation flow, not here\n const txSigningRequests: TransactionPayload[] = transactions.map(tx => ({\n nearAccountId: rpcCall.nearAccountId,\n receiverId: tx.receiverId,\n actions: tx.actions\n }));\n\n // Send batch signing request to WASM worker\n const response = await ctx.sendMessage({\n sessionId,\n message: {\n type: WorkerRequestType.SignTransactionsWithActions,\n payload: {\n rpcCall: resolvedRpcCall,\n createdAt: Date.now(),\n decryption: {\n encryptedPrivateKeyData: encryptedKeyData.encryptedData,\n encryptedPrivateKeyChacha20NonceB64u: encryptedKeyData.chacha20NonceB64u,\n },\n txSigningRequests: txSigningRequests,\n intentDigest,\n transactionContext,\n credential,\n }\n },\n onEvent,\n });\n\n if (!isSignTransactionsWithActionsSuccess(response)) {\n console.error('WebAuthnManager: Batch transaction signing failed:', response);\n const payloadError = isObject(response?.payload) && (response as any)?.payload?.error;\n throw new Error(payloadError || 'Batch transaction signing failed');\n }\n if (!response.payload.success) {\n throw new Error(response.payload.error || 'Batch transaction signing failed');\n }\n // Extract arrays from the single result - wasmResult contains arrays of all transactions\n const signedTransactions = response.payload.signedTransactions || [];\n if (signedTransactions.length !== transactions.length) {\n throw new Error(`Expected ${transactions.length} signed transactions but received ${signedTransactions.length}`);\n }\n\n // Process results for each transaction using WASM types directly\n const results = signedTransactions.map((signedTx, index) => {\n if (!signedTx || !signedTx.transaction || !signedTx.signature) {\n throw new Error(`Incomplete signed transaction data received for transaction ${index + 1}`);\n }\n return {\n signedTransaction: new SignedTransaction({\n transaction: signedTx.transaction,\n signature: signedTx.signature,\n borsh_bytes: Array.from(signedTx.borshBytes || [])\n }),\n nearAccountId: toAccountId(nearAccountId),\n logs: response.payload.logs\n };\n });\n\n return results;\n\n } catch (error: unknown) {\n console.error('WebAuthnManager: Batch transaction signing error:', error);\n throw error;\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"signTransactionsWithActions.js","names":["txSigningRequests: TransactionPayload[]","error: unknown"],"sources":["../../../../../../../../../src/core/WebAuthnManager/SignerWorkerManager/handlers/signTransactionsWithActions.ts"],"sourcesContent":["\nimport { SignedTransaction } from '../../../NearClient';\nimport { TransactionInputWasm, validateActionArgsWasm } from '../../../types/actions';\nimport { type onProgressEvents } from '../../../types/sdkSentEvents';\nimport type { ConfirmationConfig } from '../../../types/signer-worker';\nimport {\n WorkerRequestType,\n TransactionPayload,\n isSignTransactionsWithActionsSuccess,\n} from '../../../types/signer-worker';\nimport { AccountId } from \"../../../types/accountIds\";\nimport { SignerWorkerManagerContext } from '..';\nimport { RpcCallPayload } from '../../../types/signer-worker';\nimport { PASSKEY_MANAGER_DEFAULT_CONFIGS } from '../../../defaultConfigs';\nimport { toAccountId } from '../../../types/accountIds';\nimport { getLastLoggedInDeviceNumber } from '../getDeviceNumber';\nimport { isObject } from '../../../WalletIframe/validation';\nimport { generateSessionId } from '../sessionHandshake.js';\n\n/**\n * Sign multiple transactions with shared VRF challenge and credential\n * Efficiently processes multiple transactions with one PRF authentication\n */\nexport async function signTransactionsWithActions({\n ctx,\n transactions,\n rpcCall,\n onEvent,\n confirmationConfigOverride,\n title,\n body,\n sessionId: providedSessionId,\n}: {\n ctx: SignerWorkerManagerContext,\n transactions: TransactionInputWasm[],\n rpcCall: RpcCallPayload;\n onEvent?: (update: onProgressEvents) => void;\n // Allow callers to pass a partial override (e.g., { uiMode: 'drawer' })\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n title?: string;\n body?: string;\n sessionId?: string;\n}): Promise<Array<{\n signedTransaction: SignedTransaction;\n nearAccountId: AccountId;\n logs?: string[]\n}>> {\n try {\n if (transactions.length === 0) {\n throw new Error('No transactions provided for batch signing');\n }\n\n const sessionId = providedSessionId ?? generateSessionId();\n const nearAccountId = rpcCall.nearAccountId;\n\n // Validate all actions in all payloads\n transactions.forEach((txPayload, txIndex) => {\n txPayload.actions.forEach((action, actionIndex) => {\n try {\n validateActionArgsWasm(action);\n } catch (error) {\n throw new Error(`Transaction ${txIndex}, Action ${actionIndex} validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n });\n });\n\n // Retrieve encrypted key data from IndexedDB in main thread\n console.debug('WebAuthnManager: Retrieving encrypted key from IndexedDB for account:', nearAccountId);\n const deviceNumber = await getLastLoggedInDeviceNumber(nearAccountId, ctx.indexedDB.clientDB);\n const encryptedKeyData = await ctx.indexedDB.nearKeysDB.getEncryptedKey(nearAccountId, deviceNumber);\n\n if (!encryptedKeyData) {\n throw new Error(`No encrypted key found for account: ${nearAccountId}`);\n }\n\n // Normalize rpcCall to ensure required fields are present\n const resolvedRpcCall = {\n contractId: rpcCall.contractId || PASSKEY_MANAGER_DEFAULT_CONFIGS.contractId,\n nearRpcUrl: rpcCall.nearRpcUrl || (PASSKEY_MANAGER_DEFAULT_CONFIGS.nearRpcUrl.split(',')[0] || PASSKEY_MANAGER_DEFAULT_CONFIGS.nearRpcUrl),\n nearAccountId: rpcCall.nearAccountId,\n } as RpcCallPayload;\n\n // Confirm via VRF-driven flow before sending anything to the signer worker.\n // WrapKeySeed derivation is handled inside confirmTxFlow (handleTransactionSigningFlow),\n // which uses the same sessionId/requestId and delivers WrapKeySeed over the reserved port.\n if (!ctx.vrfWorkerManager) {\n throw new Error('VrfWorkerManager not available for signing');\n }\n const confirmation = await ctx.vrfWorkerManager.confirmAndPrepareSigningSession({\n ctx,\n sessionId,\n kind: 'transaction',\n txSigningRequests: transactions,\n rpcCall: resolvedRpcCall,\n confirmationConfigOverride,\n title,\n body,\n });\n\n const intentDigest = confirmation.intentDigest;\n const transactionContext = confirmation.transactionContext;\n const credential = confirmation.credential ? JSON.stringify(confirmation.credential) : undefined;\n\n // Create transaction signing requests\n // NOTE: nonce and blockHash are computed in confirmation flow, not here\n const txSigningRequests: TransactionPayload[] = transactions.map(tx => ({\n nearAccountId: rpcCall.nearAccountId,\n receiverId: tx.receiverId,\n actions: tx.actions\n }));\n\n // Send batch signing request to WASM worker\n const response = await ctx.sendMessage({\n sessionId,\n message: {\n type: WorkerRequestType.SignTransactionsWithActions,\n payload: {\n rpcCall: resolvedRpcCall,\n createdAt: Date.now(),\n decryption: {\n encryptedPrivateKeyData: encryptedKeyData.encryptedData,\n encryptedPrivateKeyChacha20NonceB64u: encryptedKeyData.chacha20NonceB64u,\n },\n txSigningRequests: txSigningRequests,\n intentDigest,\n transactionContext,\n credential,\n }\n },\n onEvent,\n });\n\n if (!isSignTransactionsWithActionsSuccess(response)) {\n console.error('WebAuthnManager: Batch transaction signing failed:', response);\n const payloadError = isObject(response?.payload) && (response as any)?.payload?.error;\n throw new Error(payloadError || 'Batch transaction signing failed');\n }\n if (!response.payload.success) {\n throw new Error(response.payload.error || 'Batch transaction signing failed');\n }\n // Extract arrays from the single result - wasmResult contains arrays of all transactions\n const signedTransactions = response.payload.signedTransactions || [];\n if (signedTransactions.length !== transactions.length) {\n throw new Error(`Expected ${transactions.length} signed transactions but received ${signedTransactions.length}`);\n }\n\n // Process results for each transaction using WASM types directly\n const results = signedTransactions.map((signedTx, index) => {\n if (!signedTx || !signedTx.transaction || !signedTx.signature) {\n throw new Error(`Incomplete signed transaction data received for transaction ${index + 1}`);\n }\n return {\n signedTransaction: new SignedTransaction({\n transaction: signedTx.transaction,\n signature: signedTx.signature,\n borsh_bytes: Array.from(signedTx.borshBytes || [])\n }),\n nearAccountId: toAccountId(nearAccountId),\n logs: response.payload.logs\n };\n });\n\n return results;\n\n } catch (error: unknown) {\n console.error('WebAuthnManager: Batch transaction signing error:', error);\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,eAAsB,4BAA4B,EAChD,KACA,cACA,SACA,SACA,4BACA,OACA,MACA,WAAW,qBAeT;AACF,KAAI;AACF,MAAI,aAAa,WAAW,EAC1B,OAAM,IAAI,MAAM;EAGlB,MAAM,YAAY,qBAAqB;EACvC,MAAM,gBAAgB,QAAQ;AAG9B,eAAa,SAAS,WAAW,YAAY;AAC3C,aAAU,QAAQ,SAAS,QAAQ,gBAAgB;AACjD,QAAI;AACF,4BAAuB;aAChB,OAAO;AACd,WAAM,IAAI,MAAM,eAAe,QAAQ,WAAW,YAAY,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU;;;;AAMnI,UAAQ,MAAM,yEAAyE;EACvF,MAAM,eAAe,MAAM,4BAA4B,eAAe,IAAI,UAAU;EACpF,MAAM,mBAAmB,MAAM,IAAI,UAAU,WAAW,gBAAgB,eAAe;AAEvF,MAAI,CAAC,iBACH,OAAM,IAAI,MAAM,uCAAuC;EAIzD,MAAM,kBAAkB;GACtB,YAAY,QAAQ,cAAc,gCAAgC;GAClE,YAAY,QAAQ,cAAe,gCAAgC,WAAW,MAAM,KAAK,MAAM,gCAAgC;GAC/H,eAAe,QAAQ;;AAMzB,MAAI,CAAC,IAAI,iBACP,OAAM,IAAI,MAAM;EAElB,MAAM,eAAe,MAAM,IAAI,iBAAiB,gCAAgC;GAC9E;GACA;GACA,MAAM;GACN,mBAAmB;GACnB,SAAS;GACT;GACA;GACA;;EAGF,MAAM,eAAe,aAAa;EAClC,MAAM,qBAAqB,aAAa;EACxC,MAAM,aAAa,aAAa,aAAa,KAAK,UAAU,aAAa,cAAc;EAIvF,MAAMA,oBAA0C,aAAa,KAAI,QAAO;GACtE,eAAe,QAAQ;GACvB,YAAY,GAAG;GACf,SAAS,GAAG;;EAId,MAAM,WAAW,MAAM,IAAI,YAAY;GACrC;GACA,SAAS;IACP,MAAM,kBAAkB;IACxB,SAAS;KACP,SAAS;KACT,WAAW,KAAK;KAChB,YAAY;MACV,yBAAyB,iBAAiB;MAC1C,sCAAsC,iBAAiB;;KAEtC;KACnB;KACA;KACA;;;GAGJ;;AAGF,MAAI,CAAC,qCAAqC,WAAW;AACnD,WAAQ,MAAM,sDAAsD;GACpE,MAAM,eAAe,SAAS,UAAU,YAAa,UAAkB,SAAS;AAChF,SAAM,IAAI,MAAM,gBAAgB;;AAElC,MAAI,CAAC,SAAS,QAAQ,QACpB,OAAM,IAAI,MAAM,SAAS,QAAQ,SAAS;EAG5C,MAAM,qBAAqB,SAAS,QAAQ,sBAAsB;AAClE,MAAI,mBAAmB,WAAW,aAAa,OAC7C,OAAM,IAAI,MAAM,YAAY,aAAa,OAAO,oCAAoC,mBAAmB;EAIzG,MAAM,UAAU,mBAAmB,KAAK,UAAU,UAAU;AAC1D,OAAI,CAAC,YAAY,CAAC,SAAS,eAAe,CAAC,SAAS,UAClD,OAAM,IAAI,MAAM,+DAA+D,QAAQ;AAEzF,UAAO;IACL,mBAAmB,IAAI,kBAAkB;KACvC,aAAa,SAAS;KACtB,WAAW,SAAS;KACpB,aAAa,MAAM,KAAK,SAAS,cAAc;;IAEjD,eAAe,YAAY;IAC3B,MAAM,SAAS,QAAQ;;;AAI3B,SAAO;UAEAC,OAAgB;AACvB,UAAQ,MAAM,qDAAqD;AACnE,QAAM"}
|
package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { assertString, init_validation, isObject } from "../../../WalletIframe/validation.js";
|
|
2
2
|
import { base58Encode, init_base58 } from "../../../../utils/base58.js";
|
|
3
|
-
import { validateVRFChallenge } from "../../../types/vrf-worker.js";
|
|
4
|
-
import { normalizeRegistrationCredential } from "../../credentialsHelpers.js";
|
|
3
|
+
import { init_vrf_worker, validateVRFChallenge } from "../../../types/vrf-worker.js";
|
|
4
|
+
import { init_credentialsHelpers, normalizeRegistrationCredential } from "../../credentialsHelpers.js";
|
|
5
5
|
|
|
6
6
|
//#region src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.ts
|
|
7
|
+
init_credentialsHelpers();
|
|
8
|
+
init_vrf_worker();
|
|
7
9
|
init_validation();
|
|
8
10
|
init_base58();
|
|
9
11
|
function validateTransactionContextMaybe(input) {
|
package/dist/esm/react/sdk/src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","names":[],"sources":["../../../../../../../../../src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.ts"],"sourcesContent":["import { normalizeRegistrationCredential } from '../../credentialsHelpers';\nimport type { WebAuthnRegistrationCredential } from '../../../types/webauthn';\nimport { validateVRFChallenge, type VRFChallenge } from '../../../types/vrf-worker';\nimport type { TransactionContext } from '../../../types/rpc';\nimport { isObject, assertString } from '../../../WalletIframe/validation';\nimport { DelegateActionInput } from '../../../types/delegate';\nimport { base58Encode } from '../../../../utils/base58';\n\n// Strongly typed payload expected from the WASM → JS boundary\nexport interface RegistrationCredentialConfirmationPayload {\n confirmed: boolean;\n requestId: string;\n intentDigest: string;\n credential: WebAuthnRegistrationCredential; // serialized PublicKeyCredential (no methods)\n vrfChallenge: VRFChallenge;\n transactionContext?: TransactionContext;\n error?: string;\n}\n\nfunction validateTransactionContextMaybe(input: unknown): TransactionContext | undefined {\n if (input == null) return undefined;\n if (!isObject(input)) {\n throw new Error('Invalid transactionContext: expected object');\n }\n\n const {\n nearPublicKeyStr,\n nextNonce,\n txBlockHeight,\n txBlockHash,\n accessKeyInfo,\n } = input as {\n nearPublicKeyStr?: unknown;\n nextNonce?: unknown;\n txBlockHeight?: unknown;\n txBlockHash?: unknown;\n accessKeyInfo?: unknown;\n };\n\n // Minimal structural validation; AccessKeyView is complex. Be tolerant because the WASM struct omits it.\n const normalizedNearPublicKeyStr = assertString(\n nearPublicKeyStr,\n 'transactionContext.nearPublicKeyStr',\n );\n const normalizedNextNonce = assertString(nextNonce, 'transactionContext.nextNonce');\n const normalizedTxBlockHeight = assertString(\n txBlockHeight,\n 'transactionContext.txBlockHeight',\n );\n const normalizedTxBlockHash = assertString(txBlockHash, 'transactionContext.txBlockHash');\n\n let normalizedAccessKeyInfo = accessKeyInfo as TransactionContext['accessKeyInfo'] | undefined;\n if (normalizedAccessKeyInfo != null && !isObject(normalizedAccessKeyInfo)) {\n throw new Error('Invalid transactionContext.accessKeyInfo: expected object');\n }\n if (normalizedAccessKeyInfo == null) {\n // Synthesize a minimal placeholder; not used by registration flows consuming this payload\n normalizedAccessKeyInfo = { nonce: 0 } as unknown as TransactionContext['accessKeyInfo'];\n }\n\n return {\n nearPublicKeyStr: normalizedNearPublicKeyStr,\n nextNonce: normalizedNextNonce,\n txBlockHeight: normalizedTxBlockHeight,\n txBlockHash: normalizedTxBlockHash,\n accessKeyInfo: normalizedAccessKeyInfo,\n };\n}\n\nfunction validateCredentialMaybe(input: unknown): WebAuthnRegistrationCredential | undefined {\n if (input == null) return undefined;\n\n const cred = normalizeRegistrationCredential(input);\n if (cred.type !== 'public-key') {\n throw new Error('Invalid credential.type: expected \"public-key\"');\n }\n\n const { id, rawId, response, authenticatorAttachment } = cred as {\n id?: unknown;\n rawId?: unknown;\n response?: unknown;\n authenticatorAttachment?: unknown;\n };\n\n // Core field/type validation (serialized shapes should be base64url strings)\n assertString(id, 'credential.id');\n assertString(rawId, 'credential.rawId');\n\n if (!isObject(response)) {\n throw new Error('Invalid credential.response: expected object');\n }\n\n const {\n clientDataJSON,\n attestationObject,\n transports,\n } = response as {\n clientDataJSON?: unknown;\n attestationObject?: unknown;\n transports?: unknown;\n };\n\n assertString(clientDataJSON, 'credential.response.clientDataJSON');\n assertString(attestationObject, 'credential.response.attestationObject');\n\n if (!Array.isArray(transports)) {\n throw new Error('Invalid credential.response.transports: expected string[]');\n }\n for (const t of transports) {\n if (typeof t !== 'string') {\n throw new Error('Invalid credential.response.transports item: expected string');\n }\n }\n\n if (authenticatorAttachment != null && typeof authenticatorAttachment !== 'string') {\n throw new Error('Invalid credential.authenticatorAttachment: expected string | undefined');\n }\n\n // Note: prf.results may be undefined/null here. We intentionally do NOT\n // require them at the boundary; internal callers that need PRF (e.g. key\n // derivation) will extract/compute them separately. Contract payloads must\n // not include PRF values.\n return cred;\n}\n\nfunction validateVrfChallengeMaybe(input: unknown): VRFChallenge | undefined {\n if (input == null) return undefined;\n return validateVRFChallenge(input as Parameters<typeof validateVRFChallenge>[0]);\n}\n\nexport function parseAndValidateRegistrationCredentialConfirmationPayload(\n payload: unknown,\n): RegistrationCredentialConfirmationPayload {\n\n if (!isObject(payload)) {\n throw new Error('Invalid response payload: expected object');\n }\n\n const {\n confirmed,\n requestId,\n intentDigest,\n credential,\n vrfChallenge,\n transactionContext,\n error,\n } = payload as {\n confirmed?: unknown;\n requestId?: unknown;\n intentDigest?: unknown;\n credential?: unknown;\n vrfChallenge?: unknown;\n transactionContext?: unknown;\n error?: unknown;\n };\n\n const normalizedRequestId = assertString(requestId, 'requestId');\n\n // intentDigest is only used for TX signing requests, not registration or link device requests\n const normalizedIntentDigest =\n intentDigest == null ? '' : assertString(intentDigest, 'intentDigest');\n\n const normalizedCredential =\n credential != null ? validateCredentialMaybe(credential) : undefined;\n\n if (!normalizedCredential) {\n throw new Error('Missing registration credential');\n }\n\n const normalizedVrfChallenge =\n vrfChallenge != null ? validateVrfChallengeMaybe(vrfChallenge) : undefined;\n\n if (!normalizedVrfChallenge) {\n throw new Error('Missing VRF Challenge');\n }\n\n const normalizedTransactionContext =\n transactionContext != null ? validateTransactionContextMaybe(transactionContext) : undefined;\n\n const normalizedError =\n error == null ? undefined : assertString(error, 'error');\n\n return {\n confirmed: !!confirmed,\n requestId: normalizedRequestId,\n intentDigest: normalizedIntentDigest,\n credential: normalizedCredential,\n vrfChallenge: normalizedVrfChallenge,\n transactionContext: normalizedTransactionContext,\n error: normalizedError,\n };\n}\n\nexport const ensureEd25519Prefix = (value: string) => {\n return value.startsWith('ed25519:') ? value : `ed25519:${value}`\n}\n\nexport const toPublicKeyString = (pk: DelegateActionInput['publicKey']): string => {\n if (typeof pk === 'string') {\n return pk;\n }\n return ensureEd25519Prefix(base58Encode(pk.keyData));\n};"],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.js","names":[],"sources":["../../../../../../../../../src/core/WebAuthnManager/SignerWorkerManager/handlers/validation.ts"],"sourcesContent":["import { normalizeRegistrationCredential } from '../../credentialsHelpers';\nimport type { WebAuthnRegistrationCredential } from '../../../types/webauthn';\nimport { validateVRFChallenge, type VRFChallenge } from '../../../types/vrf-worker';\nimport type { TransactionContext } from '../../../types/rpc';\nimport { isObject, assertString } from '../../../WalletIframe/validation';\nimport { DelegateActionInput } from '../../../types/delegate';\nimport { base58Encode } from '../../../../utils/base58';\n\n// Strongly typed payload expected from the WASM → JS boundary\nexport interface RegistrationCredentialConfirmationPayload {\n confirmed: boolean;\n requestId: string;\n intentDigest: string;\n credential: WebAuthnRegistrationCredential; // serialized PublicKeyCredential (no methods)\n vrfChallenge: VRFChallenge;\n transactionContext?: TransactionContext;\n error?: string;\n}\n\nfunction validateTransactionContextMaybe(input: unknown): TransactionContext | undefined {\n if (input == null) return undefined;\n if (!isObject(input)) {\n throw new Error('Invalid transactionContext: expected object');\n }\n\n const {\n nearPublicKeyStr,\n nextNonce,\n txBlockHeight,\n txBlockHash,\n accessKeyInfo,\n } = input as {\n nearPublicKeyStr?: unknown;\n nextNonce?: unknown;\n txBlockHeight?: unknown;\n txBlockHash?: unknown;\n accessKeyInfo?: unknown;\n };\n\n // Minimal structural validation; AccessKeyView is complex. Be tolerant because the WASM struct omits it.\n const normalizedNearPublicKeyStr = assertString(\n nearPublicKeyStr,\n 'transactionContext.nearPublicKeyStr',\n );\n const normalizedNextNonce = assertString(nextNonce, 'transactionContext.nextNonce');\n const normalizedTxBlockHeight = assertString(\n txBlockHeight,\n 'transactionContext.txBlockHeight',\n );\n const normalizedTxBlockHash = assertString(txBlockHash, 'transactionContext.txBlockHash');\n\n let normalizedAccessKeyInfo = accessKeyInfo as TransactionContext['accessKeyInfo'] | undefined;\n if (normalizedAccessKeyInfo != null && !isObject(normalizedAccessKeyInfo)) {\n throw new Error('Invalid transactionContext.accessKeyInfo: expected object');\n }\n if (normalizedAccessKeyInfo == null) {\n // Synthesize a minimal placeholder; not used by registration flows consuming this payload\n normalizedAccessKeyInfo = { nonce: 0 } as unknown as TransactionContext['accessKeyInfo'];\n }\n\n return {\n nearPublicKeyStr: normalizedNearPublicKeyStr,\n nextNonce: normalizedNextNonce,\n txBlockHeight: normalizedTxBlockHeight,\n txBlockHash: normalizedTxBlockHash,\n accessKeyInfo: normalizedAccessKeyInfo,\n };\n}\n\nfunction validateCredentialMaybe(input: unknown): WebAuthnRegistrationCredential | undefined {\n if (input == null) return undefined;\n\n const cred = normalizeRegistrationCredential(input);\n if (cred.type !== 'public-key') {\n throw new Error('Invalid credential.type: expected \"public-key\"');\n }\n\n const { id, rawId, response, authenticatorAttachment } = cred as {\n id?: unknown;\n rawId?: unknown;\n response?: unknown;\n authenticatorAttachment?: unknown;\n };\n\n // Core field/type validation (serialized shapes should be base64url strings)\n assertString(id, 'credential.id');\n assertString(rawId, 'credential.rawId');\n\n if (!isObject(response)) {\n throw new Error('Invalid credential.response: expected object');\n }\n\n const {\n clientDataJSON,\n attestationObject,\n transports,\n } = response as {\n clientDataJSON?: unknown;\n attestationObject?: unknown;\n transports?: unknown;\n };\n\n assertString(clientDataJSON, 'credential.response.clientDataJSON');\n assertString(attestationObject, 'credential.response.attestationObject');\n\n if (!Array.isArray(transports)) {\n throw new Error('Invalid credential.response.transports: expected string[]');\n }\n for (const t of transports) {\n if (typeof t !== 'string') {\n throw new Error('Invalid credential.response.transports item: expected string');\n }\n }\n\n if (authenticatorAttachment != null && typeof authenticatorAttachment !== 'string') {\n throw new Error('Invalid credential.authenticatorAttachment: expected string | undefined');\n }\n\n // Note: prf.results may be undefined/null here. We intentionally do NOT\n // require them at the boundary; internal callers that need PRF (e.g. key\n // derivation) will extract/compute them separately. Contract payloads must\n // not include PRF values.\n return cred;\n}\n\nfunction validateVrfChallengeMaybe(input: unknown): VRFChallenge | undefined {\n if (input == null) return undefined;\n return validateVRFChallenge(input as Parameters<typeof validateVRFChallenge>[0]);\n}\n\nexport function parseAndValidateRegistrationCredentialConfirmationPayload(\n payload: unknown,\n): RegistrationCredentialConfirmationPayload {\n\n if (!isObject(payload)) {\n throw new Error('Invalid response payload: expected object');\n }\n\n const {\n confirmed,\n requestId,\n intentDigest,\n credential,\n vrfChallenge,\n transactionContext,\n error,\n } = payload as {\n confirmed?: unknown;\n requestId?: unknown;\n intentDigest?: unknown;\n credential?: unknown;\n vrfChallenge?: unknown;\n transactionContext?: unknown;\n error?: unknown;\n };\n\n const normalizedRequestId = assertString(requestId, 'requestId');\n\n // intentDigest is only used for TX signing requests, not registration or link device requests\n const normalizedIntentDigest =\n intentDigest == null ? '' : assertString(intentDigest, 'intentDigest');\n\n const normalizedCredential =\n credential != null ? validateCredentialMaybe(credential) : undefined;\n\n if (!normalizedCredential) {\n throw new Error('Missing registration credential');\n }\n\n const normalizedVrfChallenge =\n vrfChallenge != null ? validateVrfChallengeMaybe(vrfChallenge) : undefined;\n\n if (!normalizedVrfChallenge) {\n throw new Error('Missing VRF Challenge');\n }\n\n const normalizedTransactionContext =\n transactionContext != null ? validateTransactionContextMaybe(transactionContext) : undefined;\n\n const normalizedError =\n error == null ? undefined : assertString(error, 'error');\n\n return {\n confirmed: !!confirmed,\n requestId: normalizedRequestId,\n intentDigest: normalizedIntentDigest,\n credential: normalizedCredential,\n vrfChallenge: normalizedVrfChallenge,\n transactionContext: normalizedTransactionContext,\n error: normalizedError,\n };\n}\n\nexport const ensureEd25519Prefix = (value: string) => {\n return value.startsWith('ed25519:') ? value : `ed25519:${value}`\n}\n\nexport const toPublicKeyString = (pk: DelegateActionInput['publicKey']): string => {\n if (typeof pk === 'string') {\n return pk;\n }\n return ensureEd25519Prefix(base58Encode(pk.keyData));\n};"],"mappings":";;;;;;;;;;AAmBA,SAAS,gCAAgC,OAAgD;AACvF,KAAI,SAAS,KAAM,QAAO;AAC1B,KAAI,CAAC,SAAS,OACZ,OAAM,IAAI,MAAM;CAGlB,MAAM,EACJ,kBACA,WACA,eACA,aACA,kBACE;CASJ,MAAM,6BAA6B,aACjC,kBACA;CAEF,MAAM,sBAAsB,aAAa,WAAW;CACpD,MAAM,0BAA0B,aAC9B,eACA;CAEF,MAAM,wBAAwB,aAAa,aAAa;CAExD,IAAI,0BAA0B;AAC9B,KAAI,2BAA2B,QAAQ,CAAC,SAAS,yBAC/C,OAAM,IAAI,MAAM;AAElB,KAAI,2BAA2B,KAE7B,2BAA0B,EAAE,OAAO;AAGrC,QAAO;EACL,kBAAkB;EAClB,WAAW;EACX,eAAe;EACf,aAAa;EACb,eAAe;;;AAInB,SAAS,wBAAwB,OAA4D;AAC3F,KAAI,SAAS,KAAM,QAAO;CAE1B,MAAM,OAAO,gCAAgC;AAC7C,KAAI,KAAK,SAAS,aAChB,OAAM,IAAI,MAAM;CAGlB,MAAM,EAAE,IAAI,OAAO,UAAU,4BAA4B;AAQzD,cAAa,IAAI;AACjB,cAAa,OAAO;AAEpB,KAAI,CAAC,SAAS,UACZ,OAAM,IAAI,MAAM;CAGlB,MAAM,EACJ,gBACA,mBACA,eACE;AAMJ,cAAa,gBAAgB;AAC7B,cAAa,mBAAmB;AAEhC,KAAI,CAAC,MAAM,QAAQ,YACjB,OAAM,IAAI,MAAM;AAElB,MAAK,MAAM,KAAK,WACd,KAAI,OAAO,MAAM,SACf,OAAM,IAAI,MAAM;AAIpB,KAAI,2BAA2B,QAAQ,OAAO,4BAA4B,SACxE,OAAM,IAAI,MAAM;AAOlB,QAAO;;AAGT,SAAS,0BAA0B,OAA0C;AAC3E,KAAI,SAAS,KAAM,QAAO;AAC1B,QAAO,qBAAqB;;AAG9B,SAAgB,0DACd,SAC2C;AAE3C,KAAI,CAAC,SAAS,SACZ,OAAM,IAAI,MAAM;CAGlB,MAAM,EACJ,WACA,WACA,cACA,YACA,cACA,oBACA,UACE;CAUJ,MAAM,sBAAsB,aAAa,WAAW;CAGpD,MAAM,yBACJ,gBAAgB,OAAO,KAAK,aAAa,cAAc;CAEzD,MAAM,uBACJ,cAAc,OAAO,wBAAwB,cAAc;AAE7D,KAAI,CAAC,qBACH,OAAM,IAAI,MAAM;CAGlB,MAAM,yBACJ,gBAAgB,OAAO,0BAA0B,gBAAgB;AAEnE,KAAI,CAAC,uBACH,OAAM,IAAI,MAAM;CAGlB,MAAM,+BACJ,sBAAsB,OAAO,gCAAgC,sBAAsB;CAErF,MAAM,kBACJ,SAAS,OAAO,SAAY,aAAa,OAAO;AAElD,QAAO;EACL,WAAW,CAAC,CAAC;EACb,WAAW;EACX,cAAc;EACd,YAAY;EACZ,cAAc;EACd,oBAAoB;EACpB,OAAO;;;AAIX,MAAa,uBAAuB,UAAkB;AACpD,QAAO,MAAM,WAAW,cAAc,QAAQ,WAAW;;AAG3D,MAAa,qBAAqB,OAAiD;AACjF,KAAI,OAAO,OAAO,SAChB,QAAO;AAET,QAAO,oBAAoB,aAAa,GAAG"}
|
|
@@ -4,7 +4,7 @@ import { SIGNER_WORKER_MANAGER_CONFIG } from "../../../config.js";
|
|
|
4
4
|
import { init_validation, isObject } from "../../WalletIframe/validation.js";
|
|
5
5
|
import { resolveWorkerUrl } from "../../sdkPaths/workers.js";
|
|
6
6
|
import { init_errors, toError } from "../../../utils/errors.js";
|
|
7
|
-
import { TouchIdPrompt } from "../touchIdPrompt.js";
|
|
7
|
+
import { TouchIdPrompt, init_touchIdPrompt } from "../touchIdPrompt.js";
|
|
8
8
|
import { WorkerControlMessage } from "../../workerControlMessages.js";
|
|
9
9
|
import { isSignerWorkerControlMessage } from "./sessionMessages.js";
|
|
10
10
|
import { checkCanRegisterUser } from "./handlers/checkCanRegisterUser.js";
|
|
@@ -25,6 +25,7 @@ import { exportNearKeypairUi } from "./handlers/exportNearKeypairUi.js";
|
|
|
25
25
|
init_IndexedDBManager();
|
|
26
26
|
init_validation();
|
|
27
27
|
init_signer_worker();
|
|
28
|
+
init_touchIdPrompt();
|
|
28
29
|
init_errors();
|
|
29
30
|
/**
|
|
30
31
|
* WebAuthnWorkers handles PRF, workers, and COSE operations
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["vrfPort: MessagePort | undefined","error: unknown","promises: Promise<void>[]","responses: WorkerResponseForRequest<T>[]"],"sources":["../../../../../../../../src/core/WebAuthnManager/SignerWorkerManager/index.ts"],"sourcesContent":["import { SIGNER_WORKER_MANAGER_CONFIG } from \"../../../config\";\nimport { ClientAuthenticatorData, UnifiedIndexedDBManager } from '../../IndexedDBManager';\nimport { IndexedDBManager } from '../../IndexedDBManager';\nimport { SignedTransaction, type NearClient } from '../../NearClient';\nimport { isObject } from '../../WalletIframe/validation';\nimport { resolveWorkerUrl } from '../../sdkPaths';\nimport {\n WorkerRequestType,\n WorkerResponseForRequest,\n isWorkerProgress,\n isWorkerError,\n isWorkerSuccess,\n WorkerProgressResponse,\n WorkerErrorResponse,\n WorkerRequestTypeMap,\n} from '../../types/signer-worker';\nimport { VrfWorkerManager } from '../VrfWorkerManager';\nimport { VRFChallenge } from '../../types/vrf-worker';\nimport type { ActionArgsWasm, TransactionInputWasm } from '../../types/actions';\nimport type { DelegateActionInput } from '../../types/delegate';\nimport type { onProgressEvents } from '../../types/sdkSentEvents';\nimport type { AuthenticatorOptions } from '../../types/authenticatorOptions';\nimport { AccountId } from \"../../types/accountIds\";\nimport { TransactionContext } from '../../types/rpc';\nimport {\n ConfirmationConfig,\n WasmSignedDelegate,\n} from '../../types/signer-worker';\nimport { TouchIdPrompt } from \"../touchIdPrompt\";\nimport { isSignerWorkerControlMessage } from './sessionMessages';\nimport { WorkerControlMessage } from '../../workerControlMessages';\n\nimport {\n decryptPrivateKeyWithPrf,\n checkCanRegisterUser,\n signTransactionsWithActions,\n recoverKeypairFromPasskey,\n extractCosePublicKey,\n signTransactionWithKeyPair,\n signNep413Message,\n deriveNearKeypairAndEncryptFromSerialized,\n signDelegateAction,\n registerDevice2WithDerivedKey,\n exportNearKeypairUi,\n} from './handlers';\nimport { RpcCallPayload } from '../../types/signer-worker';\nimport { UserPreferencesManager } from '../userPreferences';\nimport { NonceManager } from '../../nonceManager';\nimport { WebAuthnAuthenticationCredential, WebAuthnRegistrationCredential } from '../../types';\nimport { toError } from '@/utils/errors';\nimport { withSessionId } from './handlers/session';\nimport { attachSessionPort } from './sessionHandshake.js';\n\ntype WithOptionalSessionId<T> = T extends { sessionId: string }\n ? Omit<T, 'sessionId'> & { sessionId?: string }\n : T;\n\ntype SigningSessionEntry = {\n worker: Worker;\n wrapKeySeedPort?: MessagePort;\n createdAt: number;\n};\n\nexport interface SignerWorkerManagerContext {\n touchIdPrompt: TouchIdPrompt;\n nearClient: NearClient;\n indexedDB: UnifiedIndexedDBManager;\n userPreferencesManager: UserPreferencesManager;\n nonceManager: NonceManager;\n rpIdOverride?: string;\n nearExplorerUrl?: string;\n vrfWorkerManager?: VrfWorkerManager;\n sendMessage: <T extends keyof WorkerRequestTypeMap>(args: {\n message: {\n type: T;\n payload: WithOptionalSessionId<WorkerRequestTypeMap[T]['request']>;\n };\n onEvent?: (update: onProgressEvents) => void;\n timeoutMs?: number;\n sessionId?: string;\n }) => Promise<WorkerResponseForRequest<T>>;\n};\n\n/**\n * WebAuthnWorkers handles PRF, workers, and COSE operations\n *\n * Note: Challenge store removed as VRF provides cryptographic freshness\n * without needing centralized challenge management\n */\nexport class SignerWorkerManager {\n\n private indexedDB: UnifiedIndexedDBManager;\n private touchIdPrompt: TouchIdPrompt;\n private vrfWorkerManager: VrfWorkerManager;\n private nearClient: NearClient;\n private userPreferencesManager: UserPreferencesManager;\n private nonceManager: NonceManager;\n private workerBaseOrigin: string | undefined;\n private nearExplorerUrl?: string;\n\n constructor(\n vrfWorkerManager: VrfWorkerManager,\n nearClient: NearClient,\n userPreferencesManager: UserPreferencesManager,\n nonceManager: NonceManager,\n rpIdOverride?: string,\n enableSafariGetWebauthnRegistrationFallback: boolean = true,\n nearExplorerUrl?: string,\n ) {\n this.indexedDB = IndexedDBManager;\n this.touchIdPrompt = new TouchIdPrompt(rpIdOverride, enableSafariGetWebauthnRegistrationFallback);\n this.vrfWorkerManager = vrfWorkerManager;\n this.nearClient = nearClient;\n this.userPreferencesManager = userPreferencesManager;\n this.nonceManager = nonceManager;\n this.nearExplorerUrl = nearExplorerUrl;\n }\n\n setWorkerBaseOrigin(origin: string | undefined): void {\n this.workerBaseOrigin = origin;\n }\n\n getContext(): SignerWorkerManagerContext {\n return {\n sendMessage: this.sendMessage.bind(this), // bind to access this.createSecureWorker\n indexedDB: this.indexedDB,\n touchIdPrompt: this.touchIdPrompt,\n vrfWorkerManager: this.vrfWorkerManager,\n nearClient: this.nearClient,\n userPreferencesManager: this.userPreferencesManager,\n nonceManager: this.nonceManager,\n rpIdOverride: this.touchIdPrompt.getRpId(),\n nearExplorerUrl: this.nearExplorerUrl,\n };\n }\n\n createSecureWorker(): Worker {\n const workerUrlStr = resolveWorkerUrl(\n SIGNER_WORKER_MANAGER_CONFIG.WORKER.URL,\n { worker: 'signer', baseOrigin: this.workerBaseOrigin }\n )\n try {\n const worker = new Worker(workerUrlStr, {\n type: SIGNER_WORKER_MANAGER_CONFIG.WORKER.TYPE,\n name: SIGNER_WORKER_MANAGER_CONFIG.WORKER.NAME\n });\n // minimal error handler in tests; avoid noisy logs\n worker.onerror = () => {};\n return worker;\n } catch (error) {\n // Do not silently downgrade to same‑origin. Cross‑origin workers must be\n // resolvable under the configured wallet origin with proper headers.\n // Surface a precise error so tests assert the real path.\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to create secure worker: ${msg}`);\n }\n }\n\n /**\n * Executes a worker operation by sending a message to the secure worker.\n * Handles progress updates via onEvent callback, supports both single and multiple response patterns.\n * Intercepts secure confirmation handshake messages for pluggable UI.\n * Resolves with the final worker response or rejects on error/timeout.\n *\n * @template T - Worker request type.\n * @param params.message - The message to send to the worker.\n * @param params.onEvent - Optional callback for progress events.\n * @param params.timeoutMs - Optional timeout in milliseconds.\n * @returns Promise resolving to the worker response for the request.\n */\n private workerPool: Worker[] = [];\n private readonly MAX_WORKER_POOL_SIZE = 3; // Increased for security model\n // Map of active signing sessions to reserved workers and optional WrapKeySeed ports\n private signingSessions: Map<string, SigningSessionEntry> = new Map();\n private readonly SIGNING_SESSION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\n private getWorkerFromPool(): Worker {\n if (this.workerPool.length > 0) {\n return this.workerPool.pop()!;\n }\n return this.createSecureWorker();\n }\n\n private terminateAndReplaceWorker(worker: Worker): void {\n // Always terminate workers to clear memory\n worker.terminate();\n // Asynchronously create a replacement worker for the pool\n this.createReplacementWorker();\n }\n\n /**\n * Reserve a signer worker \"session\"\n *\n * What this does:\n * - Reserves a specific `Worker` instance from the pool and pins it to `sessionId`.\n * - Ensures the signer worker has a dedicated `MessagePort` attached for receiving `WrapKeySeed`\n * from the VRF worker (VRF → Signer channel).\n *\n * Port wiring:\n * - The VRF worker retains one end of a `MessageChannel` and the signer worker receives the other.\n * - This method attaches the signer-facing port via a control message (`ATTACH_WRAP_KEY_SEED_PORT`)\n * and waits for an ACK (`ATTACH_WRAP_KEY_SEED_PORT_OK`) before exposing the session.\n *\n * @param sessionId - Session identifier used to correlate MessagePorts + ready signals.\n * @param opts.signerPort - Optional signer-facing `MessagePort` created/owned by the caller (VRF-created channel).\n * If omitted, this method creates a fresh `MessageChannel` and returns `vrfPort` so the\n * caller can transfer it to the VRF worker.\n * @returns `{ worker, signerPort, vrfPort }` where `vrfPort` is only present when we created the channel here.\n */\n async reserveSignerWorkerSession(sessionId: string, opts?: { signerPort?: MessagePort }): Promise<{ worker: Worker; signerPort?: MessagePort; vrfPort?: MessagePort }> {\n if (this.signingSessions.has(sessionId)) {\n throw new Error(`Signing session already exists for id: ${sessionId}`);\n }\n // Reserve a worker from the pool for this sessionId.\n const worker = this.getWorkerFromPool();\n let signerPort = opts?.signerPort;\n let vrfPort: MessagePort | undefined;\n if (!signerPort) {\n // If caller did not provide a signer-facing port, create a channel.\n // - port1 => signer worker (receiver)\n // - port2 => VRF worker (sender) returned to caller\n const channel = new MessageChannel();\n signerPort = channel.port1;\n vrfPort = channel.port2;\n }\n\n // Attach the signerPort to the worker and wait for ACK before adding to signingSessions\n try {\n if (!signerPort) {\n throw new Error('Missing signerPort for signing session');\n }\n\n // Use centralized handshake logic (registers listener, sends message, waits for ACK)\n await attachSessionPort(worker, sessionId, signerPort);\n\n // Only add to signingSessions after successful attachment\n // (prevents callers from observing a session that can't receive WrapKeySeed yet).\n this.signingSessions.set(sessionId, {\n worker,\n wrapKeySeedPort: signerPort,\n createdAt: Date.now(),\n });\n\n } catch (err) {\n console.error('[SignerWorkerManager]: Failed to attach WrapKeySeed port to signer worker', err);\n // Best-effort cleanup\n try { signerPort?.close(); } catch {}\n try { vrfPort?.close(); } catch {}\n this.terminateAndReplaceWorker(worker);\n this.signingSessions.delete(sessionId);\n throw err;\n }\n return { worker, signerPort, vrfPort };\n }\n\n /**\n * Release a signing session: close ports and terminate/replace the worker to zeroize state.\n */\n releaseSigningSession(sessionId: string): void {\n const entry = this.signingSessions.get(sessionId);\n if (!entry) return;\n try { entry.wrapKeySeedPort?.close() } catch {}\n try { this.terminateAndReplaceWorker(entry.worker) } catch {}\n this.signingSessions.delete(sessionId);\n }\n\n /**\n * Sweep expired signing sessions based on createdAt and timeout.\n */\n sweepExpiredSigningSessions(): void {\n const now = Date.now();\n for (const [sessionId, entry] of this.signingSessions.entries()) {\n if (now - entry.createdAt > this.SIGNING_SESSION_TIMEOUT_MS) {\n this.releaseSigningSession(sessionId);\n }\n }\n }\n\n private async createReplacementWorker(): Promise<void> {\n try {\n const worker = this.createSecureWorker();\n\n // Simple health check\n const healthPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error('Health check timeout')), 5000);\n\n const onMessage = (event: MessageEvent) => {\n if (event.data?.type === WorkerControlMessage.WORKER_READY || event.data?.ready) {\n worker.removeEventListener('message', onMessage);\n clearTimeout(timeout);\n resolve();\n }\n };\n\n worker.addEventListener('message', onMessage);\n worker.onerror = () => {\n worker.removeEventListener('message', onMessage);\n clearTimeout(timeout);\n reject(new Error('Worker error during health check'));\n };\n });\n\n await healthPromise;\n\n if (this.workerPool.length < this.MAX_WORKER_POOL_SIZE) {\n this.workerPool.push(worker);\n } else {\n worker.terminate();\n }\n } catch (error: unknown) {\n console.warn('SignerWorkerManager: Failed to create replacement worker:', error);\n }\n }\n\n /**\n * Pre-warm worker pool by creating and initializing workers in advance\n * This reduces latency for the first transaction by having workers ready\n */\n async preWarmWorkerPool(): Promise<void> {\n const promises: Promise<void>[] = [];\n\n for (let i = 0; i < this.MAX_WORKER_POOL_SIZE; i++) {\n promises.push(\n new Promise<void>((resolve, reject) => {\n try {\n const worker = this.createSecureWorker();\n\n // Set up one-time ready handler\n const onReady = (event: MessageEvent) => {\n if (event.data?.type === WorkerControlMessage.WORKER_READY || event.data?.ready) {\n worker.removeEventListener('message', onReady);\n this.terminateAndReplaceWorker(worker);\n resolve();\n }\n };\n\n worker.addEventListener('message', onReady);\n\n // Set up error handler\n worker.onerror = (error) => {\n worker.removeEventListener('message', onReady);\n console.error(`WebAuthnManager: Worker ${i + 1} pre-warm failed:`, error);\n reject(error);\n };\n\n // Timeout after 5 seconds\n setTimeout(() => {\n worker.removeEventListener('message', onReady);\n // Pre-warm timeouts are benign; workers will be created on-demand later.\n // console.debug(`WebAuthnManager: Worker ${i + 1} pre-warm timeout`);\n reject(new Error('Pre-warm timeout'));\n }, 5000);\n\n } catch (error: unknown) {\n console.error(`WebAuthnManager: Failed to create worker ${i + 1}:`, error);\n reject(toError(error));\n }\n })\n );\n }\n\n try {\n await Promise.allSettled(promises);\n } catch (error: unknown) {\n console.warn('WebAuthnManager: Some workers failed to pre-warm:', error);\n }\n }\n\n private async sendMessage<T extends WorkerRequestType>({\n sessionId,\n message,\n onEvent,\n timeoutMs = SIGNER_WORKER_MANAGER_CONFIG.TIMEOUTS.DEFAULT, // 60s\n }: {\n sessionId?: string;\n message: { type: T; payload: WithOptionalSessionId<WorkerRequestTypeMap[T]['request']> };\n onEvent?: (update: onProgressEvents) => void;\n timeoutMs?: number;\n }): Promise<WorkerResponseForRequest<T>> {\n\n // Clean up any expired signing sessions before allocating a worker\n this.sweepExpiredSigningSessions();\n\n const payloadSessionId = (message.payload as any)?.sessionId as string | undefined;\n if (sessionId && payloadSessionId && payloadSessionId !== sessionId) {\n throw new Error(\n `sendMessage: payload.sessionId (${payloadSessionId}) does not match provided sessionId (${sessionId})`\n );\n }\n\n const effectiveSessionId = sessionId || payloadSessionId;\n const sessionEntry = effectiveSessionId ? this.signingSessions.get(effectiveSessionId) : undefined;\n if (effectiveSessionId && !sessionEntry) {\n throw new Error(`Signing session not found for id: ${effectiveSessionId}`);\n }\n\n // Normalize/inject sessionId into payload once to avoid duplication at call sites.\n const finalPayload = effectiveSessionId\n ? withSessionId(effectiveSessionId, message.payload)\n : (message.payload);\n\n const worker = sessionEntry ? sessionEntry.worker : this.getWorkerFromPool();\n const isSessionWorker = !!sessionEntry;\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n try {\n if (isSessionWorker && effectiveSessionId) {\n // Release reserved session to avoid leaking worker/port\n this.releaseSigningSession(effectiveSessionId);\n } else {\n this.terminateAndReplaceWorker(worker);\n }\n } catch {}\n // Notify any open modal host to transition to error state\n try {\n const seconds = Math.round(timeoutMs / 1000);\n window.postMessage({ type: 'MODAL_TIMEOUT', payload: `Timed out after ${seconds}s, try again` }, '*');\n } catch {}\n reject(new Error(`Worker operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n const responses: WorkerResponseForRequest<T>[] = [];\n\n worker.onmessage = async (event) => {\n try {\n // Ignore control messages (lifecycle/session setup) – they are handled elsewhere.\n if (isSignerWorkerControlMessage(event?.data)) {\n return;\n }\n // Ignore readiness pings that can arrive if a worker was just spawned\n if (event?.data?.type === WorkerControlMessage.WORKER_READY || event?.data?.ready) {\n return; // not a response to an operation\n }\n // Use strong typing from WASM-generated types\n const response = event.data as WorkerResponseForRequest<T>;\n responses.push(response);\n\n // Handle progress updates using WASM-generated numeric enum values\n if (isWorkerProgress(response)) {\n const progressResponse = response as WorkerProgressResponse;\n onEvent?.(progressResponse.payload as onProgressEvents);\n return; // Continue listening for more messages\n }\n\n // Handle errors using WASM-generated enum\n if (isWorkerError(response)) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n const errorResponse = response as WorkerErrorResponse;\n console.error('Worker error response:', errorResponse);\n reject(new Error(errorResponse.payload.error));\n return;\n }\n\n // Handle successful completion types using strong typing\n if (isWorkerSuccess(response)) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n resolve(response as WorkerResponseForRequest<T>);\n return;\n }\n\n // If we reach here, the response doesn't match any expected type\n console.error('Unexpected worker response format:', {\n response,\n });\n\n // Check if it's a generic Error object\n if (isObject(response) && 'message' in response && 'stack' in response) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n console.error('Worker sent generic Error object:', response);\n reject(new Error(`Worker sent generic error: ${(response as Error).message}`));\n return;\n }\n\n // Unknown response format\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n reject(new Error(`Unknown worker response format: ${JSON.stringify(response)}`));\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n console.error('Error processing worker message:', error);\n const err = toError(error);\n reject(new Error(`Worker message processing error: ${err.message}`));\n }\n };\n\n worker.onerror = (event) => {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n const errorMessage = event.error?.message || event.message || 'Unknown worker error';\n console.error('Worker error details (progress):', {\n message: errorMessage,\n filename: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n error: event.error\n });\n reject(new Error(`Worker error: ${errorMessage}`));\n };\n\n // Format message for Rust SignerWorkerMessage structure using WASM types\n const formattedMessage = {\n type: message.type, // Numeric enum value from WorkerRequestType\n payload: finalPayload,\n };\n\n worker.postMessage(formattedMessage);\n });\n }\n\n /**\n * Derive NEAR keypair from a serialized WebAuthn registration credential\n */\n async deriveNearKeypairAndEncryptFromSerialized(args: {\n credential: WebAuthnRegistrationCredential;\n nearAccountId: AccountId;\n options?: {\n authenticatorOptions?: AuthenticatorOptions;\n deviceNumber?: number;\n };\n sessionId: string;\n }): Promise<{\n success: boolean;\n nearAccountId: AccountId;\n publicKey: string;\n /**\n * Base64url-encoded AEAD nonce (ChaCha20-Poly1305) for the encrypted private key.\n */\n chacha20NonceB64u?: string;\n wrapKeySalt?: string;\n }> {\n return deriveNearKeypairAndEncryptFromSerialized({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Secure private key decryption with dual PRF\n */\n async decryptPrivateKeyWithPrf(args: {\n nearAccountId: AccountId,\n authenticators: ClientAuthenticatorData[],\n sessionId: string,\n }): Promise<{\n decryptedPrivateKey: string;\n nearAccountId: AccountId\n }> {\n return decryptPrivateKeyWithPrf({ ctx: this.getContext(), ...args });\n }\n\n async checkCanRegisterUser(args: {\n vrfChallenge: VRFChallenge,\n credential: WebAuthnRegistrationCredential,\n contractId: string;\n nearRpcUrl: string;\n authenticatorOptions?: AuthenticatorOptions; // Authenticator options for registration check\n onEvent?: (update: onProgressEvents) => void;\n }): Promise<{\n success: boolean;\n verified?: boolean;\n registrationInfo?: unknown;\n logs?: string[];\n signedTransactionBorsh?: number[];\n error?: string;\n }> {\n return checkCanRegisterUser({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Combined Device2 registration: derive NEAR keypair + sign registration transaction\n * in a single operation without requiring a separate authentication prompt.\n *\n * This replaces the old two-step flow (register → authenticate → sign).\n * PRF.second and WrapKeySeed are already in the signer worker via MessagePort.\n */\n async registerDevice2WithDerivedKey(args: {\n sessionId: string;\n nearAccountId: AccountId;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge: VRFChallenge;\n transactionContext: TransactionContext;\n contractId: string;\n wrapKeySalt: string;\n deviceNumber?: number;\n deterministicVrfPublicKey: string;\n }): Promise<{\n success: boolean;\n publicKey: string;\n signedTransaction: any;\n wrapKeySalt: string;\n encryptedData?: string;\n /**\n * Base64url-encoded AEAD nonce (ChaCha20-Poly1305) for the encrypted private key.\n */\n chacha20NonceB64u?: string;\n error?: string;\n }> {\n return registerDevice2WithDerivedKey({ ctx: this.getContext(), ...args });\n }\n\n // === ACTION-BASED SIGNING METHODS ===\n\n /**\n * Sign multiple transactions with shared VRF challenge and credential\n * Efficiently processes multiple transactions with one PRF authentication\n */\n async signTransactionsWithActions(args: {\n transactions: TransactionInputWasm[],\n rpcCall: RpcCallPayload,\n onEvent?: (update: onProgressEvents) => void,\n confirmationConfigOverride?: Partial<ConfirmationConfig>,\n title?: string;\n body?: string;\n sessionId: string,\n }): Promise<Array<{\n signedTransaction: SignedTransaction;\n nearAccountId: AccountId;\n logs?: string[]\n }>> {\n return signTransactionsWithActions({\n ctx: this.getContext(),\n ...args\n });\n }\n\n async signDelegateAction(args: {\n delegate: DelegateActionInput;\n rpcCall: RpcCallPayload;\n onEvent?: (update: onProgressEvents) => void;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n title?: string;\n body?: string;\n sessionId: string;\n }): Promise<{\n signedDelegate: WasmSignedDelegate;\n hash: string;\n nearAccountId: AccountId;\n logs?: string[];\n }> {\n return signDelegateAction({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Recover keypair from authentication credential for account recovery\n * Uses dual PRF-based Ed25519 key derivation with account-specific HKDF and AES encryption\n */\n async recoverKeypairFromPasskey(args: {\n credential: WebAuthnAuthenticationCredential;\n accountIdHint?: string;\n sessionId: string,\n }): Promise<{\n publicKey: string;\n encryptedPrivateKey: string;\n /** Base64url-encoded AEAD nonce (ChaCha20-Poly1305) for encrypted key */\n chacha20NonceB64u: string;\n accountIdHint?: string;\n wrapKeySalt: string;\n }> {\n return recoverKeypairFromPasskey({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Extract COSE public key from WebAuthn attestation object\n * Simple operation that doesn't require TouchID or progress updates\n */\n async extractCosePublicKey(attestationObjectBase64url: string): Promise<Uint8Array> {\n return extractCosePublicKey({ ctx: this.getContext(), attestationObjectBase64url });\n }\n\n /**\n * Sign transaction with raw private key (for key replacement in Option D device linking)\n * No TouchID/PRF required - uses provided private key directly\n */\n async signTransactionWithKeyPair(args: {\n nearPrivateKey: string;\n signerAccountId: string;\n receiverId: string;\n nonce: string;\n blockHash: string;\n actions: ActionArgsWasm[];\n }): Promise<{\n signedTransaction: SignedTransaction;\n logs?: string[];\n }> {\n return signTransactionWithKeyPair({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Sign a NEP-413 message using the user's passkey-derived private key\n *\n * @param payload - NEP-413 signing parameters including message, recipient, nonce, and state\n * @returns Promise resolving to signing result with account ID, public key, and signature\n */\n async signNep413Message(payload: {\n message: string;\n recipient: string;\n nonce: string;\n state: string | null;\n accountId: string;\n title?: string;\n body?: string;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n sessionId: string;\n contractId?: string;\n nearRpcUrl?: string;\n }): Promise<{\n success: boolean;\n accountId: string;\n publicKey: string;\n signature: string;\n state?: string;\n error?: string;\n }> {\n return signNep413Message({\n ctx: this.getContext(),\n payload\n });\n }\n\n /**\n * Two-phase export (worker-driven):\n * - Phase 1: collect PRF (uiMode: 'skip')\n * - Decrypt inside worker\n * - Phase 2: show export UI with decrypted key (kept open until user closes)\n */\n async exportNearKeypairUi(args: {\n nearAccountId: AccountId,\n variant?: 'drawer'|'modal',\n theme?: 'dark'|'light',\n sessionId: string,\n }): Promise<void> {\n return exportNearKeypairUi({ ctx: this.getContext(), ...args });\n }\n\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["vrfPort: MessagePort | undefined","error: unknown","promises: Promise<void>[]","responses: WorkerResponseForRequest<T>[]"],"sources":["../../../../../../../../src/core/WebAuthnManager/SignerWorkerManager/index.ts"],"sourcesContent":["import { SIGNER_WORKER_MANAGER_CONFIG } from \"../../../config\";\nimport { ClientAuthenticatorData, UnifiedIndexedDBManager } from '../../IndexedDBManager';\nimport { IndexedDBManager } from '../../IndexedDBManager';\nimport { SignedTransaction, type NearClient } from '../../NearClient';\nimport { isObject } from '../../WalletIframe/validation';\nimport { resolveWorkerUrl } from '../../sdkPaths';\nimport {\n WorkerRequestType,\n WorkerResponseForRequest,\n isWorkerProgress,\n isWorkerError,\n isWorkerSuccess,\n WorkerProgressResponse,\n WorkerErrorResponse,\n WorkerRequestTypeMap,\n} from '../../types/signer-worker';\nimport { VrfWorkerManager } from '../VrfWorkerManager';\nimport { VRFChallenge } from '../../types/vrf-worker';\nimport type { ActionArgsWasm, TransactionInputWasm } from '../../types/actions';\nimport type { DelegateActionInput } from '../../types/delegate';\nimport type { onProgressEvents } from '../../types/sdkSentEvents';\nimport type { AuthenticatorOptions } from '../../types/authenticatorOptions';\nimport { AccountId } from \"../../types/accountIds\";\nimport { TransactionContext } from '../../types/rpc';\nimport {\n ConfirmationConfig,\n WasmSignedDelegate,\n} from '../../types/signer-worker';\nimport { TouchIdPrompt } from \"../touchIdPrompt\";\nimport { isSignerWorkerControlMessage } from './sessionMessages';\nimport { WorkerControlMessage } from '../../workerControlMessages';\n\nimport {\n decryptPrivateKeyWithPrf,\n checkCanRegisterUser,\n signTransactionsWithActions,\n recoverKeypairFromPasskey,\n extractCosePublicKey,\n signTransactionWithKeyPair,\n signNep413Message,\n deriveNearKeypairAndEncryptFromSerialized,\n signDelegateAction,\n registerDevice2WithDerivedKey,\n exportNearKeypairUi,\n} from './handlers';\nimport { RpcCallPayload } from '../../types/signer-worker';\nimport { UserPreferencesManager } from '../userPreferences';\nimport { NonceManager } from '../../nonceManager';\nimport { WebAuthnAuthenticationCredential, WebAuthnRegistrationCredential } from '../../types';\nimport { toError } from '@/utils/errors';\nimport { withSessionId } from './handlers/session';\nimport { attachSessionPort } from './sessionHandshake.js';\n\ntype WithOptionalSessionId<T> = T extends { sessionId: string }\n ? Omit<T, 'sessionId'> & { sessionId?: string }\n : T;\n\ntype SigningSessionEntry = {\n worker: Worker;\n wrapKeySeedPort?: MessagePort;\n createdAt: number;\n};\n\nexport interface SignerWorkerManagerContext {\n touchIdPrompt: TouchIdPrompt;\n nearClient: NearClient;\n indexedDB: UnifiedIndexedDBManager;\n userPreferencesManager: UserPreferencesManager;\n nonceManager: NonceManager;\n rpIdOverride?: string;\n nearExplorerUrl?: string;\n vrfWorkerManager?: VrfWorkerManager;\n sendMessage: <T extends keyof WorkerRequestTypeMap>(args: {\n message: {\n type: T;\n payload: WithOptionalSessionId<WorkerRequestTypeMap[T]['request']>;\n };\n onEvent?: (update: onProgressEvents) => void;\n timeoutMs?: number;\n sessionId?: string;\n }) => Promise<WorkerResponseForRequest<T>>;\n};\n\n/**\n * WebAuthnWorkers handles PRF, workers, and COSE operations\n *\n * Note: Challenge store removed as VRF provides cryptographic freshness\n * without needing centralized challenge management\n */\nexport class SignerWorkerManager {\n\n private indexedDB: UnifiedIndexedDBManager;\n private touchIdPrompt: TouchIdPrompt;\n private vrfWorkerManager: VrfWorkerManager;\n private nearClient: NearClient;\n private userPreferencesManager: UserPreferencesManager;\n private nonceManager: NonceManager;\n private workerBaseOrigin: string | undefined;\n private nearExplorerUrl?: string;\n\n constructor(\n vrfWorkerManager: VrfWorkerManager,\n nearClient: NearClient,\n userPreferencesManager: UserPreferencesManager,\n nonceManager: NonceManager,\n rpIdOverride?: string,\n enableSafariGetWebauthnRegistrationFallback: boolean = true,\n nearExplorerUrl?: string,\n ) {\n this.indexedDB = IndexedDBManager;\n this.touchIdPrompt = new TouchIdPrompt(rpIdOverride, enableSafariGetWebauthnRegistrationFallback);\n this.vrfWorkerManager = vrfWorkerManager;\n this.nearClient = nearClient;\n this.userPreferencesManager = userPreferencesManager;\n this.nonceManager = nonceManager;\n this.nearExplorerUrl = nearExplorerUrl;\n }\n\n setWorkerBaseOrigin(origin: string | undefined): void {\n this.workerBaseOrigin = origin;\n }\n\n getContext(): SignerWorkerManagerContext {\n return {\n sendMessage: this.sendMessage.bind(this), // bind to access this.createSecureWorker\n indexedDB: this.indexedDB,\n touchIdPrompt: this.touchIdPrompt,\n vrfWorkerManager: this.vrfWorkerManager,\n nearClient: this.nearClient,\n userPreferencesManager: this.userPreferencesManager,\n nonceManager: this.nonceManager,\n rpIdOverride: this.touchIdPrompt.getRpId(),\n nearExplorerUrl: this.nearExplorerUrl,\n };\n }\n\n createSecureWorker(): Worker {\n const workerUrlStr = resolveWorkerUrl(\n SIGNER_WORKER_MANAGER_CONFIG.WORKER.URL,\n { worker: 'signer', baseOrigin: this.workerBaseOrigin }\n )\n try {\n const worker = new Worker(workerUrlStr, {\n type: SIGNER_WORKER_MANAGER_CONFIG.WORKER.TYPE,\n name: SIGNER_WORKER_MANAGER_CONFIG.WORKER.NAME\n });\n // minimal error handler in tests; avoid noisy logs\n worker.onerror = () => {};\n return worker;\n } catch (error) {\n // Do not silently downgrade to same‑origin. Cross‑origin workers must be\n // resolvable under the configured wallet origin with proper headers.\n // Surface a precise error so tests assert the real path.\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to create secure worker: ${msg}`);\n }\n }\n\n /**\n * Executes a worker operation by sending a message to the secure worker.\n * Handles progress updates via onEvent callback, supports both single and multiple response patterns.\n * Intercepts secure confirmation handshake messages for pluggable UI.\n * Resolves with the final worker response or rejects on error/timeout.\n *\n * @template T - Worker request type.\n * @param params.message - The message to send to the worker.\n * @param params.onEvent - Optional callback for progress events.\n * @param params.timeoutMs - Optional timeout in milliseconds.\n * @returns Promise resolving to the worker response for the request.\n */\n private workerPool: Worker[] = [];\n private readonly MAX_WORKER_POOL_SIZE = 3; // Increased for security model\n // Map of active signing sessions to reserved workers and optional WrapKeySeed ports\n private signingSessions: Map<string, SigningSessionEntry> = new Map();\n private readonly SIGNING_SESSION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\n private getWorkerFromPool(): Worker {\n if (this.workerPool.length > 0) {\n return this.workerPool.pop()!;\n }\n return this.createSecureWorker();\n }\n\n private terminateAndReplaceWorker(worker: Worker): void {\n // Always terminate workers to clear memory\n worker.terminate();\n // Asynchronously create a replacement worker for the pool\n this.createReplacementWorker();\n }\n\n /**\n * Reserve a signer worker \"session\"\n *\n * What this does:\n * - Reserves a specific `Worker` instance from the pool and pins it to `sessionId`.\n * - Ensures the signer worker has a dedicated `MessagePort` attached for receiving `WrapKeySeed`\n * from the VRF worker (VRF → Signer channel).\n *\n * Port wiring:\n * - The VRF worker retains one end of a `MessageChannel` and the signer worker receives the other.\n * - This method attaches the signer-facing port via a control message (`ATTACH_WRAP_KEY_SEED_PORT`)\n * and waits for an ACK (`ATTACH_WRAP_KEY_SEED_PORT_OK`) before exposing the session.\n *\n * @param sessionId - Session identifier used to correlate MessagePorts + ready signals.\n * @param opts.signerPort - Optional signer-facing `MessagePort` created/owned by the caller (VRF-created channel).\n * If omitted, this method creates a fresh `MessageChannel` and returns `vrfPort` so the\n * caller can transfer it to the VRF worker.\n * @returns `{ worker, signerPort, vrfPort }` where `vrfPort` is only present when we created the channel here.\n */\n async reserveSignerWorkerSession(sessionId: string, opts?: { signerPort?: MessagePort }): Promise<{ worker: Worker; signerPort?: MessagePort; vrfPort?: MessagePort }> {\n if (this.signingSessions.has(sessionId)) {\n throw new Error(`Signing session already exists for id: ${sessionId}`);\n }\n // Reserve a worker from the pool for this sessionId.\n const worker = this.getWorkerFromPool();\n let signerPort = opts?.signerPort;\n let vrfPort: MessagePort | undefined;\n if (!signerPort) {\n // If caller did not provide a signer-facing port, create a channel.\n // - port1 => signer worker (receiver)\n // - port2 => VRF worker (sender) returned to caller\n const channel = new MessageChannel();\n signerPort = channel.port1;\n vrfPort = channel.port2;\n }\n\n // Attach the signerPort to the worker and wait for ACK before adding to signingSessions\n try {\n if (!signerPort) {\n throw new Error('Missing signerPort for signing session');\n }\n\n // Use centralized handshake logic (registers listener, sends message, waits for ACK)\n await attachSessionPort(worker, sessionId, signerPort);\n\n // Only add to signingSessions after successful attachment\n // (prevents callers from observing a session that can't receive WrapKeySeed yet).\n this.signingSessions.set(sessionId, {\n worker,\n wrapKeySeedPort: signerPort,\n createdAt: Date.now(),\n });\n\n } catch (err) {\n console.error('[SignerWorkerManager]: Failed to attach WrapKeySeed port to signer worker', err);\n // Best-effort cleanup\n try { signerPort?.close(); } catch {}\n try { vrfPort?.close(); } catch {}\n this.terminateAndReplaceWorker(worker);\n this.signingSessions.delete(sessionId);\n throw err;\n }\n return { worker, signerPort, vrfPort };\n }\n\n /**\n * Release a signing session: close ports and terminate/replace the worker to zeroize state.\n */\n releaseSigningSession(sessionId: string): void {\n const entry = this.signingSessions.get(sessionId);\n if (!entry) return;\n try { entry.wrapKeySeedPort?.close() } catch {}\n try { this.terminateAndReplaceWorker(entry.worker) } catch {}\n this.signingSessions.delete(sessionId);\n }\n\n /**\n * Sweep expired signing sessions based on createdAt and timeout.\n */\n sweepExpiredSigningSessions(): void {\n const now = Date.now();\n for (const [sessionId, entry] of this.signingSessions.entries()) {\n if (now - entry.createdAt > this.SIGNING_SESSION_TIMEOUT_MS) {\n this.releaseSigningSession(sessionId);\n }\n }\n }\n\n private async createReplacementWorker(): Promise<void> {\n try {\n const worker = this.createSecureWorker();\n\n // Simple health check\n const healthPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error('Health check timeout')), 5000);\n\n const onMessage = (event: MessageEvent) => {\n if (event.data?.type === WorkerControlMessage.WORKER_READY || event.data?.ready) {\n worker.removeEventListener('message', onMessage);\n clearTimeout(timeout);\n resolve();\n }\n };\n\n worker.addEventListener('message', onMessage);\n worker.onerror = () => {\n worker.removeEventListener('message', onMessage);\n clearTimeout(timeout);\n reject(new Error('Worker error during health check'));\n };\n });\n\n await healthPromise;\n\n if (this.workerPool.length < this.MAX_WORKER_POOL_SIZE) {\n this.workerPool.push(worker);\n } else {\n worker.terminate();\n }\n } catch (error: unknown) {\n console.warn('SignerWorkerManager: Failed to create replacement worker:', error);\n }\n }\n\n /**\n * Pre-warm worker pool by creating and initializing workers in advance\n * This reduces latency for the first transaction by having workers ready\n */\n async preWarmWorkerPool(): Promise<void> {\n const promises: Promise<void>[] = [];\n\n for (let i = 0; i < this.MAX_WORKER_POOL_SIZE; i++) {\n promises.push(\n new Promise<void>((resolve, reject) => {\n try {\n const worker = this.createSecureWorker();\n\n // Set up one-time ready handler\n const onReady = (event: MessageEvent) => {\n if (event.data?.type === WorkerControlMessage.WORKER_READY || event.data?.ready) {\n worker.removeEventListener('message', onReady);\n this.terminateAndReplaceWorker(worker);\n resolve();\n }\n };\n\n worker.addEventListener('message', onReady);\n\n // Set up error handler\n worker.onerror = (error) => {\n worker.removeEventListener('message', onReady);\n console.error(`WebAuthnManager: Worker ${i + 1} pre-warm failed:`, error);\n reject(error);\n };\n\n // Timeout after 5 seconds\n setTimeout(() => {\n worker.removeEventListener('message', onReady);\n // Pre-warm timeouts are benign; workers will be created on-demand later.\n // console.debug(`WebAuthnManager: Worker ${i + 1} pre-warm timeout`);\n reject(new Error('Pre-warm timeout'));\n }, 5000);\n\n } catch (error: unknown) {\n console.error(`WebAuthnManager: Failed to create worker ${i + 1}:`, error);\n reject(toError(error));\n }\n })\n );\n }\n\n try {\n await Promise.allSettled(promises);\n } catch (error: unknown) {\n console.warn('WebAuthnManager: Some workers failed to pre-warm:', error);\n }\n }\n\n private async sendMessage<T extends WorkerRequestType>({\n sessionId,\n message,\n onEvent,\n timeoutMs = SIGNER_WORKER_MANAGER_CONFIG.TIMEOUTS.DEFAULT, // 60s\n }: {\n sessionId?: string;\n message: { type: T; payload: WithOptionalSessionId<WorkerRequestTypeMap[T]['request']> };\n onEvent?: (update: onProgressEvents) => void;\n timeoutMs?: number;\n }): Promise<WorkerResponseForRequest<T>> {\n\n // Clean up any expired signing sessions before allocating a worker\n this.sweepExpiredSigningSessions();\n\n const payloadSessionId = (message.payload as any)?.sessionId as string | undefined;\n if (sessionId && payloadSessionId && payloadSessionId !== sessionId) {\n throw new Error(\n `sendMessage: payload.sessionId (${payloadSessionId}) does not match provided sessionId (${sessionId})`\n );\n }\n\n const effectiveSessionId = sessionId || payloadSessionId;\n const sessionEntry = effectiveSessionId ? this.signingSessions.get(effectiveSessionId) : undefined;\n if (effectiveSessionId && !sessionEntry) {\n throw new Error(`Signing session not found for id: ${effectiveSessionId}`);\n }\n\n // Normalize/inject sessionId into payload once to avoid duplication at call sites.\n const finalPayload = effectiveSessionId\n ? withSessionId(effectiveSessionId, message.payload)\n : (message.payload);\n\n const worker = sessionEntry ? sessionEntry.worker : this.getWorkerFromPool();\n const isSessionWorker = !!sessionEntry;\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n try {\n if (isSessionWorker && effectiveSessionId) {\n // Release reserved session to avoid leaking worker/port\n this.releaseSigningSession(effectiveSessionId);\n } else {\n this.terminateAndReplaceWorker(worker);\n }\n } catch {}\n // Notify any open modal host to transition to error state\n try {\n const seconds = Math.round(timeoutMs / 1000);\n window.postMessage({ type: 'MODAL_TIMEOUT', payload: `Timed out after ${seconds}s, try again` }, '*');\n } catch {}\n reject(new Error(`Worker operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n const responses: WorkerResponseForRequest<T>[] = [];\n\n worker.onmessage = async (event) => {\n try {\n // Ignore control messages (lifecycle/session setup) – they are handled elsewhere.\n if (isSignerWorkerControlMessage(event?.data)) {\n return;\n }\n // Ignore readiness pings that can arrive if a worker was just spawned\n if (event?.data?.type === WorkerControlMessage.WORKER_READY || event?.data?.ready) {\n return; // not a response to an operation\n }\n // Use strong typing from WASM-generated types\n const response = event.data as WorkerResponseForRequest<T>;\n responses.push(response);\n\n // Handle progress updates using WASM-generated numeric enum values\n if (isWorkerProgress(response)) {\n const progressResponse = response as WorkerProgressResponse;\n onEvent?.(progressResponse.payload as onProgressEvents);\n return; // Continue listening for more messages\n }\n\n // Handle errors using WASM-generated enum\n if (isWorkerError(response)) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n const errorResponse = response as WorkerErrorResponse;\n console.error('Worker error response:', errorResponse);\n reject(new Error(errorResponse.payload.error));\n return;\n }\n\n // Handle successful completion types using strong typing\n if (isWorkerSuccess(response)) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n resolve(response as WorkerResponseForRequest<T>);\n return;\n }\n\n // If we reach here, the response doesn't match any expected type\n console.error('Unexpected worker response format:', {\n response,\n });\n\n // Check if it's a generic Error object\n if (isObject(response) && 'message' in response && 'stack' in response) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n console.error('Worker sent generic Error object:', response);\n reject(new Error(`Worker sent generic error: ${(response as Error).message}`));\n return;\n }\n\n // Unknown response format\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n reject(new Error(`Unknown worker response format: ${JSON.stringify(response)}`));\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n console.error('Error processing worker message:', error);\n const err = toError(error);\n reject(new Error(`Worker message processing error: ${err.message}`));\n }\n };\n\n worker.onerror = (event) => {\n clearTimeout(timeoutId);\n if (!isSessionWorker) this.terminateAndReplaceWorker(worker);\n const errorMessage = event.error?.message || event.message || 'Unknown worker error';\n console.error('Worker error details (progress):', {\n message: errorMessage,\n filename: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n error: event.error\n });\n reject(new Error(`Worker error: ${errorMessage}`));\n };\n\n // Format message for Rust SignerWorkerMessage structure using WASM types\n const formattedMessage = {\n type: message.type, // Numeric enum value from WorkerRequestType\n payload: finalPayload,\n };\n\n worker.postMessage(formattedMessage);\n });\n }\n\n /**\n * Derive NEAR keypair from a serialized WebAuthn registration credential\n */\n async deriveNearKeypairAndEncryptFromSerialized(args: {\n credential: WebAuthnRegistrationCredential;\n nearAccountId: AccountId;\n options?: {\n authenticatorOptions?: AuthenticatorOptions;\n deviceNumber?: number;\n };\n sessionId: string;\n }): Promise<{\n success: boolean;\n nearAccountId: AccountId;\n publicKey: string;\n /**\n * Base64url-encoded AEAD nonce (ChaCha20-Poly1305) for the encrypted private key.\n */\n chacha20NonceB64u?: string;\n wrapKeySalt?: string;\n }> {\n return deriveNearKeypairAndEncryptFromSerialized({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Secure private key decryption with dual PRF\n */\n async decryptPrivateKeyWithPrf(args: {\n nearAccountId: AccountId,\n authenticators: ClientAuthenticatorData[],\n sessionId: string,\n }): Promise<{\n decryptedPrivateKey: string;\n nearAccountId: AccountId\n }> {\n return decryptPrivateKeyWithPrf({ ctx: this.getContext(), ...args });\n }\n\n async checkCanRegisterUser(args: {\n vrfChallenge: VRFChallenge,\n credential: WebAuthnRegistrationCredential,\n contractId: string;\n nearRpcUrl: string;\n authenticatorOptions?: AuthenticatorOptions; // Authenticator options for registration check\n onEvent?: (update: onProgressEvents) => void;\n }): Promise<{\n success: boolean;\n verified?: boolean;\n registrationInfo?: unknown;\n logs?: string[];\n signedTransactionBorsh?: number[];\n error?: string;\n }> {\n return checkCanRegisterUser({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Combined Device2 registration: derive NEAR keypair + sign registration transaction\n * in a single operation without requiring a separate authentication prompt.\n *\n * This replaces the old two-step flow (register → authenticate → sign).\n * PRF.second and WrapKeySeed are already in the signer worker via MessagePort.\n */\n async registerDevice2WithDerivedKey(args: {\n sessionId: string;\n nearAccountId: AccountId;\n credential: WebAuthnRegistrationCredential;\n vrfChallenge: VRFChallenge;\n transactionContext: TransactionContext;\n contractId: string;\n wrapKeySalt: string;\n deviceNumber?: number;\n deterministicVrfPublicKey: string;\n }): Promise<{\n success: boolean;\n publicKey: string;\n signedTransaction: any;\n wrapKeySalt: string;\n encryptedData?: string;\n /**\n * Base64url-encoded AEAD nonce (ChaCha20-Poly1305) for the encrypted private key.\n */\n chacha20NonceB64u?: string;\n error?: string;\n }> {\n return registerDevice2WithDerivedKey({ ctx: this.getContext(), ...args });\n }\n\n // === ACTION-BASED SIGNING METHODS ===\n\n /**\n * Sign multiple transactions with shared VRF challenge and credential\n * Efficiently processes multiple transactions with one PRF authentication\n */\n async signTransactionsWithActions(args: {\n transactions: TransactionInputWasm[],\n rpcCall: RpcCallPayload,\n onEvent?: (update: onProgressEvents) => void,\n confirmationConfigOverride?: Partial<ConfirmationConfig>,\n title?: string;\n body?: string;\n sessionId: string,\n }): Promise<Array<{\n signedTransaction: SignedTransaction;\n nearAccountId: AccountId;\n logs?: string[]\n }>> {\n return signTransactionsWithActions({\n ctx: this.getContext(),\n ...args\n });\n }\n\n async signDelegateAction(args: {\n delegate: DelegateActionInput;\n rpcCall: RpcCallPayload;\n onEvent?: (update: onProgressEvents) => void;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n title?: string;\n body?: string;\n sessionId: string;\n }): Promise<{\n signedDelegate: WasmSignedDelegate;\n hash: string;\n nearAccountId: AccountId;\n logs?: string[];\n }> {\n return signDelegateAction({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Recover keypair from authentication credential for account recovery\n * Uses dual PRF-based Ed25519 key derivation with account-specific HKDF and AES encryption\n */\n async recoverKeypairFromPasskey(args: {\n credential: WebAuthnAuthenticationCredential;\n accountIdHint?: string;\n sessionId: string,\n }): Promise<{\n publicKey: string;\n encryptedPrivateKey: string;\n /** Base64url-encoded AEAD nonce (ChaCha20-Poly1305) for encrypted key */\n chacha20NonceB64u: string;\n accountIdHint?: string;\n wrapKeySalt: string;\n }> {\n return recoverKeypairFromPasskey({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Extract COSE public key from WebAuthn attestation object\n * Simple operation that doesn't require TouchID or progress updates\n */\n async extractCosePublicKey(attestationObjectBase64url: string): Promise<Uint8Array> {\n return extractCosePublicKey({ ctx: this.getContext(), attestationObjectBase64url });\n }\n\n /**\n * Sign transaction with raw private key (for key replacement in Option D device linking)\n * No TouchID/PRF required - uses provided private key directly\n */\n async signTransactionWithKeyPair(args: {\n nearPrivateKey: string;\n signerAccountId: string;\n receiverId: string;\n nonce: string;\n blockHash: string;\n actions: ActionArgsWasm[];\n }): Promise<{\n signedTransaction: SignedTransaction;\n logs?: string[];\n }> {\n return signTransactionWithKeyPair({ ctx: this.getContext(), ...args });\n }\n\n /**\n * Sign a NEP-413 message using the user's passkey-derived private key\n *\n * @param payload - NEP-413 signing parameters including message, recipient, nonce, and state\n * @returns Promise resolving to signing result with account ID, public key, and signature\n */\n async signNep413Message(payload: {\n message: string;\n recipient: string;\n nonce: string;\n state: string | null;\n accountId: string;\n title?: string;\n body?: string;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n sessionId: string;\n contractId?: string;\n nearRpcUrl?: string;\n }): Promise<{\n success: boolean;\n accountId: string;\n publicKey: string;\n signature: string;\n state?: string;\n error?: string;\n }> {\n return signNep413Message({\n ctx: this.getContext(),\n payload\n });\n }\n\n /**\n * Two-phase export (worker-driven):\n * - Phase 1: collect PRF (uiMode: 'skip')\n * - Decrypt inside worker\n * - Phase 2: show export UI with decrypted key (kept open until user closes)\n */\n async exportNearKeypairUi(args: {\n nearAccountId: AccountId,\n variant?: 'drawer'|'modal',\n theme?: 'dark'|'light',\n sessionId: string,\n }): Promise<void> {\n return exportNearKeypairUi({ ctx: this.getContext(), ...args });\n }\n\n}\n"],"mappings":"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"}
|
package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.js
CHANGED
|
@@ -7,6 +7,7 @@ async function maybeRefreshVrfChallenge(ctx, request, nearAccountId) {
|
|
|
7
7
|
const rpId = ctx.touchIdPrompt.getRpId();
|
|
8
8
|
const vrfWorkerManager = ctx.vrfWorkerManager;
|
|
9
9
|
if (!vrfWorkerManager) throw new Error("VrfWorkerManager not available");
|
|
10
|
+
if (!ctx.nonceManager.nearAccountId || !ctx.nonceManager.nearPublicKeyStr || String(ctx.nonceManager.nearAccountId) !== String(nearAccountId)) throw new Error("NonceManager not initialized with user data");
|
|
10
11
|
const attempts = 3;
|
|
11
12
|
return await retryWithBackoff(async (attempt) => {
|
|
12
13
|
const latestCtx = await ctx.nonceManager.getNonceBlockHashAndHeight(ctx.nearClient, { force: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vrf.js","names":["lastError: unknown"],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport { TransactionContext, VRFChallenge } from '../../../../types';\nimport type { SecureConfirmRequest } from '../types';\nimport { SecureConfirmationType } from '../types';\nimport { errorMessage, toError } from '../../../../../utils/errors';\n\nexport async function maybeRefreshVrfChallenge(\n ctx: VrfWorkerManagerContext,\n request: SecureConfirmRequest,\n nearAccountId: string,\n): Promise<{ vrfChallenge: VRFChallenge; transactionContext: TransactionContext }> {\n const rpId = ctx.touchIdPrompt.getRpId();\n const vrfWorkerManager = ctx.vrfWorkerManager;\n if (!vrfWorkerManager) throw new Error('VrfWorkerManager not available');\n\n const attempts = 3;\n return await retryWithBackoff(async (attempt) => {\n const latestCtx = await ctx.nonceManager.getNonceBlockHashAndHeight(ctx.nearClient, { force: true });\n\n const vrfChallenge = (request.type === SecureConfirmationType.REGISTER_ACCOUNT || request.type === SecureConfirmationType.LINK_DEVICE)\n ? (await vrfWorkerManager.generateVrfKeypairBootstrap({\n vrfInputData: {\n userId: nearAccountId,\n rpId,\n blockHeight: latestCtx.txBlockHeight,\n blockHash: latestCtx.txBlockHash,\n },\n saveInMemory: true,\n sessionId: request.requestId,\n })).vrfChallenge\n : await vrfWorkerManager.generateVrfChallengeForSession(\n {\n userId: nearAccountId,\n rpId,\n blockHeight: latestCtx.txBlockHeight,\n blockHash: latestCtx.txBlockHash,\n },\n request.requestId,\n );\n\n return {
|
|
1
|
+
{"version":3,"file":"vrf.js","names":["lastError: unknown"],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/vrf.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport { TransactionContext, VRFChallenge } from '../../../../types';\nimport type { SecureConfirmRequest } from '../types';\nimport { SecureConfirmationType } from '../types';\nimport { errorMessage, toError } from '../../../../../utils/errors';\n\nexport async function maybeRefreshVrfChallenge(\n ctx: VrfWorkerManagerContext,\n request: SecureConfirmRequest,\n nearAccountId: string,\n): Promise<{ vrfChallenge: VRFChallenge; transactionContext: TransactionContext }> {\n\n const rpId = ctx.touchIdPrompt.getRpId();\n const vrfWorkerManager = ctx.vrfWorkerManager;\n if (!vrfWorkerManager) {\n throw new Error('VrfWorkerManager not available');\n }\n // Only attempt a JIT refresh when NonceManager is initialized for this account.\n // Pre-login/registration flows should just skip (callers already treat this as best-effort).\n if (\n !ctx.nonceManager.nearAccountId ||\n !ctx.nonceManager.nearPublicKeyStr ||\n String(ctx.nonceManager.nearAccountId) !== String(nearAccountId)\n ) {\n throw new Error('NonceManager not initialized with user data');\n }\n\n const attempts = 3;\n return await retryWithBackoff(async (attempt) => {\n const latestCtx = await ctx.nonceManager.getNonceBlockHashAndHeight(ctx.nearClient, { force: true });\n\n const vrfChallenge = (request.type === SecureConfirmationType.REGISTER_ACCOUNT || request.type === SecureConfirmationType.LINK_DEVICE)\n ? (await vrfWorkerManager.generateVrfKeypairBootstrap({\n vrfInputData: {\n userId: nearAccountId,\n rpId,\n blockHeight: latestCtx.txBlockHeight,\n blockHash: latestCtx.txBlockHash,\n },\n saveInMemory: true,\n sessionId: request.requestId,\n })).vrfChallenge\n : await vrfWorkerManager.generateVrfChallengeForSession(\n {\n userId: nearAccountId,\n rpId,\n blockHeight: latestCtx.txBlockHeight,\n blockHash: latestCtx.txBlockHash,\n },\n request.requestId,\n );\n\n return {\n vrfChallenge,\n transactionContext: latestCtx\n };\n\n }, {\n attempts,\n baseDelayMs: 150,\n onError: (err, attempt) => {\n const msg = errorMessage(err);\n const isFinal = attempt >= attempts;\n if (isFinal) {\n console.warn(`[SecureConfirm] VRF refresh failed: ${msg}`);\n } else {\n console.debug(`[SecureConfirm] VRF refresh attempt ${attempt} failed: ${msg}`);\n }\n },\n errorFactory: () => new Error('VRF refresh failed'),\n });\n}\n\ninterface RetryOptions {\n attempts: number;\n baseDelayMs: number;\n onError?: (error: unknown, attempt: number) => void;\n errorFactory?: () => Error;\n}\n\nasync function retryWithBackoff<T>(fn: (attempt: number) => Promise<T>, options: RetryOptions): Promise<T> {\n const { attempts, baseDelayMs, onError, errorFactory } = options;\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= Math.max(1, attempts); attempt++) {\n try {\n return await fn(attempt);\n } catch (err) {\n lastError = err;\n onError?.(err, attempt);\n if (attempt < attempts) {\n const delay = baseDelayMs * attempt;\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n throw errorFactory ? errorFactory() : toError(lastError ?? new Error('Retry exhausted'));\n}\n"],"mappings":";;;;;AAMA,eAAsB,yBACpB,KACA,SACA,eACiF;CAEjF,MAAM,OAAO,IAAI,cAAc;CAC/B,MAAM,mBAAmB,IAAI;AAC7B,KAAI,CAAC,iBACH,OAAM,IAAI,MAAM;AAIlB,KACE,CAAC,IAAI,aAAa,iBAClB,CAAC,IAAI,aAAa,oBAClB,OAAO,IAAI,aAAa,mBAAmB,OAAO,eAElD,OAAM,IAAI,MAAM;CAGlB,MAAM,WAAW;AACjB,QAAO,MAAM,iBAAiB,OAAO,YAAY;EAC/C,MAAM,YAAY,MAAM,IAAI,aAAa,2BAA2B,IAAI,YAAY,EAAE,OAAO;EAE7F,MAAM,eAAgB,QAAQ,SAAS,uBAAuB,oBAAoB,QAAQ,SAAS,uBAAuB,eACrH,MAAM,iBAAiB,4BAA4B;GAClD,cAAc;IACZ,QAAQ;IACR;IACA,aAAa,UAAU;IACvB,WAAW,UAAU;;GAEvB,cAAc;GACd,WAAW,QAAQ;MACjB,eACJ,MAAM,iBAAiB,+BACrB;GACE,QAAQ;GACR;GACA,aAAa,UAAU;GACvB,WAAW,UAAU;KAEvB,QAAQ;AAGd,SAAO;GACL;GACA,oBAAoB;;IAGrB;EACD;EACA,aAAa;EACb,UAAU,KAAK,YAAY;GACzB,MAAM,MAAM,aAAa;GACzB,MAAM,UAAU,WAAW;AAC3B,OAAI,QACF,SAAQ,KAAK,uCAAuC;OAEpD,SAAQ,MAAM,uCAAuC,QAAQ,WAAW;;EAG5E,oCAAoB,IAAI,MAAM;;;AAWlC,eAAe,iBAAoB,IAAqC,SAAmC;CACzG,MAAM,EAAE,UAAU,aAAa,SAAS,iBAAiB;CACzD,IAAIA;AAEJ,MAAK,IAAI,UAAU,GAAG,WAAW,KAAK,IAAI,GAAG,WAAW,UACtD,KAAI;AACF,SAAO,MAAM,GAAG;UACT,KAAK;AACZ,cAAY;AACZ,YAAU,KAAK;AACf,MAAI,UAAU,UAAU;GACtB,MAAM,QAAQ,cAAc;AAC5B,SAAM,IAAI,SAAS,YAAY,WAAW,SAAS;;;AAKzD,OAAM,eAAe,iBAAiB,QAAQ,6BAAa,IAAI,MAAM"}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { init_accountIds, toAccountId } from "../../../../types/accountIds.js";
|
|
2
|
-
import { serializeAuthenticationCredentialWithPRF } from "../../../credentialsHelpers.js";
|
|
3
|
-
import { authenticatorsToAllowCredentials } from "../../../touchIdPrompt.js";
|
|
2
|
+
import { init_credentialsHelpers, serializeAuthenticationCredentialWithPRF } from "../../../credentialsHelpers.js";
|
|
3
|
+
import { authenticatorsToAllowCredentials, init_touchIdPrompt } from "../../../touchIdPrompt.js";
|
|
4
4
|
|
|
5
5
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.ts
|
|
6
|
+
init_credentialsHelpers();
|
|
6
7
|
init_accountIds();
|
|
8
|
+
init_touchIdPrompt();
|
|
7
9
|
async function collectAuthenticationCredentialWithPRF({ ctx, nearAccountId, vrfChallenge, onBeforePrompt, includeSecondPrfOutput = false }) {
|
|
8
10
|
const authenticators = await ctx.indexedDB.clientDB.getAuthenticatorsByUser(toAccountId(nearAccountId));
|
|
9
11
|
const { authenticatorsForPrompt, wrongPasskeyError } = await ctx.indexedDB.clientDB.ensureCurrentPasskey(toAccountId(nearAccountId), authenticators);
|
|
10
12
|
if (wrongPasskeyError) throw new Error(wrongPasskeyError);
|
|
13
|
+
if (authenticatorsForPrompt.length === 1) {
|
|
14
|
+
const expectedVrfPublicKey = authenticatorsForPrompt[0]?.vrfPublicKey;
|
|
15
|
+
if (expectedVrfPublicKey && expectedVrfPublicKey !== vrfChallenge.vrfPublicKey) throw new Error("Signing session is using a different passkey/VRF session than the current device. Please log in again and retry.");
|
|
16
|
+
}
|
|
11
17
|
onBeforePrompt?.({
|
|
12
18
|
authenticators,
|
|
13
19
|
authenticatorsForPrompt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webauthn.js","names":[],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { VRFChallenge } from '../../../../types';\nimport type { SerializableCredential } from '../types';\nimport { serializeAuthenticationCredentialWithPRF } from '../../../credentialsHelpers';\nimport { toAccountId } from '../../../../types/accountIds';\nimport { authenticatorsToAllowCredentials } from '../../../touchIdPrompt';\nimport type { ClientAuthenticatorData } from '../../../../IndexedDBManager';\n\nexport async function collectAuthenticationCredentialWithPRF({\n ctx,\n nearAccountId,\n vrfChallenge,\n onBeforePrompt,\n includeSecondPrfOutput = false,\n}: {\n ctx: VrfWorkerManagerContext;\n nearAccountId: string;\n vrfChallenge: VRFChallenge;\n onBeforePrompt?: (info: {\n authenticators: ClientAuthenticatorData[];\n authenticatorsForPrompt: ClientAuthenticatorData[];\n vrfChallenge: VRFChallenge;\n }) => void;\n /**\n * When true, include PRF.second in the serialized credential.\n * Use only for explicit recovery/export flows (higher-friction paths).\n */\n includeSecondPrfOutput?: boolean;\n}): Promise<SerializableCredential> {\n\n const authenticators = await ctx.indexedDB.clientDB.getAuthenticatorsByUser(toAccountId(nearAccountId));\n const { authenticatorsForPrompt, wrongPasskeyError } = await ctx.indexedDB.clientDB.ensureCurrentPasskey(\n toAccountId(nearAccountId),\n authenticators,\n );\n if (wrongPasskeyError) {\n throw new Error(wrongPasskeyError);\n }\n\n onBeforePrompt?.({ authenticators, authenticatorsForPrompt, vrfChallenge });\n\n const credential = await ctx.touchIdPrompt.getAuthenticationCredentialsInternal({\n nearAccountId,\n challenge: vrfChallenge,\n allowCredentials: authenticatorsToAllowCredentials(authenticatorsForPrompt),\n });\n\n const serialized = serializeAuthenticationCredentialWithPRF({\n credential,\n firstPrfOutput: true,\n secondPrfOutput: includeSecondPrfOutput,\n });\n\n // Verify that the chosen credential matches the \"current\" passkey device, when applicable.\n const { wrongPasskeyError: wrongSelectedCredentialError } = await ctx.indexedDB.clientDB.ensureCurrentPasskey(\n toAccountId(nearAccountId),\n authenticators,\n serialized.rawId,\n );\n if (wrongSelectedCredentialError) {\n throw new Error(wrongSelectedCredentialError);\n }\n\n return serialized;\n}\n
|
|
1
|
+
{"version":3,"file":"webauthn.js","names":[],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { VRFChallenge } from '../../../../types';\nimport type { SerializableCredential } from '../types';\nimport { serializeAuthenticationCredentialWithPRF } from '../../../credentialsHelpers';\nimport { toAccountId } from '../../../../types/accountIds';\nimport { authenticatorsToAllowCredentials } from '../../../touchIdPrompt';\nimport type { ClientAuthenticatorData } from '../../../../IndexedDBManager';\n\nexport async function collectAuthenticationCredentialWithPRF({\n ctx,\n nearAccountId,\n vrfChallenge,\n onBeforePrompt,\n includeSecondPrfOutput = false,\n}: {\n ctx: VrfWorkerManagerContext;\n nearAccountId: string;\n vrfChallenge: VRFChallenge;\n onBeforePrompt?: (info: {\n authenticators: ClientAuthenticatorData[];\n authenticatorsForPrompt: ClientAuthenticatorData[];\n vrfChallenge: VRFChallenge;\n }) => void;\n /**\n * When true, include PRF.second in the serialized credential.\n * Use only for explicit recovery/export flows (higher-friction paths).\n */\n includeSecondPrfOutput?: boolean;\n}): Promise<SerializableCredential> {\n\n const authenticators = await ctx.indexedDB.clientDB.getAuthenticatorsByUser(toAccountId(nearAccountId));\n const { authenticatorsForPrompt, wrongPasskeyError } = await ctx.indexedDB.clientDB.ensureCurrentPasskey(\n toAccountId(nearAccountId),\n authenticators,\n );\n if (wrongPasskeyError) {\n throw new Error(wrongPasskeyError);\n }\n\n // If we know which device we're targeting (single authenticator), ensure the VRF worker\n // challenge was generated with the same device's VRF keypair. Otherwise contract verification\n // will deterministically fail later with \"Contract verification failed\".\n if (authenticatorsForPrompt.length === 1) {\n const expectedVrfPublicKey = authenticatorsForPrompt[0]?.vrfPublicKey;\n if (expectedVrfPublicKey && expectedVrfPublicKey !== vrfChallenge.vrfPublicKey) {\n throw new Error('Signing session is using a different passkey/VRF session than the current device. Please log in again and retry.');\n }\n }\n\n onBeforePrompt?.({ authenticators, authenticatorsForPrompt, vrfChallenge });\n\n const credential = await ctx.touchIdPrompt.getAuthenticationCredentialsInternal({\n nearAccountId,\n challenge: vrfChallenge,\n allowCredentials: authenticatorsToAllowCredentials(authenticatorsForPrompt),\n });\n\n const serialized = serializeAuthenticationCredentialWithPRF({\n credential,\n firstPrfOutput: true,\n secondPrfOutput: includeSecondPrfOutput,\n });\n\n // Verify that the chosen credential matches the \"current\" passkey device, when applicable.\n const { wrongPasskeyError: wrongSelectedCredentialError } = await ctx.indexedDB.clientDB.ensureCurrentPasskey(\n toAccountId(nearAccountId),\n authenticators,\n serialized.rawId,\n );\n if (wrongSelectedCredentialError) {\n throw new Error(wrongSelectedCredentialError);\n }\n\n return serialized;\n}\n"],"mappings":";;;;;;;;AAQA,eAAsB,uCAAuC,EAC3D,KACA,eACA,cACA,gBACA,yBAAyB,SAeS;CAElC,MAAM,iBAAiB,MAAM,IAAI,UAAU,SAAS,wBAAwB,YAAY;CACxF,MAAM,EAAE,yBAAyB,sBAAsB,MAAM,IAAI,UAAU,SAAS,qBAClF,YAAY,gBACZ;AAEF,KAAI,kBACF,OAAM,IAAI,MAAM;AAMlB,KAAI,wBAAwB,WAAW,GAAG;EACxC,MAAM,uBAAuB,wBAAwB,IAAI;AACzD,MAAI,wBAAwB,yBAAyB,aAAa,aAChE,OAAM,IAAI,MAAM;;AAIpB,kBAAiB;EAAE;EAAgB;EAAyB;;CAE5D,MAAM,aAAa,MAAM,IAAI,cAAc,qCAAqC;EAC9E;EACA,WAAW;EACX,kBAAkB,iCAAiC;;CAGrD,MAAM,aAAa,yCAAyC;EAC1D;EACA,gBAAgB;EAChB,iBAAiB;;CAInB,MAAM,EAAE,mBAAmB,iCAAiC,MAAM,IAAI,UAAU,SAAS,qBACvF,YAAY,gBACZ,gBACA,WAAW;AAEb,KAAI,6BACF,OAAM,IAAI,MAAM;AAGlB,QAAO"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { needsExplicitActivation } from "../../../../../../deviceDetection.js";
|
|
2
|
-
import "../../../../utils/index.js";
|
|
2
|
+
import { init_utils } from "../../../../utils/index.js";
|
|
3
3
|
import { SecureConfirmationType } from "./types.js";
|
|
4
4
|
|
|
5
5
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.ts
|
|
6
|
+
init_utils();
|
|
6
7
|
/**
|
|
7
8
|
* determineConfirmationConfig
|
|
8
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"determineConfirmationConfig.js","names":["cfg: ConfirmationConfig","newUiMode: ConfirmationConfig['uiMode']"],"sources":["../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.ts"],"sourcesContent":["import type { ConfirmationConfig } from '../../../types/signer-worker';\nimport type { VrfWorkerManagerContext } from '../';\nimport type { SecureConfirmRequest } from './types';\nimport { SecureConfirmationType } from './types';\nimport { needsExplicitActivation } from '@/utils';\n\n/**\n * determineConfirmationConfig\n *\n * Computes the effective confirmation UI behavior used by the secure‑confirmation\n * flow by merging inputs and applying safe runtime rules.\n *\n * Order of precedence (highest → lowest):\n * 1) Request‑level override (request.confirmationConfig), when explicitly set.\n * 2) User preferences stored in the wallet host (from IndexedDB via ctx.userPreferencesManager).\n * 3) Runtime safety rules (wallet‑iframe registration/link flows) that may clamp behavior.\n *\n * Wallet‑iframe registration/link safety rule:\n * - When running inside the wallet-iframe host context, always clamp registration/link flows to\n * `{ uiMode: 'modal', behavior: 'requireClick' }` so the user activation happens inside the iframe.\n * This intentionally overrides both user preferences and request-level overrides.\n *\n * Notes\n * - The function is pure (does not mutate the input object) and safe to call multiple times.\n * - Theme and unrelated visual options are preserved in all cases.\n */\nexport function determineConfirmationConfig(\n ctx: VrfWorkerManagerContext,\n request: SecureConfirmRequest | undefined,\n): ConfirmationConfig {\n\n // Merge request‑level override over user preferences\n // Important: drop undefined/null fields from the override so they don't clobber\n // persisted preferences (e.g., behavior) with an undefined value.\n const configBase = ctx.userPreferencesManager.getConfirmationConfig();\n const rawOverride = (request?.confirmationConfig || {}) as Partial<ConfirmationConfig>;\n const cleanedOverride = Object.fromEntries(\n Object.entries(rawOverride).filter(([, v]) => v !== undefined && v !== null)\n ) as Partial<ConfirmationConfig>;\n let cfg: ConfirmationConfig = { ...configBase, ...cleanedOverride } as ConfirmationConfig;\n\n // Normalize theme default\n cfg = { ...cfg, theme: cfg.theme || 'dark' } as ConfirmationConfig;\n // Default decrypt-private-key confirmations to 'skip' UI. The flow collects\n // WebAuthn credentials silently and the worker may follow up with a\n // SHOW_SECURE_PRIVATE_KEY_UI request to display the key.\n if (request?.type === SecureConfirmationType.DECRYPT_PRIVATE_KEY_WITH_PRF) {\n return {\n uiMode: 'skip',\n behavior: cfg.behavior,\n autoProceedDelay: cfg.autoProceedDelay,\n theme: cfg.theme || 'dark',\n // container selection handled by uiMode only\n } as ConfirmationConfig;\n }\n // Detect if running inside an iframe (wallet host context)\n const inIframe = (() => window.self !== window.top)();\n\n // On Safari/iOS or mobile devices without a fresh user activation,\n // clamp to a clickable UI to reliably satisfy WebAuthn requirements.\n // - If caller/user set uiMode: 'skip', promote to 'modal' + requireClick\n // - If behavior is 'autoProceed', upgrade to 'requireClick'\n // Use shared heuristic to decide if explicit activation is necessary\n if (needsExplicitActivation()) {\n const newUiMode: ConfirmationConfig['uiMode'] = (cfg.uiMode === 'skip') ? 'drawer' : cfg.uiMode;\n cfg = {\n ...cfg,\n uiMode: newUiMode,\n behavior: 'requireClick',\n } as ConfirmationConfig;\n }\n\n // In wallet‑iframe host context: registration/link flows default to an explicit click.\n // However, if the effective config explicitly opts into auto‑proceed (or skip), honor it.\n if (\n inIframe &&\n request?.type &&\n (request.type === SecureConfirmationType.REGISTER_ACCOUNT || request.type === SecureConfirmationType.LINK_DEVICE)\n ) {\n // Cross‑origin registration/link flows: always require a visible, clickable confirmation\n // so the click lands inside the wallet iframe and satisfies WebAuthn activation.\n return {\n uiMode: 'modal',\n behavior: 'requireClick',\n autoProceedDelay: cfg.autoProceedDelay,\n theme: cfg.theme || 'dark',\n } as ConfirmationConfig;\n }\n\n // Otherwise honor caller/user configuration\n return cfg;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"determineConfirmationConfig.js","names":["cfg: ConfirmationConfig","newUiMode: ConfirmationConfig['uiMode']"],"sources":["../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/determineConfirmationConfig.ts"],"sourcesContent":["import type { ConfirmationConfig } from '../../../types/signer-worker';\nimport type { VrfWorkerManagerContext } from '../';\nimport type { SecureConfirmRequest } from './types';\nimport { SecureConfirmationType } from './types';\nimport { needsExplicitActivation } from '@/utils';\n\n/**\n * determineConfirmationConfig\n *\n * Computes the effective confirmation UI behavior used by the secure‑confirmation\n * flow by merging inputs and applying safe runtime rules.\n *\n * Order of precedence (highest → lowest):\n * 1) Request‑level override (request.confirmationConfig), when explicitly set.\n * 2) User preferences stored in the wallet host (from IndexedDB via ctx.userPreferencesManager).\n * 3) Runtime safety rules (wallet‑iframe registration/link flows) that may clamp behavior.\n *\n * Wallet‑iframe registration/link safety rule:\n * - When running inside the wallet-iframe host context, always clamp registration/link flows to\n * `{ uiMode: 'modal', behavior: 'requireClick' }` so the user activation happens inside the iframe.\n * This intentionally overrides both user preferences and request-level overrides.\n *\n * Notes\n * - The function is pure (does not mutate the input object) and safe to call multiple times.\n * - Theme and unrelated visual options are preserved in all cases.\n */\nexport function determineConfirmationConfig(\n ctx: VrfWorkerManagerContext,\n request: SecureConfirmRequest | undefined,\n): ConfirmationConfig {\n\n // Merge request‑level override over user preferences\n // Important: drop undefined/null fields from the override so they don't clobber\n // persisted preferences (e.g., behavior) with an undefined value.\n const configBase = ctx.userPreferencesManager.getConfirmationConfig();\n const rawOverride = (request?.confirmationConfig || {}) as Partial<ConfirmationConfig>;\n const cleanedOverride = Object.fromEntries(\n Object.entries(rawOverride).filter(([, v]) => v !== undefined && v !== null)\n ) as Partial<ConfirmationConfig>;\n let cfg: ConfirmationConfig = { ...configBase, ...cleanedOverride } as ConfirmationConfig;\n\n // Normalize theme default\n cfg = { ...cfg, theme: cfg.theme || 'dark' } as ConfirmationConfig;\n // Default decrypt-private-key confirmations to 'skip' UI. The flow collects\n // WebAuthn credentials silently and the worker may follow up with a\n // SHOW_SECURE_PRIVATE_KEY_UI request to display the key.\n if (request?.type === SecureConfirmationType.DECRYPT_PRIVATE_KEY_WITH_PRF) {\n return {\n uiMode: 'skip',\n behavior: cfg.behavior,\n autoProceedDelay: cfg.autoProceedDelay,\n theme: cfg.theme || 'dark',\n // container selection handled by uiMode only\n } as ConfirmationConfig;\n }\n // Detect if running inside an iframe (wallet host context)\n const inIframe = (() => window.self !== window.top)();\n\n // On Safari/iOS or mobile devices without a fresh user activation,\n // clamp to a clickable UI to reliably satisfy WebAuthn requirements.\n // - If caller/user set uiMode: 'skip', promote to 'modal' + requireClick\n // - If behavior is 'autoProceed', upgrade to 'requireClick'\n // Use shared heuristic to decide if explicit activation is necessary\n if (needsExplicitActivation()) {\n const newUiMode: ConfirmationConfig['uiMode'] = (cfg.uiMode === 'skip') ? 'drawer' : cfg.uiMode;\n cfg = {\n ...cfg,\n uiMode: newUiMode,\n behavior: 'requireClick',\n } as ConfirmationConfig;\n }\n\n // In wallet‑iframe host context: registration/link flows default to an explicit click.\n // However, if the effective config explicitly opts into auto‑proceed (or skip), honor it.\n if (\n inIframe &&\n request?.type &&\n (request.type === SecureConfirmationType.REGISTER_ACCOUNT || request.type === SecureConfirmationType.LINK_DEVICE)\n ) {\n // Cross‑origin registration/link flows: always require a visible, clickable confirmation\n // so the click lands inside the wallet iframe and satisfies WebAuthn activation.\n return {\n uiMode: 'modal',\n behavior: 'requireClick',\n autoProceedDelay: cfg.autoProceedDelay,\n theme: cfg.theme || 'dark',\n } as ConfirmationConfig;\n }\n\n // Otherwise honor caller/user configuration\n return cfg;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,4BACd,KACA,SACoB;CAKpB,MAAM,aAAa,IAAI,uBAAuB;CAC9C,MAAM,cAAe,SAAS,sBAAsB;CACpD,MAAM,kBAAkB,OAAO,YAC7B,OAAO,QAAQ,aAAa,QAAQ,GAAG,OAAO,MAAM,UAAa,MAAM;CAEzE,IAAIA,MAA0B;EAAE,GAAG;EAAY,GAAG;;AAGlD,OAAM;EAAE,GAAG;EAAK,OAAO,IAAI,SAAS;;AAIpC,KAAI,SAAS,SAAS,uBAAuB,6BAC3C,QAAO;EACL,QAAQ;EACR,UAAU,IAAI;EACd,kBAAkB,IAAI;EACtB,OAAO,IAAI,SAAS;;CAKxB,MAAM,kBAAkB,OAAO,SAAS,OAAO;AAO/C,KAAI,2BAA2B;EAC7B,MAAMC,YAA2C,IAAI,WAAW,SAAU,WAAW,IAAI;AACzF,QAAM;GACJ,GAAG;GACH,QAAQ;GACR,UAAU;;;AAMd,KACE,YACA,SAAS,SACR,QAAQ,SAAS,uBAAuB,oBAAoB,QAAQ,SAAS,uBAAuB,aAIrG,QAAO;EACL,QAAQ;EACR,UAAU;EACV,kBAAkB,IAAI;EACtB,OAAO,IAAI,SAAS;;AAKxB,QAAO"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRandomVRFChallenge } from "../../../../types/vrf-worker.js";
|
|
1
|
+
import { createRandomVRFChallenge, init_vrf_worker } from "../../../../types/vrf-worker.js";
|
|
2
2
|
import { errorMessage, init_errors } from "../../../../../utils/errors.js";
|
|
3
3
|
import { SecureConfirmationType } from "../types.js";
|
|
4
4
|
import { ERROR_MESSAGES, isUserCancelledSecureConfirm } from "../adapters/common.js";
|
|
@@ -10,6 +10,7 @@ import { createConfirmSession } from "../adapters/session.js";
|
|
|
10
10
|
import { createConfirmTxFlowAdapters } from "../adapters/createAdapters.js";
|
|
11
11
|
|
|
12
12
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.ts
|
|
13
|
+
init_vrf_worker();
|
|
13
14
|
init_errors();
|
|
14
15
|
async function mountExportViewer(payload, confirmationConfig) {
|
|
15
16
|
await ensureDefined(W3A_EXPORT_VIEWER_IFRAME_ID, () => import("../../../LitComponents/ExportPrivateKey/iframe-host.js"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localOnly.js","names":["removeCancelListener: (() => void) | undefined","err: unknown"],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { ConfirmationConfig } from '../../../../types/signer-worker';\nimport {\n SecureConfirmationType,\n TransactionSummary,\n LocalOnlySecureConfirmRequest,\n type ShowSecurePrivateKeyUiPayload,\n} from '../types';\nimport { VRFChallenge } from '../../../../types';\nimport { createRandomVRFChallenge } from '../../../../types/vrf-worker';\nimport { addLitCancelListener } from '../../../LitComponents/lit-events';\nimport { ensureDefined } from '../../../LitComponents/ensure-defined';\nimport { W3A_EXPORT_VIEWER_IFRAME_ID } from '../../../LitComponents/tags';\nimport type { ExportViewerIframeElement } from '../../../LitComponents/ExportPrivateKey/iframe-host';\nimport {\n getNearAccountId,\n getIntentDigest,\n isUserCancelledSecureConfirm,\n ERROR_MESSAGES,\n} from './index';\nimport { errorMessage } from '../../../../../utils/errors';\nimport { createConfirmSession } from '../adapters/session';\nimport { createConfirmTxFlowAdapters } from '../adapters/createAdapters';\n\nasync function mountExportViewer(\n payload: ShowSecurePrivateKeyUiPayload,\n confirmationConfig: ConfirmationConfig,\n): Promise<void> {\n await ensureDefined(W3A_EXPORT_VIEWER_IFRAME_ID, () => import('../../../LitComponents/ExportPrivateKey/iframe-host'));\n const host = document.createElement(W3A_EXPORT_VIEWER_IFRAME_ID) as ExportViewerIframeElement;\n host.theme = payload.theme || confirmationConfig.theme || 'dark';\n host.variant = payload.variant || ((confirmationConfig.uiMode === 'drawer') ? 'drawer' : 'modal');\n host.accountId = payload.nearAccountId;\n host.publicKey = payload.publicKey;\n host.privateKey = payload.privateKey;\n host.loading = false;\n\n window.parent?.postMessage({ type: 'WALLET_UI_OPENED' }, '*');\n document.body.appendChild(host);\n\n let removeCancelListener: (() => void) | undefined;\n removeCancelListener = addLitCancelListener(host, () => {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n removeCancelListener?.();\n host.remove();\n }, { once: true });\n}\n\nexport async function handleLocalOnlyFlow(\n ctx: VrfWorkerManagerContext,\n request: LocalOnlySecureConfirmRequest,\n worker: Worker,\n opts: { confirmationConfig: ConfirmationConfig; transactionSummary: TransactionSummary },\n): Promise<void> {\n\n const { confirmationConfig, transactionSummary } = opts;\n const adapters = createConfirmTxFlowAdapters(ctx);\n const session = createConfirmSession({\n adapters,\n worker,\n request,\n confirmationConfig,\n transactionSummary,\n });\n const nearAccountId = getNearAccountId(request);\n\n // SHOW_SECURE_PRIVATE_KEY_UI: purely visual; keep UI open and return confirmed immediately\n if (request.type === SecureConfirmationType.SHOW_SECURE_PRIVATE_KEY_UI) {\n try {\n await mountExportViewer(request.payload as ShowSecurePrivateKeyUiPayload, confirmationConfig);\n // Keep viewer open; do not close here.\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n });\n return;\n } catch (err: unknown) {\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: errorMessage(err) || 'Failed to render export UI',\n });\n }\n }\n\n // DECRYPT_PRIVATE_KEY_WITH_PRF: collect an authentication credential (with PRF extension results)\n // and return it to the VRF worker; VRF worker extracts PRF outputs internally.\n if (request.type === SecureConfirmationType.DECRYPT_PRIVATE_KEY_WITH_PRF) {\n const vrfChallenge = createRandomVRFChallenge() as VRFChallenge;\n try {\n const credential = await adapters.webauthn.collectAuthenticationCredentialWithPRF({\n nearAccountId,\n vrfChallenge,\n // Offline export / local decrypt needs both PRF outputs so the VRF worker can\n // recover/derive key material without requiring a pre-existing VRF session.\n includeSecondPrfOutput: true,\n });\n // No modal to keep open; export viewer will be shown by a subsequent request.\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n credential,\n });\n\n } catch (err: unknown) {\n const cancelled = isUserCancelledSecureConfirm(err);\n if (cancelled) {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n }\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: cancelled ? ERROR_MESSAGES.cancelled : ERROR_MESSAGES.collectCredentialsFailed,\n });\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"localOnly.js","names":["removeCancelListener: (() => void) | undefined","err: unknown"],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { ConfirmationConfig } from '../../../../types/signer-worker';\nimport {\n SecureConfirmationType,\n TransactionSummary,\n LocalOnlySecureConfirmRequest,\n type ShowSecurePrivateKeyUiPayload,\n} from '../types';\nimport { VRFChallenge } from '../../../../types';\nimport { createRandomVRFChallenge } from '../../../../types/vrf-worker';\nimport { addLitCancelListener } from '../../../LitComponents/lit-events';\nimport { ensureDefined } from '../../../LitComponents/ensure-defined';\nimport { W3A_EXPORT_VIEWER_IFRAME_ID } from '../../../LitComponents/tags';\nimport type { ExportViewerIframeElement } from '../../../LitComponents/ExportPrivateKey/iframe-host';\nimport {\n getNearAccountId,\n getIntentDigest,\n isUserCancelledSecureConfirm,\n ERROR_MESSAGES,\n} from './index';\nimport { errorMessage } from '../../../../../utils/errors';\nimport { createConfirmSession } from '../adapters/session';\nimport { createConfirmTxFlowAdapters } from '../adapters/createAdapters';\n\nasync function mountExportViewer(\n payload: ShowSecurePrivateKeyUiPayload,\n confirmationConfig: ConfirmationConfig,\n): Promise<void> {\n await ensureDefined(W3A_EXPORT_VIEWER_IFRAME_ID, () => import('../../../LitComponents/ExportPrivateKey/iframe-host'));\n const host = document.createElement(W3A_EXPORT_VIEWER_IFRAME_ID) as ExportViewerIframeElement;\n host.theme = payload.theme || confirmationConfig.theme || 'dark';\n host.variant = payload.variant || ((confirmationConfig.uiMode === 'drawer') ? 'drawer' : 'modal');\n host.accountId = payload.nearAccountId;\n host.publicKey = payload.publicKey;\n host.privateKey = payload.privateKey;\n host.loading = false;\n\n window.parent?.postMessage({ type: 'WALLET_UI_OPENED' }, '*');\n document.body.appendChild(host);\n\n let removeCancelListener: (() => void) | undefined;\n removeCancelListener = addLitCancelListener(host, () => {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n removeCancelListener?.();\n host.remove();\n }, { once: true });\n}\n\nexport async function handleLocalOnlyFlow(\n ctx: VrfWorkerManagerContext,\n request: LocalOnlySecureConfirmRequest,\n worker: Worker,\n opts: { confirmationConfig: ConfirmationConfig; transactionSummary: TransactionSummary },\n): Promise<void> {\n\n const { confirmationConfig, transactionSummary } = opts;\n const adapters = createConfirmTxFlowAdapters(ctx);\n const session = createConfirmSession({\n adapters,\n worker,\n request,\n confirmationConfig,\n transactionSummary,\n });\n const nearAccountId = getNearAccountId(request);\n\n // SHOW_SECURE_PRIVATE_KEY_UI: purely visual; keep UI open and return confirmed immediately\n if (request.type === SecureConfirmationType.SHOW_SECURE_PRIVATE_KEY_UI) {\n try {\n await mountExportViewer(request.payload as ShowSecurePrivateKeyUiPayload, confirmationConfig);\n // Keep viewer open; do not close here.\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n });\n return;\n } catch (err: unknown) {\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: errorMessage(err) || 'Failed to render export UI',\n });\n }\n }\n\n // DECRYPT_PRIVATE_KEY_WITH_PRF: collect an authentication credential (with PRF extension results)\n // and return it to the VRF worker; VRF worker extracts PRF outputs internally.\n if (request.type === SecureConfirmationType.DECRYPT_PRIVATE_KEY_WITH_PRF) {\n const vrfChallenge = createRandomVRFChallenge() as VRFChallenge;\n try {\n const credential = await adapters.webauthn.collectAuthenticationCredentialWithPRF({\n nearAccountId,\n vrfChallenge,\n // Offline export / local decrypt needs both PRF outputs so the VRF worker can\n // recover/derive key material without requiring a pre-existing VRF session.\n includeSecondPrfOutput: true,\n });\n // No modal to keep open; export viewer will be shown by a subsequent request.\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n credential,\n });\n\n } catch (err: unknown) {\n const cancelled = isUserCancelledSecureConfirm(err);\n if (cancelled) {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n }\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: cancelled ? ERROR_MESSAGES.cancelled : ERROR_MESSAGES.collectCredentialsFailed,\n });\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAwBA,eAAe,kBACb,SACA,oBACe;AACf,OAAM,cAAc,mCAAmC,OAAO;CAC9D,MAAM,OAAO,SAAS,cAAc;AACpC,MAAK,QAAQ,QAAQ,SAAS,mBAAmB,SAAS;AAC1D,MAAK,UAAU,QAAQ,YAAa,mBAAmB,WAAW,WAAY,WAAW;AACzF,MAAK,YAAY,QAAQ;AACzB,MAAK,YAAY,QAAQ;AACzB,MAAK,aAAa,QAAQ;AAC1B,MAAK,UAAU;AAEf,QAAO,QAAQ,YAAY,EAAE,MAAM,sBAAsB;AACzD,UAAS,KAAK,YAAY;CAE1B,IAAIA;AACJ,wBAAuB,qBAAqB,YAAY;AACtD,SAAO,QAAQ,YAAY,EAAE,MAAM,sBAAsB;AACzD;AACA,OAAK;IACJ,EAAE,MAAM;;AAGb,eAAsB,oBACpB,KACA,SACA,QACA,MACe;CAEf,MAAM,EAAE,oBAAoB,uBAAuB;CACnD,MAAM,WAAW,4BAA4B;CAC7C,MAAM,UAAU,qBAAqB;EACnC;EACA;EACA;EACA;EACA;;CAEF,MAAM,gBAAgB,iBAAiB;AAGvC,KAAI,QAAQ,SAAS,uBAAuB,2BAC1C,KAAI;AACF,QAAM,kBAAkB,QAAQ,SAA0C;AAE1E,UAAQ,qBAAqB;GAC3B,WAAW,QAAQ;GACnB,cAAc,gBAAgB;GAC9B,WAAW;;AAEb;UACOC,KAAc;AACrB,SAAO,QAAQ,qBAAqB;GAClC,WAAW,QAAQ;GACnB,cAAc,gBAAgB;GAC9B,WAAW;GACX,OAAO,aAAa,QAAQ;;;AAOlC,KAAI,QAAQ,SAAS,uBAAuB,8BAA8B;EACxE,MAAM,eAAe;AACrB,MAAI;GACF,MAAM,aAAa,MAAM,SAAS,SAAS,uCAAuC;IAChF;IACA;IAGA,wBAAwB;;AAG1B,UAAO,QAAQ,qBAAqB;IAClC,WAAW,QAAQ;IACnB,cAAc,gBAAgB;IAC9B,WAAW;IACX;;WAGKA,KAAc;GACrB,MAAM,YAAY,6BAA6B;AAC/C,OAAI,UACF,QAAO,QAAQ,YAAY,EAAE,MAAM,sBAAsB;AAE3D,UAAO,QAAQ,qBAAqB;IAClC,WAAW,QAAQ;IACnB,cAAc,gBAAgB;IAC9B,WAAW;IACX,OAAO,YAAY,eAAe,YAAY,eAAe"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { init_errors, toError } from "../../../../../utils/errors.js";
|
|
2
|
-
import { isSerializedRegistrationCredential, serializeRegistrationCredentialWithPRF } from "../../../credentialsHelpers.js";
|
|
2
|
+
import { init_credentialsHelpers, isSerializedRegistrationCredential, serializeRegistrationCredentialWithPRF } from "../../../credentialsHelpers.js";
|
|
3
3
|
import { ERROR_MESSAGES, isUserCancelledSecureConfirm } from "../adapters/common.js";
|
|
4
4
|
import { getIntentDigest, getNearAccountId, getRegisterAccountPayload } from "../adapters/requestHelpers.js";
|
|
5
5
|
import { createConfirmSession } from "../adapters/session.js";
|
|
6
6
|
import { createConfirmTxFlowAdapters } from "../adapters/createAdapters.js";
|
|
7
7
|
|
|
8
8
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.ts
|
|
9
|
+
init_credentialsHelpers();
|
|
9
10
|
init_errors();
|
|
10
11
|
async function handleRegistrationFlow(ctx, request, worker, opts) {
|
|
11
12
|
const { confirmationConfig, transactionSummary } = opts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.js","names":["uiVrfChallenge: VRFChallenge","credential: PublicKeyCredential | undefined","e: unknown","serialized: WebAuthnRegistrationCredential","err: unknown"],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { ConfirmationConfig } from '../../../../types/signer-worker';\nimport {\n TransactionSummary,\n RegistrationSecureConfirmRequest,\n} from '../types';\nimport { VRFChallenge, TransactionContext } from '../../../../types';\nimport type { WebAuthnRegistrationCredential } from '../../../../types/webauthn';\nimport {\n getNearAccountId,\n getIntentDigest,\n isUserCancelledSecureConfirm,\n ERROR_MESSAGES,\n getRegisterAccountPayload,\n} from './index';\nimport { isSerializedRegistrationCredential, serializeRegistrationCredentialWithPRF } from '../../../credentialsHelpers';\nimport { toError } from '../../../../../utils/errors';\nimport { createConfirmSession } from '../adapters/session';\nimport { createConfirmTxFlowAdapters } from '../adapters/createAdapters';\n\nexport async function handleRegistrationFlow(\n ctx: VrfWorkerManagerContext,\n request: RegistrationSecureConfirmRequest,\n worker: Worker,\n opts: { confirmationConfig: ConfirmationConfig; transactionSummary: TransactionSummary },\n): Promise<void> {\n\n const { confirmationConfig, transactionSummary } = opts;\n const adapters = createConfirmTxFlowAdapters(ctx);\n const session = createConfirmSession({\n adapters,\n worker,\n request,\n confirmationConfig,\n transactionSummary,\n });\n const nearAccountId = getNearAccountId(request);\n\n console.debug('[RegistrationFlow] start', {\n nearAccountId,\n uiMode: confirmationConfig?.uiMode,\n behavior: confirmationConfig?.behavior,\n theme: confirmationConfig?.theme,\n intentDigest: transactionSummary?.intentDigest,\n });\n\n // 1) NEAR context\n const nearRpc = await adapters.near.fetchNearContext({ nearAccountId, txCount: 1, reserveNonces: true });\n if (nearRpc.error && !nearRpc.transactionContext) {\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: `${ERROR_MESSAGES.nearRpcFailed}: ${nearRpc.details}`,\n });\n }\n const transactionContext = nearRpc.transactionContext as TransactionContext;\n session.setReservedNonces(nearRpc.reservedNonces);\n\n // 2) Initial VRF challenge via bootstrap\n const rpId = adapters.vrf.getRpId();\n const bootstrap = await adapters.vrf.generateVrfKeypairBootstrap({\n vrfInputData: {\n userId: nearAccountId,\n rpId,\n blockHeight: transactionContext.txBlockHeight,\n blockHash: transactionContext.txBlockHash,\n },\n saveInMemory: true,\n sessionId: request.requestId,\n });\n let uiVrfChallenge: VRFChallenge = bootstrap.vrfChallenge;\n console.debug('[RegistrationFlow] VRF bootstrap ok', { blockHeight: uiVrfChallenge.blockHeight });\n\n // 3) UI confirm\n const { confirmed, error: uiError } = await session.promptUser({ vrfChallenge: uiVrfChallenge });\n if (!confirmed) {\n console.debug('[RegistrationFlow] user cancelled');\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: uiError,\n });\n }\n\n // 4) JIT refresh VRF (best-effort)\n try {\n const refreshed = await adapters.vrf.maybeRefreshVrfChallenge(request, nearAccountId);\n uiVrfChallenge = refreshed.vrfChallenge;\n session.updateUI({ vrfChallenge: uiVrfChallenge });\n console.debug('[RegistrationFlow] VRF JIT refresh ok', { blockHeight: uiVrfChallenge.blockHeight });\n } catch (e) {\n console.debug('[RegistrationFlow] VRF JIT refresh skipped', e);\n }\n\n // 5) Collect registration credentials (with duplicate retry)\n let credential: PublicKeyCredential | undefined;\n let deviceNumber = request.payload?.deviceNumber;\n\n const tryCreate = async (dn?: number): Promise<PublicKeyCredential> => {\n console.debug('[RegistrationFlow] navigator.credentials.create start', { deviceNumber: dn });\n return await adapters.webauthn.createRegistrationCredential({\n nearAccountId,\n challenge: uiVrfChallenge,\n deviceNumber: dn,\n });\n };\n\n try {\n try {\n credential = await tryCreate(deviceNumber);\n console.debug('[RegistrationFlow] credentials.create ok');\n } catch (e: unknown) {\n const err = toError(e);\n const name = String(err?.name || '');\n const msg = String(err?.message || '');\n const isDuplicate = name === 'InvalidStateError' || /excluded|already\\s*registered/i.test(msg);\n if (isDuplicate) {\n const nextDeviceNumber = (deviceNumber !== undefined && Number.isFinite(deviceNumber)) ? (deviceNumber + 1) : 2;\n console.debug('[RegistrationFlow] duplicate credential, retry with next deviceNumber', { nextDeviceNumber });\n credential = await tryCreate(nextDeviceNumber);\n getRegisterAccountPayload(request).deviceNumber = nextDeviceNumber;\n } else {\n console.error('[RegistrationFlow] credentials.create failed (non-duplicate)', { name, msg });\n throw err;\n }\n }\n\n // We require registration credentials to include dual PRF outputs (first + second)\n // so VRF/NEAR key derivation can happen inside the workers without passing PRF outputs\n // as separate main-thread values.\n const serialized: WebAuthnRegistrationCredential = isSerializedRegistrationCredential(credential as unknown)\n ? (credential as unknown as WebAuthnRegistrationCredential)\n : serializeRegistrationCredentialWithPRF({\n credential: credential! as PublicKeyCredential,\n firstPrfOutput: true,\n secondPrfOutput: true,\n });\n\n // 6) Respond + close\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n credential: serialized,\n // PRF outputs are embedded in serialized credential; VRF worker extracts and sends via MessagePort\n vrfChallenge: uiVrfChallenge,\n transactionContext,\n });\n\n } catch (err: unknown) {\n const cancelled = isUserCancelledSecureConfirm(err);\n const msg = String((toError(err))?.message || err || '');\n // For missing PRF outputs, surface the error to caller (defensive path tests expect a throw)\n if (/Missing PRF result/i.test(msg) || /Missing PRF results/i.test(msg)) {\n return session.cleanupAndRethrow(err);\n }\n if (cancelled) {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n }\n\n const isPrfBrowserUnsupported =\n /WebAuthn PRF output is missing from navigator\\.credentials\\.create\\(\\)/i.test(msg)\n || /does not fully support the WebAuthn PRF extension during registration/i.test(msg)\n || /roaming hardware authenticators .* not supported in this flow/i.test(msg);\n\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: cancelled\n ? ERROR_MESSAGES.cancelled\n : (isPrfBrowserUnsupported ? msg : ERROR_MESSAGES.collectCredentialsFailed),\n });\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"registration.js","names":["uiVrfChallenge: VRFChallenge","credential: PublicKeyCredential | undefined","e: unknown","serialized: WebAuthnRegistrationCredential","err: unknown"],"sources":["../../../../../../../../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { ConfirmationConfig } from '../../../../types/signer-worker';\nimport {\n TransactionSummary,\n RegistrationSecureConfirmRequest,\n} from '../types';\nimport { VRFChallenge, TransactionContext } from '../../../../types';\nimport type { WebAuthnRegistrationCredential } from '../../../../types/webauthn';\nimport {\n getNearAccountId,\n getIntentDigest,\n isUserCancelledSecureConfirm,\n ERROR_MESSAGES,\n getRegisterAccountPayload,\n} from './index';\nimport { isSerializedRegistrationCredential, serializeRegistrationCredentialWithPRF } from '../../../credentialsHelpers';\nimport { toError } from '../../../../../utils/errors';\nimport { createConfirmSession } from '../adapters/session';\nimport { createConfirmTxFlowAdapters } from '../adapters/createAdapters';\n\nexport async function handleRegistrationFlow(\n ctx: VrfWorkerManagerContext,\n request: RegistrationSecureConfirmRequest,\n worker: Worker,\n opts: { confirmationConfig: ConfirmationConfig; transactionSummary: TransactionSummary },\n): Promise<void> {\n\n const { confirmationConfig, transactionSummary } = opts;\n const adapters = createConfirmTxFlowAdapters(ctx);\n const session = createConfirmSession({\n adapters,\n worker,\n request,\n confirmationConfig,\n transactionSummary,\n });\n const nearAccountId = getNearAccountId(request);\n\n console.debug('[RegistrationFlow] start', {\n nearAccountId,\n uiMode: confirmationConfig?.uiMode,\n behavior: confirmationConfig?.behavior,\n theme: confirmationConfig?.theme,\n intentDigest: transactionSummary?.intentDigest,\n });\n\n // 1) NEAR context\n const nearRpc = await adapters.near.fetchNearContext({ nearAccountId, txCount: 1, reserveNonces: true });\n if (nearRpc.error && !nearRpc.transactionContext) {\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: `${ERROR_MESSAGES.nearRpcFailed}: ${nearRpc.details}`,\n });\n }\n const transactionContext = nearRpc.transactionContext as TransactionContext;\n session.setReservedNonces(nearRpc.reservedNonces);\n\n // 2) Initial VRF challenge via bootstrap\n const rpId = adapters.vrf.getRpId();\n const bootstrap = await adapters.vrf.generateVrfKeypairBootstrap({\n vrfInputData: {\n userId: nearAccountId,\n rpId,\n blockHeight: transactionContext.txBlockHeight,\n blockHash: transactionContext.txBlockHash,\n },\n saveInMemory: true,\n sessionId: request.requestId,\n });\n let uiVrfChallenge: VRFChallenge = bootstrap.vrfChallenge;\n console.debug('[RegistrationFlow] VRF bootstrap ok', { blockHeight: uiVrfChallenge.blockHeight });\n\n // 3) UI confirm\n const { confirmed, error: uiError } = await session.promptUser({ vrfChallenge: uiVrfChallenge });\n if (!confirmed) {\n console.debug('[RegistrationFlow] user cancelled');\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: uiError,\n });\n }\n\n // 4) JIT refresh VRF (best-effort)\n try {\n const refreshed = await adapters.vrf.maybeRefreshVrfChallenge(request, nearAccountId);\n uiVrfChallenge = refreshed.vrfChallenge;\n session.updateUI({ vrfChallenge: uiVrfChallenge });\n console.debug('[RegistrationFlow] VRF JIT refresh ok', { blockHeight: uiVrfChallenge.blockHeight });\n } catch (e) {\n console.debug('[RegistrationFlow] VRF JIT refresh skipped', e);\n }\n\n // 5) Collect registration credentials (with duplicate retry)\n let credential: PublicKeyCredential | undefined;\n let deviceNumber = request.payload?.deviceNumber;\n\n const tryCreate = async (dn?: number): Promise<PublicKeyCredential> => {\n console.debug('[RegistrationFlow] navigator.credentials.create start', { deviceNumber: dn });\n return await adapters.webauthn.createRegistrationCredential({\n nearAccountId,\n challenge: uiVrfChallenge,\n deviceNumber: dn,\n });\n };\n\n try {\n try {\n credential = await tryCreate(deviceNumber);\n console.debug('[RegistrationFlow] credentials.create ok');\n } catch (e: unknown) {\n const err = toError(e);\n const name = String(err?.name || '');\n const msg = String(err?.message || '');\n const isDuplicate = name === 'InvalidStateError' || /excluded|already\\s*registered/i.test(msg);\n if (isDuplicate) {\n const nextDeviceNumber = (deviceNumber !== undefined && Number.isFinite(deviceNumber)) ? (deviceNumber + 1) : 2;\n console.debug('[RegistrationFlow] duplicate credential, retry with next deviceNumber', { nextDeviceNumber });\n credential = await tryCreate(nextDeviceNumber);\n getRegisterAccountPayload(request).deviceNumber = nextDeviceNumber;\n } else {\n console.error('[RegistrationFlow] credentials.create failed (non-duplicate)', { name, msg });\n throw err;\n }\n }\n\n // We require registration credentials to include dual PRF outputs (first + second)\n // so VRF/NEAR key derivation can happen inside the workers without passing PRF outputs\n // as separate main-thread values.\n const serialized: WebAuthnRegistrationCredential = isSerializedRegistrationCredential(credential as unknown)\n ? (credential as unknown as WebAuthnRegistrationCredential)\n : serializeRegistrationCredentialWithPRF({\n credential: credential! as PublicKeyCredential,\n firstPrfOutput: true,\n secondPrfOutput: true,\n });\n\n // 6) Respond + close\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n credential: serialized,\n // PRF outputs are embedded in serialized credential; VRF worker extracts and sends via MessagePort\n vrfChallenge: uiVrfChallenge,\n transactionContext,\n });\n\n } catch (err: unknown) {\n const cancelled = isUserCancelledSecureConfirm(err);\n const msg = String((toError(err))?.message || err || '');\n // For missing PRF outputs, surface the error to caller (defensive path tests expect a throw)\n if (/Missing PRF result/i.test(msg) || /Missing PRF results/i.test(msg)) {\n return session.cleanupAndRethrow(err);\n }\n if (cancelled) {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n }\n\n const isPrfBrowserUnsupported =\n /WebAuthn PRF output is missing from navigator\\.credentials\\.create\\(\\)/i.test(msg)\n || /does not fully support the WebAuthn PRF extension during registration/i.test(msg)\n || /roaming hardware authenticators .* not supported in this flow/i.test(msg);\n\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: cancelled\n ? ERROR_MESSAGES.cancelled\n : (isPrfBrowserUnsupported ? msg : ERROR_MESSAGES.collectCredentialsFailed),\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { init_accountIds, toAccountId } from "../../../../types/accountIds.js";
|
|
2
2
|
import { init_errors, toError } from "../../../../../utils/errors.js";
|
|
3
3
|
import { PASSKEY_MANAGER_DEFAULT_CONFIGS, init_defaultConfigs } from "../../../../defaultConfigs.js";
|
|
4
|
-
import { getLastLoggedInDeviceNumber } from "../../../SignerWorkerManager/getDeviceNumber.js";
|
|
4
|
+
import { getLastLoggedInDeviceNumber, init_getDeviceNumber } from "../../../SignerWorkerManager/getDeviceNumber.js";
|
|
5
5
|
import { SecureConfirmationType } from "../types.js";
|
|
6
6
|
import { ERROR_MESSAGES, isUserCancelledSecureConfirm } from "../adapters/common.js";
|
|
7
7
|
import { getIntentDigest, getNearAccountId, getSignTransactionPayload, getTxCount } from "../adapters/requestHelpers.js";
|
|
@@ -10,6 +10,7 @@ import { createConfirmTxFlowAdapters } from "../adapters/createAdapters.js";
|
|
|
10
10
|
|
|
11
11
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.ts
|
|
12
12
|
init_accountIds();
|
|
13
|
+
init_getDeviceNumber();
|
|
13
14
|
init_errors();
|
|
14
15
|
init_defaultConfigs();
|
|
15
16
|
function getSigningAuthMode(request) {
|
|
@@ -111,20 +112,10 @@ async function handleTransactionSigningFlow(ctx, request, worker, opts) {
|
|
|
111
112
|
if (!uiVrfChallenge) throw new Error("Missing vrfChallenge for WebAuthn signing flow");
|
|
112
113
|
const serializedCredential = await adapters.webauthn.collectAuthenticationCredentialWithPRF({
|
|
113
114
|
nearAccountId,
|
|
114
|
-
vrfChallenge: uiVrfChallenge
|
|
115
|
-
onBeforePrompt: ({ authenticatorsForPrompt, vrfChallenge }) => {
|
|
116
|
-
console.debug("[SigningFlow] Authenticators for transaction signing", {
|
|
117
|
-
nearAccountId,
|
|
118
|
-
authenticatorCount: authenticatorsForPrompt.length,
|
|
119
|
-
authenticators: authenticatorsForPrompt.map((a) => ({
|
|
120
|
-
deviceNumber: a.deviceNumber,
|
|
121
|
-
vrfPublicKey: a.vrfPublicKey,
|
|
122
|
-
credentialId: a.credentialId
|
|
123
|
-
})),
|
|
124
|
-
vrfChallengePublicKey: vrfChallenge.vrfPublicKey
|
|
125
|
-
});
|
|
126
|
-
}
|
|
115
|
+
vrfChallenge: uiVrfChallenge
|
|
127
116
|
});
|
|
117
|
+
let contractId;
|
|
118
|
+
let nearRpcUrl;
|
|
128
119
|
try {
|
|
129
120
|
const vrfStatus = await adapters.vrf.checkVrfStatus();
|
|
130
121
|
if (!vrfStatus.active) throw new Error("VRF keypair not active in memory. VRF session may have expired or was not properly initialized. Please refresh and try again.");
|
|
@@ -133,8 +124,6 @@ async function handleTransactionSigningFlow(ctx, request, worker, opts) {
|
|
|
133
124
|
const encryptedKeyData = await ctx.indexedDB.nearKeysDB.getEncryptedKey(nearAccountId, deviceNumber);
|
|
134
125
|
const wrapKeySalt = encryptedKeyData?.wrapKeySalt || "";
|
|
135
126
|
if (!wrapKeySalt) throw new Error("Missing wrapKeySalt in vault; re-register to upgrade vault format.");
|
|
136
|
-
let contractId;
|
|
137
|
-
let nearRpcUrl;
|
|
138
127
|
if (request.type === SecureConfirmationType.SIGN_TRANSACTION) {
|
|
139
128
|
const payload = getSignTransactionPayload(request);
|
|
140
129
|
contractId = payload?.rpcCall?.contractId;
|