@tatchi-xyz/sdk 0.17.0 → 0.19.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 -20
- package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js +507 -452
- package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/cjs/core/TatchiPasskey/index.js +1 -0
- package/dist/cjs/core/TatchiPasskey/index.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/WalletIframe/client/IframeTransport.js +0 -7
- package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
- package/dist/cjs/core/WalletIframe/client/router.js +6 -2
- package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -1
- package/dist/cjs/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/cjs/core/WebAuthnManager/index.js +23 -0
- package/dist/cjs/core/WebAuthnManager/index.js.map +1 -1
- package/dist/cjs/core/rpcCalls.js +8 -0
- package/dist/cjs/core/rpcCalls.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-B6api181.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-B-DrG_u5.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
- package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css → TouchIcon-BQWentvJ.css} +1 -1
- package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css → PasskeyAuthMenu-DwrzWMYx.css} +1 -1
- package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
- package/dist/cjs/react/components/{ShowQRCode-nZhZSaba.css → ShowQRCode-CCN4h6Uv.css} +1 -1
- package/dist/cjs/react/components/{ShowQRCode-nZhZSaba.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
- package/dist/cjs/react/hooks/usePreconnectWalletAssets.js +27 -32
- package/dist/cjs/react/hooks/usePreconnectWalletAssets.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 -20
- package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +507 -452
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +1 -0
- package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.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/WalletIframe/client/IframeTransport.js +0 -7
- 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 +6 -2
- package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +1 -1
- 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/flows/localOnly.js +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.js +23 -0
- package/dist/cjs/react/sdk/src/core/WebAuthnManager/index.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/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 -21
- package/dist/esm/core/EmailRecovery/index.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/emailRecovery.js +507 -452
- package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/esm/core/TatchiPasskey/index.js +2 -1
- package/dist/esm/core/TatchiPasskey/index.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/WalletIframe/client/IframeTransport.js +0 -7
- package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
- package/dist/esm/core/WalletIframe/client/router.js +7 -3
- package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js +1 -1
- package/dist/esm/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/localOnly.js.map +1 -1
- package/dist/esm/core/WebAuthnManager/index.js +23 -0
- package/dist/esm/core/WebAuthnManager/index.js.map +1 -1
- package/dist/esm/core/rpcCalls.js +8 -1
- package/dist/esm/core/rpcCalls.js.map +1 -1
- package/dist/esm/index.js +4 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-B6api181.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-B-DrG_u5.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
- package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css → TouchIcon-BQWentvJ.css} +1 -1
- package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css → PasskeyAuthMenu-DwrzWMYx.css} +1 -1
- package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
- package/dist/esm/react/components/{ShowQRCode-nZhZSaba.css → ShowQRCode-CCN4h6Uv.css} +1 -1
- package/dist/esm/react/components/{ShowQRCode-nZhZSaba.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
- package/dist/esm/react/hooks/usePreconnectWalletAssets.js +27 -32
- package/dist/esm/react/hooks/usePreconnectWalletAssets.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 -21
- package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +507 -452
- package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +2 -1
- package/dist/esm/react/sdk/src/core/TatchiPasskey/index.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/WalletIframe/client/IframeTransport.js +0 -7
- 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 +7 -3
- package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
- package/dist/esm/react/sdk/src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/adapters/webauthn.js +1 -1
- 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/flows/localOnly.js +1 -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/index.js +23 -0
- package/dist/esm/react/sdk/src/core/WebAuthnManager/index.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/sdk/{createAdapters-qVGD6i0g.js → createAdapters-DIRR8_Z9.js} +1 -1
- package/dist/esm/sdk/{createAdapters-BumKM2ft.js → createAdapters-Yga6W0en.js} +2 -2
- package/dist/esm/sdk/{createAdapters-BumKM2ft.js.map → createAdapters-Yga6W0en.js.map} +1 -1
- package/dist/esm/sdk/{localOnly-pXMTqh1m.js → localOnly-BHScJasw.js} +2 -2
- package/dist/esm/sdk/{localOnly-Byi3AK7A.js → localOnly-VevCI7H0.js} +3 -3
- package/dist/esm/sdk/{localOnly-Byi3AK7A.js.map → localOnly-VevCI7H0.js.map} +1 -1
- package/dist/esm/sdk/offline-export-app.js +29 -6
- package/dist/esm/sdk/offline-export-app.js.map +1 -1
- package/dist/esm/sdk/{registration-CBiS4Ua_.js → registration-bKEg9Zr2.js} +2 -2
- package/dist/esm/sdk/{registration-CBiS4Ua_.js.map → registration-bKEg9Zr2.js.map} +1 -1
- package/dist/esm/sdk/{registration-DLPLsGCz.js → registration-lDD60Ytt.js} +1 -1
- package/dist/esm/sdk/{router-BLFegW7J.js → router-DuGYOd3G.js} +6 -9
- package/dist/esm/sdk/{rpcCalls-DEv9x5-f.js → rpcCalls-BQrJMTdg.js} +2 -2
- package/dist/esm/sdk/{rpcCalls-OhgEeFig.js → rpcCalls-YVeUVMk2.js} +8 -1
- package/dist/esm/sdk/{transactions-Bk-VavcV.js → transactions-BalIhtJ9.js} +1 -1
- package/dist/esm/sdk/{transactions-BIqKZeR0.js → transactions-bqaAwL4k.js} +2 -2
- package/dist/esm/sdk/{transactions-BIqKZeR0.js.map → transactions-bqaAwL4k.js.map} +1 -1
- package/dist/esm/sdk/wallet-iframe-host.js +641 -481
- 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/TatchiPasskey/emailRecovery.d.ts +38 -6
- package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
- package/dist/types/src/core/TatchiPasskey/index.d.ts +2 -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/client/IframeTransport.d.ts.map +1 -1
- package/dist/types/src/core/WalletIframe/client/router.d.ts +3 -3
- package/dist/types/src/core/WalletIframe/client/router.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/index.d.ts +7 -0
- package/dist/types/src/core/WebAuthnManager/index.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/hooks/usePreconnectWalletAssets.d.ts.map +1 -1
- package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ERROR_MESSAGES, getIntentDigest, getNearAccountId, getRegisterAccountPayload, isSerializedRegistrationCredential, isUserCancelledSecureConfirm, serializeRegistrationCredentialWithPRF, toError } from "./requestHelpers-aUKhXiEl.js";
|
|
2
2
|
import "./validation-DhPPUba7.js";
|
|
3
|
-
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-
|
|
3
|
+
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-Yga6W0en.js";
|
|
4
4
|
import "./css-loader-BrMMlG4X.js";
|
|
5
5
|
import "./lit-events-BKobq01K.js";
|
|
6
6
|
import "./tx-tree-themes-i3It4IYY.js";
|
|
@@ -130,4 +130,4 @@ async function handleRegistrationFlow(ctx, request, worker, opts) {
|
|
|
130
130
|
|
|
131
131
|
//#endregion
|
|
132
132
|
export { handleRegistrationFlow };
|
|
133
|
-
//# sourceMappingURL=registration-
|
|
133
|
+
//# sourceMappingURL=registration-bKEg9Zr2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-
|
|
1
|
+
{"version":3,"file":"registration-bKEg9Zr2.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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"}
|
|
@@ -11,7 +11,7 @@ import "./tx-confirmer-wrapper-lHNgz9i4.js";
|
|
|
11
11
|
import { init_errors, toError } from "./errors-D9ar28Dr.js";
|
|
12
12
|
import { init_credentialsHelpers, isSerializedRegistrationCredential, serializeRegistrationCredentialWithPRF } from "./WebAuthnFallbacks-Bl4BTsNt.js";
|
|
13
13
|
import { ERROR_MESSAGES, getIntentDigest, getNearAccountId, getRegisterAccountPayload, isUserCancelledSecureConfirm } from "./requestHelpers-Dh1hEYL9.js";
|
|
14
|
-
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-
|
|
14
|
+
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-DIRR8_Z9.js";
|
|
15
15
|
|
|
16
16
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/registration.ts
|
|
17
17
|
init_credentialsHelpers();
|
|
@@ -355,13 +355,6 @@ var IframeTransport = class {
|
|
|
355
355
|
connectTimeoutMs: 8e3,
|
|
356
356
|
...options
|
|
357
357
|
};
|
|
358
|
-
try {
|
|
359
|
-
const walletUrl = new URL(this.opts.walletOrigin);
|
|
360
|
-
if (walletUrl.protocol === "chrome-extension:") {
|
|
361
|
-
const trimmed = (this.opts.servicePath || "/wallet-service").replace(/\/+$/, "");
|
|
362
|
-
if (trimmed === "/wallet-service") this.opts.servicePath = "/wallet-service.html";
|
|
363
|
-
}
|
|
364
|
-
} catch {}
|
|
365
358
|
try {
|
|
366
359
|
this.walletServiceUrl = new URL(this.opts.servicePath, this.opts.walletOrigin);
|
|
367
360
|
} catch (err) {
|
|
@@ -1407,7 +1400,7 @@ var WalletIframeRouter = class {
|
|
|
1407
1400
|
recoveryEmail: payload.recoveryEmail,
|
|
1408
1401
|
options: safeOptions && Object.keys(safeOptions).length > 0 ? safeOptions : void 0
|
|
1409
1402
|
},
|
|
1410
|
-
options: { onProgress: payload.onEvent }
|
|
1403
|
+
options: { onProgress: this.wrapOnEvent(payload.onEvent, isEmailRecoverySSEEvent) }
|
|
1411
1404
|
});
|
|
1412
1405
|
return res.result;
|
|
1413
1406
|
}
|
|
@@ -1418,7 +1411,7 @@ var WalletIframeRouter = class {
|
|
|
1418
1411
|
accountId: payload.accountId,
|
|
1419
1412
|
nearPublicKey: payload.nearPublicKey
|
|
1420
1413
|
},
|
|
1421
|
-
options: { onProgress: payload.onEvent }
|
|
1414
|
+
options: { onProgress: this.wrapOnEvent(payload.onEvent, isEmailRecoverySSEEvent) }
|
|
1422
1415
|
});
|
|
1423
1416
|
}
|
|
1424
1417
|
async stopEmailRecovery(payload) {
|
|
@@ -1758,6 +1751,7 @@ const LOGIN_PHASES = new Set(Object.values(LoginPhase));
|
|
|
1758
1751
|
const ACTION_PHASES = new Set(Object.values(ActionPhase));
|
|
1759
1752
|
const DEVICE_LINKING_PHASES = new Set(Object.values(DeviceLinkingPhase));
|
|
1760
1753
|
const ACCOUNT_RECOVERY_PHASES = new Set(Object.values(AccountRecoveryPhase));
|
|
1754
|
+
const EMAIL_RECOVERY_PHASES = new Set(Object.values(EmailRecoveryPhase));
|
|
1761
1755
|
function phaseOf(progress) {
|
|
1762
1756
|
return String(progress?.phase ?? "");
|
|
1763
1757
|
}
|
|
@@ -1776,6 +1770,9 @@ function isDeviceLinkingSSEEvent(p) {
|
|
|
1776
1770
|
function isAccountRecoverySSEEvent(p) {
|
|
1777
1771
|
return ACCOUNT_RECOVERY_PHASES.has(phaseOf(p));
|
|
1778
1772
|
}
|
|
1773
|
+
function isEmailRecoverySSEEvent(p) {
|
|
1774
|
+
return EMAIL_RECOVERY_PHASES.has(phaseOf(p));
|
|
1775
|
+
}
|
|
1779
1776
|
/**
|
|
1780
1777
|
* Strips out class functions as they cannot be sent over postMessage to iframe
|
|
1781
1778
|
*/
|
|
@@ -4,7 +4,7 @@ import "./actions-O1FD5Bq8.js";
|
|
|
4
4
|
import "./errors-D9ar28Dr.js";
|
|
5
5
|
import "./sdkSentEvents-_jrJLIhw.js";
|
|
6
6
|
import "./defaultConfigs-DpslkAQd.js";
|
|
7
|
-
import { buildSetRecoveryEmailsActions, checkCanRegisterUserContractCall, executeDeviceLinkingContractCalls, getAuthenticatorsByUser, getCredentialIdsContractCall, getDeviceLinkingAccountContractCall, getRecoveryEmailHashesContractCall, init_rpcCalls, syncAuthenticatorsContractCall, verifyAuthenticationResponse } from "./rpcCalls-
|
|
7
|
+
import { buildSetRecoveryEmailsActions, checkCanRegisterUserContractCall, executeDeviceLinkingContractCalls, getAuthenticatorsByUser, getCredentialIdsContractCall, getDeviceLinkingAccountContractCall, getEmailRecoveryVerificationResult, getRecoveryEmailHashesContractCall, init_rpcCalls, syncAuthenticatorsContractCall, verifyAuthenticationResponse } from "./rpcCalls-YVeUVMk2.js";
|
|
8
8
|
|
|
9
9
|
init_rpcCalls();
|
|
10
|
-
export { syncAuthenticatorsContractCall };
|
|
10
|
+
export { getEmailRecoveryVerificationResult, syncAuthenticatorsContractCall };
|
|
@@ -6,6 +6,13 @@ import { ActionPhase, DEFAULT_WAIT_STATUS, DeviceLinkingPhase, DeviceLinkingStat
|
|
|
6
6
|
import { DEFAULT_EMAIL_RECOVERY_CONTRACTS, init_defaultConfigs } from "./defaultConfigs-DpslkAQd.js";
|
|
7
7
|
|
|
8
8
|
//#region src/core/rpcCalls.ts
|
|
9
|
+
async function getEmailRecoveryVerificationResult(nearClient, dkimVerifierAccountId, verificationViewMethod, requestId) {
|
|
10
|
+
return await nearClient.view({
|
|
11
|
+
account: dkimVerifierAccountId,
|
|
12
|
+
method: verificationViewMethod,
|
|
13
|
+
args: { request_id: requestId }
|
|
14
|
+
});
|
|
15
|
+
}
|
|
9
16
|
/**
|
|
10
17
|
* Query the contract to get the account linked to a device public key
|
|
11
18
|
* Used in device linking flow to check if a device key has been added
|
|
@@ -387,4 +394,4 @@ var init_rpcCalls = __esm({ "src/core/rpcCalls.ts": (() => {
|
|
|
387
394
|
}) });
|
|
388
395
|
|
|
389
396
|
//#endregion
|
|
390
|
-
export { buildSetRecoveryEmailsActions, checkCanRegisterUserContractCall, executeDeviceLinkingContractCalls, getAuthenticatorsByUser, getCredentialIdsContractCall, getDeviceLinkingAccountContractCall, getRecoveryEmailHashesContractCall, init_rpcCalls, syncAuthenticatorsContractCall, verifyAuthenticationResponse };
|
|
397
|
+
export { buildSetRecoveryEmailsActions, checkCanRegisterUserContractCall, executeDeviceLinkingContractCalls, getAuthenticatorsByUser, getCredentialIdsContractCall, getDeviceLinkingAccountContractCall, getEmailRecoveryVerificationResult, getRecoveryEmailHashesContractCall, init_rpcCalls, syncAuthenticatorsContractCall, verifyAuthenticationResponse };
|
|
@@ -13,7 +13,7 @@ import "./WebAuthnFallbacks-Bl4BTsNt.js";
|
|
|
13
13
|
import { ERROR_MESSAGES, SecureConfirmationType, getIntentDigest, getNearAccountId, getSignTransactionPayload, getTxCount, init_accountIds, isUserCancelledSecureConfirm, toAccountId } from "./requestHelpers-Dh1hEYL9.js";
|
|
14
14
|
import { PASSKEY_MANAGER_DEFAULT_CONFIGS, init_defaultConfigs } from "./defaultConfigs-DpslkAQd.js";
|
|
15
15
|
import { getLastLoggedInDeviceNumber, init_getDeviceNumber } from "./getDeviceNumber-zsOHT_Um.js";
|
|
16
|
-
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-
|
|
16
|
+
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-DIRR8_Z9.js";
|
|
17
17
|
|
|
18
18
|
//#region src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.ts
|
|
19
19
|
init_accountIds();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ERROR_MESSAGES, SecureConfirmationType, getIntentDigest, getNearAccountId, getSignTransactionPayload, getTxCount, isUserCancelledSecureConfirm, toAccountId, toError } from "./requestHelpers-aUKhXiEl.js";
|
|
2
2
|
import "./validation-DhPPUba7.js";
|
|
3
3
|
import { PASSKEY_MANAGER_DEFAULT_CONFIGS, getLastLoggedInDeviceNumber } from "./getDeviceNumber-fXizNGQl.js";
|
|
4
|
-
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-
|
|
4
|
+
import { createConfirmSession, createConfirmTxFlowAdapters } from "./createAdapters-Yga6W0en.js";
|
|
5
5
|
import "./css-loader-BrMMlG4X.js";
|
|
6
6
|
import "./lit-events-BKobq01K.js";
|
|
7
7
|
import "./tx-tree-themes-i3It4IYY.js";
|
|
@@ -163,4 +163,4 @@ async function handleTransactionSigningFlow(ctx, request, worker, opts) {
|
|
|
163
163
|
|
|
164
164
|
//#endregion
|
|
165
165
|
export { handleTransactionSigningFlow };
|
|
166
|
-
//# sourceMappingURL=transactions-
|
|
166
|
+
//# sourceMappingURL=transactions-bqaAwL4k.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactions-BIqKZeR0.js","names":["uiVrfChallenge: VRFChallenge | undefined","uiVrfChallengeForUi: Partial<VRFChallenge> | undefined","err: unknown","contractId: string | undefined","nearRpcUrl: string | undefined"],"sources":["../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { ConfirmationConfig } from '../../../../types/signer-worker';\nimport {\n SecureConfirmationType,\n TransactionSummary,\n SigningSecureConfirmRequest,\n SigningAuthMode,\n} from '../types';\nimport { VRFChallenge, TransactionContext } from '../../../../types';\nimport {\n getNearAccountId,\n getIntentDigest,\n getTxCount,\n isUserCancelledSecureConfirm,\n ERROR_MESSAGES,\n getSignTransactionPayload,\n} from './index';\nimport { toAccountId } from '../../../../types/accountIds';\nimport { getLastLoggedInDeviceNumber } from '../../../SignerWorkerManager/getDeviceNumber';\nimport { toError } from '../../../../../utils/errors';\nimport { PASSKEY_MANAGER_DEFAULT_CONFIGS } from '../../../../defaultConfigs';\nimport { createConfirmSession } from '../adapters/session';\nimport { createConfirmTxFlowAdapters } from '../adapters/createAdapters';\n\nfunction getSigningAuthMode(request: SigningSecureConfirmRequest): SigningAuthMode {\n if (request.type === SecureConfirmationType.SIGN_TRANSACTION) {\n return getSignTransactionPayload(request).signingAuthMode ?? 'webauthn';\n }\n if (request.type === SecureConfirmationType.SIGN_NEP413_MESSAGE) {\n const p = request.payload as any;\n return (p?.signingAuthMode as SigningAuthMode | undefined) ?? 'webauthn';\n }\n return 'webauthn';\n}\n\nexport async function handleTransactionSigningFlow(\n ctx: VrfWorkerManagerContext,\n request: SigningSecureConfirmRequest,\n worker: Worker,\n opts: { confirmationConfig: ConfirmationConfig; transactionSummary: TransactionSummary },\n): Promise<void> {\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 const signingAuthMode = getSigningAuthMode(request);\n const usesNeeded = getTxCount(request);\n\n // 1) NEAR context + nonce reservation\n const nearRpc = await adapters.near.fetchNearContext({ nearAccountId, txCount: usesNeeded, reserveNonces: true });\n if (nearRpc.error && !nearRpc.transactionContext) {\n // eslint-disable-next-line no-console\n console.error('[SigningFlow] fetchNearContext failed', { error: nearRpc.error, details: nearRpc.details });\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 session.setReservedNonces(nearRpc.reservedNonces);\n let transactionContext = nearRpc.transactionContext as TransactionContext;\n\n // 2) Security context shown in the confirmer (rpId + block height).\n // For warmSession signing we still want to show this context even though\n // we won't collect a WebAuthn credential.\n const rpId = adapters.vrf.getRpId();\n let uiVrfChallenge: VRFChallenge | undefined;\n let uiVrfChallengeForUi: Partial<VRFChallenge> | undefined = rpId\n ? {\n userId: nearAccountId,\n rpId,\n blockHeight: transactionContext.txBlockHeight,\n blockHash: transactionContext.txBlockHash,\n }\n : undefined;\n\n // Initial VRF challenge (only needed for WebAuthn credential collection)\n if (signingAuthMode === 'webauthn') {\n uiVrfChallenge = await adapters.vrf.generateVrfChallengeForSession(\n {\n userId: nearAccountId,\n rpId,\n blockHeight: transactionContext.txBlockHeight,\n blockHash: transactionContext.txBlockHash,\n },\n request.requestId,\n );\n uiVrfChallengeForUi = uiVrfChallenge;\n }\n\n // 3) UI confirm\n const { confirmed, error: uiError } = await session.promptUser({ vrfChallenge: uiVrfChallengeForUi });\n if (!confirmed) {\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: uiError,\n });\n }\n\n // 4) Warm session: dispense WrapKeySeed and skip WebAuthn\n if (signingAuthMode === 'warmSession') {\n try {\n await adapters.vrf.dispenseSessionKey({ sessionId: request.requestId, uses: usesNeeded });\n } catch (err: unknown) {\n const msg = String((toError(err))?.message || err || '');\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: msg || 'Failed to dispense warm session key',\n });\n }\n\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n transactionContext,\n });\n return;\n }\n\n // 5) JIT refresh VRF + ctx (best-effort)\n try {\n const refreshed = await adapters.vrf.maybeRefreshVrfChallenge(request, nearAccountId);\n uiVrfChallenge = refreshed.vrfChallenge;\n transactionContext = refreshed.transactionContext;\n session.updateUI({ vrfChallenge: uiVrfChallenge });\n } catch (e) {\n console.debug('[SigningFlow] VRF JIT refresh skipped', e);\n }\n\n // 6) Collect authentication credential\n try {\n if (!uiVrfChallenge) {\n throw new Error('Missing vrfChallenge for WebAuthn signing flow');\n }\n const serializedCredential = await adapters.webauthn.collectAuthenticationCredentialWithPRF({\n nearAccountId,\n vrfChallenge: uiVrfChallenge,\n });\n\n // 5c) Derive WrapKeySeed inside the VRF worker and deliver it to the signer worker via\n // the reserved WrapKeySeed MessagePort. Main thread only sees wrapKeySalt metadata.\n let contractId: string | undefined;\n let nearRpcUrl: string | undefined;\n try {\n // Ensure VRF session is active and bound to the same account we are signing for.\n const vrfStatus = await adapters.vrf.checkVrfStatus();\n if (!vrfStatus.active) {\n throw new Error('VRF keypair not active in memory. VRF session may have expired or was not properly initialized. Please refresh and try again.');\n }\n if (!vrfStatus.nearAccountId || String(vrfStatus.nearAccountId) !== String(toAccountId(nearAccountId))) {\n throw new Error('VRF session is active but bound to a different account than the one being signed. Please log in again on this device.');\n }\n\n const deviceNumber = await getLastLoggedInDeviceNumber(toAccountId(nearAccountId), ctx.indexedDB.clientDB);\n const encryptedKeyData = await ctx.indexedDB.nearKeysDB.getEncryptedKey(nearAccountId, deviceNumber);\n // For v2+ vaults, wrapKeySalt is the canonical salt.\n const wrapKeySalt = encryptedKeyData?.wrapKeySalt || '';\n if (!wrapKeySalt) {\n throw new Error('Missing wrapKeySalt in vault; re-register to upgrade vault format.');\n }\n\n // Extract contract verification context when available.\n // - SIGN_TRANSACTION: use per-request rpcCall (already normalized by caller).\n // - SIGN_NEP413_MESSAGE: allow per-request override; fall back to PASSKEY_MANAGER_DEFAULT_CONFIGS.\n if (request.type === SecureConfirmationType.SIGN_TRANSACTION) {\n const payload = getSignTransactionPayload(request);\n contractId = payload?.rpcCall?.contractId;\n nearRpcUrl = payload?.rpcCall?.nearRpcUrl;\n } else if (request.type === SecureConfirmationType.SIGN_NEP413_MESSAGE) {\n const payload = request.payload as any;\n contractId = payload?.contractId\n || PASSKEY_MANAGER_DEFAULT_CONFIGS.contractId;\n nearRpcUrl = payload?.nearRpcUrl\n || PASSKEY_MANAGER_DEFAULT_CONFIGS.nearRpcUrl;\n }\n\n await adapters.vrf.mintSessionKeysAndSendToSigner({\n sessionId: request.requestId,\n wrapKeySalt,\n contractId,\n nearRpcUrl,\n credential: serializedCredential,\n });\n\t } catch (err) {\n\t console.error('[SigningFlow] WrapKeySeed derivation failed:', err);\n\t throw err; // Don't silently ignore - propagate the error\n\t }\n\n // 6) Respond; keep nonces reserved for worker to use\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n credential: serializedCredential,\n // prfOutput intentionally omitted to keep signer PRF-free\n // WrapKeySeed travels only over the dedicated VRF→Signer MessagePort; do not echo in the main-thread envelope\n vrfChallenge: uiVrfChallenge,\n transactionContext,\n });\n } catch (err: unknown) {\n // Treat TouchID/FaceID cancellation and related errors as a negative decision\n const cancelled = isUserCancelledSecureConfirm(err);\n // For missing PRF outputs, surface the error to caller (defensive path tests expect a throw)\n const msg = String((toError(err))?.message || err || '');\n if (/Missing PRF result/i.test(msg) || /Missing PRF results/i.test(msg)) {\n // Ensure UI is closed and nonces released, then rethrow\n return session.cleanupAndRethrow(err);\n }\n if (cancelled) {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n }\n const isWrongPasskeyError = /multiple passkeys \\(devicenumbers\\) for account/i.test(msg);\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: cancelled\n ? ERROR_MESSAGES.cancelled\n : (isWrongPasskeyError ? msg : ERROR_MESSAGES.collectCredentialsFailed),\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transactions-bqaAwL4k.js","names":["uiVrfChallenge: VRFChallenge | undefined","uiVrfChallengeForUi: Partial<VRFChallenge> | undefined","err: unknown","contractId: string | undefined","nearRpcUrl: string | undefined"],"sources":["../../../src/core/WebAuthnManager/VrfWorkerManager/confirmTxFlow/flows/transactions.ts"],"sourcesContent":["import type { VrfWorkerManagerContext } from '../../';\nimport type { ConfirmationConfig } from '../../../../types/signer-worker';\nimport {\n SecureConfirmationType,\n TransactionSummary,\n SigningSecureConfirmRequest,\n SigningAuthMode,\n} from '../types';\nimport { VRFChallenge, TransactionContext } from '../../../../types';\nimport {\n getNearAccountId,\n getIntentDigest,\n getTxCount,\n isUserCancelledSecureConfirm,\n ERROR_MESSAGES,\n getSignTransactionPayload,\n} from './index';\nimport { toAccountId } from '../../../../types/accountIds';\nimport { getLastLoggedInDeviceNumber } from '../../../SignerWorkerManager/getDeviceNumber';\nimport { toError } from '../../../../../utils/errors';\nimport { PASSKEY_MANAGER_DEFAULT_CONFIGS } from '../../../../defaultConfigs';\nimport { createConfirmSession } from '../adapters/session';\nimport { createConfirmTxFlowAdapters } from '../adapters/createAdapters';\n\nfunction getSigningAuthMode(request: SigningSecureConfirmRequest): SigningAuthMode {\n if (request.type === SecureConfirmationType.SIGN_TRANSACTION) {\n return getSignTransactionPayload(request).signingAuthMode ?? 'webauthn';\n }\n if (request.type === SecureConfirmationType.SIGN_NEP413_MESSAGE) {\n const p = request.payload as any;\n return (p?.signingAuthMode as SigningAuthMode | undefined) ?? 'webauthn';\n }\n return 'webauthn';\n}\n\nexport async function handleTransactionSigningFlow(\n ctx: VrfWorkerManagerContext,\n request: SigningSecureConfirmRequest,\n worker: Worker,\n opts: { confirmationConfig: ConfirmationConfig; transactionSummary: TransactionSummary },\n): Promise<void> {\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 const signingAuthMode = getSigningAuthMode(request);\n const usesNeeded = getTxCount(request);\n\n // 1) NEAR context + nonce reservation\n const nearRpc = await adapters.near.fetchNearContext({ nearAccountId, txCount: usesNeeded, reserveNonces: true });\n if (nearRpc.error && !nearRpc.transactionContext) {\n // eslint-disable-next-line no-console\n console.error('[SigningFlow] fetchNearContext failed', { error: nearRpc.error, details: nearRpc.details });\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 session.setReservedNonces(nearRpc.reservedNonces);\n let transactionContext = nearRpc.transactionContext as TransactionContext;\n\n // 2) Security context shown in the confirmer (rpId + block height).\n // For warmSession signing we still want to show this context even though\n // we won't collect a WebAuthn credential.\n const rpId = adapters.vrf.getRpId();\n let uiVrfChallenge: VRFChallenge | undefined;\n let uiVrfChallengeForUi: Partial<VRFChallenge> | undefined = rpId\n ? {\n userId: nearAccountId,\n rpId,\n blockHeight: transactionContext.txBlockHeight,\n blockHash: transactionContext.txBlockHash,\n }\n : undefined;\n\n // Initial VRF challenge (only needed for WebAuthn credential collection)\n if (signingAuthMode === 'webauthn') {\n uiVrfChallenge = await adapters.vrf.generateVrfChallengeForSession(\n {\n userId: nearAccountId,\n rpId,\n blockHeight: transactionContext.txBlockHeight,\n blockHash: transactionContext.txBlockHash,\n },\n request.requestId,\n );\n uiVrfChallengeForUi = uiVrfChallenge;\n }\n\n // 3) UI confirm\n const { confirmed, error: uiError } = await session.promptUser({ vrfChallenge: uiVrfChallengeForUi });\n if (!confirmed) {\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: uiError,\n });\n }\n\n // 4) Warm session: dispense WrapKeySeed and skip WebAuthn\n if (signingAuthMode === 'warmSession') {\n try {\n await adapters.vrf.dispenseSessionKey({ sessionId: request.requestId, uses: usesNeeded });\n } catch (err: unknown) {\n const msg = String((toError(err))?.message || err || '');\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: msg || 'Failed to dispense warm session key',\n });\n }\n\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n transactionContext,\n });\n return;\n }\n\n // 5) JIT refresh VRF + ctx (best-effort)\n try {\n const refreshed = await adapters.vrf.maybeRefreshVrfChallenge(request, nearAccountId);\n uiVrfChallenge = refreshed.vrfChallenge;\n transactionContext = refreshed.transactionContext;\n session.updateUI({ vrfChallenge: uiVrfChallenge });\n } catch (e) {\n console.debug('[SigningFlow] VRF JIT refresh skipped', e);\n }\n\n // 6) Collect authentication credential\n try {\n if (!uiVrfChallenge) {\n throw new Error('Missing vrfChallenge for WebAuthn signing flow');\n }\n const serializedCredential = await adapters.webauthn.collectAuthenticationCredentialWithPRF({\n nearAccountId,\n vrfChallenge: uiVrfChallenge,\n });\n\n // 5c) Derive WrapKeySeed inside the VRF worker and deliver it to the signer worker via\n // the reserved WrapKeySeed MessagePort. Main thread only sees wrapKeySalt metadata.\n let contractId: string | undefined;\n let nearRpcUrl: string | undefined;\n try {\n // Ensure VRF session is active and bound to the same account we are signing for.\n const vrfStatus = await adapters.vrf.checkVrfStatus();\n if (!vrfStatus.active) {\n throw new Error('VRF keypair not active in memory. VRF session may have expired or was not properly initialized. Please refresh and try again.');\n }\n if (!vrfStatus.nearAccountId || String(vrfStatus.nearAccountId) !== String(toAccountId(nearAccountId))) {\n throw new Error('VRF session is active but bound to a different account than the one being signed. Please log in again on this device.');\n }\n\n const deviceNumber = await getLastLoggedInDeviceNumber(toAccountId(nearAccountId), ctx.indexedDB.clientDB);\n const encryptedKeyData = await ctx.indexedDB.nearKeysDB.getEncryptedKey(nearAccountId, deviceNumber);\n // For v2+ vaults, wrapKeySalt is the canonical salt.\n const wrapKeySalt = encryptedKeyData?.wrapKeySalt || '';\n if (!wrapKeySalt) {\n throw new Error('Missing wrapKeySalt in vault; re-register to upgrade vault format.');\n }\n\n // Extract contract verification context when available.\n // - SIGN_TRANSACTION: use per-request rpcCall (already normalized by caller).\n // - SIGN_NEP413_MESSAGE: allow per-request override; fall back to PASSKEY_MANAGER_DEFAULT_CONFIGS.\n if (request.type === SecureConfirmationType.SIGN_TRANSACTION) {\n const payload = getSignTransactionPayload(request);\n contractId = payload?.rpcCall?.contractId;\n nearRpcUrl = payload?.rpcCall?.nearRpcUrl;\n } else if (request.type === SecureConfirmationType.SIGN_NEP413_MESSAGE) {\n const payload = request.payload as any;\n contractId = payload?.contractId\n || PASSKEY_MANAGER_DEFAULT_CONFIGS.contractId;\n nearRpcUrl = payload?.nearRpcUrl\n || PASSKEY_MANAGER_DEFAULT_CONFIGS.nearRpcUrl;\n }\n\n await adapters.vrf.mintSessionKeysAndSendToSigner({\n sessionId: request.requestId,\n wrapKeySalt,\n contractId,\n nearRpcUrl,\n credential: serializedCredential,\n });\n\t } catch (err) {\n\t console.error('[SigningFlow] WrapKeySeed derivation failed:', err);\n\t throw err; // Don't silently ignore - propagate the error\n\t }\n\n // 6) Respond; keep nonces reserved for worker to use\n session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: true,\n credential: serializedCredential,\n // prfOutput intentionally omitted to keep signer PRF-free\n // WrapKeySeed travels only over the dedicated VRF→Signer MessagePort; do not echo in the main-thread envelope\n vrfChallenge: uiVrfChallenge,\n transactionContext,\n });\n } catch (err: unknown) {\n // Treat TouchID/FaceID cancellation and related errors as a negative decision\n const cancelled = isUserCancelledSecureConfirm(err);\n // For missing PRF outputs, surface the error to caller (defensive path tests expect a throw)\n const msg = String((toError(err))?.message || err || '');\n if (/Missing PRF result/i.test(msg) || /Missing PRF results/i.test(msg)) {\n // Ensure UI is closed and nonces released, then rethrow\n return session.cleanupAndRethrow(err);\n }\n if (cancelled) {\n window.parent?.postMessage({ type: 'WALLET_UI_CLOSED' }, '*');\n }\n const isWrongPasskeyError = /multiple passkeys \\(devicenumbers\\) for account/i.test(msg);\n return session.confirmAndCloseModal({\n requestId: request.requestId,\n intentDigest: getIntentDigest(request),\n confirmed: false,\n error: cancelled\n ? ERROR_MESSAGES.cancelled\n : (isWrongPasskeyError ? msg : ERROR_MESSAGES.collectCredentialsFailed),\n });\n }\n}\n"],"mappings":"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"}
|