@seams/wallet 0.8.0 → 0.9.1
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/README.md +140 -254
- package/THIRD_PARTY_NOTICES.md +7 -1
- package/dist/.build-inputs.sha256 +1 -1
- package/dist/esm/SeamsWeb/SeamsWeb.js +98 -1825
- package/dist/esm/SeamsWeb/assembly/createWalletIframeRouter.js +4 -15
- package/dist/esm/SeamsWeb/index.js +2 -2
- package/dist/esm/SeamsWeb/operations/devices/scanDevice.js +3 -361
- package/dist/esm/SeamsWeb/operations/near/delegateAction.js +18 -106
- package/dist/esm/SeamsWeb/operations/recovery/walletRecovery.js +3 -3
- package/dist/esm/SeamsWeb/operations/recovery/walletRecoveryCommit.js +8 -209
- package/dist/esm/SeamsWeb/operations/recovery/walletRecoveryDurablePayload.js +5 -5
- package/dist/esm/SeamsWeb/operations/recovery/walletRecoveryJournal.js +2 -64
- package/dist/esm/SeamsWeb/operations/tempo/executeEvmFamilyTransaction.js +1 -1
- package/dist/esm/SeamsWeb/operations/tempo/index.js +1 -13
- package/dist/esm/SeamsWeb/publicApi/auth.js +3 -19
- package/dist/esm/SeamsWeb/publicApi/createPublicApi.js +59 -94
- package/dist/esm/SeamsWeb/publicApi/currentWallet.js +1 -1
- package/dist/esm/SeamsWeb/publicApi/devices.js +33 -64
- package/dist/esm/SeamsWeb/publicApi/evm.js +28 -93
- package/dist/esm/SeamsWeb/publicApi/keyExport.js +26 -52
- package/dist/esm/SeamsWeb/publicApi/near.js +140 -435
- package/dist/esm/SeamsWeb/publicApi/placement.js +206 -0
- package/dist/esm/SeamsWeb/publicApi/session.js +13 -0
- package/dist/esm/SeamsWeb/publicApi/tempo.js +64 -221
- package/dist/esm/SeamsWeb/publicApi/{awaitNearReady.js → waitForNearAccount.js} +12 -12
- package/dist/esm/SeamsWeb/walletIframe/client/deviceCommands.js +50 -0
- package/dist/esm/SeamsWeb/walletIframe/client/emailOtpCommands.js +25 -0
- package/dist/esm/SeamsWeb/walletIframe/client/evmFamilyCommands.js +118 -0
- package/dist/esm/SeamsWeb/walletIframe/client/inboundMessages.js +223 -0
- package/dist/esm/SeamsWeb/walletIframe/client/nearCommands.js +153 -0
- package/dist/esm/SeamsWeb/walletIframe/client/overlay/overlay-styles.js +2 -2
- package/dist/esm/SeamsWeb/walletIframe/client/placementCommands.js +65 -0
- package/dist/esm/SeamsWeb/walletIframe/client/preferenceState.js +93 -0
- package/dist/esm/SeamsWeb/walletIframe/client/preferences.js +117 -0
- package/dist/esm/SeamsWeb/walletIframe/client/registrationCommands.js +92 -0
- package/dist/esm/SeamsWeb/walletIframe/client/router.js +241 -583
- package/dist/esm/SeamsWeb/walletIframe/client/sessionCommands.js +61 -0
- package/dist/esm/SeamsWeb/walletIframe/coordinator.js +175 -134
- package/dist/esm/SeamsWeb/walletIframe/host/ui/auth-menu/AuthMenuSurface.js +13 -1
- package/dist/esm/SeamsWeb/walletIframe/host/ui/auth-menu/mountAuthMenuSurface.js +1 -1
- package/dist/esm/SeamsWeb/walletIframe/shared/configuration.js +37 -0
- package/dist/esm/SeamsWeb/walletIframe/shared/exactSessionState.js +31 -11
- package/dist/esm/SeamsWeb/walletIframe/shared/facadeBoundary.js +96 -0
- package/dist/esm/SeamsWeb/walletIframe/shared/messages.js +6 -32
- package/dist/esm/advanced.js +3 -3
- package/dist/esm/build-paths.js +0 -4
- package/dist/esm/core/accountData/near/accountProjection.js +3 -3
- package/dist/esm/core/accountData/near/keyMaterial.js +2 -2
- package/dist/esm/core/config/chains.js +1 -28
- package/dist/esm/core/config/configBuilder.js +3 -14
- package/dist/esm/core/config/defaultConfigs.js +4 -6
- package/dist/esm/core/{signingEngine/workerManager/ecdsaPresignLifecycle.js → config/presignatures.js} +2 -2
- package/dist/esm/core/diagnostics/registration.js +8 -0
- package/dist/esm/core/indexedDB/accountKeyMaterial.js +1 -1
- package/dist/esm/core/indexedDB/linkedAuthoritySignerMaterial.js +4 -125
- package/dist/esm/core/indexedDB/normalization.js +7 -1
- package/dist/esm/core/indexedDB/pendingWalletRecoveryCommit.js +1 -1
- package/dist/esm/core/indexedDB/pendingWalletRegistrationCommit.js +3 -41
- package/dist/esm/core/indexedDB/seamsWalletDB/accountSignerRows.js +261 -0
- package/dist/esm/core/indexedDB/seamsWalletDB/ecdsaCapabilityManifestLookups.js +2 -201
- package/dist/esm/core/indexedDB/seamsWalletDB/ecdsaCapabilityManifestRecords.js +5 -736
- package/dist/esm/core/indexedDB/seamsWalletDB/ecdsaCapabilityManifestStore.js +6 -1084
- package/dist/esm/core/indexedDB/seamsWalletDB/ecdsaClientPresignatures.js +20 -138
- package/dist/esm/core/indexedDB/seamsWalletDB/manager.js +100 -4
- package/dist/esm/core/indexedDB/seamsWalletDB/nonceLeaseRows.js +156 -0
- package/dist/esm/core/indexedDB/seamsWalletDB/registrationSetup.js +4 -11
- package/dist/esm/core/indexedDB/seamsWalletDB/repositories.js +91 -547
- package/dist/esm/core/indexedDB/seamsWalletDB/signerOutboxRows.js +90 -0
- package/dist/esm/core/indexedDB/seamsWalletDB/walletCustodyEcdsaContinuity.js +7 -92
- package/dist/esm/core/indexedDB/seamsWalletDB/walletOwnershipGeneration.js +43 -0
- package/dist/esm/core/indexedDB/seamsWalletDB/walletSessionAuthorizationStore.js +103 -157
- package/dist/esm/core/indexedDB/unifiedIndexedDBManager.js +2 -1
- package/dist/esm/core/indexedDB/walletCustodyEd25519MaterialRecord.js +1 -1
- package/dist/esm/core/rpcClients/evm/nonceBackend.js +1 -176
- package/dist/esm/core/rpcClients/near/accountExists.js +34 -0
- package/dist/esm/core/rpcClients/relayer/ecdsaPrepareSession.js +42 -0
- package/dist/esm/core/rpcClients/relayer/relayerHttp.js +31 -1
- package/dist/esm/core/rpcClients/relayer/routerAbNormalSigning.js +47 -11
- package/dist/esm/core/rpcClients/relayer/walletRecoveryFinalize.js +2 -48
- package/dist/esm/core/rpcClients/relayer/walletRecoveryPrepare.js +9 -9
- package/dist/esm/core/rpcClients/relayer/walletRecoveryRotate.js +1 -223
- package/dist/esm/core/rpcClients/relayer/walletRegistration.js +36 -2197
- package/dist/esm/core/rpcClients/relayer/walletSessionAuthorizationStatus.js +145 -14
- package/dist/esm/core/signingEngine/chains/evm/evmAdapter.js +1 -1
- package/dist/esm/core/signingEngine/chains/near/display.js +1 -27
- package/dist/esm/core/signingEngine/chains/near/nearSignerWasm.js +2 -2
- package/dist/esm/core/signingEngine/flows/registration/accountLifecycle.js +6 -39
- package/dist/esm/core/signingEngine/flows/shared/signingConfirmation.js +2 -2
- package/dist/esm/core/signingEngine/flows/shared/signingStateMachine.js +1 -11
- package/dist/esm/core/signingEngine/flows/signEvmFamily/authPlanning.js +2 -2
- package/dist/esm/core/signingEngine/flows/signEvmFamily/ecdsaSelection.js +3 -3
- package/dist/esm/core/signingEngine/flows/signEvmFamily/emailOtpSigningSession.js +3 -136
- package/dist/esm/core/signingEngine/flows/signEvmFamily/freshWalletSessionRetry.js +1 -1
- package/dist/esm/core/signingEngine/flows/signEvmFamily/operationIds.js +1 -1
- package/dist/esm/core/signingEngine/flows/signEvmFamily/preparedSigning.js +2 -3
- package/dist/esm/core/signingEngine/flows/signEvmFamily/readySecp256k1Material.js +40 -5
- package/dist/esm/core/signingEngine/flows/signEvmFamily/signEvmFamily.js +4 -4
- package/dist/esm/core/signingEngine/flows/signEvmFamily/signers/ecdsaDerivationClientSigningMaterialSource.js +1 -1
- package/dist/esm/core/signingEngine/flows/signEvmFamily/signers/secp256k1.js +27 -53
- package/dist/esm/core/signingEngine/flows/signEvmFamily/signingFlow.js +5 -5
- package/dist/esm/core/signingEngine/flows/signEvmFamily/signingFlowRuntime.js +40 -33
- package/dist/esm/core/signingEngine/flows/signEvmFamily/thresholdAdmission.js +8 -2
- package/dist/esm/core/signingEngine/flows/signNear/implicitAccountFunding.js +1 -1
- package/dist/esm/core/signingEngine/flows/signNear/shared/ed25519YaoNormalSigning.js +177 -68
- package/dist/esm/core/signingEngine/flows/signNear/shared/implicitAccountFundingPort.js +1 -8
- package/dist/esm/core/signingEngine/flows/signNear/shared/operationStepUpPreparation.js +1 -38
- package/dist/esm/core/signingEngine/flows/signNear/shared/signatureOnlySigning.js +53 -8
- package/dist/esm/core/signingEngine/flows/signNear/signDelegate.js +5 -5
- package/dist/esm/core/signingEngine/flows/signNear/signNear.js +30 -44
- package/dist/esm/core/signingEngine/flows/signNear/signNep413.js +21 -12
- package/dist/esm/core/signingEngine/flows/signNear/signTransactions.js +59 -11
- package/dist/esm/core/signingEngine/interfaces/ecdsaChainTarget.js +1 -1
- package/dist/esm/core/signingEngine/nonce/nonceLaneKeys.js +1 -35
- package/dist/esm/core/signingEngine/nonce/nonceTypes.js +2 -26
- package/dist/esm/core/signingEngine/routerAb/ecdsaDerivation/httpRequest.js +4 -3
- package/dist/esm/core/signingEngine/routerAb/ecdsaDerivation/poolFillRoutes.js +5 -1
- package/dist/esm/core/signingEngine/routerAb/ecdsaDerivation/presignaturePool.js +112 -162
- package/dist/esm/core/signingEngine/routerAb/ecdsaDerivation/presignaturePoolPolicy.js +31 -0
- package/dist/esm/core/signingEngine/routerAb/ecdsaDerivation/signingMaterialRef.js +1 -1
- package/dist/esm/core/signingEngine/session/availability/availableSigningLanes.js +3 -913
- package/dist/esm/core/signingEngine/session/emailOtp/challengeDelivery.js +1 -45
- package/dist/esm/core/signingEngine/session/emailOtp/ecdsaSigningSessionAuthority.js +1 -81
- package/dist/esm/core/signingEngine/session/identity/clientSessionPersistenceState.js +1 -43
- package/dist/esm/core/signingEngine/session/identity/emailOtpEcdsaDerivationIdentity.js +1 -9
- package/dist/esm/core/signingEngine/session/identity/evmFamilyEcdsaIdentity.js +3 -125
- package/dist/esm/core/signingEngine/session/identity/exactSigningLaneIdentity.js +3 -19
- package/dist/esm/core/signingEngine/session/identity/laneIdentity.js +2 -106
- package/dist/esm/core/signingEngine/session/keyMaterialBrands.js +1 -1
- package/dist/esm/core/signingEngine/session/lifecycle/walletSessionFailure.js +1 -1
- package/dist/esm/core/signingEngine/session/material/activeEcdsaCapabilityRuntime.js +1 -114
- package/dist/esm/core/signingEngine/session/material/activeWalletAuthorityEcdsaRuntime.js +2 -2
- package/dist/esm/core/signingEngine/session/material/ecdsaCapabilityManifest.js +2 -187
- package/dist/esm/core/signingEngine/session/material/ecdsaRoleLocalMaterialResolver.js +2 -18
- package/dist/esm/core/signingEngine/session/material/ecdsaSigningCapability.js +2 -130
- package/dist/esm/core/signingEngine/session/material/linkedEcdsaHolderRuntime.js +1 -25
- package/dist/esm/core/signingEngine/session/material/nearEd25519YaoMaterialActivation.js +1 -73
- package/dist/esm/core/signingEngine/session/material/walletSigningStateFailure.js +1 -69
- package/dist/esm/core/signingEngine/session/operationState/preparedOperation.js +1 -5
- package/dist/esm/core/signingEngine/session/operationState/transactionState.js +0 -1
- package/dist/esm/core/signingEngine/session/passkey/prfCache.js +1 -5
- package/dist/esm/core/signingEngine/session/persistence/durableSealedSessionCommands.js +1 -9
- package/dist/esm/core/signingEngine/session/persistence/ecdsaRoleLocalRecords.js +3 -202
- package/dist/esm/core/signingEngine/session/persistence/sealedSessionRecords.js +4 -83
- package/dist/esm/core/signingEngine/session/persistence/sealedSessionStore.js +2 -2
- package/dist/esm/core/signingEngine/session/planning/planner.js +2 -13
- package/dist/esm/core/signingEngine/session/sealedRecovery/materialActivationKey.js +1 -8
- package/dist/esm/core/signingEngine/session/warmCapabilities/routerAbWalletSessionCredential.js +2 -1
- package/dist/esm/core/signingEngine/session/warmCapabilities/sealedRefreshParity.js +2 -41
- package/dist/esm/core/signingEngine/stepUpConfirmation/intentDigestPreparation.js +1 -14
- package/dist/esm/core/signingEngine/stepUpConfirmation/types.js +1 -7
- package/dist/esm/core/signingEngine/threshold/commitQueueShared.js +1 -127
- package/dist/esm/core/signingEngine/threshold/crypto/ecdsaDerivationClientWasm.js +3 -297
- package/dist/esm/core/signingEngine/threshold/ecdsa/operationStepUp.js +10 -24
- package/dist/esm/core/signingEngine/threshold/ed25519/walletSession.js +7 -209
- package/dist/esm/core/signingEngine/threshold/ed25519/yaoPublicCapabilityReferences.js +5 -208
- package/dist/esm/core/signingEngine/threshold/sessionPolicy.js +3 -9
- package/dist/esm/core/signingEngine/uiConfirm/nearFundingNotice.js +1 -17
- package/dist/esm/core/signingEngine/uiConfirm/ui/confirm-surface-resize.js +2 -173
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/ConfirmationContent.js +3 -3
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/ReviewDisclosure.js +2 -2
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/TransactionReceipt.js +1 -1
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/TransactionReview.js +5 -4
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/mountConfirmationSurface.js +2 -2
- package/dist/esm/core/signingEngine/uiConfirm/ui/surface-resize-events.js +1 -6
- package/dist/esm/core/signingEngine/uiConfirm/ui/transaction-display/abi/abiDecode.js +1 -1
- package/dist/esm/core/signingEngine/webauthnAuth/credentials/credentialExtensions.js +1 -19
- package/dist/esm/core/signingEngine/webauthnAuth/credentials/helpers.js +2 -170
- package/dist/esm/core/signingEngine/workerManager/ecdsaPresignPoolIdentity.js +27 -5
- package/dist/esm/core/signingEngine/workerManager/validation.js +1 -104
- package/dist/esm/core/signingEngine/workerManager/workerTypes.js +1 -33
- package/dist/esm/core/types/rpc.js +1 -4
- package/dist/esm/core/types/sdkSentEvents.js +1 -24
- package/dist/esm/core/walletRuntimePaths/base.js +1 -28
- package/dist/esm/externalEvm/controller.js +7 -7
- package/dist/esm/index.js +8 -7
- package/dist/esm/react/components/AccountMenuButton/AuthenticationMethodsModal.js +9 -9
- package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.css +1 -2
- package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.js +9 -185
- package/dist/esm/react/components/AccountMenuButton/WalletRegionSection.js +303 -0
- package/dist/esm/react/components/AccountMenuButton/WalletSettingsLayout.js +31 -5
- package/dist/esm/react/components/AccountMenuButton/index.js +21 -13
- package/dist/esm/react/components/AccountMenuButton/types.js +2 -1
- package/dist/esm/react/components/HostedSeamsAuthMenu/shell.js +5 -17
- package/dist/esm/react/components/QRCodeScanner.js +5 -5
- package/dist/esm/react/components/ShowQRCode.js +13 -13
- package/dist/esm/react/context/SeamsWebProvider.js +1 -2
- package/dist/esm/react/context/index.js +8 -10
- package/dist/esm/react/context/seamsManagerSingleton.js +1 -1
- package/dist/esm/react/context/useLoginStateRefresher.js +10 -13
- package/dist/esm/react/context/useNearProvisioningStateRefresh.js +3 -3
- package/dist/esm/react/context/useSeamsContextValue.js +33 -81
- package/dist/esm/react/context/useSeamsWithSdkFlow.js +22 -51
- package/dist/esm/react/context/useWalletIframeLifecycle.js +20 -110
- package/dist/esm/react/hooks/useAccountInput.js +10 -13
- package/dist/esm/react/hooks/useDeviceLinking.js +1 -1
- package/dist/esm/react/hooks/useNearClient.js +1 -1
- package/dist/esm/react/hooks/useQRCamera.js +2 -8
- package/dist/esm/react/hooks/useWallet.js +5 -6
- package/dist/esm/react/hooks/useWalletAuth.js +3 -4
- package/dist/esm/react/hooks/useWalletDevices.js +2 -2
- package/dist/esm/react/index.js +4 -4
- package/dist/esm/react/transactionReview/TransactionReviewHost.js +1 -1
- package/dist/esm/react/transactionReview/boundCalls.js +5 -39
- package/dist/esm/react/transactionReview/controller.js +3 -4
- package/dist/esm/react/transactionReview/snapshot.js +1 -1
- package/dist/esm/react/utils/walletIframe.js +11 -52
- package/dist/esm/sdk/{ConfirmationDrawer-DrsREojk.js → ConfirmationDrawer-DY0_yeUV.js} +1 -1
- package/dist/esm/sdk/NonceCoordinator-CFFq8-Q9.js +1 -0
- package/dist/esm/sdk/accountLifecycle-CAMVowDl.js +1 -0
- package/dist/esm/sdk/activeWalletSession-DiZcKjB_.js +1 -0
- package/dist/esm/sdk/adapters-DdDOQzl4.js +2 -0
- package/dist/esm/sdk/appearance-ZGVLwA4N.js +1 -0
- package/dist/esm/sdk/authenticatorOptions-DMLnDWT2.js +1 -0
- package/dist/esm/sdk/authorizationAdmission-Ckx6q6tp.js +1 -0
- package/dist/esm/sdk/bytes-BBYkulRB.js +1 -0
- package/dist/esm/sdk/canonicalPrimitives-CKPGgpxg.js +1 -0
- package/dist/esm/sdk/canonicalSignerErrorCode-DEHsPxNm.js +1 -0
- package/dist/esm/sdk/{capabilityKinds-XaXXiD2B.js → capabilityKinds-CKQ4Uqnv.js} +1 -1
- package/dist/esm/sdk/chains-CiYQT1K4.js +1 -0
- package/dist/esm/sdk/challengeDelivery-DxXAkOfS.js +1 -0
- package/dist/esm/sdk/clientSessionPersistenceState-CImFWDj6.js +1 -0
- package/dist/esm/sdk/commitQueue-iBNUt9Bz.js +1 -0
- package/dist/esm/sdk/configBuilder-ZiZwFKt4.js +1 -0
- package/dist/esm/sdk/configHelpers-D8Ivi6p8.js +1 -0
- package/dist/esm/sdk/digestEncoding-Dzc1rzWV.js +1 -0
- package/dist/esm/sdk/display-ClqZq-Xt.js +1 -0
- package/dist/esm/sdk/ecdsaCapabilityManifest-BlzJAQF8.js +1 -0
- package/dist/{public/sdk/ecdsaChainTarget-CRcRR78w.js → esm/sdk/ecdsaChainTarget-C8ZtMZ8l.js} +1 -1
- package/dist/esm/sdk/ecdsaDerivationClientWasm-CVeNEou2.js +1 -0
- package/dist/esm/sdk/ecdsaDerivationExport-BZFHSMCv.js +1 -0
- package/dist/esm/sdk/{ecdsaWalletRecords-Cm1DdexN.js → ecdsaWalletRecords-D4WeYc7H.js} +1 -1
- package/dist/esm/sdk/emailOtpEcdsaDerivationIdentity-B8HzTh4T.js +1 -0
- package/dist/esm/sdk/enrichDisplayModelWithAbi-69bNckvi.js +1 -0
- package/dist/esm/sdk/{evmCryptoWasm-CwEXiLrC.js → evmCryptoWasm-BXsIyRon.js} +1 -1
- package/dist/esm/sdk/export-viewer-host-CsFeiIhd.js +1 -0
- package/dist/esm/sdk/exportKeypairOperation-DGQIYML3.js +1 -0
- package/dist/esm/sdk/helpers-Ddy72ULN.js +1 -0
- package/dist/esm/sdk/host-c1__wJwz.js +1 -0
- package/dist/esm/sdk/intentDigest-CE-tLw87.js +1 -0
- package/dist/esm/sdk/jsxRuntime.module-BcZNe_OA.js +2 -0
- package/dist/esm/sdk/lanes-DnBwWv4l.js +1 -0
- package/dist/esm/sdk/localOnly-ClCo6602.js +1 -0
- package/dist/esm/sdk/messages-vxz27Way.js +1 -0
- package/dist/esm/sdk/mountExportPrivateKeySurface-CBZ0wRYj.js +1 -0
- package/dist/{public/sdk/mountRecoveryCodeBackupSurface-BBCTaQsu.js → esm/sdk/mountRecoveryCodeBackupSurface-B1qhFF6G.js} +2 -2
- package/dist/esm/sdk/nearEd25519YaoMaterialActivation-fWQI3rYj.js +1 -0
- package/dist/esm/sdk/nearEd25519YaoSigningPreparation-B0d1AG3u.js +1 -0
- package/dist/{public/sdk/nonceLaneKeys-BBYi4g51.js → esm/sdk/nonceLaneKeys-Fkvk2UPy.js} +1 -1
- package/dist/esm/sdk/normalization-CpLZcL2f.js +1 -0
- package/dist/esm/sdk/normalization-DCvuCvh0.js +1 -0
- package/dist/esm/sdk/normalize-kUDm5zfS.js +1 -0
- package/dist/esm/sdk/{operationFingerprint-DtQb0pdp.js → operationFingerprint-CTR9G1NT.js} +1 -1
- package/dist/esm/sdk/passkey-custody-BQj44jEM.js +1 -0
- package/dist/esm/sdk/pendingWalletRecoveryCodeBackup-yJN8VAHn.js +1 -0
- package/dist/esm/sdk/presignaturePool-DwlTReFO.js +1 -0
- package/dist/esm/sdk/presignatures-DB2IPD-A.js +1 -0
- package/dist/esm/sdk/{prfCache-Mbo7_USg.js → prfCache-BMpqZZ-v.js} +1 -1
- package/dist/esm/sdk/primitives-CAcl7ON7.js +1 -0
- package/dist/esm/sdk/promptText-D2f5Rg0h.js +1 -0
- package/dist/esm/sdk/recovery-entrypoint-Bl5GgbW9.js +1 -0
- package/dist/esm/sdk/registration-C4sALQZO.js +1 -0
- package/dist/esm/sdk/registration-CEqVAgNJ.js +1 -0
- package/dist/esm/sdk/{registrationAccounts-DIeEVy6W.js → registrationAccounts-D4RVetMz.js} +1 -1
- package/dist/esm/sdk/registrationAuthMethodInput-6ccY2Vuh.js +1 -0
- package/dist/esm/sdk/registrationIds-CdPqm-Ya.js +1 -0
- package/dist/esm/sdk/registrationIntent-DOkZcKSP.js +1 -0
- package/dist/esm/sdk/registrationSignerPlan-B9GCvpTV.js +1 -0
- package/dist/esm/sdk/requireStepUpAuth-DCVqmeee.js +1 -0
- package/dist/esm/sdk/routerAbNormalSigning-BG75eyI2.js +1 -0
- package/dist/esm/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/esm/sdk/runtime-auth-BKFyLISf.js +1 -0
- package/dist/esm/sdk/runtime-device-link-ENxdEXQW.js +1 -0
- package/dist/esm/sdk/runtime-ecdsa-tempo-DhGEb9U7.js +1 -0
- package/dist/esm/sdk/runtime-email-otp-dgsP7XZi.js +1 -0
- package/dist/esm/sdk/runtime-export-D2RCm5Gk.js +1 -0
- package/dist/esm/sdk/runtime-near-Bf-9MFBQ.js +1 -0
- package/dist/esm/sdk/runtime-preferences-LQ8SPE7o.js +1 -0
- package/dist/esm/sdk/runtime-recovery-BuEzJzuZ.js +1 -0
- package/dist/esm/sdk/runtime-recovery-codes-BZMiAR_5.js +1 -0
- package/dist/esm/sdk/sdkSentEvents-D3q1h-Uo.js +1 -0
- package/dist/esm/sdk/secp256k1-DSLttQND.js +1 -0
- package/dist/esm/sdk/{secureRandomId-CTdlJ5Mx.js → secureRandomId-BIekT8bE.js} +1 -1
- package/dist/esm/sdk/sessionPolicy-J-RrlPZQ.js +1 -0
- package/dist/esm/sdk/shared-8ffIBYw2.js +6 -0
- package/dist/esm/sdk/signEvmFamily-KUNWKVeh.js +1 -0
- package/dist/esm/sdk/{signEvmFamilyWithUiConfirmForTempo-DgTbh6jX.js → signEvmFamilyWithUiConfirmForTempo-Dc57bJ3V.js} +1 -1
- package/dist/esm/sdk/{signEvmWithUiConfirm-ChreN7aZ.js → signEvmWithUiConfirm-CqxL7UbT.js} +1 -1
- package/dist/esm/sdk/signNear-BhTkDm2-.js +1 -0
- package/dist/esm/sdk/{signatureUses-CQkkUcwT.js → signatureUses-CjJ233KX.js} +1 -1
- package/dist/esm/sdk/signerDomain-vQmlnsbF.js +1 -0
- package/dist/esm/sdk/signingFlow-vrXxrhlG.js +2 -0
- package/dist/esm/sdk/signingQueue-BrGJXBqe.js +1 -0
- package/dist/esm/sdk/{signingSessionSeal-Mr2Xp44o.js → signingSessionSeal-CDLUmAFY.js} +1 -1
- package/dist/esm/sdk/singletons-8UH3gOnZ.js +1 -0
- package/dist/esm/sdk/theme-_AUTWLS_.js +1 -0
- package/dist/esm/sdk/thresholdEcdsa-CO7xo1So.js +1 -0
- package/dist/esm/sdk/trace-BvbCxdXF.js +1 -0
- package/dist/esm/sdk/transaction-activity-D40ih2j-.js +1 -0
- package/dist/esm/sdk/transactionReviewAdmission-C-a3ctCJ.js +1 -0
- package/dist/esm/sdk/transactionState-DVinJk4K.js +1 -0
- package/dist/esm/sdk/tx-confirm-ui.js +7 -11
- package/dist/esm/sdk/{promptText-s8TQ6ckX.js → types-BNUuaUtl.js} +1 -1
- package/dist/esm/sdk/{types-M7vxrYtJ.js → types-D3GM-uHR.js} +1 -1
- package/dist/esm/sdk/wallet-iframe-host-ecdsa.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-full.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-near.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-runtime.js +1 -1
- package/dist/esm/sdk/wallet-recovery-C1kesLCF.js +1 -0
- package/dist/esm/sdk/wallet-ui.css +1 -1
- package/dist/esm/sdk/walletAuthMethodRecord-CXedSgpV.js +1 -0
- package/dist/esm/sdk/walletAuthority-B5hXHWpK.js +1 -0
- package/dist/esm/sdk/walletCustodyEcdsaContinuity-abNZ_dvX.js +1 -0
- package/dist/esm/sdk/{walletIframeIdentity-C0b0XMQF.js → walletIframeIdentity-DJ0KOBHg.js} +1 -1
- package/dist/esm/sdk/walletOwnershipGeneration-DoXVMDWe.js +1 -0
- package/dist/esm/sdk/walletRecoveryCommit-Cc9AqHr0.js +1 -0
- package/dist/esm/sdk/walletRecoveryRotate-DWTAFYiv.js +1 -0
- package/dist/esm/sdk/walletSessionAuthorizationProjection-DWBksIJR.js +1 -0
- package/dist/esm/sdk/walletSessionAuthorizationStatus-o1VgsLhA.js +1 -0
- package/dist/esm/sdk/walletSessionAuthorizationStore-gEYPmu-G.js +1 -0
- package/dist/esm/sdk/walletSessionFailure-Bu4VPKTz.js +1 -0
- package/dist/esm/sdk/warmSessionHydration-DgjuUacN.js +1 -0
- package/dist/esm/sdk/{webauthnP256-qu06GNFm.js → webauthnP256-BEz4DEAs.js} +1 -1
- package/dist/esm/sdk/{webauthnPromptCoordinator-DO-qfECu.js → webauthnPromptCoordinator-BEudHQBr.js} +1 -1
- package/dist/esm/shared-ts/src/authorization/capabilityKinds.js +1 -7
- package/dist/esm/shared-ts/src/authorization/delegatedAuthority.js +2 -20
- package/dist/esm/shared-ts/src/authorization/index.js +1 -2
- package/dist/esm/shared-ts/src/authorization/operationFingerprint.js +1 -20
- package/dist/esm/shared-ts/src/authorization/walletAuthority.js +4 -51
- package/dist/esm/shared-ts/src/authorization/walletSessionIssuance.js +1 -112
- package/dist/esm/shared-ts/src/device-linking/activeWalletSession.js +13 -3
- package/dist/esm/shared-ts/src/device-linking/authorityActivation.js +6 -116
- package/dist/esm/shared-ts/src/device-linking/committedSignerPackages.js +3 -270
- package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +2 -2
- package/dist/esm/shared-ts/src/device-linking/deviceManagement.js +1 -12
- package/dist/esm/shared-ts/src/device-linking/digests.js +1 -109
- package/dist/esm/shared-ts/src/device-linking/index.js +0 -2
- package/dist/esm/shared-ts/src/device-linking/parsers.js +7 -921
- package/dist/esm/shared-ts/src/device-linking/requestProof.js +1 -19
- package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +5 -358
- package/dist/esm/shared-ts/src/device-linking/walletSessionCredentialDelivery.js +1 -172
- package/dist/esm/shared-ts/src/device-linking/wireFields.js +4 -5
- package/dist/esm/shared-ts/src/near/actions.js +1 -13
- package/dist/esm/shared-ts/src/near/nearClient.js +1 -1
- package/dist/esm/shared-ts/src/passkey-custody/custodyEnvelope.js +3 -59
- package/dist/esm/shared-ts/src/passkey-custody/custodySecretBinding.js +4 -8
- package/dist/esm/shared-ts/src/passkey-custody/index.js +0 -1
- package/dist/esm/shared-ts/src/signing-lanes/index.js +0 -1
- package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +0 -59
- package/dist/esm/shared-ts/src/threshold/ed25519OperationFingerprint.js +1 -1
- package/dist/esm/shared-ts/src/threshold/keyMaterialBrands.js +1 -4
- package/dist/esm/shared-ts/src/threshold/participants.js +1 -2
- package/dist/esm/shared-ts/src/threshold/signingRootScope.js +1 -4
- package/dist/esm/shared-ts/src/utils/authenticatorOptions.js +1 -12
- package/dist/esm/shared-ts/src/utils/canonicalPrimitives.js +2 -5
- package/dist/esm/shared-ts/src/utils/domainIds.js +1 -7
- package/dist/esm/shared-ts/src/utils/ecdsaCapabilityActivation.js +1 -16
- package/dist/esm/shared-ts/src/utils/ecdsaServerTiming.js +6 -1
- package/dist/esm/shared-ts/src/utils/emailOtpDomain.js +1 -23
- package/dist/esm/shared-ts/src/utils/emailOtpRecoveryKey.js +1 -42
- package/dist/esm/shared-ts/src/utils/errors.js +1 -43
- package/dist/esm/shared-ts/src/utils/index.js +18 -22
- package/dist/esm/shared-ts/src/utils/near.js +2 -74
- package/dist/esm/shared-ts/src/utils/normalize.js +1 -22
- package/dist/esm/shared-ts/src/utils/registrationAuthMethodInput.js +1 -74
- package/dist/esm/shared-ts/src/utils/registrationEstablishedSession.js +6 -275
- package/dist/esm/shared-ts/src/utils/registrationIds.js +1 -203
- package/dist/esm/shared-ts/src/utils/registrationIntent.js +1 -389
- package/dist/esm/shared-ts/src/utils/registrationSignerPlan.js +2 -434
- package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +6 -414
- package/dist/esm/shared-ts/src/utils/routerAbEd25519Yao.js +1 -334
- package/dist/esm/shared-ts/src/utils/routerAbEd25519YaoDigests.js +2 -40
- package/dist/esm/shared-ts/src/utils/routerAbNormalSigningIdentity.js +1 -1
- package/dist/esm/shared-ts/src/utils/signingSessionSeal.js +1 -6
- package/dist/esm/shared-ts/src/utils/thresholdEcdsaKeyHandle.js +1 -6
- package/dist/esm/shared-ts/src/utils/validation.js +2 -17
- package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +1 -28
- package/dist/esm/shared-ts/src/utils/walletAuthMethodRecord.js +1 -11
- package/dist/esm/shared-ts/src/utils/walletCapabilityBindings.js +1 -7
- package/dist/esm/shared-ts/src/wallet-recovery/index.js +3 -5
- package/dist/esm/shared-ts/src/wallet-recovery/recoveryCodeIssuance.js +1 -35
- package/dist/esm/shared-ts/src/wallet-recovery/recoveryCodeLocator.js +0 -32
- package/dist/esm/shared-ts/src/wallet-recovery/recoveryCodeReservation.js +1 -15
- package/dist/esm/shared-ts/src/wallet-recovery/recoveryKeyId.js +0 -11
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -1
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEcdsaPossession.js +2 -42
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEnvelopeSet.js +3 -53
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryRotation.js +2 -63
- package/dist/esm/threshold.js +1 -1
- package/dist/esm/utils/intentDigest.js +1 -4
- package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
- package/dist/esm/wasm/router_ab_ecdsa_client/pkg/router_ab_ecdsa_client_bg.wasm +0 -0
- package/dist/esm/wasm/router_ab_ed25519_yao_client/pkg/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/public/headers.manifest.json +1 -1
- package/dist/public/sdk/{ConfirmationDrawer-DrsREojk.js → ConfirmationDrawer-DY0_yeUV.js} +1 -1
- package/dist/public/sdk/NonceCoordinator-CFFq8-Q9.js +1 -0
- package/dist/public/sdk/accountLifecycle-CAMVowDl.js +1 -0
- package/dist/public/sdk/activeWalletSession-DiZcKjB_.js +1 -0
- package/dist/public/sdk/adapters-DdDOQzl4.js +2 -0
- package/dist/public/sdk/appearance-ZGVLwA4N.js +1 -0
- package/dist/public/sdk/authenticatorOptions-DMLnDWT2.js +1 -0
- package/dist/public/sdk/authorizationAdmission-Ckx6q6tp.js +1 -0
- package/dist/public/sdk/bytes-BBYkulRB.js +1 -0
- package/dist/public/sdk/canonicalPrimitives-CKPGgpxg.js +1 -0
- package/dist/public/sdk/canonicalSignerErrorCode-DEHsPxNm.js +1 -0
- package/dist/public/sdk/{capabilityKinds-XaXXiD2B.js → capabilityKinds-CKQ4Uqnv.js} +1 -1
- package/dist/public/sdk/chains-CiYQT1K4.js +1 -0
- package/dist/public/sdk/challengeDelivery-DxXAkOfS.js +1 -0
- package/dist/public/sdk/clientSessionPersistenceState-CImFWDj6.js +1 -0
- package/dist/public/sdk/commitQueue-iBNUt9Bz.js +1 -0
- package/dist/public/sdk/configBuilder-ZiZwFKt4.js +1 -0
- package/dist/public/sdk/configHelpers-D8Ivi6p8.js +1 -0
- package/dist/public/sdk/digestEncoding-Dzc1rzWV.js +1 -0
- package/dist/public/sdk/display-ClqZq-Xt.js +1 -0
- package/dist/public/sdk/ecdsaCapabilityManifest-BlzJAQF8.js +1 -0
- package/dist/{esm/sdk/ecdsaChainTarget-CRcRR78w.js → public/sdk/ecdsaChainTarget-C8ZtMZ8l.js} +1 -1
- package/dist/public/sdk/ecdsaDerivationClientWasm-CVeNEou2.js +1 -0
- package/dist/public/sdk/ecdsaDerivationExport-BZFHSMCv.js +1 -0
- package/dist/public/sdk/{ecdsaWalletRecords-Cm1DdexN.js → ecdsaWalletRecords-D4WeYc7H.js} +1 -1
- package/dist/public/sdk/emailOtpEcdsaDerivationIdentity-B8HzTh4T.js +1 -0
- package/dist/public/sdk/enrichDisplayModelWithAbi-69bNckvi.js +1 -0
- package/dist/public/sdk/{evmCryptoWasm-CwEXiLrC.js → evmCryptoWasm-BXsIyRon.js} +1 -1
- package/dist/public/sdk/export-viewer-host-CsFeiIhd.js +1 -0
- package/dist/public/sdk/exportKeypairOperation-DGQIYML3.js +1 -0
- package/dist/public/sdk/helpers-Ddy72ULN.js +1 -0
- package/dist/public/sdk/host-c1__wJwz.js +1 -0
- package/dist/public/sdk/intentDigest-CE-tLw87.js +1 -0
- package/dist/public/sdk/jsxRuntime.module-BcZNe_OA.js +2 -0
- package/dist/public/sdk/lanes-DnBwWv4l.js +1 -0
- package/dist/public/sdk/localOnly-ClCo6602.js +1 -0
- package/dist/public/sdk/messages-vxz27Way.js +1 -0
- package/dist/public/sdk/mountExportPrivateKeySurface-CBZ0wRYj.js +1 -0
- package/dist/{esm/sdk/mountRecoveryCodeBackupSurface-BBCTaQsu.js → public/sdk/mountRecoveryCodeBackupSurface-B1qhFF6G.js} +2 -2
- package/dist/public/sdk/nearEd25519YaoMaterialActivation-fWQI3rYj.js +1 -0
- package/dist/public/sdk/nearEd25519YaoSigningPreparation-B0d1AG3u.js +1 -0
- package/dist/{esm/sdk/nonceLaneKeys-BBYi4g51.js → public/sdk/nonceLaneKeys-Fkvk2UPy.js} +1 -1
- package/dist/public/sdk/normalization-CpLZcL2f.js +1 -0
- package/dist/public/sdk/normalization-DCvuCvh0.js +1 -0
- package/dist/public/sdk/normalize-kUDm5zfS.js +1 -0
- package/dist/public/sdk/{operationFingerprint-DtQb0pdp.js → operationFingerprint-CTR9G1NT.js} +1 -1
- package/dist/public/sdk/passkey-custody-BQj44jEM.js +1 -0
- package/dist/public/sdk/pendingWalletRecoveryCodeBackup-yJN8VAHn.js +1 -0
- package/dist/public/sdk/presignaturePool-DwlTReFO.js +1 -0
- package/dist/public/sdk/presignatures-DB2IPD-A.js +1 -0
- package/dist/public/sdk/{prfCache-Mbo7_USg.js → prfCache-BMpqZZ-v.js} +1 -1
- package/dist/public/sdk/primitives-CAcl7ON7.js +1 -0
- package/dist/public/sdk/promptText-D2f5Rg0h.js +1 -0
- package/dist/public/sdk/recovery-entrypoint-Bl5GgbW9.js +1 -0
- package/dist/public/sdk/registration-C4sALQZO.js +1 -0
- package/dist/public/sdk/registration-CEqVAgNJ.js +1 -0
- package/dist/public/sdk/{registrationAccounts-DIeEVy6W.js → registrationAccounts-D4RVetMz.js} +1 -1
- package/dist/public/sdk/registrationAuthMethodInput-6ccY2Vuh.js +1 -0
- package/dist/public/sdk/registrationIds-CdPqm-Ya.js +1 -0
- package/dist/public/sdk/registrationIntent-DOkZcKSP.js +1 -0
- package/dist/public/sdk/registrationSignerPlan-B9GCvpTV.js +1 -0
- package/dist/public/sdk/requireStepUpAuth-DCVqmeee.js +1 -0
- package/dist/public/sdk/routerAbNormalSigning-BG75eyI2.js +1 -0
- package/dist/public/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/public/sdk/runtime-auth-BKFyLISf.js +1 -0
- package/dist/public/sdk/runtime-device-link-ENxdEXQW.js +1 -0
- package/dist/public/sdk/runtime-ecdsa-tempo-DhGEb9U7.js +1 -0
- package/dist/public/sdk/runtime-email-otp-dgsP7XZi.js +1 -0
- package/dist/public/sdk/runtime-export-D2RCm5Gk.js +1 -0
- package/dist/public/sdk/runtime-near-Bf-9MFBQ.js +1 -0
- package/dist/public/sdk/runtime-preferences-LQ8SPE7o.js +1 -0
- package/dist/public/sdk/runtime-recovery-BuEzJzuZ.js +1 -0
- package/dist/public/sdk/runtime-recovery-codes-BZMiAR_5.js +1 -0
- package/dist/public/sdk/sdkSentEvents-D3q1h-Uo.js +1 -0
- package/dist/public/sdk/secp256k1-DSLttQND.js +1 -0
- package/dist/public/sdk/{secureRandomId-CTdlJ5Mx.js → secureRandomId-BIekT8bE.js} +1 -1
- package/dist/public/sdk/sessionPolicy-J-RrlPZQ.js +1 -0
- package/dist/public/sdk/shared-8ffIBYw2.js +6 -0
- package/dist/public/sdk/signEvmFamily-KUNWKVeh.js +1 -0
- package/dist/public/sdk/{signEvmFamilyWithUiConfirmForTempo-DgTbh6jX.js → signEvmFamilyWithUiConfirmForTempo-Dc57bJ3V.js} +1 -1
- package/dist/public/sdk/{signEvmWithUiConfirm-ChreN7aZ.js → signEvmWithUiConfirm-CqxL7UbT.js} +1 -1
- package/dist/public/sdk/signNear-BhTkDm2-.js +1 -0
- package/dist/public/sdk/{signatureUses-CQkkUcwT.js → signatureUses-CjJ233KX.js} +1 -1
- package/dist/public/sdk/signerDomain-vQmlnsbF.js +1 -0
- package/dist/public/sdk/signingFlow-vrXxrhlG.js +2 -0
- package/dist/public/sdk/signingQueue-BrGJXBqe.js +1 -0
- package/dist/public/sdk/{signingSessionSeal-Mr2Xp44o.js → signingSessionSeal-CDLUmAFY.js} +1 -1
- package/dist/public/sdk/singletons-8UH3gOnZ.js +1 -0
- package/dist/public/sdk/theme-_AUTWLS_.js +1 -0
- package/dist/public/sdk/thresholdEcdsa-CO7xo1So.js +1 -0
- package/dist/public/sdk/trace-BvbCxdXF.js +1 -0
- package/dist/public/sdk/transaction-activity-D40ih2j-.js +1 -0
- package/dist/public/sdk/transactionReviewAdmission-C-a3ctCJ.js +1 -0
- package/dist/public/sdk/transactionState-DVinJk4K.js +1 -0
- package/dist/public/sdk/tx-confirm-ui.js +7 -11
- package/dist/public/sdk/{promptText-s8TQ6ckX.js → types-BNUuaUtl.js} +1 -1
- package/dist/public/sdk/{types-M7vxrYtJ.js → types-D3GM-uHR.js} +1 -1
- package/dist/public/sdk/wallet-iframe-host-ecdsa.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-full.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-near.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-runtime.js +1 -1
- package/dist/public/sdk/wallet-recovery-C1kesLCF.js +1 -0
- package/dist/public/sdk/wallet-ui.css +1 -1
- package/dist/public/sdk/walletAuthMethodRecord-CXedSgpV.js +1 -0
- package/dist/public/sdk/walletAuthority-B5hXHWpK.js +1 -0
- package/dist/public/sdk/walletCustodyEcdsaContinuity-abNZ_dvX.js +1 -0
- package/dist/public/sdk/{walletIframeIdentity-C0b0XMQF.js → walletIframeIdentity-DJ0KOBHg.js} +1 -1
- package/dist/public/sdk/walletOwnershipGeneration-DoXVMDWe.js +1 -0
- package/dist/public/sdk/walletRecoveryCommit-Cc9AqHr0.js +1 -0
- package/dist/public/sdk/walletRecoveryRotate-DWTAFYiv.js +1 -0
- package/dist/public/sdk/walletSessionAuthorizationProjection-DWBksIJR.js +1 -0
- package/dist/public/sdk/walletSessionAuthorizationStatus-o1VgsLhA.js +1 -0
- package/dist/public/sdk/walletSessionAuthorizationStore-gEYPmu-G.js +1 -0
- package/dist/public/sdk/walletSessionFailure-Bu4VPKTz.js +1 -0
- package/dist/public/sdk/warmSessionHydration-DgjuUacN.js +1 -0
- package/dist/public/sdk/{webauthnP256-qu06GNFm.js → webauthnP256-BEz4DEAs.js} +1 -1
- package/dist/public/sdk/{webauthnPromptCoordinator-DO-qfECu.js → webauthnPromptCoordinator-BEudHQBr.js} +1 -1
- package/dist/public/sdk/workers/device-linking-key.worker.js +18 -0
- package/dist/public/sdk/workers/ecdsa-derivation-client.worker.js +1490 -1268
- package/dist/public/sdk/workers/ecdsa-online-client.worker.js +96 -0
- package/dist/public/sdk/workers/ecdsa-presign-client.worker.js +101 -1
- package/dist/public/sdk/workers/email-otp.worker.js +267 -237
- package/dist/public/sdk/workers/evm-crypto.worker.js +12 -8
- package/dist/public/sdk/workers/passkey-mpc-export.worker.js +30 -1
- package/dist/public/sdk/workers/router_ab_ecdsa_client_bg.wasm +0 -0
- package/dist/public/sdk/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/public/sdk/workers/shamir3pass.worker.js +10 -8
- package/dist/public/sdk/workers/tempo-signer.worker.js +12 -8
- package/dist/public/sdk/workers/wallet-custody-ceremony.worker.js +3 -1
- package/dist/public/sdk/workers/wallet_custody_ceremony_bg.wasm +0 -0
- package/dist/public/sdk/workers/wasm_signer_worker_bg.wasm +0 -0
- package/dist/public/wallet-assets.manifest.json +391 -295
- package/dist/public/wallet-service/index.html +4 -4
- package/dist/types/shared-ts/src/device-linking/activeWalletSession.d.ts +2 -1
- package/dist/types/shared-ts/src/device-linking/contracts.d.ts +10 -0
- package/dist/types/shared-ts/src/threshold/ed25519OperationFingerprint.d.ts +2 -1
- package/dist/types/shared-ts/src/utils/emailOtpDomain.d.ts +3 -1
- package/dist/types/shared-ts/src/utils/routerAbPublicKeyset.d.ts +0 -9
- package/dist/types/shared-ts/src/utils/walletManagementProtocol.d.ts +1 -1
- package/dist/types/wallet/build-paths.d.ts +0 -4
- package/dist/types/wallet/src/SeamsWeb/SeamsWeb.d.ts +26 -146
- package/dist/types/wallet/src/SeamsWeb/assembly/browserSigningSurfaceAssembly.d.ts +7 -6
- package/dist/types/wallet/src/SeamsWeb/assembly/browserSigningSurfacePorts.d.ts +2 -4
- package/dist/types/wallet/src/SeamsWeb/assembly/createWalletIframeRouter.d.ts +2 -2
- package/dist/types/wallet/src/SeamsWeb/assembly/initializeBrowserSigningRuntime.d.ts +0 -2
- package/dist/types/wallet/src/SeamsWeb/index.d.ts +1 -1
- package/dist/types/wallet/src/SeamsWeb/operations/auth/login.d.ts +2 -8
- package/dist/types/wallet/src/SeamsWeb/operations/auth/unlockCompletion.d.ts +26 -0
- package/dist/types/wallet/src/SeamsWeb/operations/auth/unlockPendingRegistration.d.ts +14 -0
- package/dist/types/wallet/src/SeamsWeb/operations/auth/unlockSessionPolicy.d.ts +16 -0
- package/dist/types/wallet/src/SeamsWeb/operations/authMethods/emailOtp/challenge.d.ts +2 -2
- package/dist/types/wallet/src/SeamsWeb/operations/authMethods/emailOtp/googleEmailOtpWalletAuthFlow.d.ts +3 -2
- package/dist/types/wallet/src/SeamsWeb/operations/authMethods/revokeAuthMethod.d.ts +17 -1
- package/dist/types/wallet/src/SeamsWeb/operations/devices/linkDevice.d.ts +0 -7
- package/dist/types/wallet/src/SeamsWeb/operations/devices/walletHostComposition.d.ts +2 -0
- package/dist/types/wallet/src/SeamsWeb/operations/near/actions.d.ts +4 -21
- package/dist/types/wallet/src/SeamsWeb/operations/near/delegateAction.d.ts +4 -14
- package/dist/types/wallet/src/SeamsWeb/operations/near/signDelegateAction.d.ts +14 -0
- package/dist/types/wallet/src/SeamsWeb/operations/near/signNEP413.d.ts +2 -2
- package/dist/types/wallet/src/SeamsWeb/operations/registration/pendingEcdsaRegistrationRecovery.d.ts +11 -11
- package/dist/types/wallet/src/SeamsWeb/operations/registration/pendingEcdsaRegistrationRecoveryValidation.d.ts +18 -4
- package/dist/types/wallet/src/SeamsWeb/operations/registration/pendingRegistrationRecovery.d.ts +4 -20
- package/dist/types/wallet/src/SeamsWeb/operations/registration/registration.d.ts +10 -4
- package/dist/types/wallet/src/SeamsWeb/operations/registration/registrationEd25519Yao.d.ts +1 -1
- package/dist/types/wallet/src/SeamsWeb/operations/registration/registrationSignerSet.d.ts +1 -0
- package/dist/types/wallet/src/SeamsWeb/operations/registration/registrationTerminalCommit.d.ts +0 -4
- package/dist/types/wallet/src/SeamsWeb/operations/registration/registrationTiming.d.ts +2 -3
- package/dist/types/wallet/src/SeamsWeb/operations/tempo/index.d.ts +0 -3
- package/dist/types/wallet/src/SeamsWeb/publicApi/auth.d.ts +4 -13
- package/dist/types/wallet/src/SeamsWeb/publicApi/createPublicApi.d.ts +22 -43
- package/dist/types/wallet/src/SeamsWeb/publicApi/devices.d.ts +3 -21
- package/dist/types/wallet/src/SeamsWeb/publicApi/evm.d.ts +10 -16
- package/dist/types/wallet/src/SeamsWeb/publicApi/evmFamilyCommands.d.ts +6 -0
- package/dist/types/wallet/src/SeamsWeb/publicApi/index.d.ts +2 -2
- package/dist/types/wallet/src/SeamsWeb/publicApi/keyExport.d.ts +8 -16
- package/dist/types/wallet/src/SeamsWeb/publicApi/near.d.ts +10 -10
- package/dist/types/wallet/src/SeamsWeb/publicApi/nearCommands.d.ts +17 -0
- package/dist/types/wallet/src/SeamsWeb/publicApi/placement.d.ts +90 -0
- package/dist/types/wallet/src/SeamsWeb/publicApi/placement.typecheck.d.ts +2 -0
- package/dist/types/wallet/src/SeamsWeb/publicApi/session.d.ts +3 -0
- package/dist/types/wallet/src/SeamsWeb/publicApi/tempo.d.ts +11 -11
- package/dist/types/wallet/src/SeamsWeb/publicApi/types.d.ts +106 -243
- package/dist/types/wallet/src/SeamsWeb/publicApi/{awaitNearReady.d.ts → waitForNearAccount.d.ts} +7 -7
- package/dist/types/wallet/src/SeamsWeb/signingSurface/BrowserSigningSurface.d.ts +33 -78
- package/dist/types/wallet/src/SeamsWeb/signingSurface/ports.d.ts +8 -31
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/deviceCommands.d.ts +4 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/emailOtpCommands.d.ts +4 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/evmFamilyCommands.d.ts +6 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/inboundMessages.d.ts +62 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/nearCommands.d.ts +6 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/placementCommands.d.ts +31 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/preferenceState.d.ts +35 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/preferences.d.ts +10 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/registrationCommands.d.ts +6 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/router.d.ts +36 -121
- package/dist/types/wallet/src/SeamsWeb/walletIframe/client/sessionCommands.d.ts +6 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/coordinator.d.ts +29 -35
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/WalletHostRuntime.d.ts +98 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/auth-menu/controller.d.ts +2 -2
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/context.d.ts +11 -9
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createDeviceDomain.d.ts +20 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createEmailOtpCommands.d.ts +11 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createEvmFamilyCommands.d.ts +8 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createNearCommands.d.ts +4 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createPlacementCommands.d.ts +11 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createRegistrationCommands.d.ts +4 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/createSessionCommands.d.ts +16 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/handlers/placement.d.ts +3 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/handlers/walletIframeHandler.types.d.ts +7 -3
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/hostedWalletSeamsSession.d.ts +2 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/reconcileWalletPlacement.d.ts +10 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/requestRouter.d.ts +4 -4
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/requestWalletMove.d.ts +11 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/runtimeContext.d.ts +5 -3
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/runtimeLoader.d.ts +0 -1
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/sessionObserver.d.ts +39 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/walletMoveLocator.d.ts +5 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/walletMutationGuard.d.ts +3 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/shared/configuration.d.ts +30 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/shared/emailOtpLifecycle.d.ts +43 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/shared/exactSessionState.d.ts +15 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/shared/facadeBoundary.d.ts +14 -0
- package/dist/types/wallet/src/SeamsWeb/walletIframe/shared/messages.d.ts +35 -100
- package/dist/types/wallet/src/core/config/chains.d.ts +1 -3
- package/dist/types/wallet/src/core/config/configBuilder.d.ts +16 -6
- package/dist/types/wallet/src/core/config/defaultConfigs.d.ts +3 -4
- package/dist/types/wallet/src/core/config/defineConfig.d.ts +3 -6
- package/dist/types/wallet/src/core/config/presignatures.d.ts +3 -0
- package/dist/types/wallet/src/core/diagnostics/registration.d.ts +2 -0
- package/dist/types/wallet/src/core/indexedDB/normalization.d.ts +5 -0
- package/dist/types/wallet/src/core/indexedDB/passkeyClientDB.types.d.ts +2 -2
- package/dist/types/wallet/src/core/indexedDB/pendingWalletRegistrationCommit.d.ts +0 -10
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/accountSignerRows.d.ts +44 -0
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/ecdsaCapabilityManifestStore.d.ts +0 -2
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/ecdsaClientPresignatures.d.ts +0 -5
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/manager.d.ts +11 -0
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/nonceLeaseRows.d.ts +23 -0
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/repositories.d.ts +1 -0
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/signerOutboxRows.d.ts +15 -0
- package/dist/types/wallet/src/core/indexedDB/seamsWalletDB/walletOwnershipGeneration.d.ts +6 -0
- package/dist/types/wallet/src/core/indexedDB/unifiedIndexedDBManager.d.ts +1 -1
- package/dist/types/wallet/src/core/rpcClients/near/accountExists.d.ts +3 -0
- package/dist/types/wallet/src/core/rpcClients/near/rpcCalls.d.ts +1 -14
- package/dist/types/wallet/src/core/rpcClients/relayer/ecdsaPrepareSession.d.ts +13 -0
- package/dist/types/wallet/src/core/rpcClients/relayer/ownerWalletExecutionLanePreflight.d.ts +3 -3
- package/dist/types/wallet/src/core/rpcClients/relayer/relayerHttp.d.ts +17 -0
- package/dist/types/wallet/src/core/rpcClients/relayer/routerAbNormalSigning.d.ts +19 -3
- package/dist/types/wallet/src/core/rpcClients/relayer/walletRegistration.d.ts +29 -40
- package/dist/types/wallet/src/core/rpcClients/relayer/walletSessionAuthorizationStatus.d.ts +34 -0
- package/dist/types/wallet/src/core/signingEngine/assembly/ports/shared.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/assembly/ports/warmSigning.d.ts +2 -1
- package/dist/types/wallet/src/core/signingEngine/assembly/warmup.d.ts +2 -14
- package/dist/types/wallet/src/core/signingEngine/chains/near/nearSignerWasm.d.ts +2 -6
- package/dist/types/wallet/src/core/signingEngine/flows/recovery/public.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/emailOtpPublic.d.ts +1 -32
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/emailOtpSigningSession.d.ts +3 -82
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/readySecp256k1Material.d.ts +62 -1
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/requireEvmFamilyStepUpAuth.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/signers/secp256k1.d.ts +4 -55
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/signingFlow.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/flows/signEvmFamily/thresholdAdmission.d.ts +3 -2
- package/dist/types/wallet/src/core/signingEngine/flows/signNear/shared/ed25519YaoNormalSigning.d.ts +45 -1
- package/dist/types/wallet/src/core/signingEngine/flows/signNear/shared/signatureOnlySigning.d.ts +16 -2
- package/dist/types/wallet/src/core/signingEngine/flows/signNear/signNear.d.ts +1 -2
- package/dist/types/wallet/src/core/signingEngine/flows/signNear/signNep413.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/interfaces/ecdsaChainTarget.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/interfaces/near.d.ts +3 -0
- package/dist/types/wallet/src/core/signingEngine/nonce/nearTransactionReadiness.d.ts +3 -0
- package/dist/types/wallet/src/core/signingEngine/routerAb/ecdsaDerivation/presignaturePool.d.ts +9 -5
- package/dist/types/wallet/src/core/signingEngine/routerAb/ecdsaDerivation/presignaturePoolPolicy.d.ts +5 -0
- package/dist/types/wallet/src/core/signingEngine/session/SigningSessionCoordinator.d.ts +1 -7
- package/dist/types/wallet/src/core/signingEngine/session/availability/persistedAvailableSigningLanes.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/session/availability/readiness.d.ts +0 -17
- package/dist/types/wallet/src/core/signingEngine/session/emailOtp/EmailOtpWalletSessionCoordinator.d.ts +2 -2
- package/dist/types/wallet/src/core/signingEngine/session/emailOtp/ecdsaSigningSessionAuthority.d.ts +2 -33
- package/dist/types/wallet/src/core/signingEngine/session/emailOtp/exportRecovery.d.ts +2 -2
- package/dist/types/wallet/src/core/signingEngine/session/emailOtp/exportRecoveryRuntime.d.ts +14 -3
- package/dist/types/wallet/src/core/signingEngine/session/emailOtp/publicTypes.d.ts +1 -2
- package/dist/types/wallet/src/core/signingEngine/session/emailOtp/workerEnrollment.d.ts +0 -12
- package/dist/types/wallet/src/core/signingEngine/session/lanes/walletExecutionLaneHydration.d.ts +11 -25
- package/dist/types/wallet/src/core/signingEngine/session/lifecycle/walletSessionStatus.d.ts +0 -8
- package/dist/types/wallet/src/core/signingEngine/session/material/ecdsaSigningCapability.d.ts +2 -2
- package/dist/types/wallet/src/core/signingEngine/session/operationState/preparedOperation.d.ts +0 -8
- package/dist/types/wallet/src/core/signingEngine/session/operationState/trace.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/session/operationState/transactionState.d.ts +0 -1
- package/dist/types/wallet/src/core/signingEngine/session/passkey/ed25519YaoRecoveryCapability.d.ts +2 -0
- package/dist/types/wallet/src/core/signingEngine/session/public.d.ts +1 -1
- package/dist/types/wallet/src/core/signingEngine/session/routerAbSigningWalletSession.d.ts +2 -0
- package/dist/types/wallet/src/core/signingEngine/session/userPreferences.d.ts +8 -11
- package/dist/types/wallet/src/core/signingEngine/session/warmCapabilities/capabilityReader.d.ts +2 -1
- package/dist/types/wallet/src/core/signingEngine/session/warmCapabilities/capabilityReaderCore.d.ts +2 -1
- package/dist/types/wallet/src/core/signingEngine/stepUpConfirmation/confirmOperation.d.ts +3 -1
- package/dist/types/wallet/src/core/signingEngine/stepUpConfirmation/otpPrompt/authLane.d.ts +6 -12
- package/dist/types/wallet/src/core/signingEngine/threshold/ecdsa/operationStepUp.d.ts +6 -5
- package/dist/types/wallet/src/core/signingEngine/threshold/ed25519/yaoClient.d.ts +6 -17
- package/dist/types/wallet/src/core/signingEngine/uiConfirm/handlers/flows/signing.d.ts +2 -0
- package/dist/types/wallet/src/core/signingEngine/uiConfirm/handlers/handlePromptFromWorker.d.ts +2 -0
- package/dist/types/wallet/src/core/signingEngine/uiConfirm/ui/preact/ReviewDisclosure.d.ts +1 -0
- package/dist/types/wallet/src/core/signingEngine/uiConfirm/uiConfirm.types.d.ts +3 -0
- package/dist/types/wallet/src/core/signingEngine/walletCustody/ceremonyDriver.d.ts +0 -1
- package/dist/types/wallet/src/core/signingEngine/walletCustody/walletRegistrationEd25519.d.ts +17 -0
- package/dist/types/wallet/src/core/signingEngine/workerManager/SignerWorkerManager.d.ts +0 -1
- package/dist/types/wallet/src/core/signingEngine/workerManager/ecdsaPresignLifecycle.d.ts +0 -2
- package/dist/types/wallet/src/core/signingEngine/workerManager/ecdsaPresignPoolIdentity.d.ts +9 -0
- package/dist/types/wallet/src/core/signingEngine/workerManager/workerTransport.d.ts +0 -5
- package/dist/types/wallet/src/core/signingEngine/workerManager/workerTypes.d.ts +15 -27
- package/dist/types/wallet/src/core/signingEngine/workerManager/workers/email-otp/enrollment.d.ts +1 -17
- package/dist/types/wallet/src/core/types/rpc.d.ts +0 -1
- package/dist/types/wallet/src/core/types/sdkPublicResults.d.ts +1 -0
- package/dist/types/wallet/src/core/types/sdkSentEvents.d.ts +2 -0
- package/dist/types/wallet/src/core/types/seams.d.ts +12 -9
- package/dist/types/wallet/src/core/types/signer-worker.d.ts +2 -1
- package/dist/types/wallet/src/externalEvm/controller.d.ts +5 -1
- package/dist/types/wallet/src/index.d.ts +5 -2
- package/dist/types/wallet/src/react/components/AccountMenuButton/WalletRegionSection.d.ts +54 -0
- package/dist/types/wallet/src/react/components/AccountMenuButton/WalletSettingsLayout.d.ts +7 -2
- package/dist/types/wallet/src/react/components/AccountMenuButton/index.d.ts +1 -1
- package/dist/types/wallet/src/react/components/AccountMenuButton/types.d.ts +1 -0
- package/dist/types/wallet/src/react/components/HostedSeamsAuthMenu/public.d.ts +1 -1
- package/dist/types/wallet/src/react/components/HostedSeamsAuthMenu/types.d.ts +2 -5
- package/dist/types/wallet/src/react/context/SeamsWebProvider.d.ts +0 -5
- package/dist/types/wallet/src/react/context/useLoginStateRefresher.d.ts +1 -1
- package/dist/types/wallet/src/react/context/useNearProvisioningStateRefresh.d.ts +1 -1
- package/dist/types/wallet/src/react/context/useSeamsContextValue.d.ts +2 -2
- package/dist/types/wallet/src/react/context/useWalletIframeLifecycle.d.ts +4 -2
- package/dist/types/wallet/src/react/hooks/useQRCamera.d.ts +1 -7
- package/dist/types/wallet/src/react/hooks/useWallet.d.ts +5 -6
- package/dist/types/wallet/src/react/hooks/useWalletAuth.d.ts +1 -1
- package/dist/types/wallet/src/react/hooks/useWalletDevices.d.ts +1 -1
- package/dist/types/wallet/src/react/index.d.ts +2 -2
- package/dist/types/wallet/src/react/transactionReview/boundCalls.d.ts +0 -26
- package/dist/types/wallet/src/react/types.d.ts +12 -20
- package/dist/types/wallet/src/react/utils/walletIframe.d.ts +2 -6
- package/dist/workers/device-linking-key.worker.js +18 -0
- package/dist/workers/ecdsa-derivation-client.worker.js +1490 -1268
- package/dist/workers/ecdsa-online-client.worker.js +96 -0
- package/dist/workers/ecdsa-presign-client.worker.js +101 -1
- package/dist/workers/email-otp.worker.js +267 -237
- package/dist/workers/evm-crypto.worker.js +12 -8
- package/dist/workers/passkey-mpc-export.worker.js +30 -1
- package/dist/workers/router_ab_ecdsa_client_bg.wasm +0 -0
- package/dist/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/workers/shamir3pass.worker.js +10 -8
- package/dist/workers/tempo-signer.worker.js +12 -8
- package/dist/workers/wallet-custody-ceremony.worker.js +3 -1
- package/dist/workers/wallet_custody_ceremony_bg.wasm +0 -0
- package/dist/workers/wasm_signer_worker_bg.wasm +0 -0
- package/package.json +1 -1
- package/dist/esm/SeamsWeb/assembly/browserSigningSurfaceAssembly.js +0 -817
- package/dist/esm/SeamsWeb/assembly/browserWorkerWarmupPolicy.js +0 -31
- package/dist/esm/SeamsWeb/assembly/configureBrowserIndexedDB.js +0 -10
- package/dist/esm/SeamsWeb/assembly/createBrowserRecoveryPublicDeps.js +0 -95
- package/dist/esm/SeamsWeb/assembly/createBrowserSigningRuntime.js +0 -34
- package/dist/esm/SeamsWeb/assembly/createBrowserSigningStores.js +0 -39
- package/dist/esm/SeamsWeb/assembly/createBrowserStepUpRuntime.js +0 -34
- package/dist/esm/SeamsWeb/assembly/createBrowserWarmSessionPublicDeps.js +0 -29
- package/dist/esm/SeamsWeb/assembly/initializeBrowserSigningRuntime.js +0 -19
- package/dist/esm/SeamsWeb/assembly/runtimeConfig.js +0 -12
- package/dist/esm/SeamsWeb/operations/auth/login.js +0 -4383
- package/dist/esm/SeamsWeb/operations/auth/scheduleEcdsaSessionPresignaturePrefill.js +0 -41
- package/dist/esm/SeamsWeb/operations/auth/scheduleLinkedDevicePresignaturePrefill.js +0 -64
- package/dist/esm/SeamsWeb/operations/auth/walletAuth.js +0 -142
- package/dist/esm/SeamsWeb/operations/auth/walletUnlockEcdsaSubject.js +0 -33
- package/dist/esm/SeamsWeb/operations/auth/walletUnlockSubject.js +0 -288
- package/dist/esm/SeamsWeb/operations/authMethods/addAuthMethodSourceClaim.js +0 -72
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/addEmailOtp.js +0 -191
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/challenge.js +0 -247
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/googleEmailOtpWalletAuthFlow.js +0 -568
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/localEmailOtpProjection.js +0 -69
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/registrationAuthority.js +0 -62
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/registrationOffer.js +0 -69
- package/dist/esm/SeamsWeb/operations/authMethods/emailOtp/walletActivation.js +0 -95
- package/dist/esm/SeamsWeb/operations/authMethods/passkey/addPasskey.js +0 -260
- package/dist/esm/SeamsWeb/operations/authMethods/passkey/ecdsaBootstrap.js +0 -17
- package/dist/esm/SeamsWeb/operations/authMethods/passkey/exactPasskeyAuthority.js +0 -34
- package/dist/esm/SeamsWeb/operations/authMethods/passkey/localUnlock.js +0 -16
- package/dist/esm/SeamsWeb/operations/authMethods/passkey/loginAssertion.js +0 -25
- package/dist/esm/SeamsWeb/operations/authMethods/passkey/registrationAuthority.js +0 -84
- package/dist/esm/SeamsWeb/operations/authMethods/revokeAuthMethod.js +0 -205
- package/dist/esm/SeamsWeb/operations/authMethods/sourcePasskeyProof.js +0 -12
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingAuthorityInstallation.js +0 -444
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingComposition.js +0 -106
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingEd25519ExportRoot.js +0 -194
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingHttpTransport.js +0 -524
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingOwnerTransport.js +0 -135
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingResume.js +0 -212
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingTargetCredential.js +0 -63
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingTargetEd25519ExportRoot.js +0 -61
- package/dist/esm/SeamsWeb/operations/devices/deviceLinkingWorkerChannels.js +0 -337
- package/dist/esm/SeamsWeb/operations/devices/linkDevice.js +0 -75
- package/dist/esm/SeamsWeb/operations/devices/linkDeviceFlow.js +0 -1383
- package/dist/esm/SeamsWeb/operations/devices/linkDeviceFlowSupport.js +0 -143
- package/dist/esm/SeamsWeb/operations/devices/linkDeviceTargetActivation.js +0 -119
- package/dist/esm/SeamsWeb/operations/devices/walletHostComposition.js +0 -130
- package/dist/esm/SeamsWeb/operations/devices/walletHostOwnerAuthority.js +0 -191
- package/dist/esm/SeamsWeb/operations/evm/index.js +0 -35
- package/dist/esm/SeamsWeb/operations/near/actions.js +0 -484
- package/dist/esm/SeamsWeb/operations/near/commandSubject.js +0 -14
- package/dist/esm/SeamsWeb/operations/near/index.js +0 -37
- package/dist/esm/SeamsWeb/operations/near/signNEP413.js +0 -116
- package/dist/esm/SeamsWeb/operations/recovery/accountSync.js +0 -21
- package/dist/esm/SeamsWeb/operations/recovery/recoveryWalletBinding.js +0 -43
- package/dist/esm/SeamsWeb/operations/recovery/syncAccount.js +0 -912
- package/dist/esm/SeamsWeb/operations/recovery/walletRecoveryCodeBackup.js +0 -100
- package/dist/esm/SeamsWeb/operations/recovery/walletRecoveryRotation.js +0 -213
- package/dist/esm/SeamsWeb/operations/registration/pendingEcdsaRegistrationRecovery.js +0 -184
- package/dist/esm/SeamsWeb/operations/registration/pendingEcdsaRegistrationRecoveryUnlock.js +0 -247
- package/dist/esm/SeamsWeb/operations/registration/pendingEcdsaRegistrationRecoveryValidation.js +0 -134
- package/dist/esm/SeamsWeb/operations/registration/pendingRegistrationRecovery.js +0 -354
- package/dist/esm/SeamsWeb/operations/registration/registration.js +0 -3818
- package/dist/esm/SeamsWeb/operations/registration/registrationEd25519Yao.js +0 -166
- package/dist/esm/SeamsWeb/operations/registration/registrationSignerSet.js +0 -60
- package/dist/esm/SeamsWeb/operations/registration/registrationStrictEcdsa.js +0 -343
- package/dist/esm/SeamsWeb/operations/registration/registrationTerminalCommit.js +0 -296
- package/dist/esm/SeamsWeb/operations/registration/registrationTiming.js +0 -682
- package/dist/esm/SeamsWeb/operations/session/thresholdEcdsaProvisioning.js +0 -36
- package/dist/esm/SeamsWeb/operations/session/thresholdWarmSessionBootstrap.js +0 -20
- package/dist/esm/SeamsWeb/publicApi/preferences.js +0 -61
- package/dist/esm/SeamsWeb/publicApi/recovery.js +0 -19
- package/dist/esm/SeamsWeb/publicApi/types.js +0 -10
- package/dist/esm/SeamsWeb/signingSurface/BrowserSigningSurface.js +0 -3917
- package/dist/esm/SeamsWeb/walletIframe/host/restoredSessionPresignaturePrefill.js +0 -29
- package/dist/esm/core/browser/walletIframe/events.js +0 -6
- package/dist/esm/core/browser/walletIframe/host-mode.js +0 -9
- package/dist/esm/core/config/managedRuntimeScope.js +0 -16
- package/dist/esm/core/indexedDB/seamsWalletDB/pendingWalletRecoveryCodeBackup.js +0 -144
- package/dist/esm/core/platform/browser/createBrowserPlatformRuntime.js +0 -535
- package/dist/esm/core/platform/secretSources.js +0 -111
- package/dist/esm/core/platform/signerCoreCommandAdapters.js +0 -122
- package/dist/esm/core/rpcClients/near/rpcCalls.js +0 -376
- package/dist/esm/core/rpcClients/relayer/ownerWalletExecutionLanePreflight.js +0 -67
- package/dist/esm/core/rpcClients/relayer/passkeyCustodyEnvelope.js +0 -218
- package/dist/esm/core/rpcClients/relayer/sealedRefreshCapabilities.js +0 -148
- package/dist/esm/core/rpcClients/relayer/thresholdEcdsa.js +0 -235
- package/dist/esm/core/rpcClients/relayer/walletRecoveryGoogleEmailOtp.js +0 -161
- package/dist/esm/core/rpcClients/relayer/walletRegistrationTerminalResponse.js +0 -718
- package/dist/esm/core/signingEngine/assembly/createManagers.js +0 -80
- package/dist/esm/core/signingEngine/assembly/createPorts.js +0 -54
- package/dist/esm/core/signingEngine/assembly/ports/emailOtp.js +0 -30
- package/dist/esm/core/signingEngine/assembly/ports/evmFamily.js +0 -73
- package/dist/esm/core/signingEngine/assembly/ports/near.js +0 -21
- package/dist/esm/core/signingEngine/assembly/ports/recovery.js +0 -75
- package/dist/esm/core/signingEngine/assembly/ports/registration.js +0 -22
- package/dist/esm/core/signingEngine/assembly/ports/session.js +0 -25
- package/dist/esm/core/signingEngine/assembly/ports/shared.js +0 -39
- package/dist/esm/core/signingEngine/assembly/ports/stepUpRuntime.js +0 -67
- package/dist/esm/core/signingEngine/assembly/ports/warmSigning.js +0 -92
- package/dist/esm/core/signingEngine/assembly/warmup.js +0 -64
- package/dist/esm/core/signingEngine/flows/recovery/ecdsaDerivationExport.js +0 -427
- package/dist/esm/core/signingEngine/flows/recovery/ecdsaExportFlow.js +0 -660
- package/dist/esm/core/signingEngine/flows/recovery/ecdsaExportMaterial.js +0 -249
- package/dist/esm/core/signingEngine/flows/recovery/ed25519YaoExportFlow.js +0 -353
- package/dist/esm/core/signingEngine/flows/recovery/exportKeypairOperation.js +0 -213
- package/dist/esm/core/signingEngine/flows/recovery/exportLaneSelection.js +0 -283
- package/dist/esm/core/signingEngine/flows/recovery/keyExportConfirmation.js +0 -325
- package/dist/esm/core/signingEngine/flows/recovery/keyExportFlow.js +0 -81
- package/dist/esm/core/signingEngine/flows/recovery/passkeyEd25519YaoRecovery.js +0 -192
- package/dist/esm/core/signingEngine/flows/recovery/public.js +0 -26
- package/dist/esm/core/signingEngine/flows/recovery/stepUpAuthorization.js +0 -139
- package/dist/esm/core/signingEngine/flows/registration/nearProvisioningRegistry.js +0 -79
- package/dist/esm/core/signingEngine/flows/registration/public.js +0 -85
- package/dist/esm/core/signingEngine/flows/registration/services/ecdsaRegistrationSessions.js +0 -77
- package/dist/esm/core/signingEngine/flows/registration/services/passkeyEd25519YaoAddSigner.js +0 -82
- package/dist/esm/core/signingEngine/flows/registration/session.js +0 -24
- package/dist/esm/core/signingEngine/flows/signEvmFamily/emailOtpPublic.js +0 -123
- package/dist/esm/core/signingEngine/nonce/NonceCoordinator.js +0 -1026
- package/dist/esm/core/signingEngine/nonce/evmNonceLane.js +0 -182
- package/dist/esm/core/signingEngine/nonce/nearNonceLane.js +0 -669
- package/dist/esm/core/signingEngine/nonce/nonceDiagnostics.js +0 -232
- package/dist/esm/core/signingEngine/nonce/nonceLeaseState.js +0 -128
- package/dist/esm/core/signingEngine/nonce/nonceUtils.js +0 -33
- package/dist/esm/core/signingEngine/session/SigningSessionCoordinator.js +0 -344
- package/dist/esm/core/signingEngine/session/authority/authorityOperationResolver.js +0 -114
- package/dist/esm/core/signingEngine/session/availability/canonicalLaneInventory.js +0 -127
- package/dist/esm/core/signingEngine/session/availability/clientSessionExpiryInvalidator.js +0 -72
- package/dist/esm/core/signingEngine/session/availability/persistedAvailableSigningLanes.js +0 -214
- package/dist/esm/core/signingEngine/session/availability/readiness.js +0 -464
- package/dist/esm/core/signingEngine/session/emailOtp/EmailOtpWalletSessionCoordinator.js +0 -130
- package/dist/esm/core/signingEngine/session/emailOtp/ecdsaBootstrapCommit.js +0 -106
- package/dist/esm/core/signingEngine/session/emailOtp/ecdsaLifecycleRuntime.js +0 -47
- package/dist/esm/core/signingEngine/session/emailOtp/ecdsaLogin.js +0 -930
- package/dist/esm/core/signingEngine/session/emailOtp/ecdsaPublication.js +0 -414
- package/dist/esm/core/signingEngine/session/emailOtp/ecdsaRecovery.js +0 -264
- package/dist/esm/core/signingEngine/session/emailOtp/ed25519ExportContext.js +0 -373
- package/dist/esm/core/signingEngine/session/emailOtp/exportRecovery.js +0 -284
- package/dist/esm/core/signingEngine/session/emailOtp/exportRecoveryRuntime.js +0 -50
- package/dist/esm/core/signingEngine/session/emailOtp/persistedSnapshot.js +0 -22
- package/dist/esm/core/signingEngine/session/emailOtp/publicTypes.js +0 -38
- package/dist/esm/core/signingEngine/session/emailOtp/routePlan.js +0 -60
- package/dist/esm/core/signingEngine/session/emailOtp/runtimeConfig.js +0 -24
- package/dist/esm/core/signingEngine/session/emailOtp/sealedRefreshPolicy.js +0 -49
- package/dist/esm/core/signingEngine/session/emailOtp/sealedRestoreOrchestrator.js +0 -234
- package/dist/esm/core/signingEngine/session/emailOtp/sealedRuntimePurpose.js +0 -16
- package/dist/esm/core/signingEngine/session/emailOtp/sealedSessionRegistry.js +0 -40
- package/dist/esm/core/signingEngine/session/emailOtp/status.js +0 -72
- package/dist/esm/core/signingEngine/session/emailOtp/walletUnlock.js +0 -168
- package/dist/esm/core/signingEngine/session/emailOtp/warmSessionRuntime.js +0 -70
- package/dist/esm/core/signingEngine/session/emailOtp/workerEnrollment.js +0 -159
- package/dist/esm/core/signingEngine/session/emailOtp/workerRequests.js +0 -84
- package/dist/esm/core/signingEngine/session/emailOtp/zeroize.js +0 -9
- package/dist/esm/core/signingEngine/session/identity/exactWalletSessionCredential.js +0 -104
- package/dist/esm/core/signingEngine/session/identity/exactWalletSessionReader.js +0 -54
- package/dist/esm/core/signingEngine/session/identity/ownerLaneScope.js +0 -185
- package/dist/esm/core/signingEngine/session/lanes/walletExecutionLaneHydration.js +0 -194
- package/dist/esm/core/signingEngine/session/lifecycle/canonicalWalletSessionStatus.js +0 -32
- package/dist/esm/core/signingEngine/session/lifecycle/walletSessionStatus.js +0 -123
- package/dist/esm/core/signingEngine/session/material/ecdsaCapabilityHydration.js +0 -75
- package/dist/esm/core/signingEngine/session/material/ecdsaSealedRuntime.js +0 -197
- package/dist/esm/core/signingEngine/session/material/mpcCapabilityHydration.js +0 -79
- package/dist/esm/core/signingEngine/session/material/nearEd25519YaoSigningPreparation.js +0 -122
- package/dist/esm/core/signingEngine/session/material/restorableMpcMaterialRef.internal.js +0 -21
- package/dist/esm/core/signingEngine/session/passkey/ecdsaBootstrap.js +0 -184
- package/dist/esm/core/signingEngine/session/passkey/ecdsaKeyFactsInventory.js +0 -205
- package/dist/esm/core/signingEngine/session/passkey/ecdsaRecovery.js +0 -84
- package/dist/esm/core/signingEngine/session/passkey/ecdsaSessionProvision.js +0 -224
- package/dist/esm/core/signingEngine/session/passkey/ecdsaWarmCapabilityBootstrap.js +0 -147
- package/dist/esm/core/signingEngine/session/passkey/ed25519Provisioner.js +0 -55
- package/dist/esm/core/signingEngine/session/passkey/ed25519SessionProvision.js +0 -228
- package/dist/esm/core/signingEngine/session/passkey/ed25519YaoLocalMaterial.js +0 -536
- package/dist/esm/core/signingEngine/session/passkey/ed25519YaoRecoveryCapability.js +0 -94
- package/dist/esm/core/signingEngine/session/passkey/ed25519YaoSealedSession.js +0 -57
- package/dist/esm/core/signingEngine/session/passkey/ed25519YaoWarmRecovery.js +0 -281
- package/dist/esm/core/signingEngine/session/passkey/passkeyCustodySessionCache.js +0 -90
- package/dist/esm/core/signingEngine/session/passkey/public.js +0 -15
- package/dist/esm/core/signingEngine/session/passkey/unlockEcdsaWarmupPlanner.js +0 -247
- package/dist/esm/core/signingEngine/session/persistence/clientSessionPersistence.js +0 -135
- package/dist/esm/core/signingEngine/session/persistence/walletSessionAuthorizationProjection.js +0 -51
- package/dist/esm/core/signingEngine/session/planning/operationIdBinding.js +0 -36
- package/dist/esm/core/signingEngine/session/postconditions/runtimePostconditions.js +0 -163
- package/dist/esm/core/signingEngine/session/public.js +0 -44
- package/dist/esm/core/signingEngine/session/routerAbSigningWalletSession.js +0 -119
- package/dist/esm/core/signingEngine/session/sealedRecovery/exactRecordLookup.js +0 -148
- package/dist/esm/core/signingEngine/session/sealedRecovery/recoveryRecord.js +0 -248
- package/dist/esm/core/signingEngine/session/sealedRecovery/restoreCoordinator.js +0 -229
- package/dist/esm/core/signingEngine/session/userPreferences.js +0 -212
- package/dist/esm/core/signingEngine/session/warmCapabilities/capabilityReader.js +0 -62
- package/dist/esm/core/signingEngine/session/warmCapabilities/capabilityReaderCore.js +0 -293
- package/dist/esm/core/signingEngine/session/warmCapabilities/clearVolatileWarmSigningMaterial.js +0 -44
- package/dist/esm/core/signingEngine/session/warmCapabilities/ecdsaBootstrapPersistence.js +0 -107
- package/dist/esm/core/signingEngine/session/warmCapabilities/ecdsaBootstrapQueue.js +0 -22
- package/dist/esm/core/signingEngine/session/warmCapabilities/ecdsaLoginPrefill.js +0 -93
- package/dist/esm/core/signingEngine/session/warmCapabilities/ecdsaLoginPrefillSigningMaterialSource.js +0 -50
- package/dist/esm/core/signingEngine/session/warmCapabilities/ecdsaProvisionPlan.js +0 -9
- package/dist/esm/core/signingEngine/session/warmCapabilities/ed25519SealedSessionRuntime.js +0 -251
- package/dist/esm/core/signingEngine/session/warmCapabilities/nearEd25519CapabilityRehydration.js +0 -98
- package/dist/esm/core/signingEngine/session/warmCapabilities/public.js +0 -31
- package/dist/esm/core/signingEngine/session/warmCapabilities/readModel.js +0 -155
- package/dist/esm/core/signingEngine/session/warmCapabilities/routerAbEd25519WalletSessionState.js +0 -256
- package/dist/esm/core/signingEngine/session/warmCapabilities/statusReader.js +0 -100
- package/dist/esm/core/signingEngine/session/warmCapabilities/transitions.js +0 -47
- package/dist/esm/core/signingEngine/session/warmCapabilities/types.js +0 -122
- package/dist/esm/core/signingEngine/session/warmCapabilities/volatileWarmMaterialCommands.js +0 -45
- package/dist/esm/core/signingEngine/stepUpConfirmation/channel/confirmCommon.js +0 -89
- package/dist/esm/core/signingEngine/stepUpConfirmation/channel/confirmTypes.js +0 -12
- package/dist/esm/core/signingEngine/stepUpConfirmation/otpPrompt/authLane.js +0 -31
- package/dist/esm/core/signingEngine/stepUpConfirmation/otpPrompt/exportAuthorization.js +0 -108
- package/dist/esm/core/signingEngine/stepUpConfirmation/passkeyPrompt/touchIdPrompt.js +0 -271
- package/dist/esm/core/signingEngine/stepUpConfirmation/passkeyPrompt/webauthnPromptCoordinator.js +0 -167
- package/dist/esm/core/signingEngine/stepUpConfirmation/userConfirmationType.js +0 -15
- package/dist/esm/core/signingEngine/threshold/crypto/ed25519YaoLaneWasm.js +0 -67
- package/dist/esm/core/signingEngine/threshold/ecdsa/activation.js +0 -267
- package/dist/esm/core/signingEngine/threshold/ecdsa/bootstrapSession.js +0 -115
- package/dist/esm/core/signingEngine/threshold/ecdsa/postRegistrationSessionActivation.js +0 -132
- package/dist/esm/core/signingEngine/threshold/ecdsa/signingQueue.js +0 -16
- package/dist/esm/core/signingEngine/threshold/ed25519/commitQueue.js +0 -16
- package/dist/esm/core/signingEngine/threshold/ed25519/connectSession.js +0 -137
- package/dist/esm/core/signingEngine/threshold/ed25519/yaoActiveClientRegistry.js +0 -146
- package/dist/esm/core/signingEngine/threshold/ed25519/yaoClient.js +0 -563
- package/dist/esm/core/signingEngine/threshold/ed25519/yaoPageLifecycleOwner.js +0 -23
- package/dist/esm/core/signingEngine/uiConfirm/PasskeyMpcExportManager.js +0 -233
- package/dist/esm/core/signingEngine/uiConfirm/PasskeyMpcSessionDurableState.js +0 -493
- package/dist/esm/core/signingEngine/uiConfirm/PasskeyMpcSessionManager.js +0 -746
- package/dist/esm/core/signingEngine/uiConfirm/UiConfirmManager.js +0 -599
- package/dist/esm/core/signingEngine/uiConfirm/confirmationReadinessRegistry.js +0 -41
- package/dist/esm/core/signingEngine/uiConfirm/exportConfirmRequest.js +0 -149
- package/dist/esm/core/signingEngine/uiConfirm/handlers/determineConfirmationConfig.js +0 -82
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flowOrchestrator.js +0 -363
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flows/adapters/adapters.js +0 -337
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flows/adapters/request.js +0 -120
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flows/localOnly.js +0 -149
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flows/registration.js +0 -235
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flows/requestRegistrationCredentialConfirmation.js +0 -178
- package/dist/esm/core/signingEngine/uiConfirm/handlers/flows/signing.js +0 -684
- package/dist/esm/core/signingEngine/uiConfirm/handlers/handlePromptFromWorker.js +0 -90
- package/dist/esm/core/signingEngine/uiConfirm/ui/appearance.js +0 -27
- package/dist/esm/core/signingEngine/uiConfirm/ui/confirm-ui.js +0 -516
- package/dist/esm/core/signingEngine/uiConfirm/ui/export-private-key-reveal.js +0 -155
- package/dist/esm/core/signingEngine/uiConfirm/ui/export-viewer-host.js +0 -207
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/ExportPrivateKeySurface.js +0 -318
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/RecoveryCodeBackupSurface.js +0 -518
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/confirmation-controller.js +0 -80
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/mountExportPrivateKeySurface.js +0 -86
- package/dist/esm/core/signingEngine/uiConfirm/ui/preact/mountRecoveryCodeBackupSurface.js +0 -82
- package/dist/esm/core/signingEngine/uiConfirm/ui/surface-measurement-binding.js +0 -12
- package/dist/esm/core/signingEngine/uiConfirm/ui/transaction-activity.js +0 -46
- package/dist/esm/core/signingEngine/uiConfirm/ui/transaction-display/confirmation-tree.js +0 -27
- package/dist/esm/core/signingEngine/uiConfirm/warmSessionUiConfirm.js +0 -65
- package/dist/esm/core/signingEngine/walletCustody/activateEd25519Capability.js +0 -122
- package/dist/esm/core/signingEngine/walletCustody/ceremonyActiveClientMetadata.js +0 -94
- package/dist/esm/core/signingEngine/walletCustody/ceremonyDriver.js +0 -171
- package/dist/esm/core/signingEngine/walletCustody/ceremonyStepRunner.js +0 -20
- package/dist/esm/core/signingEngine/walletCustody/ed25519ActiveClient.js +0 -100
- package/dist/esm/core/signingEngine/walletCustody/ed25519Projection.js +0 -32
- package/dist/esm/core/signingEngine/walletCustody/ed25519SeedMaterial.js +0 -92
- package/dist/esm/core/signingEngine/walletCustody/emailOtpLink.js +0 -132
- package/dist/esm/core/signingEngine/walletCustody/joinCustodyWire.js +0 -64
- package/dist/esm/core/signingEngine/walletCustody/openCustodyCache.js +0 -126
- package/dist/esm/core/signingEngine/walletCustody/passkeyLink.js +0 -180
- package/dist/esm/core/signingEngine/walletCustody/recoveryReplacementEnvelope.js +0 -60
- package/dist/esm/core/signingEngine/walletCustody/registrationCeremony.js +0 -460
- package/dist/esm/core/signingEngine/walletCustody/unlockedEd25519ExportRootCapability.js +0 -258
- package/dist/esm/core/signingEngine/walletCustody/walletRecoveryCredential.js +0 -23
- package/dist/esm/core/signingEngine/walletCustody/walletRecoveryEcdsa.js +0 -75
- package/dist/esm/core/signingEngine/walletCustody/walletRecoveryEd25519.js +0 -129
- package/dist/esm/core/signingEngine/walletCustody/walletRecoveryManifest.js +0 -178
- package/dist/esm/core/signingEngine/walletCustody/walletRecoveryRotation.js +0 -102
- package/dist/esm/core/signingEngine/webauthnAuth/credentials/collectAuthenticationCredentialForChallengeB64u.js +0 -154
- package/dist/esm/core/signingEngine/webauthnAuth/device/signerSlot.js +0 -25
- package/dist/esm/core/signingEngine/webauthnAuth/walletOriginWebAuthn.js +0 -109
- package/dist/esm/core/signingEngine/workerManager/SignerWorkerManager.js +0 -68
- package/dist/esm/core/signingEngine/workerManager/deviceLinkingPorts.js +0 -342
- package/dist/esm/core/signingEngine/workerManager/deviceLinkingSourceContribution.js +0 -158
- package/dist/esm/core/signingEngine/workerManager/ecdsaClientWorkerChannels.js +0 -13
- package/dist/esm/core/signingEngine/workerManager/workerTransport.js +0 -734
- package/dist/esm/core/types/confirmationConfig.js +0 -39
- package/dist/esm/core/types/secure-confirm-worker.js +0 -22
- package/dist/esm/core/walletRuntimePaths/emailOtpWorker.js +0 -12
- package/dist/esm/core/walletRuntimePaths/multichainWorkers.js +0 -25
- package/dist/esm/core/walletRuntimePaths/walletCustodyCeremonyWorker.js +0 -18
- package/dist/esm/core/walletRuntimePaths/workers.js +0 -93
- package/dist/esm/react/context/useEagerPrewarm.js +0 -38
- package/dist/esm/sdk/EvmClient-DoxytQaJ.js +0 -1
- package/dist/esm/sdk/NearClient-vJ65Wjrq.js +0 -1
- package/dist/esm/sdk/NonceCoordinator-BBeadCSq.js +0 -1
- package/dist/esm/sdk/accountLifecycle-EyfYPnuT.js +0 -1
- package/dist/esm/sdk/actions-DZLxCcrU.js +0 -1
- package/dist/esm/sdk/adapters-DtAyuoiA.js +0 -2
- package/dist/esm/sdk/base-Xtd32asf.js +0 -1
- package/dist/esm/sdk/bytes-t5S5mkat.js +0 -1
- package/dist/esm/sdk/canonicalPrimitives-MPGET2cl.js +0 -1
- package/dist/esm/sdk/canonicalSignerErrorCode-C0hh_SVi.js +0 -1
- package/dist/esm/sdk/chains-yAls2d9X.js +0 -1
- package/dist/esm/sdk/challengeDelivery-cAsaUC6U.js +0 -1
- package/dist/esm/sdk/configHelpers-CseiVoZD.js +0 -1
- package/dist/esm/sdk/csp-stylesheet-B1fAhrGB.js +0 -2
- package/dist/esm/sdk/defaultConfigs-CWpApkMq.js +0 -1
- package/dist/esm/sdk/display-jK7_hYho.js +0 -1
- package/dist/esm/sdk/domainIds-GDzjOs6i.js +0 -1
- package/dist/esm/sdk/ecdsaCapabilityManifest-CHFu-QrV.js +0 -1
- package/dist/esm/sdk/ecdsaPresignLifecycle-CQnCxSlq.js +0 -1
- package/dist/esm/sdk/ecdsaPresignPoolIdentity-Ci-ovDlv.js +0 -1
- package/dist/esm/sdk/enrichDisplayModelWithAbi-CR-4ebuU.js +0 -1
- package/dist/esm/sdk/evmFamilyEcdsaIdentity-Br3iFdQx.js +0 -1
- package/dist/esm/sdk/exactSessionState-CjD8gekO.js +0 -210
- package/dist/esm/sdk/exactSigningLaneIdentity-olheZx_n.js +0 -1
- package/dist/esm/sdk/export-viewer-host-jo7h_0wl.js +0 -1
- package/dist/esm/sdk/helpers-D4QckQhq.js +0 -1
- package/dist/esm/sdk/host-BAqOYnju.js +0 -1
- package/dist/esm/sdk/intentDigest-CB6zy3lN.js +0 -1
- package/dist/esm/sdk/jsxRuntime.module-CoHsKD_3.js +0 -1
- package/dist/esm/sdk/keyMaterialBrands-uVZHfAh3.js +0 -1
- package/dist/esm/sdk/localOnly-DBQRG6Qh.js +0 -1
- package/dist/esm/sdk/messages-Cv2j4SKI.js +0 -1
- package/dist/esm/sdk/mountExportPrivateKeySurface-G7Z_9JMQ.js +0 -1
- package/dist/esm/sdk/nearEd25519YaoMaterialActivation-DQIw8ho3.js +0 -1
- package/dist/esm/sdk/nearEd25519YaoSigningPreparation-Bp_CvWRz.js +0 -1
- package/dist/esm/sdk/nearRpcResults--cBcfmp4.js +0 -1
- package/dist/esm/sdk/normalization-BGPR6osg.js +0 -1
- package/dist/esm/sdk/operationFingerprint-5-wH2Ht8.js +0 -1
- package/dist/esm/sdk/passkey-custody-LP4UTFbn.js +0 -1
- package/dist/esm/sdk/pendingWalletRecoveryCodeBackup-BNk4ebsY.js +0 -1
- package/dist/esm/sdk/recovery-entrypoint-DkT8sFO5.js +0 -1
- package/dist/esm/sdk/registration-Btozh7uh.js +0 -1
- package/dist/esm/sdk/registration-CSAG_h4Y.js +0 -1
- package/dist/esm/sdk/registrationIds-BIel5S0i.js +0 -1
- package/dist/esm/sdk/registrationIntent-DV1GYZ3K.js +0 -1
- package/dist/esm/sdk/registrationPreparationPreload-vOCqNuG4.js +0 -1
- package/dist/esm/sdk/registrationSignerPlan-FzD3TwxB.js +0 -1
- package/dist/esm/sdk/relayerHttp-DaPeS929.js +0 -1
- package/dist/esm/sdk/routePlan-B_KJaPtm.js +0 -1
- package/dist/esm/sdk/router-Dd3fFHk3.js +0 -1
- package/dist/esm/sdk/routerAbNormalSigning-D_fHjq5l.js +0 -1
- package/dist/esm/sdk/runtime-auth-B2M91rSx.js +0 -1
- package/dist/esm/sdk/runtime-device-link-ojjPSRaG.js +0 -1
- package/dist/esm/sdk/runtime-ecdsa-tempo-CE4JLgmn.js +0 -1
- package/dist/esm/sdk/runtime-email-otp-DDwtKVAe.js +0 -1
- package/dist/esm/sdk/runtime-export-JXYk8sQ-.js +0 -1
- package/dist/esm/sdk/runtime-near-BB8AG6dV.js +0 -1
- package/dist/esm/sdk/runtime-preferences-DKFZYccW.js +0 -1
- package/dist/esm/sdk/runtime-recovery-C_XjsDBg.js +0 -1
- package/dist/esm/sdk/runtime-recovery-codes-CWp839mH.js +0 -1
- package/dist/esm/sdk/runtimeContext-BpObgzbj.js +0 -6
- package/dist/esm/sdk/runtimeLoader-DjgBf_yF.js +0 -1
- package/dist/esm/sdk/sdkSentEvents-_RGAEeld.js +0 -1
- package/dist/esm/sdk/secp256k1-B_6W9QDJ.js +0 -1
- package/dist/esm/sdk/sessionPolicy-CNVK7nJ6.js +0 -1
- package/dist/esm/sdk/shared-j_KsFbCT.js +0 -1
- package/dist/esm/sdk/signEvmFamily-CcLVBm0f.js +0 -1
- package/dist/esm/sdk/signNear-mWbTE2Dl.js +0 -1
- package/dist/esm/sdk/signerDomain-BhUTzDmF.js +0 -1
- package/dist/esm/sdk/signerLoader-By0IY24G.js +0 -1
- package/dist/esm/sdk/signingFlow-LUWrZi2d.js +0 -2
- package/dist/esm/sdk/trace-M34pNGuF.js +0 -1
- package/dist/esm/sdk/transaction-activity-BbDod7ji.js +0 -1
- package/dist/esm/sdk/transactionReview-CBE5oH4c.js +0 -1
- package/dist/esm/sdk/transactionReviewAdmission-0ZgWs6q3.js +0 -1
- package/dist/esm/sdk/transactionState-9d7f3xVj.js +0 -1
- package/dist/esm/sdk/validation-dC1-_uyG.js +0 -1
- package/dist/esm/sdk/wallet-recovery-CcDZ1hMH.js +0 -1
- package/dist/esm/sdk/walletAuthority-CoWSeqvQ.js +0 -1
- package/dist/esm/sdk/walletCustodyEcdsaContinuity-B7xi7nwh.js +0 -1
- package/dist/esm/sdk/walletRecoveryCommit-ljxVeo-d.js +0 -1
- package/dist/esm/sdk/walletRecoveryRotate-HztDcDaY.js +0 -1
- package/dist/esm/sdk/warmSessionHydration-BPGM0YRU.js +0 -1
- package/dist/esm/shared-ts/src/authorization/walletCustodyOperation.js +0 -16
- package/dist/esm/shared-ts/src/device-linking/contracts.js +0 -8
- package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +0 -167
- package/dist/esm/shared-ts/src/passkey-custody/ceremonyCommitPayload.js +0 -43
- package/dist/esm/shared-ts/src/signing-lanes/participants.js +0 -256
- package/dist/esm/shared-ts/src/signing-lanes/recordParsers.js +0 -479
- package/dist/esm/shared-ts/src/threshold/secp256k1.js +0 -6
- package/dist/esm/shared-ts/src/utils/addAuthMethodRegistration.js +0 -103
- package/dist/esm/shared-ts/src/utils/ecdsaKeyFactsInventory.js +0 -43
- package/dist/esm/shared-ts/src/utils/exactKeys.js +0 -17
- package/dist/esm/shared-ts/src/utils/routerAbTraceContext.js +0 -36
- package/dist/esm/shared-ts/src/utils/walletAddSignerActivation.js +0 -32
- package/dist/public/sdk/EvmClient-DoxytQaJ.js +0 -1
- package/dist/public/sdk/NearClient-vJ65Wjrq.js +0 -1
- package/dist/public/sdk/NonceCoordinator-BBeadCSq.js +0 -1
- package/dist/public/sdk/accountLifecycle-EyfYPnuT.js +0 -1
- package/dist/public/sdk/actions-DZLxCcrU.js +0 -1
- package/dist/public/sdk/adapters-DtAyuoiA.js +0 -2
- package/dist/public/sdk/base-Xtd32asf.js +0 -1
- package/dist/public/sdk/bytes-t5S5mkat.js +0 -1
- package/dist/public/sdk/canonicalPrimitives-MPGET2cl.js +0 -1
- package/dist/public/sdk/canonicalSignerErrorCode-C0hh_SVi.js +0 -1
- package/dist/public/sdk/chains-yAls2d9X.js +0 -1
- package/dist/public/sdk/challengeDelivery-cAsaUC6U.js +0 -1
- package/dist/public/sdk/configHelpers-CseiVoZD.js +0 -1
- package/dist/public/sdk/csp-stylesheet-B1fAhrGB.js +0 -2
- package/dist/public/sdk/defaultConfigs-CWpApkMq.js +0 -1
- package/dist/public/sdk/display-jK7_hYho.js +0 -1
- package/dist/public/sdk/domainIds-GDzjOs6i.js +0 -1
- package/dist/public/sdk/ecdsaCapabilityManifest-CHFu-QrV.js +0 -1
- package/dist/public/sdk/ecdsaPresignLifecycle-CQnCxSlq.js +0 -1
- package/dist/public/sdk/ecdsaPresignPoolIdentity-Ci-ovDlv.js +0 -1
- package/dist/public/sdk/enrichDisplayModelWithAbi-CR-4ebuU.js +0 -1
- package/dist/public/sdk/evmFamilyEcdsaIdentity-Br3iFdQx.js +0 -1
- package/dist/public/sdk/exactSessionState-CjD8gekO.js +0 -210
- package/dist/public/sdk/exactSigningLaneIdentity-olheZx_n.js +0 -1
- package/dist/public/sdk/export-viewer-host-jo7h_0wl.js +0 -1
- package/dist/public/sdk/helpers-D4QckQhq.js +0 -1
- package/dist/public/sdk/host-BAqOYnju.js +0 -1
- package/dist/public/sdk/intentDigest-CB6zy3lN.js +0 -1
- package/dist/public/sdk/jsxRuntime.module-CoHsKD_3.js +0 -1
- package/dist/public/sdk/keyMaterialBrands-uVZHfAh3.js +0 -1
- package/dist/public/sdk/localOnly-DBQRG6Qh.js +0 -1
- package/dist/public/sdk/messages-Cv2j4SKI.js +0 -1
- package/dist/public/sdk/mountExportPrivateKeySurface-G7Z_9JMQ.js +0 -1
- package/dist/public/sdk/nearEd25519YaoMaterialActivation-DQIw8ho3.js +0 -1
- package/dist/public/sdk/nearEd25519YaoSigningPreparation-Bp_CvWRz.js +0 -1
- package/dist/public/sdk/nearRpcResults--cBcfmp4.js +0 -1
- package/dist/public/sdk/normalization-BGPR6osg.js +0 -1
- package/dist/public/sdk/operationFingerprint-5-wH2Ht8.js +0 -1
- package/dist/public/sdk/passkey-custody-LP4UTFbn.js +0 -1
- package/dist/public/sdk/pendingWalletRecoveryCodeBackup-BNk4ebsY.js +0 -1
- package/dist/public/sdk/recovery-entrypoint-DkT8sFO5.js +0 -1
- package/dist/public/sdk/registration-Btozh7uh.js +0 -1
- package/dist/public/sdk/registration-CSAG_h4Y.js +0 -1
- package/dist/public/sdk/registrationIds-BIel5S0i.js +0 -1
- package/dist/public/sdk/registrationIntent-DV1GYZ3K.js +0 -1
- package/dist/public/sdk/registrationPreparationPreload-vOCqNuG4.js +0 -1
- package/dist/public/sdk/registrationSignerPlan-FzD3TwxB.js +0 -1
- package/dist/public/sdk/relayerHttp-DaPeS929.js +0 -1
- package/dist/public/sdk/routePlan-B_KJaPtm.js +0 -1
- package/dist/public/sdk/router-Dd3fFHk3.js +0 -1
- package/dist/public/sdk/routerAbNormalSigning-D_fHjq5l.js +0 -1
- package/dist/public/sdk/runtime-auth-B2M91rSx.js +0 -1
- package/dist/public/sdk/runtime-device-link-ojjPSRaG.js +0 -1
- package/dist/public/sdk/runtime-ecdsa-tempo-CE4JLgmn.js +0 -1
- package/dist/public/sdk/runtime-email-otp-DDwtKVAe.js +0 -1
- package/dist/public/sdk/runtime-export-JXYk8sQ-.js +0 -1
- package/dist/public/sdk/runtime-near-BB8AG6dV.js +0 -1
- package/dist/public/sdk/runtime-preferences-DKFZYccW.js +0 -1
- package/dist/public/sdk/runtime-recovery-C_XjsDBg.js +0 -1
- package/dist/public/sdk/runtime-recovery-codes-CWp839mH.js +0 -1
- package/dist/public/sdk/runtimeContext-BpObgzbj.js +0 -6
- package/dist/public/sdk/runtimeLoader-DjgBf_yF.js +0 -1
- package/dist/public/sdk/sdkSentEvents-_RGAEeld.js +0 -1
- package/dist/public/sdk/secp256k1-B_6W9QDJ.js +0 -1
- package/dist/public/sdk/sessionPolicy-CNVK7nJ6.js +0 -1
- package/dist/public/sdk/shared-j_KsFbCT.js +0 -1
- package/dist/public/sdk/signEvmFamily-CcLVBm0f.js +0 -1
- package/dist/public/sdk/signNear-mWbTE2Dl.js +0 -1
- package/dist/public/sdk/signerDomain-BhUTzDmF.js +0 -1
- package/dist/public/sdk/signerLoader-By0IY24G.js +0 -1
- package/dist/public/sdk/signingFlow-LUWrZi2d.js +0 -2
- package/dist/public/sdk/trace-M34pNGuF.js +0 -1
- package/dist/public/sdk/transaction-activity-BbDod7ji.js +0 -1
- package/dist/public/sdk/transactionReview-CBE5oH4c.js +0 -1
- package/dist/public/sdk/transactionReviewAdmission-0ZgWs6q3.js +0 -1
- package/dist/public/sdk/transactionState-9d7f3xVj.js +0 -1
- package/dist/public/sdk/validation-dC1-_uyG.js +0 -1
- package/dist/public/sdk/wallet-recovery-CcDZ1hMH.js +0 -1
- package/dist/public/sdk/walletAuthority-CoWSeqvQ.js +0 -1
- package/dist/public/sdk/walletCustodyEcdsaContinuity-B7xi7nwh.js +0 -1
- package/dist/public/sdk/walletRecoveryCommit-ljxVeo-d.js +0 -1
- package/dist/public/sdk/walletRecoveryRotate-HztDcDaY.js +0 -1
- package/dist/public/sdk/warmSessionHydration-BPGM0YRU.js +0 -1
- package/dist/public/sdk/workers/evm_crypto.wasm +0 -0
- package/dist/public/sdk/workers/near_signer.wasm +0 -0
- package/dist/public/sdk/workers/tempo_signer.wasm +0 -0
- package/dist/types/wallet/src/SeamsWeb/assembly/browserWorkerWarmupPolicy.d.ts +0 -4
- package/dist/types/wallet/src/SeamsWeb/assembly/configureBrowserIndexedDB.d.ts +0 -3
- package/dist/types/wallet/src/SeamsWeb/operations/auth/walletAuth.d.ts +0 -56
- package/dist/types/wallet/src/SeamsWeb/operations/evm/index.d.ts +0 -9
- package/dist/types/wallet/src/SeamsWeb/operations/near/index.d.ts +0 -11
- package/dist/types/wallet/src/SeamsWeb/operations/recovery/accountSync.d.ts +0 -19
- package/dist/types/wallet/src/SeamsWeb/publicApi/devices.typecheck.d.ts +0 -2
- package/dist/types/wallet/src/SeamsWeb/publicApi/preferences.d.ts +0 -8
- package/dist/types/wallet/src/SeamsWeb/publicApi/recovery.d.ts +0 -14
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/config-guards.d.ts +0 -15
- package/dist/types/wallet/src/SeamsWeb/walletIframe/host/registrationPreparationPreload.d.ts +0 -2
- package/dist/types/wallet/src/core/signingEngine/flows/registration/public.d.ts +0 -68
- package/dist/types/wallet/src/react/context/useEagerPrewarm.d.ts +0 -3
- package/dist/workers/evm_crypto.wasm +0 -0
- package/dist/workers/near_signer.wasm +0 -0
- package/dist/workers/tempo_signer.wasm +0 -0
- /package/dist/esm/sdk/{accountIds-C3Ihsd2c.js → accountIds-BzZs7YoX.js} +0 -0
- /package/dist/esm/sdk/{base64-ojm5DKcF.js → base64-CsEj-_bC.js} +0 -0
- /package/dist/esm/sdk/{browser-CsOGMbMy.js → browser-D4wUl_77.js} +0 -0
- /package/dist/esm/sdk/{errors-DfbnsXjO.js → errors-BZO3LF6G.js} +0 -0
- /package/dist/esm/sdk/{events-BJyVcnsn.js → events-DsQJQ0Cl.js} +0 -0
- /package/dist/esm/sdk/{executeWorkerOperation-CrFf3FkL.js → executeWorkerOperation-BInr8RYN.js} +0 -0
- /package/dist/esm/sdk/{jsonRpc-C85RYR0A.js → jsonRpc-DrCYQIM9.js} +0 -0
- /package/dist/esm/sdk/{keccak-zexutGfG.js → keccak-B02Fekdh.js} +0 -0
- /package/dist/esm/sdk/{profileAccountProjection-DHCaMtOu.js → profileAccountProjection-DmmfMood.js} +0 -0
- /package/dist/esm/sdk/{signerSlot-BQ1g5JNV.js → signerSlot-Dto7dObP.js} +0 -0
- /package/dist/esm/sdk/{surface-measurement-reporter-OICExWKE.js → surface-measurement-reporter-IlPOI3QK.js} +0 -0
- /package/dist/public/sdk/{accountIds-C3Ihsd2c.js → accountIds-BzZs7YoX.js} +0 -0
- /package/dist/public/sdk/{base64-ojm5DKcF.js → base64-CsEj-_bC.js} +0 -0
- /package/dist/public/sdk/{browser-CsOGMbMy.js → browser-D4wUl_77.js} +0 -0
- /package/dist/public/sdk/{errors-DfbnsXjO.js → errors-BZO3LF6G.js} +0 -0
- /package/dist/public/sdk/{events-BJyVcnsn.js → events-DsQJQ0Cl.js} +0 -0
- /package/dist/public/sdk/{executeWorkerOperation-CrFf3FkL.js → executeWorkerOperation-BInr8RYN.js} +0 -0
- /package/dist/public/sdk/{jsonRpc-C85RYR0A.js → jsonRpc-DrCYQIM9.js} +0 -0
- /package/dist/public/sdk/{keccak-zexutGfG.js → keccak-B02Fekdh.js} +0 -0
- /package/dist/public/sdk/{profileAccountProjection-DHCaMtOu.js → profileAccountProjection-DmmfMood.js} +0 -0
- /package/dist/public/sdk/{signerSlot-BQ1g5JNV.js → signerSlot-Dto7dObP.js} +0 -0
- /package/dist/public/sdk/{surface-measurement-reporter-OICExWKE.js → surface-measurement-reporter-IlPOI3QK.js} +0 -0
|
@@ -1,4383 +0,0 @@
|
|
|
1
|
-
import { mpcMaterialActivationRefsEqual, parseThresholdEcdsaSessionId, parseThresholdEd25519SessionId, parseWalletId } from "../../../shared-ts/src/utils/domainIds.js";
|
|
2
|
-
import { parseMpcWalletSigningQuotaId, parseWalletSessionAuthorizationId, parseWalletSessionId, parseWalletSessionMintId } from "../../../shared-ts/src/authorization/capabilityKinds.js";
|
|
3
|
-
import { joinNormalizedUrl } from "../../../shared-ts/src/utils/normalize.js";
|
|
4
|
-
import { isObject } from "../../../shared-ts/src/utils/validation.js";
|
|
5
|
-
import { base64UrlDecode, base64UrlEncode } from "../../../shared-ts/src/utils/base64.js";
|
|
6
|
-
import { parseWalletSessionOperationCredentialV1 } from "../../../shared-ts/src/device-linking/activeWalletSession.js";
|
|
7
|
-
import { WalletSessionStatusReadScope } from "../../../core/rpcClients/relayer/walletSessionAuthorizationStatus.js";
|
|
8
|
-
import { parseRouterAbEd25519NormalSigningState } from "../../../shared-ts/src/utils/signingSessionSeal.js";
|
|
9
|
-
import { base58Encode } from "../../../shared-ts/src/utils/base58.js";
|
|
10
|
-
import { deriveImplicitNearAccountIdFromEd25519PublicKey } from "../../../shared-ts/src/utils/near.js";
|
|
11
|
-
import { toAccountId } from "../../../core/types/accountIds.js";
|
|
12
|
-
import { SIGNER_AUTH_METHODS } from "../../../shared-ts/src/utils/signerDomain.js";
|
|
13
|
-
import { UnlockEventPhase, createUnlockFlowEvent } from "../../../core/types/sdkSentEvents.js";
|
|
14
|
-
import { nearEd25519SigningKeyIdFromString } from "../../../shared-ts/src/utils/registrationIds.js";
|
|
15
|
-
import { buildEmailOtpWalletAuthMethodBinding, buildPasskeyAuthScope, buildPasskeyWalletAuthMethodBinding, buildWalletIdentity, parseRpId } from "../../../shared-ts/src/utils/walletCapabilityBindings.js";
|
|
16
|
-
import { thresholdEcdsaChainTargetKey } from "../../../core/signingEngine/interfaces/ecdsaChainTarget.js";
|
|
17
|
-
import { normalizeRuntimePolicyScope } from "../../../shared-ts/src/threshold/signingRootScope.js";
|
|
18
|
-
import { buildBaseEvmFamilyEcdsaKeyIdentity, buildEvmFamilyEcdsaSessionLanePolicy, deriveEvmFamilySigningKeySlotId, evmFamilyEcdsaWalletKeyToIdentity, resolveThresholdSigningRootBindingFromRuntimePolicyScope, toEvmFamilyEcdsaKeyHandle, toRpId } from "../../../core/signingEngine/session/identity/evmFamilyEcdsaIdentity.js";
|
|
19
|
-
import { exactEd25519SigningLaneIdentity, nearEd25519SignerBindingFromBoundaryFields } from "../../../core/signingEngine/session/identity/exactSigningLaneIdentity.js";
|
|
20
|
-
import { secureRandomId } from "../../../shared-ts/src/utils/secureRandomId.js";
|
|
21
|
-
import { DEFAULT_UNLOCK_REMAINING_USES, resolveWalletUnlockSessionUsesFromRequestedUses } from "../../../core/signingEngine/threshold/sessionPolicy.js";
|
|
22
|
-
import { parseSignerSlot } from "../../../shared-ts/src/utils/signerSlot.js";
|
|
23
|
-
import { IndexedDbEd25519YaoPublicCapabilityReferenceStore, publishEd25519YaoPublicCapabilityReferenceAndLane } from "../../../core/signingEngine/threshold/ed25519/yaoPublicCapabilityReferences.js";
|
|
24
|
-
import { isWalletCustodySeedBinding } from "../../../shared-ts/src/passkey-custody/custodySecretBinding.js";
|
|
25
|
-
import { sameRouterAbMpcMaterialActivationRef } from "../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
|
|
26
|
-
import { ROUTER_AB_ED25519_YAO_WARM_RECOVERY_BOOTSTRAP_PATH_V1, parseRouterAbEd25519YaoWarmRecoveryBootstrapRequestV1 } from "../../../shared-ts/src/utils/routerAbEd25519Yao.js";
|
|
27
|
-
import { ROUTER_AB_ED25519_YAO_ACTIVE_CLIENT_KIND_V1, RouterAbEd25519YaoClientV1 } from "../../../core/signingEngine/threshold/ed25519/yaoClient.js";
|
|
28
|
-
import { buildPasskeyWalletAuthAuthority, parseEmailOtpWalletAuthAuthority, parseWalletAuthAuthorityRef, walletAuthAuthorityRef } from "../../../shared-ts/src/utils/walletAuthAuthority.js";
|
|
29
|
-
import { destroyLinkedDeviceEcdsaHolderMaterialWasm, reconcileCanonicalEcdsaActivationWasm, storeLinkedDeviceEcdsaHolderMaterialWasm } from "../../../core/signingEngine/threshold/crypto/ecdsaDerivationClientWasm.js";
|
|
30
|
-
import { sameRouterAbEcdsaDerivationPublicCapabilityV1, sameRouterAbEcdsaDerivationPublicIdentityV1, sameRouterAbEcdsaRegistrationActivationReceiptV1, sameRouterAbServerIdentityV1 } from "../../../shared-ts/src/utils/routerAbEcdsaDerivation.js";
|
|
31
|
-
import { WALLET_CUSTODY_ED25519_MATERIAL_KEY_KIND } from "../../../core/indexedDB/walletCustodyEd25519MaterialRecord.js";
|
|
32
|
-
import "../../../shared-ts/src/device-linking/index.js";
|
|
33
|
-
import { openWalletAuthorityLinkedSignerMaterialV1 } from "../../../core/indexedDB/linkedAuthoritySignerMaterial.js";
|
|
34
|
-
import { getUserFriendlyErrorMessage, isUserCancellationError, toError } from "../../../shared-ts/src/utils/errors.js";
|
|
35
|
-
import { computeWalletEcdsaKeyFactsInventoryChallengeDigestB64u } from "../../../shared-ts/src/utils/ecdsaKeyFactsInventory.js";
|
|
36
|
-
import { WalletSessionAuthorizationUpgradeRequiredError, walletSessionAuthorizations } from "../../../core/indexedDB/seamsWalletDB/walletSessionAuthorizationStore.js";
|
|
37
|
-
import { installLinkedEcdsaHolderRuntimeV1, removeLinkedEcdsaHolderRuntimeV1, resolveLinkedEcdsaHolderRuntimeV1 } from "../../../core/signingEngine/session/material/linkedEcdsaHolderRuntime.js";
|
|
38
|
-
import { fetchWalletEcdsaKeyFactsInventoryWithOperationCredential, fetchWalletEcdsaKeyFactsInventoryWithWebAuthn } from "../../../core/rpcClients/relayer/walletRegistration.js";
|
|
39
|
-
import { ecdsaAvailableLaneForTarget, isConcreteAvailableSigningLane } from "../../../core/signingEngine/session/availability/availableSigningLanes.js";
|
|
40
|
-
import { buildRouterAbEd25519SigningWalletSession } from "../../../core/signingEngine/session/routerAbSigningWalletSession.js";
|
|
41
|
-
import { buildPasskeyRouterAbEd25519WalletSessionState } from "../../../core/signingEngine/session/warmCapabilities/routerAbEd25519WalletSessionState.js";
|
|
42
|
-
import { persistPasskeyEd25519YaoSignerMaterialV1 } from "../../../core/signingEngine/session/passkey/ed25519YaoLocalMaterial.js";
|
|
43
|
-
import { buildPasskeyEd25519RestoreMetadata, persistPasskeyEd25519YaoSessionForRefresh } from "../../../core/signingEngine/session/passkey/ed25519YaoSealedSession.js";
|
|
44
|
-
import { IndexedDBManager } from "../../../core/indexedDB/index.js";
|
|
45
|
-
import { getNearThresholdKeyMaterial } from "../../../core/accountData/near/keyMaterial.js";
|
|
46
|
-
import { isEcdsaCredentialFreeSessionActivationAuthorization } from "../../../core/signingEngine/threshold/ecdsa/postRegistrationSessionActivation.js";
|
|
47
|
-
import { exactWalletSessionAuthorityIdentity } from "../../../core/signingEngine/session/persistence/walletSessionAuthorizationProjection.js";
|
|
48
|
-
import { getNearAccountProjection } from "../../../core/accountData/near/accountProjection.js";
|
|
49
|
-
import { readExactWalletSessionAuthentication } from "../../../core/signingEngine/session/identity/exactWalletSessionReader.js";
|
|
50
|
-
import { destroyUnlockedWalletEd25519ExportRootCapabilitiesV1, establishUnlockedWalletEd25519ExportRootCapabilityV1, walletCustodyCeremonyTransportFromWorkerContextV1 } from "../../../core/signingEngine/walletCustody/unlockedEd25519ExportRootCapability.js";
|
|
51
|
-
import { unlockEmailOtpAuthorityWallet } from "../../../core/signingEngine/session/emailOtp/walletUnlock.js";
|
|
52
|
-
import { disposeWalletCustodyEd25519ActiveClientV1 } from "../../../core/signingEngine/walletCustody/ed25519ActiveClient.js";
|
|
53
|
-
import { browserExactWalletSessionReadPorts } from "../../../core/signingEngine/assembly/ports/emailOtp.js";
|
|
54
|
-
import { listBrowserCanonicalEcdsaSigningCapabilitiesForWallet, resolveBrowserActiveEcdsaCapabilityRuntime } from "../../assembly/browserSigningSurfaceAssembly.js";
|
|
55
|
-
import { rememberPasskeyCustodySessionEnvelope } from "../../../core/signingEngine/session/passkey/passkeyCustodySessionCache.js";
|
|
56
|
-
import { listConfiguredThresholdEcdsaPublicationTargets } from "../session/thresholdEcdsaProvisioning.js";
|
|
57
|
-
import { openWalletCustodyEd25519ActiveClientV1, walletCustodyActivationFactsFromActiveClientMetadataV1, walletCustodyCacheEnvelopeFromRecordV1 } from "../../../core/signingEngine/walletCustody/openCustodyCache.js";
|
|
58
|
-
import { joinCustodyWireFromEnvelopeRecord } from "../../../core/signingEngine/walletCustody/joinCustodyWire.js";
|
|
59
|
-
import { verifyPasskeyWalletUnlock } from "../../../core/rpcClients/near/rpcCalls.js";
|
|
60
|
-
import { passkeyCredentialIdB64uFromAuthentication, passkeyPrfFirstB64uFromCredential } from "../authMethods/passkey/ecdsaBootstrap.js";
|
|
61
|
-
import { scheduleEcdsaSessionPresignaturePrefill } from "./scheduleEcdsaSessionPresignaturePrefill.js";
|
|
62
|
-
import { resolveManagedRuntimeScopeBootstrap } from "../../../core/config/managedRuntimeScope.js";
|
|
63
|
-
import { exactPasskeyWalletAuthAuthorityRefForCredential, exactPasskeyWalletAuthMethodForCredential } from "../authMethods/passkey/exactPasskeyAuthority.js";
|
|
64
|
-
import { scheduleLinkedDevicePresignaturePrefill } from "./scheduleLinkedDevicePresignaturePrefill.js";
|
|
65
|
-
import { createRouterAbNormalSigningPolicy } from "../session/thresholdWarmSessionBootstrap.js";
|
|
66
|
-
import { assertWalletRuntimePostconditions } from "../../../core/signingEngine/session/postconditions/runtimePostconditions.js";
|
|
67
|
-
import { buildConfiguredTargetKeyCompletion, collectConfiguredTargetThresholdEcdsaWarmKeys, configuredTargetThresholdEcdsaWarmKey, mergeCanonicalThresholdEcdsaWarmSessionContexts, parseActiveEcdsaSignerRecordForUnlock, planUnlockEcdsaWarmup, requireCompleteConfiguredTargetKeyContext } from "../../../core/signingEngine/session/passkey/unlockEcdsaWarmupPlanner.js";
|
|
68
|
-
import { collectPasskeyLoginAssertion } from "../authMethods/passkey/loginAssertion.js";
|
|
69
|
-
import { collectFreshLocalPasskeyUnlockCredential, createLocalUnlockChallengeB64u } from "../authMethods/passkey/localUnlock.js";
|
|
70
|
-
import { resolveEcdsaActivationJournalSelectors } from "./walletUnlockEcdsaSubject.js";
|
|
71
|
-
import { resolveWalletCapabilitySubjectResolution } from "./walletUnlockSubject.js";
|
|
72
|
-
//#region src/SeamsWeb/operations/auth/login.ts
|
|
73
|
-
function emitUnlockEvent(onEvent, unlockSubjectId, event) {
|
|
74
|
-
onEvent?.(createUnlockFlowEvent({
|
|
75
|
-
flowId: `unlock:${unlockSubjectId}`,
|
|
76
|
-
accountId: unlockSubjectId,
|
|
77
|
-
...event
|
|
78
|
-
}));
|
|
79
|
-
}
|
|
80
|
-
function resolveLoginWalletUnlockSelection(selection) {
|
|
81
|
-
switch (selection?.mode) {
|
|
82
|
-
case "ed25519_only": return {
|
|
83
|
-
mode: "ed25519_only",
|
|
84
|
-
ed25519: true
|
|
85
|
-
};
|
|
86
|
-
case "ecdsa_only": return {
|
|
87
|
-
mode: "ecdsa_only",
|
|
88
|
-
ecdsa: true
|
|
89
|
-
};
|
|
90
|
-
case "ed25519_and_ecdsa":
|
|
91
|
-
case void 0: return {
|
|
92
|
-
mode: "ed25519_and_ecdsa",
|
|
93
|
-
ed25519: true,
|
|
94
|
-
ecdsa: true
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
return assertNeverLoginState(selection);
|
|
98
|
-
}
|
|
99
|
-
function resolveLoginWalletUnlockSelectionForSubjectSet(args) {
|
|
100
|
-
if (args.selection) return resolveLoginWalletUnlockSelection(args.selection);
|
|
101
|
-
let hasNearEd25519 = false;
|
|
102
|
-
let hasEvmFamilyEcdsa = false;
|
|
103
|
-
for (const subject of args.subjectSet.subjects) switch (subject.kind) {
|
|
104
|
-
case "near_ed25519_wallet":
|
|
105
|
-
hasNearEd25519 = true;
|
|
106
|
-
break;
|
|
107
|
-
case "evm_family_ecdsa_wallet":
|
|
108
|
-
hasEvmFamilyEcdsa = true;
|
|
109
|
-
break;
|
|
110
|
-
default: return assertNeverLoginState(subject);
|
|
111
|
-
}
|
|
112
|
-
if (hasNearEd25519 && hasEvmFamilyEcdsa) return {
|
|
113
|
-
mode: "ed25519_and_ecdsa",
|
|
114
|
-
ed25519: true,
|
|
115
|
-
ecdsa: true
|
|
116
|
-
};
|
|
117
|
-
if (hasNearEd25519) return {
|
|
118
|
-
mode: "ed25519_only",
|
|
119
|
-
ed25519: true
|
|
120
|
-
};
|
|
121
|
-
if (hasEvmFamilyEcdsa) return {
|
|
122
|
-
mode: "ecdsa_only",
|
|
123
|
-
ecdsa: true
|
|
124
|
-
};
|
|
125
|
-
throw new Error("[login] wallet unlock subject set has no supported capability");
|
|
126
|
-
}
|
|
127
|
-
function buildAnonymousWalletSession() {
|
|
128
|
-
return {
|
|
129
|
-
appIdentity: { kind: "anonymous" },
|
|
130
|
-
authentication: { kind: "signed_out" },
|
|
131
|
-
capabilityProjection: { kind: "not_requested" },
|
|
132
|
-
nonceDiagnostics: null
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
function isNearEd25519WalletSubject(subject) {
|
|
136
|
-
return subject.kind === "near_ed25519_wallet";
|
|
137
|
-
}
|
|
138
|
-
function isEvmFamilyEcdsaWalletSubject(subject) {
|
|
139
|
-
return subject.kind === "evm_family_ecdsa_wallet";
|
|
140
|
-
}
|
|
141
|
-
function selectNearEd25519WalletSubject(subjectSet) {
|
|
142
|
-
const nearSubjects = subjectSet.subjects.filter(isNearEd25519WalletSubject);
|
|
143
|
-
if (nearSubjects.length === 0) return null;
|
|
144
|
-
if (nearSubjects.length > 1) throw new Error("[WalletSession] multiple NEAR Ed25519 subjects found for wallet session");
|
|
145
|
-
return nearSubjects[0] || null;
|
|
146
|
-
}
|
|
147
|
-
function resolveLoginWalletIdentity(args) {
|
|
148
|
-
const nearSubject = selectNearEd25519WalletSubject(args.subjectSet);
|
|
149
|
-
const ecdsaSubjects = args.subjectSet.subjects.filter(isEvmFamilyEcdsaWalletSubject);
|
|
150
|
-
for (const subject of args.subjectSet.subjects) if (String(subject.walletId) !== String(args.subjectSet.walletId)) throw new Error("[login] wallet unlock subject belongs to a different wallet");
|
|
151
|
-
switch (args.selection.mode) {
|
|
152
|
-
case "ed25519_only":
|
|
153
|
-
if (!nearSubject || ecdsaSubjects.length !== 0) throw new Error("[login] NEAR Ed25519 unlock requires one exact NEAR subject set");
|
|
154
|
-
return {
|
|
155
|
-
kind: "near_ed25519_capable_wallet",
|
|
156
|
-
walletId: args.subjectSet.walletId,
|
|
157
|
-
subjectSet: args.subjectSet,
|
|
158
|
-
nearAccountId: nearSubject.nearAccountId,
|
|
159
|
-
nearEd25519SigningKeyId: nearSubject.nearEd25519SigningKeyId,
|
|
160
|
-
signerSlot: nearSubject.signerSlot
|
|
161
|
-
};
|
|
162
|
-
case "ecdsa_only": {
|
|
163
|
-
const [firstEcdsaSubject, ...remainingEcdsaSubjects] = ecdsaSubjects;
|
|
164
|
-
if (nearSubject || !firstEcdsaSubject) throw new Error("[login] ECDSA-only unlock requires exact ECDSA subjects");
|
|
165
|
-
return {
|
|
166
|
-
kind: "evm_family_ecdsa_only_wallet",
|
|
167
|
-
walletId: args.subjectSet.walletId,
|
|
168
|
-
subjectSet: args.subjectSet,
|
|
169
|
-
ecdsaSubjects: [firstEcdsaSubject, ...remainingEcdsaSubjects]
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
case "ed25519_and_ecdsa":
|
|
173
|
-
if (!nearSubject || ecdsaSubjects.length === 0) throw new Error("[login] combined unlock requires exact NEAR and ECDSA subjects");
|
|
174
|
-
return {
|
|
175
|
-
kind: "near_ed25519_capable_wallet",
|
|
176
|
-
walletId: args.subjectSet.walletId,
|
|
177
|
-
subjectSet: args.subjectSet,
|
|
178
|
-
nearAccountId: nearSubject.nearAccountId,
|
|
179
|
-
nearEd25519SigningKeyId: nearSubject.nearEd25519SigningKeyId,
|
|
180
|
-
signerSlot: nearSubject.signerSlot
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
return assertNeverLoginState(args.selection);
|
|
184
|
-
}
|
|
185
|
-
function requireNearLoginWalletBinding(identity) {
|
|
186
|
-
if (identity.kind === "near_ed25519_capable_wallet") return identity;
|
|
187
|
-
throw new Error("[login] NEAR Ed25519 warm-up requires an exact NEAR subject");
|
|
188
|
-
}
|
|
189
|
-
function assertEcdsaWarmupMatchesUnlockSubjects(args) {
|
|
190
|
-
const allowedThresholdKeyIds = /* @__PURE__ */ new Set();
|
|
191
|
-
for (const subject of args.identity.subjectSet.subjects) if (subject.kind === "evm_family_ecdsa_wallet") allowedThresholdKeyIds.add(String(subject.ecdsaThresholdKeyId));
|
|
192
|
-
if (allowedThresholdKeyIds.size === 0) throw new Error("[login] ECDSA warm-up requires an exact ECDSA unlock subject");
|
|
193
|
-
for (const warmKey of args.context.ecdsaKeys) {
|
|
194
|
-
const thresholdKeyId = String(warmKey.key?.ecdsaThresholdKeyId || "").trim();
|
|
195
|
-
if (thresholdKeyId && !allowedThresholdKeyIds.has(thresholdKeyId)) throw new Error("[login] ECDSA warm-up key does not match the unlock subject set");
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
function ecdsaActivationSelectorsFromSubjectSet(subjectSet) {
|
|
199
|
-
const selectors = [];
|
|
200
|
-
for (const subject of subjectSet.subjects) {
|
|
201
|
-
if (subject.kind !== "evm_family_ecdsa_wallet") continue;
|
|
202
|
-
selectors.push({
|
|
203
|
-
capability: subject.capability,
|
|
204
|
-
authority: subject.authority
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
return selectors;
|
|
208
|
-
}
|
|
209
|
-
async function reconcileCanonicalEcdsaActivationSelectors(args) {
|
|
210
|
-
let didFinalize = false;
|
|
211
|
-
let pending = false;
|
|
212
|
-
for (const selector of args.selectors) {
|
|
213
|
-
const result = await reconcileCanonicalEcdsaActivationWasm({
|
|
214
|
-
workerCtx: args.workerCtx,
|
|
215
|
-
command: {
|
|
216
|
-
kind: "reconcile_canonical_ecdsa_activation_v1",
|
|
217
|
-
capability: selector.capability,
|
|
218
|
-
authority: selector.authority
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
switch (result.kind) {
|
|
222
|
-
case "canonical_ecdsa_activation_reconciliation_absent_v1": break;
|
|
223
|
-
case "canonical_ecdsa_activation_reconciliation_finalized_v1":
|
|
224
|
-
didFinalize = true;
|
|
225
|
-
break;
|
|
226
|
-
case "canonical_ecdsa_activation_reconciliation_pending_v1":
|
|
227
|
-
pending = true;
|
|
228
|
-
break;
|
|
229
|
-
case "canonical_ecdsa_activation_reconciliation_failed_v1": return {
|
|
230
|
-
kind: "failed",
|
|
231
|
-
didFinalize,
|
|
232
|
-
code: result.code
|
|
233
|
-
};
|
|
234
|
-
default: assertNeverLoginState(result);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return pending ? {
|
|
238
|
-
kind: "pending",
|
|
239
|
-
didFinalize
|
|
240
|
-
} : {
|
|
241
|
-
kind: "settled",
|
|
242
|
-
didFinalize
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
function reportNonSettledEcdsaActivationReconciliation(result) {
|
|
246
|
-
switch (result.kind) {
|
|
247
|
-
case "settled": return;
|
|
248
|
-
case "pending":
|
|
249
|
-
console.warn("[login] ECDSA activation remains prepared and requires confirmation");
|
|
250
|
-
return;
|
|
251
|
-
case "failed":
|
|
252
|
-
console.warn("[login] ECDSA activation reconciliation failed without changing active state", { code: result.code });
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
assertNeverLoginState(result);
|
|
256
|
-
}
|
|
257
|
-
function walletAuthMethodBindingFromRecord(record) {
|
|
258
|
-
const wallet = buildWalletIdentity({ walletId: record.walletId });
|
|
259
|
-
switch (record.kind) {
|
|
260
|
-
case "passkey": {
|
|
261
|
-
const rpId = parseRpId(record.rpId);
|
|
262
|
-
if (!rpId.ok) return null;
|
|
263
|
-
return buildPasskeyWalletAuthMethodBinding({
|
|
264
|
-
walletAuthMethodId: record.walletAuthMethodId,
|
|
265
|
-
scope: buildPasskeyAuthScope({
|
|
266
|
-
wallet,
|
|
267
|
-
rpId: rpId.value
|
|
268
|
-
}),
|
|
269
|
-
credentialIdB64u: record.credentialIdB64u
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
case "email_otp": return buildEmailOtpWalletAuthMethodBinding({
|
|
273
|
-
walletAuthMethodId: record.walletAuthMethodId,
|
|
274
|
-
wallet,
|
|
275
|
-
emailHashHex: record.emailHashHex,
|
|
276
|
-
registrationAuthorityId: record.registrationAuthorityId
|
|
277
|
-
});
|
|
278
|
-
default: return null;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
function walletAuthAuthorityForSelectedPasskeyMethod(record) {
|
|
282
|
-
return {
|
|
283
|
-
walletId: record.walletId,
|
|
284
|
-
factor: {
|
|
285
|
-
kind: "passkey",
|
|
286
|
-
credentialIdB64u: record.credentialIdB64u
|
|
287
|
-
},
|
|
288
|
-
verifier: {
|
|
289
|
-
kind: "webauthn",
|
|
290
|
-
rpId: record.rpId
|
|
291
|
-
},
|
|
292
|
-
bindingId: record.walletAuthMethodId
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
async function walletAuthAuthorityRefForSelectedPasskeyMethod(record) {
|
|
296
|
-
return await walletAuthAuthorityRef({ authority: walletAuthAuthorityForSelectedPasskeyMethod(record) });
|
|
297
|
-
}
|
|
298
|
-
async function resolveExactLinkedEmailOtpAuthority(args) {
|
|
299
|
-
const authority = parseEmailOtpWalletAuthAuthority({
|
|
300
|
-
walletId: args.authMethod.walletId,
|
|
301
|
-
factor: {
|
|
302
|
-
kind: "email_otp",
|
|
303
|
-
provider: args.provider,
|
|
304
|
-
providerUserId: args.providerSubjectId
|
|
305
|
-
},
|
|
306
|
-
verifier: {
|
|
307
|
-
kind: "email_otp_wallet_auth_method",
|
|
308
|
-
emailHashHex: args.authMethod.emailHashHex
|
|
309
|
-
},
|
|
310
|
-
bindingId: args.authMethod.walletAuthMethodId
|
|
311
|
-
});
|
|
312
|
-
if (!authority) throw new Error("[login] linked Email OTP provider identity does not match selected authority");
|
|
313
|
-
return authority;
|
|
314
|
-
}
|
|
315
|
-
async function walletAuthAuthorityForLinkedDeviceMethod(args) {
|
|
316
|
-
if (args.selection.authMethod.kind === "passkey") return walletAuthAuthorityForSelectedPasskeyMethod(args.selection.authMethod);
|
|
317
|
-
const providerIdentity = args.providerIdentity;
|
|
318
|
-
if (!providerIdentity) throw new Error("[login] linked Email OTP authority provider identity is missing");
|
|
319
|
-
return await resolveExactLinkedEmailOtpAuthority({
|
|
320
|
-
authMethod: args.selection.authMethod,
|
|
321
|
-
provider: providerIdentity.provider,
|
|
322
|
-
providerSubjectId: providerIdentity.providerSubjectId
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
async function walletAuthAuthorityRefForLinkedDeviceMethod(args) {
|
|
326
|
-
return await walletAuthAuthorityRef({ authority: await walletAuthAuthorityForLinkedDeviceMethod(args) });
|
|
327
|
-
}
|
|
328
|
-
function selectedSignerMaterialForActivation(materials, authorityId, walletAuthMethodId, activation) {
|
|
329
|
-
let selected = null;
|
|
330
|
-
for (const material of materials) {
|
|
331
|
-
if (material.authorityId !== authorityId || material.walletAuthMethodId !== walletAuthMethodId || material.activationId !== activation.activationId) continue;
|
|
332
|
-
if (selected) return null;
|
|
333
|
-
selected = material;
|
|
334
|
-
}
|
|
335
|
-
return selected;
|
|
336
|
-
}
|
|
337
|
-
function linkedDeviceUnlockIdentityMismatchLabels(input) {
|
|
338
|
-
const failures = [];
|
|
339
|
-
if (input.selection.walletId !== input.walletId) failures.push("selection_wallet_id");
|
|
340
|
-
if (!input.allowUnselectedSibling && input.selection.walletAuthMethodId !== input.authMethod.walletAuthMethodId) failures.push("selection_auth_method_id");
|
|
341
|
-
if (input.authMethod.walletId !== input.walletId) failures.push("auth_method_wallet_id");
|
|
342
|
-
if (input.authMethod.status !== "active") failures.push("auth_method_inactive");
|
|
343
|
-
if (input.expectedKind && input.authMethod.kind !== input.expectedKind) failures.push(`auth_method_not_${input.expectedKind}`);
|
|
344
|
-
if (input.authority.walletId !== input.walletId) failures.push("authority_wallet_id");
|
|
345
|
-
if (input.authority.state !== "active") failures.push("authority_inactive");
|
|
346
|
-
if (input.authority.authorityId !== input.authMethod.walletAuthorityId) failures.push("authority_auth_method_id");
|
|
347
|
-
return failures;
|
|
348
|
-
}
|
|
349
|
-
async function resolveLinkedDevicePasskeyAuthoritySelection(walletIdInput) {
|
|
350
|
-
const parsedWalletId = parseWalletId(walletIdInput);
|
|
351
|
-
if (!parsedWalletId.ok) return null;
|
|
352
|
-
const walletId = parsedWalletId.value;
|
|
353
|
-
try {
|
|
354
|
-
const resolved = await IndexedDBManager.resolveSelectedWalletAuthority(String(walletId));
|
|
355
|
-
if (resolved.kind !== "resolved") return null;
|
|
356
|
-
const { selection, authMethod, authority } = resolved;
|
|
357
|
-
if (linkedDeviceUnlockIdentityMismatchLabels({
|
|
358
|
-
walletId,
|
|
359
|
-
selection,
|
|
360
|
-
authMethod,
|
|
361
|
-
authority,
|
|
362
|
-
expectedKind: "passkey"
|
|
363
|
-
}).length > 0) return null;
|
|
364
|
-
if (authMethod.status !== "active" || authMethod.kind !== "passkey") return null;
|
|
365
|
-
if (authority.state !== "active") return null;
|
|
366
|
-
if (authority.provenance.kind !== "device_link") return null;
|
|
367
|
-
return {
|
|
368
|
-
kind: "linked_device_passkey_authority_selection_v1",
|
|
369
|
-
walletId,
|
|
370
|
-
selection,
|
|
371
|
-
authMethod,
|
|
372
|
-
authority,
|
|
373
|
-
signerMaterials: resolved.signerMaterials,
|
|
374
|
-
exportRoot: resolved.exportRoot
|
|
375
|
-
};
|
|
376
|
-
} catch {
|
|
377
|
-
return null;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
async function resolveLinkedDeviceEmailOtpAuthoritySelection(args) {
|
|
381
|
-
const parsedWalletId = parseWalletId(args.walletIdInput);
|
|
382
|
-
const emailHashHex = String(args.emailHashHex || "").trim().toLowerCase();
|
|
383
|
-
const providerSubjectId = String(args.providerSubjectId || "").trim();
|
|
384
|
-
if (!parsedWalletId.ok || !emailHashHex || !providerSubjectId) return { kind: "none" };
|
|
385
|
-
const walletId = parsedWalletId.value;
|
|
386
|
-
let resolved;
|
|
387
|
-
try {
|
|
388
|
-
resolved = args.walletAuthMethodId ? await IndexedDBManager.resolveWalletAuthorityForMethod(String(walletId), args.walletAuthMethodId) : await IndexedDBManager.resolveSelectedWalletAuthority(String(walletId));
|
|
389
|
-
} catch (error) {
|
|
390
|
-
return {
|
|
391
|
-
kind: "rejected",
|
|
392
|
-
message: error instanceof Error ? error.message : "Selected Email OTP authority is unavailable"
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
if (resolved.kind === "missing_selection") return { kind: "none" };
|
|
396
|
-
if (resolved.kind !== "resolved") return {
|
|
397
|
-
kind: "rejected",
|
|
398
|
-
message: "Selected Email OTP authority is unavailable"
|
|
399
|
-
};
|
|
400
|
-
const { selection, authMethod, authority } = resolved;
|
|
401
|
-
if (authMethod.kind !== "email_otp") return { kind: "none" };
|
|
402
|
-
if (linkedDeviceUnlockIdentityMismatchLabels({
|
|
403
|
-
walletId,
|
|
404
|
-
selection,
|
|
405
|
-
authMethod,
|
|
406
|
-
authority,
|
|
407
|
-
expectedKind: "email_otp",
|
|
408
|
-
allowUnselectedSibling: Boolean(args.walletAuthMethodId)
|
|
409
|
-
}).length > 0 || authMethod.emailHashHex.toLowerCase() !== emailHashHex) return {
|
|
410
|
-
kind: "rejected",
|
|
411
|
-
message: "Selected Email OTP authority is inactive or does not match the verified email"
|
|
412
|
-
};
|
|
413
|
-
if (authMethod.status !== "active" || authority.state !== "active") return {
|
|
414
|
-
kind: "rejected",
|
|
415
|
-
message: "Selected Email OTP authority is inactive"
|
|
416
|
-
};
|
|
417
|
-
try {
|
|
418
|
-
await resolveExactLinkedEmailOtpAuthority({
|
|
419
|
-
authMethod,
|
|
420
|
-
provider: args.provider,
|
|
421
|
-
providerSubjectId
|
|
422
|
-
});
|
|
423
|
-
} catch (error) {
|
|
424
|
-
return {
|
|
425
|
-
kind: "rejected",
|
|
426
|
-
message: error instanceof Error ? error.message : "Selected Email OTP provider identity does not match the local authority"
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
if (authority.provenance.kind === "device_link" && resolved.signerMaterials.length === 0) return {
|
|
430
|
-
kind: "rejected",
|
|
431
|
-
message: "Selected linked Email OTP authority has no signer material"
|
|
432
|
-
};
|
|
433
|
-
if (resolved.signerMaterials.some((material) => material.kind !== "wallet_authority_linked_signer_material_v1")) return {
|
|
434
|
-
kind: "rejected",
|
|
435
|
-
message: "Selected Email OTP authority has an invalid linked signer material set"
|
|
436
|
-
};
|
|
437
|
-
return {
|
|
438
|
-
kind: "selected",
|
|
439
|
-
selection: {
|
|
440
|
-
kind: "linked_device_email_otp_authority_selection_v1",
|
|
441
|
-
walletId,
|
|
442
|
-
selection,
|
|
443
|
-
authMethod,
|
|
444
|
-
authority,
|
|
445
|
-
signerMaterials: resolved.signerMaterials,
|
|
446
|
-
exportRoot: resolved.exportRoot
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
function linkedDeviceActivationForCapability(authority, subject) {
|
|
451
|
-
const activation = subject.keyFamily === "ed25519" ? authority.signerActivations.ed25519 : authority.signerActivations.ecdsa;
|
|
452
|
-
if (!activation) throw new Error(`[login] linked Wallet Session requested unavailable ${subject.keyFamily} material`);
|
|
453
|
-
if (!mpcMaterialActivationRefsEqual(activation.materialActivation, subject.materialActivation)) throw new Error("[login] linked Wallet Session material activation does not match authority");
|
|
454
|
-
return activation.materialActivation;
|
|
455
|
-
}
|
|
456
|
-
function assertLinkedDeviceWalletSessionExact(selection, walletSession) {
|
|
457
|
-
if (walletSession.walletId !== selection.walletId || walletSession.authorityId !== selection.authority.authorityId || walletSession.authMethodId !== selection.authMethod.walletAuthMethodId || walletSession.authorityDigestB64u !== selection.authority.authorityDigestB64u || walletSession.authorityRevocationEpoch !== selection.authority.revocationEpoch) throw new Error("[login] linked Wallet Session identity does not match selected authority");
|
|
458
|
-
for (const subject of walletSession.capabilitySubjects) switch (subject.kind) {
|
|
459
|
-
case "sign":
|
|
460
|
-
case "export_keys": {
|
|
461
|
-
const activation = linkedDeviceActivationForCapability(selection.authority, subject);
|
|
462
|
-
const material = selectedSignerMaterialForActivation(selection.signerMaterials, selection.authority.authorityId, selection.authMethod.walletAuthMethodId, activation);
|
|
463
|
-
if (!material || material.keyFamily !== subject.keyFamily) throw new Error("[login] linked Wallet Session signer material is unavailable");
|
|
464
|
-
if (!mpcMaterialActivationRefsEqual(material.materialActivation, subject.materialActivation)) throw new Error("[login] linked Wallet Session signer material activation is invalid");
|
|
465
|
-
break;
|
|
466
|
-
}
|
|
467
|
-
case "link_devices":
|
|
468
|
-
case "revoke_devices": break;
|
|
469
|
-
default: return assertNeverLoginState(subject);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
function assertLinkedPasskeyMaterialTargetFactor(material, selection) {
|
|
473
|
-
const target = material.targetFactor;
|
|
474
|
-
if (target.kind !== "passkey" || target.walletAuthMethodId !== selection.authMethod.walletAuthMethodId || target.rpId !== selection.authMethod.rpId || target.credentialIdB64u !== selection.authMethod.credentialIdB64u) throw new Error("[login] linked passkey signer material target factor does not match V2 auth");
|
|
475
|
-
}
|
|
476
|
-
async function openLinkedDeviceSignerMaterialsWithFactorSecret(args) {
|
|
477
|
-
if (args.factorSecret32.byteLength !== 32) throw new Error("[login] linked signer material requires a 32-byte factor secret");
|
|
478
|
-
const factorSecret = args.factorSecret32.slice();
|
|
479
|
-
try {
|
|
480
|
-
const opened = [];
|
|
481
|
-
for (const material of args.selection.signerMaterials) {
|
|
482
|
-
if (material.kind !== "wallet_authority_linked_signer_material_v1") throw new Error("[login] linked signer material is not a linked sealed record");
|
|
483
|
-
if (args.selection.kind === "linked_device_passkey_authority_selection_v1") assertLinkedPasskeyMaterialTargetFactor(material, args.selection);
|
|
484
|
-
else assertLinkedEmailOtpMaterialTargetFactor(material, args.selection);
|
|
485
|
-
const result = await openWalletAuthorityLinkedSignerMaterialV1({
|
|
486
|
-
record: material,
|
|
487
|
-
factorSecret,
|
|
488
|
-
expected: {
|
|
489
|
-
authorityId: args.selection.authority.authorityId,
|
|
490
|
-
walletId: args.selection.walletId,
|
|
491
|
-
walletAuthMethodId: args.selection.authMethod.walletAuthMethodId,
|
|
492
|
-
packageSetDigestB64u: material.packageSetDigestB64u,
|
|
493
|
-
targetFactor: material.targetFactor,
|
|
494
|
-
materialActivation: material.materialActivation,
|
|
495
|
-
keyFamily: material.keyFamily
|
|
496
|
-
}
|
|
497
|
-
});
|
|
498
|
-
if (result.kind !== "opened_wallet_authority_linked_signer_material_v1") throw new Error(`[login] linked signer material open failed: ${result.reason}`);
|
|
499
|
-
opened.push(result);
|
|
500
|
-
}
|
|
501
|
-
const [first, ...rest] = opened;
|
|
502
|
-
if (!first) throw new Error("[login] linked signer material set is empty");
|
|
503
|
-
return [first, ...rest];
|
|
504
|
-
} finally {
|
|
505
|
-
factorSecret.fill(0);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
function assertLinkedEmailOtpMaterialTargetFactor(material, selection) {
|
|
509
|
-
const target = material.targetFactor;
|
|
510
|
-
if (target.kind !== "email_otp" || target.walletAuthMethodId !== selection.authMethod.walletAuthMethodId || target.emailHashHex.toLowerCase() !== selection.authMethod.emailHashHex.toLowerCase() || target.registrationAuthorityId !== selection.authMethod.registrationAuthorityId) throw new Error("[login] linked Email OTP signer material target factor does not match V2 auth");
|
|
511
|
-
}
|
|
512
|
-
async function openLinkedDeviceEmailOtpSignerMaterials(args) {
|
|
513
|
-
if (args.factorSecret32.byteLength !== 32) throw new Error("[login] linked Email OTP unlock requires a 32-byte factor secret");
|
|
514
|
-
return await openLinkedDeviceSignerMaterialsWithFactorSecret({
|
|
515
|
-
selection: args.selection,
|
|
516
|
-
factorSecret32: args.factorSecret32
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
function recentUnlockAccountFromUser(user) {
|
|
520
|
-
const walletId = String(user.walletId || "").trim();
|
|
521
|
-
if (!walletId) throw new Error("[login] recent unlock account is missing walletId");
|
|
522
|
-
const displayName = String(user.loginDisplayName || "").trim() || walletId;
|
|
523
|
-
return {
|
|
524
|
-
walletId,
|
|
525
|
-
nearAccountId: user.nearAccountId,
|
|
526
|
-
displayName,
|
|
527
|
-
signerSlot: user.signerSlot,
|
|
528
|
-
...typeof user.lastLogin === "number" ? { lastLogin: user.lastLogin } : {},
|
|
529
|
-
authMethod: user.authMethod || null
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
async function recentUnlockAccountFromLinkedDeviceSelection(selection) {
|
|
533
|
-
const resolved = await IndexedDBManager.resolveSelectedWalletAuthority(String(selection.walletId)).catch(() => null);
|
|
534
|
-
if (!resolved || resolved.kind !== "resolved" || resolved.selection.walletAuthMethodId !== selection.walletAuthMethodId || resolved.authMethod.status !== "active" || resolved.authority.state !== "active" || resolved.authority.provenance.kind !== "device_link") return null;
|
|
535
|
-
const nearSubject = await resolveLinkedDeviceNearUnlockSubject({
|
|
536
|
-
walletId: selection.walletId,
|
|
537
|
-
authMethod: resolved.authMethod,
|
|
538
|
-
authority: resolved.authority,
|
|
539
|
-
signerMaterials: resolved.signerMaterials
|
|
540
|
-
});
|
|
541
|
-
if (nearSubject.kind !== "resolved") return null;
|
|
542
|
-
let authMethod;
|
|
543
|
-
switch (resolved.authMethod.kind) {
|
|
544
|
-
case SIGNER_AUTH_METHODS.passkey:
|
|
545
|
-
authMethod = SIGNER_AUTH_METHODS.passkey;
|
|
546
|
-
break;
|
|
547
|
-
case SIGNER_AUTH_METHODS.emailOtp:
|
|
548
|
-
authMethod = SIGNER_AUTH_METHODS.emailOtp;
|
|
549
|
-
break;
|
|
550
|
-
default: return assertNeverLoginState(resolved.authMethod);
|
|
551
|
-
}
|
|
552
|
-
return {
|
|
553
|
-
walletId: String(selection.walletId),
|
|
554
|
-
nearAccountId: nearSubject.subject.nearAccountId,
|
|
555
|
-
displayName: String(selection.walletId),
|
|
556
|
-
signerSlot: nearSubject.subject.signerSlot,
|
|
557
|
-
lastLogin: selection.updatedAtMs,
|
|
558
|
-
authMethod
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
function recentUnlockAccountKey(account) {
|
|
562
|
-
return `${account.walletId}:${account.authMethod ?? ""}`;
|
|
563
|
-
}
|
|
564
|
-
function latestRecentUnlockAccount(accounts) {
|
|
565
|
-
let latest = null;
|
|
566
|
-
for (const account of accounts) if (!latest || (account.lastLogin ?? 0) > (latest.lastLogin ?? 0)) latest = account;
|
|
567
|
-
return latest;
|
|
568
|
-
}
|
|
569
|
-
async function readWalletAuthMethodBindingsForSession(walletId) {
|
|
570
|
-
if (!walletId) return [];
|
|
571
|
-
return (await IndexedDBManager.listWalletAuthMethodsV2ForWallet(String(walletId)).catch(() => [])).filter((record) => record.status === "active").map(walletAuthMethodBindingFromRecord).filter((binding) => Boolean(binding));
|
|
572
|
-
}
|
|
573
|
-
function selectThresholdWarmupAuthMethodBinding(args) {
|
|
574
|
-
if (args.authMethod === SIGNER_AUTH_METHODS.passkey) return null;
|
|
575
|
-
if (args.authMethod !== SIGNER_AUTH_METHODS.emailOtp) throw new Error(`[login] unsupported wallet auth method for warm-up: ${args.authMethod}`);
|
|
576
|
-
const matches = args.authMethods.filter((binding) => binding.kind === "email_otp");
|
|
577
|
-
if (matches.length !== 1) throw new Error("[login] Email OTP warm-up requires one active wallet auth-method binding");
|
|
578
|
-
const binding = matches[0];
|
|
579
|
-
if (String(binding.wallet.walletId) !== String(args.walletId)) throw new Error("[login] Email OTP warm-up auth-method binding wallet mismatch");
|
|
580
|
-
return binding;
|
|
581
|
-
}
|
|
582
|
-
async function readThresholdWarmupAuthMethodBinding(args) {
|
|
583
|
-
return selectThresholdWarmupAuthMethodBinding({
|
|
584
|
-
authMethods: await readWalletAuthMethodBindingsForSession(args.walletId),
|
|
585
|
-
authMethod: args.authMethod,
|
|
586
|
-
walletId: args.walletId
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
async function readActiveWalletPasskeyAuthenticators(walletId) {
|
|
590
|
-
const [authenticators, authMethods] = await Promise.all([IndexedDBManager.listWalletPasskeyAuthenticators(String(walletId)), IndexedDBManager.listWalletAuthMethodsV2ForWallet(String(walletId)).catch(() => [])]);
|
|
591
|
-
const activeCredentialIds = /* @__PURE__ */ new Set();
|
|
592
|
-
for (const method of authMethods) if (method.kind === "passkey" && method.status === "active") activeCredentialIds.add(method.credentialIdB64u);
|
|
593
|
-
return authenticators.filter((authenticator) => activeCredentialIds.has(authenticator.credentialId));
|
|
594
|
-
}
|
|
595
|
-
function isActiveThresholdLoginSigningSession(sessionStatus) {
|
|
596
|
-
return sessionStatus?.status === "active";
|
|
597
|
-
}
|
|
598
|
-
function resolveLoginEcdsaKeyFactsInventoryAuthority(args) {
|
|
599
|
-
if (!args.request) return null;
|
|
600
|
-
switch (args.request.mode) {
|
|
601
|
-
case "wallet_session_operation_credential_v1": try {
|
|
602
|
-
return {
|
|
603
|
-
kind: "wallet_session_operation_credential_v1",
|
|
604
|
-
operationCredential: parseLoginEcdsaInventoryOperationCredential(args.request.operationCredential)
|
|
605
|
-
};
|
|
606
|
-
} catch {
|
|
607
|
-
return null;
|
|
608
|
-
}
|
|
609
|
-
case "webauthn": return { kind: "webauthn" };
|
|
610
|
-
}
|
|
611
|
-
return null;
|
|
612
|
-
}
|
|
613
|
-
function parseLoginEcdsaInventoryOperationCredential(value) {
|
|
614
|
-
if (value.kind === "opaque_wallet_session_operation_credential_v1") return parseWalletSessionOperationCredentialV1(value);
|
|
615
|
-
if (value.kind !== "opaque_hosted_wallet_session_operation_credential_v1" || !/^wsh_[A-Za-z0-9_-]{43}$/.test(value.token)) throw new Error("Hosted Wallet Session operation credential is invalid");
|
|
616
|
-
const walletSessionId = parseWalletSessionId(value.walletSessionId);
|
|
617
|
-
if (!walletSessionId.ok) throw new Error(`Hosted Wallet Session ID is invalid: ${walletSessionId.error.message}`);
|
|
618
|
-
return {
|
|
619
|
-
kind: value.kind,
|
|
620
|
-
token: value.token,
|
|
621
|
-
walletSessionId: walletSessionId.value
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
function resolveLoginWarmupRouteAuthorization() {
|
|
625
|
-
return { kind: "none" };
|
|
626
|
-
}
|
|
627
|
-
function loginPasskeyCredentialIdB64u(args) {
|
|
628
|
-
return String(args.authenticators.find((authenticator) => authenticator.signerSlot === args.signerSlot)?.credentialId || args.authenticators[0]?.credentialId || "").trim();
|
|
629
|
-
}
|
|
630
|
-
function buildLoginPasskeyWalletAuthAuthority(args) {
|
|
631
|
-
return buildPasskeyWalletAuthAuthority({
|
|
632
|
-
walletId: args.walletId,
|
|
633
|
-
rpId: args.rpId,
|
|
634
|
-
credentialIdB64u: args.credentialIdB64u
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
function resolveLoginEd25519SessionAuthority(args) {
|
|
638
|
-
if (!args.wantsEd25519Warmup) return { kind: "not_requested" };
|
|
639
|
-
if (args.authMethod === SIGNER_AUTH_METHODS.passkey) return {
|
|
640
|
-
kind: "passkey",
|
|
641
|
-
authority: {
|
|
642
|
-
kind: "wallet_auth_authority",
|
|
643
|
-
authority: buildLoginPasskeyWalletAuthAuthority({
|
|
644
|
-
walletId: args.walletId,
|
|
645
|
-
rpId: args.rpId,
|
|
646
|
-
credentialIdB64u: args.passkeyCredentialIdB64u
|
|
647
|
-
})
|
|
648
|
-
},
|
|
649
|
-
source: "login"
|
|
650
|
-
};
|
|
651
|
-
if (args.authMethod === SIGNER_AUTH_METHODS.emailOtp) throw new Error("[login] Email OTP warm-up requires its proof-bound unlock flow");
|
|
652
|
-
throw new Error(`[login] unsupported wallet auth method for Ed25519 warm-up: ${args.authMethod}`);
|
|
653
|
-
}
|
|
654
|
-
function requireRequestedLoginEd25519SessionAuthority(authority) {
|
|
655
|
-
if (authority.kind === "not_requested") throw new Error("[login] threshold Ed25519 warm-up authority is missing");
|
|
656
|
-
return authority;
|
|
657
|
-
}
|
|
658
|
-
function bindLoginEd25519SessionAuthorityToAuthenticatedCredential(args) {
|
|
659
|
-
if (args.authority.kind === "email_otp") return args.authority;
|
|
660
|
-
return {
|
|
661
|
-
kind: "passkey",
|
|
662
|
-
authority: {
|
|
663
|
-
kind: "wallet_auth_authority",
|
|
664
|
-
authority: buildLoginPasskeyWalletAuthAuthority({
|
|
665
|
-
walletId: args.walletId,
|
|
666
|
-
rpId: args.rpId,
|
|
667
|
-
credentialIdB64u: args.credentialIdB64u
|
|
668
|
-
})
|
|
669
|
-
},
|
|
670
|
-
source: "login"
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
function loginEd25519ExactProvisionAuthBinding(authority) {
|
|
674
|
-
switch (authority.kind) {
|
|
675
|
-
case "passkey": return {
|
|
676
|
-
kind: "passkey",
|
|
677
|
-
rpId: toRpId(authority.authority.authority.verifier.rpId),
|
|
678
|
-
credentialIdB64u: String(authority.authority.authority.factor.credentialIdB64u || "").trim()
|
|
679
|
-
};
|
|
680
|
-
case "email_otp": return {
|
|
681
|
-
kind: "email_otp",
|
|
682
|
-
providerSubjectId: String(authority.authority.authority.factor.providerUserId || "").trim()
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
throw new Error("[login] unsupported Ed25519 exact provision authority");
|
|
686
|
-
}
|
|
687
|
-
function loginEd25519ExactProvisionLaneIdentity(args) {
|
|
688
|
-
return exactEd25519SigningLaneIdentity({
|
|
689
|
-
signer: nearEd25519SignerBindingFromBoundaryFields({
|
|
690
|
-
walletId: args.walletBinding.walletId,
|
|
691
|
-
nearAccountId: args.walletBinding.nearAccountId,
|
|
692
|
-
nearEd25519SigningKeyId: args.walletBinding.nearEd25519SigningKeyId,
|
|
693
|
-
signerSlot: args.signerSlot
|
|
694
|
-
}),
|
|
695
|
-
auth: loginEd25519ExactProvisionAuthBinding(args.authority),
|
|
696
|
-
walletSessionId: args.walletSessionId,
|
|
697
|
-
quotaId: args.quotaId,
|
|
698
|
-
thresholdSessionId: args.thresholdSessionId
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
function resolveLoginWarmEd25519ProvisioningIdentity(args) {
|
|
702
|
-
switch (args.mintPlan.kind) {
|
|
703
|
-
case "not_requested": throw new Error("[login] threshold Ed25519 mint plan is missing");
|
|
704
|
-
case "wallet_custody":
|
|
705
|
-
if (args.ecdsaMint) return {
|
|
706
|
-
kind: "exact_ed25519_provisioning",
|
|
707
|
-
operationCredential: args.ecdsaMint.operationCredential,
|
|
708
|
-
laneIdentity: loginEd25519ExactProvisionLaneIdentity({
|
|
709
|
-
walletBinding: args.walletBinding,
|
|
710
|
-
signerSlot: args.signerSlot,
|
|
711
|
-
thresholdSessionId: args.mintPlan.thresholdSessionId,
|
|
712
|
-
walletSessionId: args.ecdsaMint.operationCredential.walletSessionId,
|
|
713
|
-
quotaId: args.ecdsaMint.quotaId,
|
|
714
|
-
authority: args.authority
|
|
715
|
-
})
|
|
716
|
-
};
|
|
717
|
-
return {
|
|
718
|
-
kind: "fresh_ed25519_provisioning",
|
|
719
|
-
materialActivation: args.mintPlan.custody.ed25519.capability.materialActivation
|
|
720
|
-
};
|
|
721
|
-
case "fresh": throw new Error("[login] fresh Ed25519 passkey provisioning requires canonical material activation");
|
|
722
|
-
case "ecdsa_authorized":
|
|
723
|
-
if (!args.ecdsaMint) throw new Error("[login] threshold Ed25519 warm-up requires the ECDSA bootstrap session minted during unlock");
|
|
724
|
-
return {
|
|
725
|
-
kind: "exact_ed25519_provisioning",
|
|
726
|
-
operationCredential: args.ecdsaMint.operationCredential,
|
|
727
|
-
laneIdentity: loginEd25519ExactProvisionLaneIdentity({
|
|
728
|
-
walletBinding: args.walletBinding,
|
|
729
|
-
signerSlot: args.signerSlot,
|
|
730
|
-
thresholdSessionId: args.mintPlan.thresholdSessionId,
|
|
731
|
-
walletSessionId: args.ecdsaMint.operationCredential.walletSessionId,
|
|
732
|
-
quotaId: args.ecdsaMint.quotaId,
|
|
733
|
-
authority: args.authority
|
|
734
|
-
})
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
return assertNeverLoginState(args.mintPlan);
|
|
738
|
-
}
|
|
739
|
-
function resolveLoginPasskeyMaterialActivation(identity, mintPlan) {
|
|
740
|
-
if (identity.kind === "fresh_ed25519_provisioning" && identity.materialActivation) return identity.materialActivation;
|
|
741
|
-
if (mintPlan.kind === "wallet_custody") return mintPlan.custody.ed25519.capability.materialActivation;
|
|
742
|
-
throw new Error("[login] passkey Ed25519 warm-up requires a canonical material activation");
|
|
743
|
-
}
|
|
744
|
-
function resolveLoginEd25519ProvisionScope(args) {
|
|
745
|
-
if (args.mintPlan.kind !== "wallet_custody") return args.fallback;
|
|
746
|
-
return {
|
|
747
|
-
relayerKeyId: args.mintPlan.custody.ed25519.relayerKeyId,
|
|
748
|
-
participantIds: args.mintPlan.custody.ed25519.participantIds,
|
|
749
|
-
runtimePolicyScope: args.mintPlan.custody.ed25519.capability.runtimePolicyScope,
|
|
750
|
-
routerAbNormalSigning: args.fallback.routerAbNormalSigning
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
function passkeyUnlockEd25519Connection(args) {
|
|
754
|
-
const session = args.session;
|
|
755
|
-
const custody = args.custody.ed25519;
|
|
756
|
-
const passkeyPrfFirstB64u = args.credential ? passkeyPrfFirstB64uFromCredential(args.credential) : "";
|
|
757
|
-
if (session.walletId !== String(args.walletBinding.walletId) || session.nearAccountId !== String(args.walletBinding.nearAccountId) || session.nearEd25519SigningKeyId !== String(args.walletBinding.nearEd25519SigningKeyId) || custody.signerSlot !== args.signerSlot || session.relayerKeyId !== args.provisionScope.relayerKeyId || session.thresholdSessionId !== custody.capability.lifecycle.thresholdSessionId || session.remainingUses !== args.remainingUses || !sameEd25519ParticipantIds(session.participantIds, args.provisionScope.participantIds) || !args.provisionScope.runtimePolicyScope || !sameThresholdRuntimePolicyScope(session.runtimePolicyScope, args.provisionScope.runtimePolicyScope) || !sameRouterAbEd25519NormalSigningState(session.routerAbNormalSigning, args.provisionScope.routerAbNormalSigning) || !passkeyPrfFirstB64u) throw new Error("[login] verified unlock returned an invalid Ed25519 Wallet Session");
|
|
758
|
-
switch (session.sessionKind) {
|
|
759
|
-
case "issued_exact_wallet_session":
|
|
760
|
-
if (session.operationCredential.walletSessionId !== session.walletSessionId) throw new Error("[login] verified unlock returned a mismatched Ed25519 credential");
|
|
761
|
-
return {
|
|
762
|
-
ok: true,
|
|
763
|
-
...session,
|
|
764
|
-
passkeyPrfFirstB64u
|
|
765
|
-
};
|
|
766
|
-
case "already_committed_exact_wallet_session": {
|
|
767
|
-
const authorization = args.unlockAuthorization;
|
|
768
|
-
if (!authorization) throw new Error("[login] verified unlock reused an Ed25519 Wallet Session without its authorization");
|
|
769
|
-
if (authorization.operationCredential.walletSessionId !== session.walletSessionId || authorization.record.walletId !== session.walletId || authorization.record.authorizationId !== session.authorizationId || authorization.record.quotaId !== session.quotaId || authorization.record.expiresAtMs !== session.expiresAtMs) throw new Error("[login] verified unlock reused a mismatched Ed25519 Wallet Session");
|
|
770
|
-
return {
|
|
771
|
-
ok: true,
|
|
772
|
-
...session,
|
|
773
|
-
operationCredential: authorization.operationCredential,
|
|
774
|
-
passkeyPrfFirstB64u
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
|
-
default: return assertNeverLoginState(session);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
function resolveLoginNoServerSessionPasskeyCredentialPlan(args) {
|
|
781
|
-
if (args.hasLoginCredential) return { kind: "passkey_credential_already_collected" };
|
|
782
|
-
if (!args.requiresLocalPasskeyUnlock) return { kind: "no_local_passkey_required" };
|
|
783
|
-
if (args.requireThresholdWarmup) return { kind: "wallet_unlock_owns_passkey_credential" };
|
|
784
|
-
return { kind: "local_unlock_passkey_assertion" };
|
|
785
|
-
}
|
|
786
|
-
function resolveLoginWarmupPasskeyCredentialPlan(args) {
|
|
787
|
-
if (args.warmupPlan.signersToWarm.includes("ed25519") && args.requiresLocalPasskeyUnlock) return { kind: "wallet_custody" };
|
|
788
|
-
if (args.hasLoginCredential) return { kind: "existing_passkey_credential" };
|
|
789
|
-
args.routeAuthorization.kind;
|
|
790
|
-
if (args.requiresLocalPasskeyUnlock) throw new Error("[login] passkey warm-up requires the verified wallet-unlock credential");
|
|
791
|
-
return { kind: "no_passkey_credential_required" };
|
|
792
|
-
}
|
|
793
|
-
function authenticatorsForCredentialIds(args) {
|
|
794
|
-
if (!args.credentialIds) return args.authenticators;
|
|
795
|
-
const allowed = /* @__PURE__ */ new Set();
|
|
796
|
-
for (const credentialId of args.credentialIds) allowed.add(credentialId.trim());
|
|
797
|
-
const authenticators = [];
|
|
798
|
-
for (const authenticator of args.authenticators) if (allowed.has(String(authenticator.credentialId || "").trim())) authenticators.push(authenticator);
|
|
799
|
-
if (!authenticators.length) throw new Error("[login] no local authenticator matches the required credential");
|
|
800
|
-
return authenticators;
|
|
801
|
-
}
|
|
802
|
-
function uniqueLoginCredentialIds(authenticators) {
|
|
803
|
-
const credentialIds = [];
|
|
804
|
-
const seen = /* @__PURE__ */ new Set();
|
|
805
|
-
for (const authenticator of authenticators) {
|
|
806
|
-
const credentialId = String(authenticator.credentialId || "").trim();
|
|
807
|
-
if (!credentialId || seen.has(credentialId)) continue;
|
|
808
|
-
seen.add(credentialId);
|
|
809
|
-
credentialIds.push(credentialId);
|
|
810
|
-
}
|
|
811
|
-
return credentialIds;
|
|
812
|
-
}
|
|
813
|
-
function parseLoginChallengeCredentialIds(value) {
|
|
814
|
-
if (!Array.isArray(value)) return [];
|
|
815
|
-
const credentialIds = [];
|
|
816
|
-
const seen = /* @__PURE__ */ new Set();
|
|
817
|
-
for (const entry of value) {
|
|
818
|
-
const credentialId = typeof entry === "string" ? entry.trim() : "";
|
|
819
|
-
if (!credentialId || seen.has(credentialId)) continue;
|
|
820
|
-
seen.add(credentialId);
|
|
821
|
-
credentialIds.push(credentialId);
|
|
822
|
-
}
|
|
823
|
-
return credentialIds;
|
|
824
|
-
}
|
|
825
|
-
function resolveLoginPasskeyPromptCredentialIds(args) {
|
|
826
|
-
const signerAuthenticators = [];
|
|
827
|
-
for (const authenticator of args.authenticators) if (authenticator.signerSlot === args.signerSlot) signerAuthenticators.push(authenticator);
|
|
828
|
-
const localCredentialIds = uniqueLoginCredentialIds(signerAuthenticators.length > 0 ? signerAuthenticators : args.authenticators);
|
|
829
|
-
if (localCredentialIds.length === 0) throw new Error("[login] selected wallet has no local passkey credential ID");
|
|
830
|
-
if (args.serverCredentialIds.length === 0) return localCredentialIds;
|
|
831
|
-
const serverCredentialIds = new Set(args.serverCredentialIds);
|
|
832
|
-
const matchingCredentialIds = [];
|
|
833
|
-
for (const credentialId of localCredentialIds) if (serverCredentialIds.has(credentialId)) matchingCredentialIds.push(credentialId);
|
|
834
|
-
if (matchingCredentialIds.length === 0) throw new Error("[login] server passkey allow-list does not match local wallet credentials");
|
|
835
|
-
return matchingCredentialIds;
|
|
836
|
-
}
|
|
837
|
-
function resolveLoginUnlockWarmupBranchPlan(args) {
|
|
838
|
-
const identity = resolveLoginWalletIdentity({
|
|
839
|
-
subjectSet: args.subjectSet,
|
|
840
|
-
selection: args.selection
|
|
841
|
-
});
|
|
842
|
-
switch (args.selection.mode) {
|
|
843
|
-
case "ed25519_only": return {
|
|
844
|
-
kind: "near_ed25519_only",
|
|
845
|
-
wantsEd25519Warmup: true,
|
|
846
|
-
wantsEcdsaWarmup: false
|
|
847
|
-
};
|
|
848
|
-
case "ecdsa_only":
|
|
849
|
-
if (identity.kind !== "evm_family_ecdsa_only_wallet") throw new Error("[login] ECDSA-only warm-up requires exact ECDSA subjects");
|
|
850
|
-
return {
|
|
851
|
-
kind: "evm_family_ecdsa_only",
|
|
852
|
-
wantsEd25519Warmup: false,
|
|
853
|
-
wantsEcdsaWarmup: args.hasConfiguredEcdsaTargets
|
|
854
|
-
};
|
|
855
|
-
case "ed25519_and_ecdsa": return {
|
|
856
|
-
kind: "near_ed25519_and_evm_family_ecdsa",
|
|
857
|
-
wantsEd25519Warmup: true,
|
|
858
|
-
wantsEcdsaWarmup: args.hasConfiguredEcdsaTargets
|
|
859
|
-
};
|
|
860
|
-
}
|
|
861
|
-
return assertNeverLoginState(args.selection);
|
|
862
|
-
}
|
|
863
|
-
function resolveThresholdLoginWarmupPhaseInput(args) {
|
|
864
|
-
const relayerUrl = String(args.context.configs?.network.relayer?.url || "").trim();
|
|
865
|
-
if (!relayerUrl) throw new Error("[login] threshold warm session requires relayer.url to be configured");
|
|
866
|
-
const configuredEcdsaTargets = listConfiguredThresholdEcdsaPublicationTargets(args.context.configs.network.chains);
|
|
867
|
-
const branchPlan = resolveLoginUnlockWarmupBranchPlan({
|
|
868
|
-
subjectSet: args.subjectSet,
|
|
869
|
-
selection: args.selection,
|
|
870
|
-
hasConfiguredEcdsaTargets: configuredEcdsaTargets.length > 0
|
|
871
|
-
});
|
|
872
|
-
const wantsEcdsaWarmup = branchPlan.wantsEcdsaWarmup;
|
|
873
|
-
const wantsEd25519Warmup = branchPlan.wantsEd25519Warmup;
|
|
874
|
-
const rpId = String(args.context.signingEngine.getRpId() || "").trim();
|
|
875
|
-
return {
|
|
876
|
-
kind: "threshold_login_warmup_phase_input",
|
|
877
|
-
signerSlot: args.signerSlot,
|
|
878
|
-
selection: args.selection,
|
|
879
|
-
relayerUrl,
|
|
880
|
-
rpId,
|
|
881
|
-
configuredEcdsaTargets,
|
|
882
|
-
selectedEcdsaTargets: wantsEcdsaWarmup ? configuredEcdsaTargets : [],
|
|
883
|
-
wantsEd25519Warmup,
|
|
884
|
-
wantsEcdsaWarmup,
|
|
885
|
-
ed25519SessionAuthority: resolveLoginEd25519SessionAuthority({
|
|
886
|
-
wantsEd25519Warmup,
|
|
887
|
-
authMethod: args.authMethod,
|
|
888
|
-
walletId: args.subjectSet.walletId,
|
|
889
|
-
rpId,
|
|
890
|
-
passkeyCredentialIdB64u: loginPasskeyCredentialIdB64u({
|
|
891
|
-
authenticators: args.authenticators,
|
|
892
|
-
signerSlot: args.signerSlot
|
|
893
|
-
}),
|
|
894
|
-
routeAuthorization: args.routeAuthorization
|
|
895
|
-
}),
|
|
896
|
-
keyFactsInventoryAuthority: args.keyFactsInventoryAuthority,
|
|
897
|
-
routeAuthorization: args.routeAuthorization
|
|
898
|
-
};
|
|
899
|
-
}
|
|
900
|
-
async function assertPasskeyUnlockRuntimePostconditions(args) {
|
|
901
|
-
const requiredTargets = [...args.signersWarmed.includes("ed25519") ? [{ curve: "ed25519" }] : [], ...args.signersWarmed.includes("ecdsa") ? listConfiguredThresholdEcdsaPublicationTargets(args.context.configs.network.chains).map((target) => ({
|
|
902
|
-
curve: "ecdsa",
|
|
903
|
-
chainTarget: target.chainTarget
|
|
904
|
-
})) : []];
|
|
905
|
-
const credentialIdB64u = passkeyCredentialIdB64uFromAuthentication(args.credential);
|
|
906
|
-
if (!credentialIdB64u) throw new Error("[login] runtime lane selection requires the authenticated credential");
|
|
907
|
-
const walletId = String(args.walletIdentity.walletId);
|
|
908
|
-
const authenticator = await IndexedDBManager.getWalletPasskeyAuthenticator({
|
|
909
|
-
walletId,
|
|
910
|
-
credentialId: credentialIdB64u
|
|
911
|
-
});
|
|
912
|
-
const derivedSignerSlot = parseSignerSlot(authenticator?.signerSlot, { min: 1 });
|
|
913
|
-
if (!authenticator || derivedSignerSlot === null) throw new Error("[login] authenticated credential resolves no exact local authenticator for its signer slot");
|
|
914
|
-
const ownerScope = {
|
|
915
|
-
auth: {
|
|
916
|
-
kind: "passkey",
|
|
917
|
-
rpId: toRpId(args.context.signingEngine.getRpId()),
|
|
918
|
-
credentialIdB64u
|
|
919
|
-
},
|
|
920
|
-
signerSlot: derivedSignerSlot
|
|
921
|
-
};
|
|
922
|
-
if (requiredTargets.length === 0) return;
|
|
923
|
-
await assertWalletRuntimePostconditions({
|
|
924
|
-
source: "wallet_unlock",
|
|
925
|
-
walletId: String(args.walletIdentity.walletId),
|
|
926
|
-
ownerScope,
|
|
927
|
-
requiredTargets,
|
|
928
|
-
readOwnerScopedSigningLanes: async (input) => await args.context.signingEngine.readOwnerScopedSigningLanes(input, args.statusReads)
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
async function markPasskeyLoginSelectionUnlocked(args) {
|
|
932
|
-
const credentialIdB64u = passkeyCredentialIdB64uFromAuthentication(args.credential);
|
|
933
|
-
if (!credentialIdB64u) throw new Error("[login] successful Passkey unlock omitted its credential identity");
|
|
934
|
-
const authority = await exactPasskeyWalletAuthAuthorityRefForCredential({
|
|
935
|
-
walletId: args.walletIdentity.walletId,
|
|
936
|
-
rpId: args.context.signingEngine.getRpId(),
|
|
937
|
-
credentialIdB64u
|
|
938
|
-
});
|
|
939
|
-
await args.context.signingEngine.markWalletSelectionUnlocked({
|
|
940
|
-
walletId: args.walletIdentity.walletId,
|
|
941
|
-
walletAuthMethodId: authority.walletAuthMethodId
|
|
942
|
-
});
|
|
943
|
-
}
|
|
944
|
-
function buildNearLoginUnlockAccountSubject(args) {
|
|
945
|
-
if (args.userData && String(args.userData.walletId) !== String(args.walletId)) throw new Error("[login] NEAR account projection belongs to a different wallet");
|
|
946
|
-
const operationalPublicKey = typeof args.userData?.operationalPublicKey === "string" ? args.userData.operationalPublicKey.trim() : "";
|
|
947
|
-
return {
|
|
948
|
-
kind: "near_wallet",
|
|
949
|
-
walletId: args.walletId,
|
|
950
|
-
operationalPublicKey: operationalPublicKey || null
|
|
951
|
-
};
|
|
952
|
-
}
|
|
953
|
-
async function readNearLoginUnlockAccountPhase(args) {
|
|
954
|
-
emitUnlockEvent(args.onEvent, String(args.identity.nearAccountId), {
|
|
955
|
-
phase: UnlockEventPhase.STEP_02_ACCOUNT_LOOKUP_STARTED,
|
|
956
|
-
status: "running",
|
|
957
|
-
authMethod: "passkey"
|
|
958
|
-
});
|
|
959
|
-
const hintUserPromise = args.signerSlotHint !== null ? args.signingEngine.getUserBySignerSlot(args.identity.nearAccountId, args.signerSlotHint).catch(() => null) : Promise.resolve(null);
|
|
960
|
-
const [hintUser, lastUser, latestByAccount, authenticators] = await Promise.all([
|
|
961
|
-
hintUserPromise,
|
|
962
|
-
args.signingEngine.getLastUser().catch(() => null),
|
|
963
|
-
getNearAccountProjection(IndexedDBManager, args.identity.nearAccountId).catch(() => null),
|
|
964
|
-
readActiveWalletPasskeyAuthenticators(args.identity.walletId)
|
|
965
|
-
]);
|
|
966
|
-
if (authenticators.length === 0) throw new Error(`No authenticators found for account ${args.identity.nearAccountId}. Please register an account.`);
|
|
967
|
-
let userData = null;
|
|
968
|
-
if (hintUser && hintUser.nearAccountId === args.identity.nearAccountId) userData = hintUser;
|
|
969
|
-
else if (latestByAccount && latestByAccount.nearAccountId === args.identity.nearAccountId) userData = latestByAccount;
|
|
970
|
-
else if (lastUser && lastUser.nearAccountId === args.identity.nearAccountId) userData = lastUser;
|
|
971
|
-
else userData = await args.signingEngine.getUserBySignerSlot(args.identity.nearAccountId, Number(args.identity.signerSlot)).catch(() => null);
|
|
972
|
-
const accountSubject = buildNearLoginUnlockAccountSubject({
|
|
973
|
-
userData,
|
|
974
|
-
walletId: args.identity.walletId
|
|
975
|
-
});
|
|
976
|
-
emitUnlockEvent(args.onEvent, String(args.identity.nearAccountId), {
|
|
977
|
-
phase: UnlockEventPhase.STEP_02_ACCOUNT_LOOKUP_SUCCEEDED,
|
|
978
|
-
status: "succeeded",
|
|
979
|
-
authMethod: "passkey",
|
|
980
|
-
data: {
|
|
981
|
-
signerSlot: Number(args.identity.signerSlot),
|
|
982
|
-
...accountSubject.operationalPublicKey ? { operationalPublicKey: accountSubject.operationalPublicKey } : { walletKind: accountSubject.kind }
|
|
983
|
-
}
|
|
984
|
-
});
|
|
985
|
-
return {
|
|
986
|
-
kind: "login_unlock_account_phase_ready",
|
|
987
|
-
accountSubject,
|
|
988
|
-
authenticators,
|
|
989
|
-
baseSignerSlot: args.signerSlotHint ?? Number(args.identity.signerSlot),
|
|
990
|
-
localUnlockAuthMethod: SIGNER_AUTH_METHODS.passkey,
|
|
991
|
-
requiresLocalPasskeyUnlock: true
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
async function readEcdsaLoginUnlockAccountPhase(args) {
|
|
995
|
-
const unlockSubjectId = String(args.identity.walletId);
|
|
996
|
-
emitUnlockEvent(args.onEvent, unlockSubjectId, {
|
|
997
|
-
phase: UnlockEventPhase.STEP_02_ACCOUNT_LOOKUP_STARTED,
|
|
998
|
-
status: "running",
|
|
999
|
-
authMethod: "passkey"
|
|
1000
|
-
});
|
|
1001
|
-
const [profile, eligibleAuthenticators] = await Promise.all([IndexedDBManager.getProfile(unlockSubjectId), readActiveWalletPasskeyAuthenticators(args.identity.walletId)]);
|
|
1002
|
-
if (!profile || eligibleAuthenticators.length === 0) throw new Error(`[login] ECDSA wallet ${unlockSubjectId} has no local passkey profile`);
|
|
1003
|
-
const persistedSignerSlot = parseSignerSlot(profile.defaultSignerSlot, { min: 1 });
|
|
1004
|
-
const baseSignerSlot = args.signerSlotHint ?? persistedSignerSlot;
|
|
1005
|
-
if (baseSignerSlot === null) throw new Error("[login] ECDSA wallet profile is missing its exact signerSlot");
|
|
1006
|
-
emitUnlockEvent(args.onEvent, unlockSubjectId, {
|
|
1007
|
-
phase: UnlockEventPhase.STEP_02_ACCOUNT_LOOKUP_SUCCEEDED,
|
|
1008
|
-
status: "succeeded",
|
|
1009
|
-
authMethod: "passkey",
|
|
1010
|
-
data: {
|
|
1011
|
-
signerSlot: baseSignerSlot,
|
|
1012
|
-
walletKind: "ecdsa_wallet_only"
|
|
1013
|
-
}
|
|
1014
|
-
});
|
|
1015
|
-
return {
|
|
1016
|
-
kind: "login_unlock_account_phase_ready",
|
|
1017
|
-
accountSubject: {
|
|
1018
|
-
kind: "ecdsa_wallet_only",
|
|
1019
|
-
walletId: args.identity.walletId,
|
|
1020
|
-
operationalPublicKey: null
|
|
1021
|
-
},
|
|
1022
|
-
authenticators: eligibleAuthenticators,
|
|
1023
|
-
baseSignerSlot,
|
|
1024
|
-
localUnlockAuthMethod: SIGNER_AUTH_METHODS.passkey,
|
|
1025
|
-
requiresLocalPasskeyUnlock: true
|
|
1026
|
-
};
|
|
1027
|
-
}
|
|
1028
|
-
async function readLoginUnlockAccountPhase(args) {
|
|
1029
|
-
switch (args.identity.kind) {
|
|
1030
|
-
case "near_ed25519_capable_wallet": return await readNearLoginUnlockAccountPhase({
|
|
1031
|
-
signingEngine: args.signingEngine,
|
|
1032
|
-
identity: args.identity,
|
|
1033
|
-
signerSlotHint: args.signerSlotHint,
|
|
1034
|
-
onEvent: args.onEvent
|
|
1035
|
-
});
|
|
1036
|
-
case "evm_family_ecdsa_only_wallet": return await readEcdsaLoginUnlockAccountPhase({
|
|
1037
|
-
identity: args.identity,
|
|
1038
|
-
signerSlotHint: args.signerSlotHint,
|
|
1039
|
-
onEvent: args.onEvent
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
return assertNeverLoginState(args.identity);
|
|
1043
|
-
}
|
|
1044
|
-
function buildSuccessfulLoginResult(args) {
|
|
1045
|
-
switch (args.identity.kind) {
|
|
1046
|
-
case "near_ed25519_capable_wallet":
|
|
1047
|
-
if (args.accountSubject.kind !== "near_wallet") throw new Error("[login] NEAR unlock returned an ECDSA-only account subject");
|
|
1048
|
-
return {
|
|
1049
|
-
success: true,
|
|
1050
|
-
kind: "near_wallet_unlocked",
|
|
1051
|
-
walletId: args.identity.walletId,
|
|
1052
|
-
loggedInNearAccountId: String(args.identity.nearAccountId),
|
|
1053
|
-
operationalPublicKey: args.accountSubject.operationalPublicKey,
|
|
1054
|
-
nearAccountId: args.identity.nearAccountId
|
|
1055
|
-
};
|
|
1056
|
-
case "evm_family_ecdsa_only_wallet":
|
|
1057
|
-
if (args.accountSubject.kind !== "ecdsa_wallet_only") throw new Error("[login] ECDSA-only unlock returned a NEAR account subject");
|
|
1058
|
-
return {
|
|
1059
|
-
success: true,
|
|
1060
|
-
kind: "ecdsa_wallet_unlocked",
|
|
1061
|
-
walletId: args.identity.walletId
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
return assertNeverLoginState(args.identity);
|
|
1065
|
-
}
|
|
1066
|
-
async function unlockResolvedWalletSubjectSet(context, subjectSet, options) {
|
|
1067
|
-
return await unlockInternal(context, subjectSet, options, { kind: "wallet_only" });
|
|
1068
|
-
}
|
|
1069
|
-
async function resolveLinkedDeviceNearUnlockSubject(args) {
|
|
1070
|
-
const activation = args.authority.signerActivations.ed25519;
|
|
1071
|
-
if (!activation) return { kind: "absent" };
|
|
1072
|
-
const material = selectedSignerMaterialForActivation(args.signerMaterials, args.authority.authorityId, args.authMethod.walletAuthMethodId, activation.materialActivation);
|
|
1073
|
-
if (!material || material.kind !== "wallet_authority_linked_signer_material_v1" || material.keyFamily !== "ed25519" || !mpcMaterialActivationRefsEqual(material.materialActivation, activation.materialActivation)) return { kind: "invalid" };
|
|
1074
|
-
const application = material.publicFacts.applicationBinding;
|
|
1075
|
-
if (application.wallet_id !== String(args.walletId)) return { kind: "invalid" };
|
|
1076
|
-
let match = null;
|
|
1077
|
-
const references = await new IndexedDbEd25519YaoPublicCapabilityReferenceStore(IndexedDBManager).listLanes();
|
|
1078
|
-
for (const reference of references) {
|
|
1079
|
-
let factorMatches;
|
|
1080
|
-
switch (args.authMethod.kind) {
|
|
1081
|
-
case SIGNER_AUTH_METHODS.passkey:
|
|
1082
|
-
factorMatches = reference.auth.kind === SIGNER_AUTH_METHODS.passkey && String(reference.auth.rpId) === String(args.authMethod.rpId) && String(reference.auth.credentialIdB64u) === String(args.authMethod.credentialIdB64u);
|
|
1083
|
-
break;
|
|
1084
|
-
case SIGNER_AUTH_METHODS.emailOtp:
|
|
1085
|
-
factorMatches = reference.auth.kind === SIGNER_AUTH_METHODS.emailOtp;
|
|
1086
|
-
break;
|
|
1087
|
-
default: return assertNeverLoginState(args.authMethod);
|
|
1088
|
-
}
|
|
1089
|
-
if (!factorMatches || String(reference.walletId) !== String(args.walletId) || reference.signerSlot !== application.key_creation_signer_slot || String(reference.nearEd25519SigningKeyId) !== application.near_ed25519_signing_key_id || String(reference.thresholdSessionId) !== material.publicFacts.targetBinding.lifecycle.session_id || !mpcMaterialActivationRefsEqual(reference.materialActivation, activation.materialActivation)) continue;
|
|
1090
|
-
if (match) return { kind: "invalid" };
|
|
1091
|
-
match = reference;
|
|
1092
|
-
}
|
|
1093
|
-
if (!match) return { kind: "invalid" };
|
|
1094
|
-
const signerSlot = parseSignerSlot(match.signerSlot, { min: 1 });
|
|
1095
|
-
if (!signerSlot) return { kind: "invalid" };
|
|
1096
|
-
return {
|
|
1097
|
-
kind: "resolved",
|
|
1098
|
-
subject: {
|
|
1099
|
-
kind: "near_ed25519_wallet",
|
|
1100
|
-
walletId: args.walletId,
|
|
1101
|
-
nearAccountId: match.nearAccountId,
|
|
1102
|
-
nearEd25519SigningKeyId: match.nearEd25519SigningKeyId,
|
|
1103
|
-
signerSlot
|
|
1104
|
-
}
|
|
1105
|
-
};
|
|
1106
|
-
}
|
|
1107
|
-
/**
|
|
1108
|
-
* The exact authority reference for a linked device whose factor carries no
|
|
1109
|
-
* local credential. It names the authority by its own digest and the exact
|
|
1110
|
-
* auth method, so it cannot be reconstructed from factor fields several
|
|
1111
|
-
* methods may share.
|
|
1112
|
-
*/
|
|
1113
|
-
function requireLinkedDeviceWalletAuthAuthorityRef(input) {
|
|
1114
|
-
const authorityRef = parseWalletAuthAuthorityRef({
|
|
1115
|
-
kind: "wallet_auth_authority_ref",
|
|
1116
|
-
walletId: input.authority.walletId,
|
|
1117
|
-
authorityDigest: input.authority.authorityDigestB64u,
|
|
1118
|
-
walletAuthMethodId: input.authMethod.walletAuthMethodId
|
|
1119
|
-
});
|
|
1120
|
-
if (!authorityRef) throw new Error("[login] linked device wallet authority reference is invalid");
|
|
1121
|
-
return authorityRef;
|
|
1122
|
-
}
|
|
1123
|
-
async function resolveLinkedDeviceUnlockSubjectSet(walletIdInput) {
|
|
1124
|
-
const parsedWalletId = parseWalletId(walletIdInput);
|
|
1125
|
-
if (!parsedWalletId.ok) return null;
|
|
1126
|
-
const walletId = parsedWalletId.value;
|
|
1127
|
-
try {
|
|
1128
|
-
const resolved = await IndexedDBManager.resolveSelectedWalletAuthority(String(walletId));
|
|
1129
|
-
if (resolved.kind !== "resolved") return null;
|
|
1130
|
-
const { selection, authMethod, authority } = resolved;
|
|
1131
|
-
if (linkedDeviceUnlockIdentityMismatchLabels({
|
|
1132
|
-
walletId,
|
|
1133
|
-
selection,
|
|
1134
|
-
authMethod,
|
|
1135
|
-
authority
|
|
1136
|
-
}).length > 0) return null;
|
|
1137
|
-
if (authMethod.status !== "active") return null;
|
|
1138
|
-
if (authority.state !== "active") return null;
|
|
1139
|
-
const subjects = [];
|
|
1140
|
-
const nearSubject = await resolveLinkedDeviceNearUnlockSubject({
|
|
1141
|
-
walletId,
|
|
1142
|
-
authMethod,
|
|
1143
|
-
authority,
|
|
1144
|
-
signerMaterials: resolved.signerMaterials
|
|
1145
|
-
});
|
|
1146
|
-
if (nearSubject.kind === "invalid") return null;
|
|
1147
|
-
if (nearSubject.kind === "resolved") subjects.push(nearSubject.subject);
|
|
1148
|
-
const ecdsaActivation = authority.signerActivations.ecdsa;
|
|
1149
|
-
if (ecdsaActivation) {
|
|
1150
|
-
const ecdsaMaterial = selectedSignerMaterialForActivation(resolved.signerMaterials, authority.authorityId, authMethod.walletAuthMethodId, ecdsaActivation.materialActivation);
|
|
1151
|
-
if (!ecdsaMaterial || ecdsaMaterial.keyFamily !== "ecdsa_secp256k1") return null;
|
|
1152
|
-
if (!mpcMaterialActivationRefsEqual(ecdsaMaterial.materialActivation, ecdsaActivation.materialActivation)) return null;
|
|
1153
|
-
let authorityRef;
|
|
1154
|
-
try {
|
|
1155
|
-
authorityRef = authMethod.kind === SIGNER_AUTH_METHODS.passkey ? await walletAuthAuthorityRefForSelectedPasskeyMethod(authMethod) : requireLinkedDeviceWalletAuthAuthorityRef({
|
|
1156
|
-
authority,
|
|
1157
|
-
authMethod
|
|
1158
|
-
});
|
|
1159
|
-
} catch {
|
|
1160
|
-
return null;
|
|
1161
|
-
}
|
|
1162
|
-
subjects.push({
|
|
1163
|
-
kind: "evm_family_ecdsa_wallet",
|
|
1164
|
-
walletId,
|
|
1165
|
-
capability: ecdsaActivation.materialActivation.capability,
|
|
1166
|
-
authority: authorityRef,
|
|
1167
|
-
ecdsaThresholdKeyId: ecdsaMaterial.ecdsaThresholdKeyId
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
const firstSubject = subjects[0];
|
|
1171
|
-
if (!firstSubject) return null;
|
|
1172
|
-
return {
|
|
1173
|
-
kind: "wallet_unlock_subject_set",
|
|
1174
|
-
walletId,
|
|
1175
|
-
subjects: [firstSubject, ...subjects.slice(1)]
|
|
1176
|
-
};
|
|
1177
|
-
} catch {
|
|
1178
|
-
return null;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
function linkedDeviceRuntimeRequiresCurve(walletSession, curve) {
|
|
1182
|
-
return walletSession.capabilitySubjects.some((subject) => (subject.kind === "sign" || subject.kind === "export_keys") && subject.keyFamily === (curve === "ed25519" ? "ed25519" : "ecdsa_secp256k1"));
|
|
1183
|
-
}
|
|
1184
|
-
function linkedDeviceEd25519Material(materials) {
|
|
1185
|
-
const matches = materials.filter((material) => material.keyFamily === "ed25519");
|
|
1186
|
-
if (matches.length > 1) throw new Error("[login] linked passkey has multiple active Ed25519 materials");
|
|
1187
|
-
return matches[0] ?? null;
|
|
1188
|
-
}
|
|
1189
|
-
function linkedDeviceEcdsaMaterial(materials) {
|
|
1190
|
-
const matches = materials.filter((material) => material.keyFamily === "ecdsa_secp256k1");
|
|
1191
|
-
if (matches.length > 1) throw new Error("[login] linked passkey has multiple active ECDSA materials");
|
|
1192
|
-
return matches[0] ?? null;
|
|
1193
|
-
}
|
|
1194
|
-
async function activateLinkedDeviceEcdsaHolderRuntime(args) {
|
|
1195
|
-
const existing = resolveLinkedEcdsaHolderRuntimeV1({
|
|
1196
|
-
walletId: args.selection.walletId,
|
|
1197
|
-
materialActivation: args.material.materialActivation
|
|
1198
|
-
});
|
|
1199
|
-
if (existing) {
|
|
1200
|
-
const [existingAuthorityRef, requestedAuthorityRef] = await Promise.all([walletAuthAuthorityRef({ authority: existing.factorAuthority }), walletAuthAuthorityRef({ authority: args.factorAuthority })]);
|
|
1201
|
-
if (existing.authorityId !== args.selection.authority.authorityId || existing.walletAuthMethodId !== args.selection.authMethod.walletAuthMethodId || existing.ecdsaThresholdKeyId !== args.material.publicFacts.ecdsaThresholdKeyId || existingAuthorityRef.authorityDigest !== requestedAuthorityRef.authorityDigest) throw new Error("[login] linked ECDSA holder runtime conflicts with the selected authority");
|
|
1202
|
-
return {
|
|
1203
|
-
runtime: existing,
|
|
1204
|
-
installed: false
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
const holderHandleId = secureRandomId("linked-ecdsa-holder");
|
|
1208
|
-
try {
|
|
1209
|
-
const stored = await storeLinkedDeviceEcdsaHolderMaterialWasm({
|
|
1210
|
-
holderHandleId,
|
|
1211
|
-
ownedSigningShare32: args.material.material.slice(),
|
|
1212
|
-
activationReceiptJson: JSON.stringify(args.material.publicFacts.activationReceipt),
|
|
1213
|
-
workerCtx: args.context.signingEngine.getSignerWorkerContext()
|
|
1214
|
-
});
|
|
1215
|
-
const runtime = {
|
|
1216
|
-
kind: "linked_ecdsa_holder_runtime_v1",
|
|
1217
|
-
walletId: args.selection.walletId,
|
|
1218
|
-
authorityId: args.selection.authority.authorityId,
|
|
1219
|
-
walletAuthMethodId: args.selection.authMethod.walletAuthMethodId,
|
|
1220
|
-
factorAuthority: args.factorAuthority,
|
|
1221
|
-
materialActivation: args.material.materialActivation,
|
|
1222
|
-
holderHandleId: stored.holderHandleId,
|
|
1223
|
-
ecdsaThresholdKeyId: args.material.publicFacts.ecdsaThresholdKeyId,
|
|
1224
|
-
activationReceipt: args.material.publicFacts.activationReceipt
|
|
1225
|
-
};
|
|
1226
|
-
installLinkedEcdsaHolderRuntimeV1(runtime);
|
|
1227
|
-
return {
|
|
1228
|
-
runtime,
|
|
1229
|
-
installed: true
|
|
1230
|
-
};
|
|
1231
|
-
} catch (error) {
|
|
1232
|
-
await destroyLinkedDeviceEcdsaHolderMaterialWasm({
|
|
1233
|
-
holderHandleId,
|
|
1234
|
-
workerCtx: args.context.signingEngine.getSignerWorkerContext()
|
|
1235
|
-
}).catch(() => void 0);
|
|
1236
|
-
throw error;
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
async function resolveLinkedDevicePostLinkSelection(factor) {
|
|
1240
|
-
if (factor.kind === "passkey") {
|
|
1241
|
-
const selection = await resolveLinkedDevicePasskeyAuthoritySelection(String(factor.walletId));
|
|
1242
|
-
if (!selection) throw new Error("[login] linked Passkey authority is unavailable after link");
|
|
1243
|
-
return selection;
|
|
1244
|
-
}
|
|
1245
|
-
const resolution = await resolveLinkedDeviceEmailOtpAuthoritySelection({
|
|
1246
|
-
walletIdInput: String(factor.walletId),
|
|
1247
|
-
walletAuthMethodId: String(factor.walletAuthMethodId),
|
|
1248
|
-
emailHashHex: factor.emailHashHex,
|
|
1249
|
-
provider: factor.providerIdentity.provider,
|
|
1250
|
-
providerSubjectId: factor.providerIdentity.providerSubjectId
|
|
1251
|
-
});
|
|
1252
|
-
if (resolution.kind !== "selected") throw new Error(resolution.kind === "rejected" ? resolution.message : "[login] linked Email OTP authority is unavailable after link");
|
|
1253
|
-
return resolution.selection;
|
|
1254
|
-
}
|
|
1255
|
-
async function linkedDeviceEd25519SessionAfterLink(args) {
|
|
1256
|
-
const metadata = linkedDeviceEd25519Metadata(args.material);
|
|
1257
|
-
const nearAccountId = deriveImplicitNearAccountIdFromEd25519PublicKey(`ed25519:${base58Encode(metadata.registeredPublicKey)}`);
|
|
1258
|
-
const requestResult = parseRouterAbEd25519YaoWarmRecoveryBootstrapRequestV1({
|
|
1259
|
-
kind: "router_ab_ed25519_yao_warm_recovery_bootstrap_request_v1",
|
|
1260
|
-
walletId: String(args.selection.walletId),
|
|
1261
|
-
nearAccountId,
|
|
1262
|
-
nearEd25519SigningKeyId: metadata.applicationBinding.near_ed25519_signing_key_id,
|
|
1263
|
-
signerSlot: metadata.applicationBinding.key_creation_signer_slot,
|
|
1264
|
-
thresholdSessionId: metadata.scope.threshold_session_id,
|
|
1265
|
-
signingWorkerId: metadata.scope.signing_worker_id,
|
|
1266
|
-
participantIds: metadata.participantIds
|
|
1267
|
-
});
|
|
1268
|
-
if (!requestResult.ok) throw new Error(requestResult.message);
|
|
1269
|
-
const response = await fetch(`${new URL(args.relayerUrl).origin}${ROUTER_AB_ED25519_YAO_WARM_RECOVERY_BOOTSTRAP_PATH_V1}`, {
|
|
1270
|
-
method: "POST",
|
|
1271
|
-
headers: {
|
|
1272
|
-
Authorization: `Bearer ${args.operationCredential.token}`,
|
|
1273
|
-
"Content-Type": "application/json"
|
|
1274
|
-
},
|
|
1275
|
-
body: JSON.stringify(requestResult.value)
|
|
1276
|
-
});
|
|
1277
|
-
const raw = await response.json().catch(() => null);
|
|
1278
|
-
if (!response.ok || !isObject(raw)) {
|
|
1279
|
-
const message = isObject(raw) ? String(raw.message || "").trim() : "";
|
|
1280
|
-
throw new Error(`[login] linked Ed25519 post-link bootstrap failed (HTTP ${response.status}): ${message || "invalid response"}`);
|
|
1281
|
-
}
|
|
1282
|
-
const thresholdSessionId = parseThresholdEd25519SessionId(raw.thresholdSessionId);
|
|
1283
|
-
const walletSessionId = parseWalletSessionId(raw.walletSessionId);
|
|
1284
|
-
const quotaId = parseMpcWalletSigningQuotaId(raw.quotaId);
|
|
1285
|
-
const runtimePolicyScope = normalizeRuntimePolicyScope(raw.runtimePolicyScope);
|
|
1286
|
-
const routerAbNormalSigning = parseRouterAbEd25519NormalSigningState(raw.routerAbNormalSigning);
|
|
1287
|
-
const participantIds = Array.isArray(raw.participantIds) ? raw.participantIds : [];
|
|
1288
|
-
if (raw.kind !== "router_ab_ed25519_yao_warm_recovery_bootstrap_v1" && raw.kind !== "router_ab_ed25519_yao_v2_session_bootstrap_v1" || String(raw.walletId) !== String(args.selection.walletId) || String(raw.nearAccountId) !== requestResult.value.nearAccountId || String(raw.nearEd25519SigningKeyId) !== requestResult.value.nearEd25519SigningKeyId || String(raw.signingWorkerId) !== requestResult.value.signingWorkerId || !thresholdSessionId.ok || !walletSessionId.ok || !quotaId.ok || !runtimePolicyScope || !routerAbNormalSigning || participantIds.length !== 2 || !Number.isSafeInteger(participantIds[0]) || !Number.isSafeInteger(participantIds[1]) || String(walletSessionId.value) !== String(args.operationCredential.walletSessionId) || String(thresholdSessionId.value) !== requestResult.value.thresholdSessionId) throw new Error("[login] linked Ed25519 post-link bootstrap identity is invalid");
|
|
1289
|
-
const expiresAtMs = Number(raw.thresholdExpiresAtMs);
|
|
1290
|
-
if (!Number.isSafeInteger(expiresAtMs) || expiresAtMs <= Date.now()) throw new Error("[login] linked Ed25519 post-link bootstrap is expired");
|
|
1291
|
-
return {
|
|
1292
|
-
walletId: String(args.selection.walletId),
|
|
1293
|
-
nearAccountId: requestResult.value.nearAccountId,
|
|
1294
|
-
nearEd25519SigningKeyId: requestResult.value.nearEd25519SigningKeyId,
|
|
1295
|
-
relayerKeyId: requestResult.value.signingWorkerId,
|
|
1296
|
-
participantIds: [participantIds[0], participantIds[1]],
|
|
1297
|
-
thresholdSessionId: thresholdSessionId.value,
|
|
1298
|
-
authorizationId: args.walletSession.authorizationId,
|
|
1299
|
-
walletSessionId: walletSessionId.value,
|
|
1300
|
-
quotaId: quotaId.value,
|
|
1301
|
-
expiresAtMs,
|
|
1302
|
-
remainingUses: DEFAULT_UNLOCK_REMAINING_USES,
|
|
1303
|
-
runtimePolicyScope,
|
|
1304
|
-
routerAbNormalSigning,
|
|
1305
|
-
operationCredential: args.operationCredential
|
|
1306
|
-
};
|
|
1307
|
-
}
|
|
1308
|
-
async function activateLinkedDeviceSignerRuntimesAfterLink(args) {
|
|
1309
|
-
const selection = await resolveLinkedDevicePostLinkSelection(args.factor);
|
|
1310
|
-
assertLinkedDeviceWalletSessionExact(selection, args.walletSession);
|
|
1311
|
-
const relayerUrl = String(args.context.configs.network.relayer?.url || "").trim();
|
|
1312
|
-
if (!relayerUrl) throw new Error("[login] linked post-link activation requires relayer.url");
|
|
1313
|
-
await walletSessionAuthorizations.writeExactWithOperationCredential({
|
|
1314
|
-
record: args.walletSession,
|
|
1315
|
-
operationCredential: args.operationCredential
|
|
1316
|
-
});
|
|
1317
|
-
const openedMaterials = await openLinkedDeviceSignerMaterialsWithFactorSecret({
|
|
1318
|
-
selection,
|
|
1319
|
-
factorSecret32: args.factorSecret32
|
|
1320
|
-
});
|
|
1321
|
-
try {
|
|
1322
|
-
const providerIdentity = args.factor.kind === "email_otp" ? args.factor.providerIdentity : void 0;
|
|
1323
|
-
const factorAuthority = await walletAuthAuthorityForLinkedDeviceMethod({
|
|
1324
|
-
selection,
|
|
1325
|
-
...providerIdentity ? { providerIdentity } : {}
|
|
1326
|
-
});
|
|
1327
|
-
const ecdsaMaterial = linkedDeviceEcdsaMaterial(openedMaterials);
|
|
1328
|
-
if (ecdsaMaterial) {
|
|
1329
|
-
const { runtime } = await activateLinkedDeviceEcdsaHolderRuntime({
|
|
1330
|
-
context: args.context,
|
|
1331
|
-
selection,
|
|
1332
|
-
factorAuthority,
|
|
1333
|
-
material: ecdsaMaterial
|
|
1334
|
-
});
|
|
1335
|
-
scheduleLinkedDevicePresignaturePrefill({
|
|
1336
|
-
runtime,
|
|
1337
|
-
operationCredential: args.operationCredential,
|
|
1338
|
-
expiresAtMs: args.walletSession.expiresAtMs,
|
|
1339
|
-
relayerUrl,
|
|
1340
|
-
workerCtx: args.context.signingEngine.getSignerWorkerContext()
|
|
1341
|
-
});
|
|
1342
|
-
}
|
|
1343
|
-
const ed25519Material = linkedDeviceEd25519Material(openedMaterials);
|
|
1344
|
-
if (ed25519Material) {
|
|
1345
|
-
const session = await linkedDeviceEd25519SessionAfterLink({
|
|
1346
|
-
relayerUrl,
|
|
1347
|
-
selection,
|
|
1348
|
-
walletSession: args.walletSession,
|
|
1349
|
-
operationCredential: args.operationCredential,
|
|
1350
|
-
material: ed25519Material
|
|
1351
|
-
});
|
|
1352
|
-
await activateLinkedDeviceEd25519Runtime({
|
|
1353
|
-
context: args.context,
|
|
1354
|
-
selection,
|
|
1355
|
-
session,
|
|
1356
|
-
material: ed25519Material,
|
|
1357
|
-
relayerUrl,
|
|
1358
|
-
...providerIdentity ? { providerIdentity } : {}
|
|
1359
|
-
});
|
|
1360
|
-
}
|
|
1361
|
-
if (selection.exportRoot) {
|
|
1362
|
-
if (args.factor.kind === "passkey") await args.context.signingEngine.establishUnlockedWalletEd25519ExportRootCapabilityV1({
|
|
1363
|
-
existingEnvelope: selection.exportRoot.envelope,
|
|
1364
|
-
passkeyPrfFirstB64u: base64UrlEncode(args.factorSecret32),
|
|
1365
|
-
walletId: String(selection.walletId),
|
|
1366
|
-
walletAuthMethodId: String(selection.authMethod.walletAuthMethodId),
|
|
1367
|
-
walletSessionId: String(args.operationCredential.walletSessionId),
|
|
1368
|
-
expiresAtMs: args.walletSession.expiresAtMs
|
|
1369
|
-
});
|
|
1370
|
-
else if (isWalletCustodySeedBinding(selection.exportRoot.envelope.binding) || selection.exportRoot.envelope.binding.kind === "ed25519_yao_client_root_v1") await establishUnlockedWalletEd25519ExportRootCapabilityV1(walletCustodyCeremonyTransportFromWorkerContextV1(args.context.signingEngine.getSignerWorkerContext()), {
|
|
1371
|
-
existingEnvelope: selection.exportRoot.envelope,
|
|
1372
|
-
existingFactorSecret: args.factorSecret32,
|
|
1373
|
-
walletId: String(selection.walletId),
|
|
1374
|
-
walletAuthMethodId: String(selection.authMethod.walletAuthMethodId),
|
|
1375
|
-
walletSessionId: String(args.operationCredential.walletSessionId),
|
|
1376
|
-
expiresAtMs: args.walletSession.expiresAtMs
|
|
1377
|
-
});
|
|
1378
|
-
}
|
|
1379
|
-
await args.context.signingEngine.markWalletSelectionUnlocked({
|
|
1380
|
-
walletId: selection.walletId,
|
|
1381
|
-
walletAuthMethodId: selection.authMethod.walletAuthMethodId
|
|
1382
|
-
});
|
|
1383
|
-
} finally {
|
|
1384
|
-
for (const openedMaterial of openedMaterials) openedMaterial.material.fill(0);
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
function linkedDeviceEd25519Metadata(material) {
|
|
1388
|
-
const binding = material.publicFacts.targetBinding;
|
|
1389
|
-
const receipt = material.publicFacts.activationReceipt;
|
|
1390
|
-
return {
|
|
1391
|
-
kind: ROUTER_AB_ED25519_YAO_ACTIVE_CLIENT_KIND_V1,
|
|
1392
|
-
scope: {
|
|
1393
|
-
lifecycle_id: binding.lifecycle.lifecycle_id,
|
|
1394
|
-
root_share_epoch: binding.lifecycle.root_share_epoch,
|
|
1395
|
-
account_id: binding.lifecycle.account_id,
|
|
1396
|
-
threshold_session_id: binding.lifecycle.session_id,
|
|
1397
|
-
signer_set_id: binding.lifecycle.signer_set_id,
|
|
1398
|
-
signing_worker_id: binding.lifecycle.selected_server_id,
|
|
1399
|
-
material_activation: binding.material_activation
|
|
1400
|
-
},
|
|
1401
|
-
applicationBinding: material.publicFacts.applicationBinding,
|
|
1402
|
-
participantIds: material.publicFacts.participantIds,
|
|
1403
|
-
registeredPublicKey: Uint8Array.from(receipt.registered_public_key),
|
|
1404
|
-
signingWorkerVerifyingShare: Uint8Array.from(receipt.signing_worker_verifying_share),
|
|
1405
|
-
stateEpoch: BigInt(receipt.state_epoch),
|
|
1406
|
-
transcript: Uint8Array.from(receipt.transcript),
|
|
1407
|
-
activeCapabilityBinding: binding.session_id,
|
|
1408
|
-
materialActivation: material.materialActivation
|
|
1409
|
-
};
|
|
1410
|
-
}
|
|
1411
|
-
function linkedDeviceEmailOtpProviderSubjectId(providerIdentity) {
|
|
1412
|
-
const providerSubjectId = String(providerIdentity?.providerSubjectId || "").trim();
|
|
1413
|
-
if (!providerSubjectId) throw new Error("[login] linked Email OTP lane provider identity is missing");
|
|
1414
|
-
return providerSubjectId;
|
|
1415
|
-
}
|
|
1416
|
-
function linkedDeviceEd25519SessionFromEmailOtpBootstrap(args) {
|
|
1417
|
-
const session = args.session;
|
|
1418
|
-
if (session.authorityScope.kind !== "email_otp" || String(session.authorityScope.providerUserId) !== String(args.providerIdentity.providerSubjectId)) {
|
|
1419
|
-
const mismatches = [...session.authorityScope.kind !== "email_otp" ? ["scope.kind"] : [], ...session.authorityScope.kind === "email_otp" && String(session.authorityScope.providerUserId) !== String(args.providerIdentity.providerSubjectId) ? ["scope.providerUserId"] : []];
|
|
1420
|
-
throw new Error(`[login] linked Email OTP Ed25519 session authority mismatch: ${mismatches.join(", ")}`);
|
|
1421
|
-
}
|
|
1422
|
-
const thresholdSessionId = parseThresholdEd25519SessionId(session.thresholdSessionId);
|
|
1423
|
-
const authorizationId = parseWalletSessionAuthorizationId(session.authorizationId);
|
|
1424
|
-
const walletSessionId = parseWalletSessionId(session.walletSessionId);
|
|
1425
|
-
const quotaId = parseMpcWalletSigningQuotaId(session.quotaId);
|
|
1426
|
-
if (!thresholdSessionId.ok || !authorizationId.ok || !walletSessionId.ok || !quotaId.ok) throw new Error("[login] linked Email OTP Ed25519 session identity is invalid");
|
|
1427
|
-
if (args.operationCredential.walletSessionId !== walletSessionId.value) throw new Error("[login] linked Email OTP Ed25519 credential identifies another session");
|
|
1428
|
-
return {
|
|
1429
|
-
walletId: String(session.walletId),
|
|
1430
|
-
nearAccountId: session.nearAccountId,
|
|
1431
|
-
nearEd25519SigningKeyId: session.nearEd25519SigningKeyId,
|
|
1432
|
-
relayerKeyId: session.routerAbNormalSigning.signingWorkerId,
|
|
1433
|
-
participantIds: session.participantIds,
|
|
1434
|
-
thresholdSessionId: thresholdSessionId.value,
|
|
1435
|
-
authorizationId: authorizationId.value,
|
|
1436
|
-
walletSessionId: walletSessionId.value,
|
|
1437
|
-
quotaId: quotaId.value,
|
|
1438
|
-
expiresAtMs: session.expiresAtMs,
|
|
1439
|
-
remainingUses: session.remainingUses,
|
|
1440
|
-
runtimePolicyScope: session.runtimePolicyScope,
|
|
1441
|
-
routerAbNormalSigning: session.routerAbNormalSigning,
|
|
1442
|
-
operationCredential: args.operationCredential
|
|
1443
|
-
};
|
|
1444
|
-
}
|
|
1445
|
-
function linkedDeviceEd25519YaoLaneReference(args) {
|
|
1446
|
-
const nearAccountId = toAccountId(args.session.nearAccountId);
|
|
1447
|
-
const common = {
|
|
1448
|
-
walletId: args.selection.walletId,
|
|
1449
|
-
nearAccountId,
|
|
1450
|
-
thresholdSessionId: args.session.thresholdSessionId,
|
|
1451
|
-
runtimePolicyScope: args.session.runtimePolicyScope,
|
|
1452
|
-
materialActivation: args.material.materialActivation,
|
|
1453
|
-
nearEd25519SigningKeyId: nearEd25519SigningKeyIdFromString(args.session.nearEd25519SigningKeyId),
|
|
1454
|
-
signerSlot: args.material.publicFacts.applicationBinding.key_creation_signer_slot
|
|
1455
|
-
};
|
|
1456
|
-
if (args.selection.authMethod.kind === "passkey") return {
|
|
1457
|
-
...common,
|
|
1458
|
-
auth: {
|
|
1459
|
-
kind: "passkey",
|
|
1460
|
-
rpId: toRpId(args.selection.authMethod.rpId),
|
|
1461
|
-
credentialIdB64u: args.selection.authMethod.credentialIdB64u
|
|
1462
|
-
}
|
|
1463
|
-
};
|
|
1464
|
-
return {
|
|
1465
|
-
...common,
|
|
1466
|
-
auth: {
|
|
1467
|
-
kind: "email_otp",
|
|
1468
|
-
providerSubjectId: linkedDeviceEmailOtpProviderSubjectId(args.providerIdentity)
|
|
1469
|
-
},
|
|
1470
|
-
remainingUses: args.session.remainingUses,
|
|
1471
|
-
expiresAtMs: args.session.expiresAtMs
|
|
1472
|
-
};
|
|
1473
|
-
}
|
|
1474
|
-
async function activateLinkedDeviceEd25519Runtime(args) {
|
|
1475
|
-
const metadata = linkedDeviceEd25519Metadata(args.material);
|
|
1476
|
-
const application = metadata.applicationBinding;
|
|
1477
|
-
const mismatchLabels = [];
|
|
1478
|
-
if (args.session.walletId !== String(args.selection.walletId)) mismatchLabels.push("walletId");
|
|
1479
|
-
if (application.wallet_id !== String(args.selection.walletId)) mismatchLabels.push("application.walletId");
|
|
1480
|
-
if (metadata.scope.account_id !== String(args.selection.walletId)) mismatchLabels.push("material.walletId");
|
|
1481
|
-
if (args.session.nearEd25519SigningKeyId !== application.near_ed25519_signing_key_id) mismatchLabels.push("nearEd25519SigningKeyId");
|
|
1482
|
-
if (args.session.thresholdSessionId !== metadata.scope.threshold_session_id) mismatchLabels.push("thresholdSessionId");
|
|
1483
|
-
if (args.session.relayerKeyId !== metadata.scope.signing_worker_id) mismatchLabels.push("signingWorkerId");
|
|
1484
|
-
if (mismatchLabels.length > 0) throw new Error(`[login] linked Ed25519 Wallet Session does not match local material: ${mismatchLabels.join(", ")}`);
|
|
1485
|
-
const activeClient = (await RouterAbEd25519YaoClientV1.initializeBundled()).importLinkedMaterial({
|
|
1486
|
-
ownedClientScalarShare: args.material.material,
|
|
1487
|
-
publicReceipt: args.material.publicFacts.activationReceipt,
|
|
1488
|
-
metadata
|
|
1489
|
-
});
|
|
1490
|
-
let activated = false;
|
|
1491
|
-
try {
|
|
1492
|
-
const activatedIdentity = await args.context.signingEngine.activateVerifiedNearEd25519YaoMaterial({
|
|
1493
|
-
activeClient,
|
|
1494
|
-
facts: {
|
|
1495
|
-
thresholdSessionId: args.session.thresholdSessionId,
|
|
1496
|
-
signer: nearEd25519SignerBindingFromBoundaryFields({
|
|
1497
|
-
walletId: args.selection.walletId,
|
|
1498
|
-
nearAccountId: toAccountId(args.session.nearAccountId),
|
|
1499
|
-
nearEd25519SigningKeyId: nearEd25519SigningKeyIdFromString(args.session.nearEd25519SigningKeyId),
|
|
1500
|
-
signerSlot: application.key_creation_signer_slot
|
|
1501
|
-
}),
|
|
1502
|
-
signingRootId: application.signing_root_id,
|
|
1503
|
-
signingRootVersion: metadata.scope.root_share_epoch,
|
|
1504
|
-
routerAbNormalSigning: args.session.routerAbNormalSigning,
|
|
1505
|
-
runtimePolicyScope: args.session.runtimePolicyScope,
|
|
1506
|
-
relayerUrl: args.relayerUrl
|
|
1507
|
-
}
|
|
1508
|
-
});
|
|
1509
|
-
const nearAccountId = toAccountId(args.session.nearAccountId);
|
|
1510
|
-
if (String(activatedIdentity.walletId) !== String(args.selection.walletId) || String(activatedIdentity.nearAccountId) !== String(nearAccountId) || !mpcMaterialActivationRefsEqual(activatedIdentity.materialActivation, args.material.materialActivation)) throw new Error("[login] linked Ed25519 activation identity does not match the V2 session");
|
|
1511
|
-
await publishEd25519YaoPublicCapabilityReferenceAndLane(new IndexedDbEd25519YaoPublicCapabilityReferenceStore(IndexedDBManager), linkedDeviceEd25519YaoLaneReference({
|
|
1512
|
-
selection: args.selection,
|
|
1513
|
-
session: args.session,
|
|
1514
|
-
material: args.material,
|
|
1515
|
-
...args.providerIdentity ? { providerIdentity: args.providerIdentity } : {}
|
|
1516
|
-
}));
|
|
1517
|
-
activated = true;
|
|
1518
|
-
} finally {
|
|
1519
|
-
if (!activated) activeClient.dispose();
|
|
1520
|
-
}
|
|
1521
|
-
const nearAccountId = toAccountId(args.session.nearAccountId);
|
|
1522
|
-
return {
|
|
1523
|
-
success: true,
|
|
1524
|
-
kind: "near_wallet_unlocked",
|
|
1525
|
-
walletId: args.selection.walletId,
|
|
1526
|
-
loggedInNearAccountId: String(nearAccountId),
|
|
1527
|
-
operationalPublicKey: `ed25519:${base58Encode(metadata.registeredPublicKey)}`,
|
|
1528
|
-
nearAccountId
|
|
1529
|
-
};
|
|
1530
|
-
}
|
|
1531
|
-
function emailOtpUnlockSource(selection) {
|
|
1532
|
-
const [first, ...rest] = selection.signerMaterials;
|
|
1533
|
-
if (selection.authority.provenance.kind === "device_link") {
|
|
1534
|
-
if (!first) throw new Error("[login] linked Email OTP authority has no signer material");
|
|
1535
|
-
return {
|
|
1536
|
-
kind: "linked_device",
|
|
1537
|
-
selection,
|
|
1538
|
-
signerMaterials: [first, ...rest]
|
|
1539
|
-
};
|
|
1540
|
-
}
|
|
1541
|
-
if (first) throw new Error("[login] owner Email OTP authority must not carry linked signer material");
|
|
1542
|
-
return {
|
|
1543
|
-
kind: "owner_authority",
|
|
1544
|
-
selection
|
|
1545
|
-
};
|
|
1546
|
-
}
|
|
1547
|
-
/**
|
|
1548
|
-
* What this unlock should build, decided by the branch rather than by whichever
|
|
1549
|
-
* fields happened to be present.
|
|
1550
|
-
*
|
|
1551
|
-
* A linked device names the signer slot its own sealed material carries. An
|
|
1552
|
-
* owner authority has none, so the request is assembled from its exact
|
|
1553
|
-
* authority projection and the runtime is built inside the unlock.
|
|
1554
|
-
*/
|
|
1555
|
-
async function emailOtpAuthorityUnlockEd25519Request(input) {
|
|
1556
|
-
const { source } = input;
|
|
1557
|
-
if (source.kind === "linked_device") {
|
|
1558
|
-
const ed25519Material = source.signerMaterials.find((material) => material.kind === "wallet_authority_linked_signer_material_v1" && material.keyFamily === "ed25519");
|
|
1559
|
-
if (!ed25519Material) return { kind: "no_ed25519" };
|
|
1560
|
-
return {
|
|
1561
|
-
kind: "linked_device",
|
|
1562
|
-
signerSlot: ed25519Material.publicFacts.applicationBinding.key_creation_signer_slot,
|
|
1563
|
-
remainingUses: DEFAULT_UNLOCK_REMAINING_USES
|
|
1564
|
-
};
|
|
1565
|
-
}
|
|
1566
|
-
if (!source.selection.authority.signerActivations.ed25519 || await hasPendingJoinedNearRegistration(source.selection)) return { kind: "no_ed25519" };
|
|
1567
|
-
return await input.context.signingEngine.resolveOwnerAuthorityEd25519UnlockRequestInternal({
|
|
1568
|
-
walletSession: {
|
|
1569
|
-
walletId: source.selection.walletId,
|
|
1570
|
-
walletSessionUserId: String(source.selection.walletId)
|
|
1571
|
-
},
|
|
1572
|
-
providerSubjectId: input.providerIdentity.providerSubjectId,
|
|
1573
|
-
walletAuthMethodId: String(source.selection.authMethod.walletAuthMethodId),
|
|
1574
|
-
remainingUses: DEFAULT_UNLOCK_REMAINING_USES
|
|
1575
|
-
}) ?? { kind: "no_ed25519" };
|
|
1576
|
-
}
|
|
1577
|
-
async function hasPendingJoinedNearRegistration(selection) {
|
|
1578
|
-
const activation = selection.authority.signerActivations.ed25519?.materialActivation;
|
|
1579
|
-
if (!activation) return false;
|
|
1580
|
-
return (await IndexedDBManager.listPendingWalletRegistrationCommits()).some(pendingNearRegistrationMatchesAuthority.bind(void 0, selection, activation));
|
|
1581
|
-
}
|
|
1582
|
-
function pendingNearRegistrationMatchesAuthority(selection, activation, pending) {
|
|
1583
|
-
return pending.operation === "near_provisioning" && pending.phase === "joined" && pending.signerPlanKind === "near_ed25519_and_evm_family_ecdsa" && pending.walletId === selection.walletId && pending.walletAuthMethodId === selection.authMethod.walletAuthMethodId && mpcMaterialActivationRefsEqual(pending.localMaterial.ed25519.metadata.materialActivation, activation);
|
|
1584
|
-
}
|
|
1585
|
-
/**
|
|
1586
|
-
* Install the Ed25519 runtime an owner authority's unlock just built.
|
|
1587
|
-
*
|
|
1588
|
-
* Everything is checked against the authority and method that were selected,
|
|
1589
|
-
* before the handle is used: a session naming a different method, or a
|
|
1590
|
-
* capability naming a different activation, must not be able to activate a
|
|
1591
|
-
* runtime under this one.
|
|
1592
|
-
*/
|
|
1593
|
-
async function unlockOwnerAuthorityEmailOtpEd25519(input) {
|
|
1594
|
-
const { selection, unlocked } = input;
|
|
1595
|
-
const session = unlocked.walletSession;
|
|
1596
|
-
if (session.walletId !== selection.walletId || session.authorityId !== selection.authority.authorityId || session.authMethodId !== selection.authMethod.walletAuthMethodId || session.authorityDigestB64u !== selection.authority.authorityDigestB64u || session.authorityRevocationEpoch !== selection.authority.revocationEpoch) throw new Error("[login] owner Email OTP Wallet Session does not match the selected authority");
|
|
1597
|
-
const activation = selection.authority.signerActivations.ed25519?.materialActivation;
|
|
1598
|
-
if (!activation) return;
|
|
1599
|
-
if (unlocked.ed25519Activation.kind !== "ed25519_activation_ready") {
|
|
1600
|
-
if (await hasPendingJoinedNearRegistration(selection)) return;
|
|
1601
|
-
throw new Error("[login] owner Email OTP unlock built no Ed25519 runtime to install");
|
|
1602
|
-
}
|
|
1603
|
-
const ready = unlocked.ed25519Activation;
|
|
1604
|
-
if (!mpcMaterialActivationRefsEqual(ready.bootstrap.capability.materialActivation, activation)) throw new Error("[login] owner Email OTP Ed25519 capability names another activation");
|
|
1605
|
-
if (!mpcMaterialActivationRefsEqual(ready.metadata.materialActivation, activation)) throw new Error("[login] owner Email OTP Ed25519 runtime names another activation");
|
|
1606
|
-
if (ready.bootstrap.session.walletSessionId !== unlocked.operationCredential.walletSessionId) throw new Error("[login] owner Email OTP Ed25519 session credential mismatch");
|
|
1607
|
-
const authority = await walletAuthAuthorityRefForLinkedDeviceMethod({
|
|
1608
|
-
selection,
|
|
1609
|
-
providerIdentity: input.providerIdentity
|
|
1610
|
-
});
|
|
1611
|
-
await input.context.signingEngine.activateOwnerAuthorityEd25519RuntimeInternal({
|
|
1612
|
-
walletSession: {
|
|
1613
|
-
walletId: selection.walletId,
|
|
1614
|
-
walletSessionUserId: String(selection.walletId)
|
|
1615
|
-
},
|
|
1616
|
-
providerSubjectId: input.providerIdentity.providerSubjectId,
|
|
1617
|
-
walletAuthMethodId: String(selection.authMethod.walletAuthMethodId),
|
|
1618
|
-
emailHashHex: input.emailHashHex,
|
|
1619
|
-
authority,
|
|
1620
|
-
activeClientHandle: ready.activeClientHandle,
|
|
1621
|
-
metadata: ready.metadata,
|
|
1622
|
-
bootstrap: ready.bootstrap
|
|
1623
|
-
});
|
|
1624
|
-
}
|
|
1625
|
-
function ownerAuthorityWalletCustodySeedEnvelope(unlocked) {
|
|
1626
|
-
switch (unlocked.walletCustodySeed.kind) {
|
|
1627
|
-
case "owner_authority_seed_envelope": return unlocked.walletCustodySeed.existingEnvelope;
|
|
1628
|
-
case "linked_device_seed_unavailable": throw new Error("[login] owner Email OTP unlock returned linked-device custody state");
|
|
1629
|
-
default: return assertNeverLoginState(unlocked.walletCustodySeed);
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
async function unlockLinkedDeviceEmailOtpWallet(args) {
|
|
1633
|
-
const providerIdentity = {
|
|
1634
|
-
provider: args.providerSubjectId.startsWith("google:") ? "google" : "email",
|
|
1635
|
-
providerSubjectId: args.providerSubjectId
|
|
1636
|
-
};
|
|
1637
|
-
const resolution = await resolveLinkedDeviceEmailOtpAuthoritySelection({
|
|
1638
|
-
walletIdInput: args.walletIdInput,
|
|
1639
|
-
emailHashHex: args.emailHashHex,
|
|
1640
|
-
provider: providerIdentity.provider,
|
|
1641
|
-
providerSubjectId: providerIdentity.providerSubjectId,
|
|
1642
|
-
walletAuthMethodId: args.walletAuthMethodId
|
|
1643
|
-
});
|
|
1644
|
-
if (resolution.kind === "none") throw new Error("[login] linked Email OTP authority is unavailable");
|
|
1645
|
-
if (resolution.kind === "rejected") throw new Error(resolution.message);
|
|
1646
|
-
const selection = resolution.selection;
|
|
1647
|
-
if (String(selection.authMethod.walletAuthMethodId) !== String(args.walletAuthMethodId)) throw new Error("[login] linked Email OTP selected auth method changed during unlock");
|
|
1648
|
-
const relayUrl = String(args.relayUrl || "").trim();
|
|
1649
|
-
if (!relayUrl) throw new Error("[login] linked Email OTP unlock requires relayer.url");
|
|
1650
|
-
const source = emailOtpUnlockSource(selection);
|
|
1651
|
-
const ed25519Request = await emailOtpAuthorityUnlockEd25519Request({
|
|
1652
|
-
context: args.context,
|
|
1653
|
-
source,
|
|
1654
|
-
providerIdentity
|
|
1655
|
-
});
|
|
1656
|
-
const unlocked = await unlockEmailOtpAuthorityWallet({
|
|
1657
|
-
relayUrl,
|
|
1658
|
-
walletId: String(selection.walletId),
|
|
1659
|
-
walletAuthMethodId: String(selection.authMethod.walletAuthMethodId),
|
|
1660
|
-
challengeId: args.challengeId,
|
|
1661
|
-
otpCode: args.otpCode,
|
|
1662
|
-
ed25519: ed25519Request,
|
|
1663
|
-
workerCtx: args.context.signingEngine.getSignerWorkerContext()
|
|
1664
|
-
});
|
|
1665
|
-
const factorSecret32 = unlocked.factorSecret32;
|
|
1666
|
-
const effectiveProviderIdentity = providerIdentity;
|
|
1667
|
-
let openedMaterials = null;
|
|
1668
|
-
let installedEcdsaRuntime = null;
|
|
1669
|
-
let ownedActiveClientHandle = unlocked.ed25519Activation.kind === "ed25519_activation_ready" ? unlocked.ed25519Activation.activeClientHandle : null;
|
|
1670
|
-
try {
|
|
1671
|
-
if (source.kind === "owner_authority") {
|
|
1672
|
-
await walletSessionAuthorizations.writeExactWithOperationCredential({
|
|
1673
|
-
record: unlocked.walletSession,
|
|
1674
|
-
operationCredential: unlocked.operationCredential
|
|
1675
|
-
});
|
|
1676
|
-
await unlockOwnerAuthorityEmailOtpEd25519({
|
|
1677
|
-
context: args.context,
|
|
1678
|
-
selection,
|
|
1679
|
-
unlocked,
|
|
1680
|
-
providerIdentity: effectiveProviderIdentity,
|
|
1681
|
-
emailHashHex: args.emailHashHex
|
|
1682
|
-
});
|
|
1683
|
-
ownedActiveClientHandle = null;
|
|
1684
|
-
if (!factorSecret32) throw new Error("[login] owner Email OTP factor secret ownership was lost");
|
|
1685
|
-
await establishUnlockedWalletEd25519ExportRootCapabilityV1(walletCustodyCeremonyTransportFromWorkerContextV1(args.context.signingEngine.getSignerWorkerContext()), {
|
|
1686
|
-
existingEnvelope: ownerAuthorityWalletCustodySeedEnvelope(unlocked),
|
|
1687
|
-
existingFactorSecret: factorSecret32,
|
|
1688
|
-
walletId: String(selection.walletId),
|
|
1689
|
-
walletAuthMethodId: String(selection.authMethod.walletAuthMethodId),
|
|
1690
|
-
walletSessionId: String(unlocked.operationCredential.walletSessionId),
|
|
1691
|
-
expiresAtMs: unlocked.walletSession.expiresAtMs
|
|
1692
|
-
});
|
|
1693
|
-
await args.context.signingEngine.markWalletSelectionUnlocked({
|
|
1694
|
-
walletId: selection.walletId,
|
|
1695
|
-
walletAuthMethodId: selection.authMethod.walletAuthMethodId
|
|
1696
|
-
});
|
|
1697
|
-
args.context.signingEngine.setWalletAuthenticated({
|
|
1698
|
-
kind: "authenticated",
|
|
1699
|
-
walletId: selection.walletId,
|
|
1700
|
-
authMethod: SIGNER_AUTH_METHODS.emailOtp
|
|
1701
|
-
});
|
|
1702
|
-
resumeNearAfterSuccessfulUnlock({
|
|
1703
|
-
context: args.context,
|
|
1704
|
-
sessionAuthority: {
|
|
1705
|
-
record: unlocked.walletSession,
|
|
1706
|
-
operationCredential: unlocked.operationCredential
|
|
1707
|
-
},
|
|
1708
|
-
factor: {
|
|
1709
|
-
kind: "email_otp",
|
|
1710
|
-
provider: providerIdentity.provider,
|
|
1711
|
-
providerSubject: providerIdentity.providerSubjectId,
|
|
1712
|
-
emailHashHex: args.emailHashHex
|
|
1713
|
-
},
|
|
1714
|
-
ownedFactorSecret: factorSecret32.slice().buffer,
|
|
1715
|
-
custodyEnvelope: ownerAuthorityWalletCustodySeedEnvelope(unlocked)
|
|
1716
|
-
});
|
|
1717
|
-
return;
|
|
1718
|
-
}
|
|
1719
|
-
assertLinkedDeviceWalletSessionExact(selection, unlocked.walletSession);
|
|
1720
|
-
if (!factorSecret32) throw new Error("[login] linked Email OTP factor secret ownership was lost");
|
|
1721
|
-
openedMaterials = await openLinkedDeviceEmailOtpSignerMaterials({
|
|
1722
|
-
selection,
|
|
1723
|
-
factorSecret32
|
|
1724
|
-
});
|
|
1725
|
-
const ed25519Material = linkedDeviceEd25519Material(openedMaterials);
|
|
1726
|
-
const ecdsaMaterial = linkedDeviceEcdsaMaterial(openedMaterials);
|
|
1727
|
-
if (linkedDeviceRuntimeRequiresCurve(unlocked.walletSession, "ed25519")) {
|
|
1728
|
-
if (!ed25519Material || !unlocked.ed25519Activation.bootstrap) throw new Error("[login] linked Email OTP Ed25519 runtime material or capability is missing");
|
|
1729
|
-
if (!mpcMaterialActivationRefsEqual(unlocked.ed25519Activation.bootstrap.capability.materialActivation, ed25519Material.materialActivation)) throw new Error("[login] linked Email OTP Ed25519 capability activation is invalid");
|
|
1730
|
-
}
|
|
1731
|
-
if (linkedDeviceRuntimeRequiresCurve(unlocked.walletSession, "ecdsa")) {
|
|
1732
|
-
if (!ecdsaMaterial) throw new Error("[login] linked Email OTP ECDSA runtime material is missing");
|
|
1733
|
-
const activatedEcdsa = await activateLinkedDeviceEcdsaHolderRuntime({
|
|
1734
|
-
context: args.context,
|
|
1735
|
-
selection,
|
|
1736
|
-
factorAuthority: await walletAuthAuthorityForLinkedDeviceMethod({
|
|
1737
|
-
selection,
|
|
1738
|
-
providerIdentity: effectiveProviderIdentity
|
|
1739
|
-
}),
|
|
1740
|
-
material: ecdsaMaterial
|
|
1741
|
-
});
|
|
1742
|
-
if (activatedEcdsa.installed) installedEcdsaRuntime = activatedEcdsa.runtime;
|
|
1743
|
-
}
|
|
1744
|
-
let loginResult;
|
|
1745
|
-
if (ed25519Material && unlocked.ed25519Activation.bootstrap) {
|
|
1746
|
-
const ed25519Session = linkedDeviceEd25519SessionFromEmailOtpBootstrap({
|
|
1747
|
-
session: unlocked.ed25519Activation.bootstrap.session,
|
|
1748
|
-
operationCredential: unlocked.operationCredential,
|
|
1749
|
-
providerIdentity: effectiveProviderIdentity
|
|
1750
|
-
});
|
|
1751
|
-
if (ed25519Session.walletSessionId !== unlocked.operationCredential.walletSessionId) throw new Error("[login] linked Email OTP Ed25519 session credential mismatch");
|
|
1752
|
-
loginResult = await activateLinkedDeviceEd25519Runtime({
|
|
1753
|
-
context: args.context,
|
|
1754
|
-
selection,
|
|
1755
|
-
session: ed25519Session,
|
|
1756
|
-
material: ed25519Material,
|
|
1757
|
-
relayerUrl: relayUrl,
|
|
1758
|
-
providerIdentity: effectiveProviderIdentity
|
|
1759
|
-
});
|
|
1760
|
-
} else if (ecdsaMaterial) loginResult = {
|
|
1761
|
-
success: true,
|
|
1762
|
-
kind: "ecdsa_wallet_unlocked",
|
|
1763
|
-
walletId: selection.walletId
|
|
1764
|
-
};
|
|
1765
|
-
else throw new Error("[login] linked Email OTP has no unlockable signing runtime");
|
|
1766
|
-
await walletSessionAuthorizations.writeExactWithOperationCredential({
|
|
1767
|
-
record: unlocked.walletSession,
|
|
1768
|
-
operationCredential: unlocked.operationCredential
|
|
1769
|
-
});
|
|
1770
|
-
if (selection.exportRoot && isWalletCustodySeedBinding(selection.exportRoot.envelope.binding)) await establishUnlockedWalletEd25519ExportRootCapabilityV1(walletCustodyCeremonyTransportFromWorkerContextV1(args.context.signingEngine.getSignerWorkerContext()), {
|
|
1771
|
-
existingEnvelope: selection.exportRoot.envelope,
|
|
1772
|
-
existingFactorSecret: factorSecret32,
|
|
1773
|
-
walletId: String(selection.walletId),
|
|
1774
|
-
walletAuthMethodId: String(selection.authMethod.walletAuthMethodId),
|
|
1775
|
-
walletSessionId: String(unlocked.operationCredential.walletSessionId),
|
|
1776
|
-
expiresAtMs: unlocked.walletSession.expiresAtMs
|
|
1777
|
-
});
|
|
1778
|
-
await args.context.signingEngine.markWalletSelectionUnlocked({
|
|
1779
|
-
walletId: selection.walletId,
|
|
1780
|
-
walletAuthMethodId: selection.authMethod.walletAuthMethodId
|
|
1781
|
-
});
|
|
1782
|
-
args.context.signingEngine.setWalletAuthenticated({
|
|
1783
|
-
kind: "authenticated",
|
|
1784
|
-
walletId: loginResult.walletId,
|
|
1785
|
-
authMethod: SIGNER_AUTH_METHODS.emailOtp
|
|
1786
|
-
});
|
|
1787
|
-
} catch (error) {
|
|
1788
|
-
if (installedEcdsaRuntime) {
|
|
1789
|
-
removeLinkedEcdsaHolderRuntimeV1({
|
|
1790
|
-
walletId: installedEcdsaRuntime.walletId,
|
|
1791
|
-
materialActivation: installedEcdsaRuntime.materialActivation,
|
|
1792
|
-
holderHandleId: installedEcdsaRuntime.holderHandleId
|
|
1793
|
-
});
|
|
1794
|
-
await destroyLinkedDeviceEcdsaHolderMaterialWasm({
|
|
1795
|
-
holderHandleId: installedEcdsaRuntime.holderHandleId,
|
|
1796
|
-
workerCtx: args.context.signingEngine.getSignerWorkerContext()
|
|
1797
|
-
}).catch(() => void 0);
|
|
1798
|
-
}
|
|
1799
|
-
const workerContext = args.context.signingEngine.getSignerWorkerContext();
|
|
1800
|
-
if (workerContext) await destroyUnlockedWalletEd25519ExportRootCapabilitiesV1(walletCustodyCeremonyTransportFromWorkerContextV1(workerContext), {
|
|
1801
|
-
kind: "wallet_session",
|
|
1802
|
-
walletSessionId: String(unlocked.operationCredential.walletSessionId)
|
|
1803
|
-
});
|
|
1804
|
-
await Promise.allSettled([args.context.signingEngine.clearVolatileWarmSigningMaterial(selection.walletId), walletSessionAuthorizations.clearWallet(selection.walletId)]);
|
|
1805
|
-
throw error;
|
|
1806
|
-
} finally {
|
|
1807
|
-
if (ownedActiveClientHandle) {
|
|
1808
|
-
const workerContext = args.context.signingEngine.getSignerWorkerContext();
|
|
1809
|
-
if (workerContext) await disposeWalletCustodyEd25519ActiveClientV1({
|
|
1810
|
-
workerContext,
|
|
1811
|
-
activeClientHandle: ownedActiveClientHandle
|
|
1812
|
-
}).catch(() => void 0);
|
|
1813
|
-
ownedActiveClientHandle = null;
|
|
1814
|
-
}
|
|
1815
|
-
for (const openedMaterial of openedMaterials || []) openedMaterial.material.fill(0);
|
|
1816
|
-
factorSecret32?.fill(0);
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
async function unlockInternal(context, subjectSet, options, _completion) {
|
|
1820
|
-
const { onEvent, onError, afterCall } = options || {};
|
|
1821
|
-
const { signingEngine } = context;
|
|
1822
|
-
const walletUnlockSelection = resolveLoginWalletUnlockSelectionForSubjectSet({
|
|
1823
|
-
selection: options?.unlockSelection,
|
|
1824
|
-
subjectSet
|
|
1825
|
-
});
|
|
1826
|
-
const walletIdentity = resolveLoginWalletIdentity({
|
|
1827
|
-
subjectSet,
|
|
1828
|
-
selection: walletUnlockSelection
|
|
1829
|
-
});
|
|
1830
|
-
const unlockSubjectId = walletIdentity.kind === "near_ed25519_capable_wallet" ? String(walletIdentity.nearAccountId) : String(walletIdentity.walletId);
|
|
1831
|
-
let loginCredential;
|
|
1832
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
1833
|
-
phase: UnlockEventPhase.STEP_01_STARTED,
|
|
1834
|
-
status: "started",
|
|
1835
|
-
authMethod: "passkey"
|
|
1836
|
-
});
|
|
1837
|
-
try {
|
|
1838
|
-
signingEngine.assertSealedRefreshStartupParity().catch((error) => {
|
|
1839
|
-
console.warn("[login] sealed refresh startup parity check failed during unlock; continuing to local passkey prompt", error instanceof Error ? error.message : String(error || "unknown error"));
|
|
1840
|
-
});
|
|
1841
|
-
if (typeof window !== "undefined" && !window.isSecureContext) {
|
|
1842
|
-
const errorMessage = "Passkey operations require a secure context (HTTPS or localhost).";
|
|
1843
|
-
return await finalizeLoginError({
|
|
1844
|
-
unlockSubjectId,
|
|
1845
|
-
message: errorMessage,
|
|
1846
|
-
error: new Error(errorMessage),
|
|
1847
|
-
onEvent,
|
|
1848
|
-
onError,
|
|
1849
|
-
afterCall,
|
|
1850
|
-
callAfterCall: false
|
|
1851
|
-
});
|
|
1852
|
-
}
|
|
1853
|
-
const { accountSubject, authenticators, baseSignerSlot, localUnlockAuthMethod, requiresLocalPasskeyUnlock } = await readLoginUnlockAccountPhase({
|
|
1854
|
-
signingEngine,
|
|
1855
|
-
identity: walletIdentity,
|
|
1856
|
-
signerSlotHint: parseSignerSlot(options?.signerSlot, { min: 1 }),
|
|
1857
|
-
onEvent
|
|
1858
|
-
});
|
|
1859
|
-
const collectLocalPasskeyCredentialForChallenge = async (args) => {
|
|
1860
|
-
const eligibleAuthenticators = authenticatorsForCredentialIds({
|
|
1861
|
-
authenticators,
|
|
1862
|
-
credentialIds: args.credentialIds
|
|
1863
|
-
});
|
|
1864
|
-
const credential = await collectPasskeyLoginAssertion({
|
|
1865
|
-
signingEngine,
|
|
1866
|
-
subjectId: unlockSubjectId,
|
|
1867
|
-
challengeB64u: args.challengeB64u,
|
|
1868
|
-
authenticators: eligibleAuthenticators,
|
|
1869
|
-
onPromptStarted: () => {
|
|
1870
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
1871
|
-
phase: UnlockEventPhase.STEP_03_PASSKEY_PROMPT_STARTED,
|
|
1872
|
-
status: "waiting_for_user",
|
|
1873
|
-
authMethod: "passkey",
|
|
1874
|
-
interaction: {
|
|
1875
|
-
kind: "passkey_assert",
|
|
1876
|
-
overlay: "show"
|
|
1877
|
-
}
|
|
1878
|
-
});
|
|
1879
|
-
},
|
|
1880
|
-
onPromptSucceeded: () => {
|
|
1881
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
1882
|
-
phase: UnlockEventPhase.STEP_03_PASSKEY_PROMPT_SUCCEEDED,
|
|
1883
|
-
status: "succeeded",
|
|
1884
|
-
authMethod: "passkey",
|
|
1885
|
-
interaction: {
|
|
1886
|
-
kind: "passkey_assert",
|
|
1887
|
-
overlay: "hide"
|
|
1888
|
-
}
|
|
1889
|
-
});
|
|
1890
|
-
}
|
|
1891
|
-
});
|
|
1892
|
-
if (args.saveAsLoginCredential) loginCredential = credential;
|
|
1893
|
-
return credential;
|
|
1894
|
-
};
|
|
1895
|
-
const collectFreshLocalPasskeyUnlockCredentialForLogin = async () => {
|
|
1896
|
-
const credential = await collectFreshLocalPasskeyUnlockCredential({
|
|
1897
|
-
currentCredential: loginCredential,
|
|
1898
|
-
collectCredentialForChallenge: async (challengeB64u) => await collectLocalPasskeyCredentialForChallenge({
|
|
1899
|
-
challengeB64u,
|
|
1900
|
-
saveAsLoginCredential: true,
|
|
1901
|
-
credentialIds: resolveLoginPasskeyPromptCredentialIds({
|
|
1902
|
-
authenticators,
|
|
1903
|
-
signerSlot: baseSignerSlot,
|
|
1904
|
-
serverCredentialIds: []
|
|
1905
|
-
})
|
|
1906
|
-
})
|
|
1907
|
-
});
|
|
1908
|
-
if (credential) loginCredential = credential;
|
|
1909
|
-
};
|
|
1910
|
-
const signingSessionPolicy = (() => {
|
|
1911
|
-
const ttlMsRaw = options?.signingSession?.ttlMs ?? context.configs?.signing.sessionDefaults?.ttlMs;
|
|
1912
|
-
const configuredRemainingUses = options?.signingSession?.remainingUses;
|
|
1913
|
-
const defaultRemainingUses = context.configs?.signing.sessionDefaults?.remainingUses;
|
|
1914
|
-
const requestedRemainingUses = configuredRemainingUses ?? defaultRemainingUses ?? DEFAULT_UNLOCK_REMAINING_USES;
|
|
1915
|
-
const ttlMs = typeof ttlMsRaw === "number" ? Math.floor(ttlMsRaw) : Math.floor(Number(ttlMsRaw) || 0);
|
|
1916
|
-
const unlockRemainingUses = resolveWalletUnlockSessionUsesFromRequestedUses({ requestedRemainingUses });
|
|
1917
|
-
return {
|
|
1918
|
-
ttlMs: Math.max(0, ttlMs),
|
|
1919
|
-
unlockRemainingUses
|
|
1920
|
-
};
|
|
1921
|
-
})();
|
|
1922
|
-
const requireThresholdWarmup = signingSessionPolicy.ttlMs > 0 && signingSessionPolicy.unlockRemainingUses != null;
|
|
1923
|
-
const thresholdKeyMaterialPrefetch = requireThresholdWarmup && walletIdentity.kind === "near_ed25519_capable_wallet" ? getNearThresholdKeyMaterial({
|
|
1924
|
-
clientDB: IndexedDBManager,
|
|
1925
|
-
keyMaterialStore: IndexedDBManager
|
|
1926
|
-
}, walletIdentity.nearAccountId, baseSignerSlot).catch(() => null) : Promise.resolve(null);
|
|
1927
|
-
let completedPasskeyExchangeEcdsaActivation = null;
|
|
1928
|
-
let completedPasskeyEd25519Session = null;
|
|
1929
|
-
let completedPasskeyWalletSessionAuthorization = null;
|
|
1930
|
-
let completedPasskeySessionCustody = null;
|
|
1931
|
-
let localWarmupRouteAuthorization = resolveLoginWarmupRouteAuthorization();
|
|
1932
|
-
let warmupPhase = null;
|
|
1933
|
-
const requireActiveWarmSession = (source, sessionStatus) => {
|
|
1934
|
-
if (isActiveThresholdLoginSigningSession(sessionStatus)) return sessionStatus;
|
|
1935
|
-
const status = String(sessionStatus?.status || "not_found");
|
|
1936
|
-
throw new Error(`[login] ${source} did not produce an active warm signing session (status=${status})`);
|
|
1937
|
-
};
|
|
1938
|
-
const warmThresholdSigningSessions = async (warmupInput) => {
|
|
1939
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
1940
|
-
phase: UnlockEventPhase.STEP_05_SIGNING_SESSION_WARMUP_STARTED,
|
|
1941
|
-
status: "running",
|
|
1942
|
-
authMethod: loginCredential ? "passkey" : "warm_session"
|
|
1943
|
-
});
|
|
1944
|
-
const nearWalletBinding = warmupInput.wantsEd25519Warmup ? requireNearLoginWalletBinding(walletIdentity) : null;
|
|
1945
|
-
const managedRuntimeScopeBootstrap = resolveManagedRuntimeScopeBootstrap(context.configs);
|
|
1946
|
-
let volatileWarmMaterialCleared = false;
|
|
1947
|
-
const clearVolatileWarmMaterialForUnlock = async () => {
|
|
1948
|
-
if (volatileWarmMaterialCleared) return;
|
|
1949
|
-
volatileWarmMaterialCleared = true;
|
|
1950
|
-
await signingEngine.clearVolatileWarmSigningMaterial(walletIdentity.walletId);
|
|
1951
|
-
};
|
|
1952
|
-
if (warmupInput.wantsEcdsaWarmup) reportNonSettledEcdsaActivationReconciliation(await reconcileCanonicalEcdsaActivationSelectors({
|
|
1953
|
-
workerCtx: signingEngine.getSignerWorkerContext(),
|
|
1954
|
-
selectors: ecdsaActivationSelectorsFromSubjectSet(walletIdentity.subjectSet)
|
|
1955
|
-
}));
|
|
1956
|
-
const storedCanonicalEcdsaContext = warmupInput.wantsEcdsaWarmup ? await resolveCanonicalThresholdEcdsaWarmSessionContext(context, walletIdentity.walletId, {
|
|
1957
|
-
keyFactsInventoryAuthority: warmupInput.keyFactsInventoryAuthority,
|
|
1958
|
-
keyFactsInventoryRequested: Boolean(options?.ecdsaKeyFactsInventory),
|
|
1959
|
-
relayerUrl: warmupInput.relayerUrl,
|
|
1960
|
-
rpId: warmupInput.rpId
|
|
1961
|
-
}, localUnlockAuthMethod) : { ecdsaKeys: [] };
|
|
1962
|
-
const thresholdKeyMaterial = await thresholdKeyMaterialPrefetch;
|
|
1963
|
-
const participantIds = thresholdKeyMaterial?.participants.map((participant) => participant.id) || [];
|
|
1964
|
-
if (warmupInput.wantsEcdsaWarmup) assertEcdsaWarmupMatchesUnlockSubjects({
|
|
1965
|
-
identity: walletIdentity,
|
|
1966
|
-
context: storedCanonicalEcdsaContext
|
|
1967
|
-
});
|
|
1968
|
-
const warmupPlan = resolveThresholdLoginWarmupPlan({
|
|
1969
|
-
selection: warmupInput.selection,
|
|
1970
|
-
selectedEcdsaTargets: warmupInput.selectedEcdsaTargets,
|
|
1971
|
-
storedCanonicalEcdsaContext,
|
|
1972
|
-
wantsEd25519Warmup: warmupInput.wantsEd25519Warmup
|
|
1973
|
-
});
|
|
1974
|
-
const passkeyExchangeEcdsaActivationForWarmup = completedPasskeyExchangeEcdsaActivation;
|
|
1975
|
-
const passkeyExchangeOwnsFirstEcdsaActivation = Boolean(passkeyExchangeEcdsaActivationForWarmup && warmupPlan.signersToWarm.includes("ecdsa"));
|
|
1976
|
-
const ed25519DependsOnEcdsa = passkeyExchangeOwnsFirstEcdsaActivation ? warmupPlan.signersToWarm.includes("ed25519") : warmupPlan.ed25519DependsOnEcdsa;
|
|
1977
|
-
const ecdsaDependsOnEd25519 = passkeyExchangeOwnsFirstEcdsaActivation ? false : warmupPlan.ecdsaDependsOnEd25519;
|
|
1978
|
-
const warmupPasskeyCredentialPlan = resolveLoginWarmupPasskeyCredentialPlan({
|
|
1979
|
-
requiresLocalPasskeyUnlock,
|
|
1980
|
-
hasLoginCredential: Boolean(loginCredential),
|
|
1981
|
-
routeAuthorization: warmupInput.routeAuthorization,
|
|
1982
|
-
warmupPlan
|
|
1983
|
-
});
|
|
1984
|
-
await clearVolatileWarmMaterialForUnlock();
|
|
1985
|
-
const plannedEd25519SessionId = createThresholdLoginWarmSessionId("threshold-login");
|
|
1986
|
-
let ed25519MintPlan = !warmupPlan.signersToWarm.includes("ed25519") ? { kind: "not_requested" } : ed25519DependsOnEcdsa ? {
|
|
1987
|
-
kind: "ecdsa_authorized",
|
|
1988
|
-
thresholdSessionId: plannedEd25519SessionId
|
|
1989
|
-
} : { kind: "fresh" };
|
|
1990
|
-
switch (warmupPasskeyCredentialPlan.kind) {
|
|
1991
|
-
case "existing_passkey_credential":
|
|
1992
|
-
case "no_passkey_credential_required": break;
|
|
1993
|
-
case "wallet_custody":
|
|
1994
|
-
if (warmupInput.ed25519SessionAuthority.kind !== "passkey") throw new Error("[login] wallet custody requires passkey wallet authority");
|
|
1995
|
-
if (!completedPasskeySessionCustody || completedPasskeySessionCustody.ed25519.kind !== "active") throw createThresholdEd25519DeviceLinkRequiredError();
|
|
1996
|
-
ed25519MintPlan = {
|
|
1997
|
-
kind: "wallet_custody",
|
|
1998
|
-
thresholdSessionId: plannedEd25519SessionId,
|
|
1999
|
-
custody: {
|
|
2000
|
-
...completedPasskeySessionCustody,
|
|
2001
|
-
ed25519: completedPasskeySessionCustody.ed25519
|
|
2002
|
-
}
|
|
2003
|
-
};
|
|
2004
|
-
break;
|
|
2005
|
-
default: return assertNeverLoginState(warmupPasskeyCredentialPlan);
|
|
2006
|
-
}
|
|
2007
|
-
if (nearWalletBinding && !thresholdKeyMaterial && ed25519MintPlan.kind !== "wallet_custody") throw new Error(`[login] threshold warm-up requires threshold key material for ${nearWalletBinding.nearAccountId} signer slot ${warmupInput.signerSlot}`);
|
|
2008
|
-
const authenticatedPasskeyCredentialIdB64u = loginCredential ? passkeyCredentialIdB64uFromAuthentication(loginCredential) : "";
|
|
2009
|
-
const localPasskeyCredentialIdB64u = String(authenticatedPasskeyCredentialIdB64u || authenticators.find((authenticator) => authenticator.signerSlot === baseSignerSlot)?.credentialId || authenticators[0]?.credentialId || "").trim();
|
|
2010
|
-
const credentialState = loginCredential ? {
|
|
2011
|
-
kind: "available",
|
|
2012
|
-
credential: loginCredential,
|
|
2013
|
-
localPasskeyCredentialIdB64u
|
|
2014
|
-
} : localPasskeyCredentialIdB64u ? {
|
|
2015
|
-
kind: "credential_id_only",
|
|
2016
|
-
localPasskeyCredentialIdB64u
|
|
2017
|
-
} : {
|
|
2018
|
-
kind: "unavailable",
|
|
2019
|
-
localPasskeyCredentialIdB64u: ""
|
|
2020
|
-
};
|
|
2021
|
-
const runtimeScopeBootstrapState = managedRuntimeScopeBootstrap ? {
|
|
2022
|
-
kind: "available",
|
|
2023
|
-
runtimeScopeBootstrap: managedRuntimeScopeBootstrap
|
|
2024
|
-
} : { kind: "unavailable" };
|
|
2025
|
-
const warmupResult = await primeThresholdLoginWarmSigners({
|
|
2026
|
-
statusReads,
|
|
2027
|
-
context,
|
|
2028
|
-
signingEngine,
|
|
2029
|
-
walletIdentity,
|
|
2030
|
-
signerSlot: warmupInput.signerSlot,
|
|
2031
|
-
thresholdKeyMaterial,
|
|
2032
|
-
relayerUrl: warmupInput.relayerUrl,
|
|
2033
|
-
relayerKeyId: thresholdKeyMaterial?.relayerKeyId || "",
|
|
2034
|
-
participantIds,
|
|
2035
|
-
ttlMs: signingSessionPolicy.ttlMs,
|
|
2036
|
-
unlockRemainingUses: requireLoginUnlockSessionUses(signingSessionPolicy.unlockRemainingUses),
|
|
2037
|
-
ecdsaContext: warmupPlan.ecdsaContext,
|
|
2038
|
-
credentialState,
|
|
2039
|
-
runtimeScopeBootstrapState,
|
|
2040
|
-
signersToWarm: warmupPlan.signersToWarm,
|
|
2041
|
-
ed25519DependsOnEcdsa,
|
|
2042
|
-
ecdsaDependency: ecdsaDependsOnEd25519 ? { kind: "ed25519_wallet_session_authority" } : { kind: "none" },
|
|
2043
|
-
ed25519MintPlan,
|
|
2044
|
-
ed25519SessionAuthority: warmupInput.ed25519SessionAuthority,
|
|
2045
|
-
routeAuthorization: warmupInput.routeAuthorization,
|
|
2046
|
-
passkeyExchangeEcdsaActivation: passkeyExchangeEcdsaActivationForWarmup,
|
|
2047
|
-
passkeyUnlockEd25519Session: completedPasskeyEd25519Session,
|
|
2048
|
-
passkeyUnlockWalletSessionAuthorization: completedPasskeyWalletSessionAuthorization
|
|
2049
|
-
});
|
|
2050
|
-
if (warmupPlan.signersToWarm.includes("ed25519")) {
|
|
2051
|
-
const ed25519Session = warmupResult.ed25519Session;
|
|
2052
|
-
if (!ed25519Session) throw new Error("[login] threshold warm-up omitted the Ed25519 session result");
|
|
2053
|
-
const activeSigningSession = requireActiveWarmSession("threshold warm-up", createActiveLoginSigningSessionStatus({
|
|
2054
|
-
session: ed25519Session,
|
|
2055
|
-
authMethod: localUnlockAuthMethod
|
|
2056
|
-
}));
|
|
2057
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
2058
|
-
phase: UnlockEventPhase.STEP_05_ED25519_SIGNING_SESSION_READY,
|
|
2059
|
-
status: "succeeded",
|
|
2060
|
-
authMethod: "warm_session"
|
|
2061
|
-
});
|
|
2062
|
-
if (warmupPlan.signersToWarm.includes("ecdsa")) emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
2063
|
-
phase: UnlockEventPhase.STEP_05_ECDSA_SIGNING_SESSION_READY,
|
|
2064
|
-
status: "succeeded",
|
|
2065
|
-
authMethod: "warm_session"
|
|
2066
|
-
});
|
|
2067
|
-
return {
|
|
2068
|
-
kind: "threshold_login_warmup_ready",
|
|
2069
|
-
signingSession: activeSigningSession,
|
|
2070
|
-
signersWarmed: warmupPlan.signersToWarm
|
|
2071
|
-
};
|
|
2072
|
-
}
|
|
2073
|
-
if (warmupPlan.signersToWarm.length !== 1 || warmupPlan.signersToWarm[0] !== "ecdsa") throw new Error("[login] threshold warm-up signer selection is invalid");
|
|
2074
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
2075
|
-
phase: UnlockEventPhase.STEP_05_ECDSA_SIGNING_SESSION_READY,
|
|
2076
|
-
status: "succeeded",
|
|
2077
|
-
authMethod: "warm_session"
|
|
2078
|
-
});
|
|
2079
|
-
return {
|
|
2080
|
-
kind: "threshold_login_ecdsa_only_warmup_ready",
|
|
2081
|
-
signersWarmed: ["ecdsa"]
|
|
2082
|
-
};
|
|
2083
|
-
};
|
|
2084
|
-
const persistSuccessfulLoginState = async (signerSlot) => {
|
|
2085
|
-
await signingEngine.setLastUser(walletIdentity.walletId, signerSlot);
|
|
2086
|
-
if (walletIdentity.kind === "near_ed25519_capable_wallet") {
|
|
2087
|
-
if (!(accountSubject.kind === "near_wallet" && accountSubject.operationalPublicKey === null)) await signingEngine.activateAuthenticatedWalletState({
|
|
2088
|
-
walletId: walletIdentity.walletId,
|
|
2089
|
-
nearAccountId: toAccountId(walletIdentity.nearAccountId),
|
|
2090
|
-
signerSlot,
|
|
2091
|
-
nearClient: context.nearClient
|
|
2092
|
-
});
|
|
2093
|
-
}
|
|
2094
|
-
};
|
|
2095
|
-
const recoverNonceLanesAfterUnlock = async () => {
|
|
2096
|
-
await signingEngine.getNonceCoordinator().recoverDurableLeases({ walletId: walletIdentity.walletId }).catch((error) => {
|
|
2097
|
-
console.warn("[login] nonce lane durable recovery after unlock failed", error);
|
|
2098
|
-
});
|
|
2099
|
-
};
|
|
2100
|
-
const noServerSessionPasskeyCredentialPlan = resolveLoginNoServerSessionPasskeyCredentialPlan({
|
|
2101
|
-
requiresLocalPasskeyUnlock,
|
|
2102
|
-
requireThresholdWarmup,
|
|
2103
|
-
hasLoginCredential: Boolean(loginCredential)
|
|
2104
|
-
});
|
|
2105
|
-
switch (noServerSessionPasskeyCredentialPlan.kind) {
|
|
2106
|
-
case "wallet_unlock_owns_passkey_credential":
|
|
2107
|
-
case "passkey_credential_already_collected":
|
|
2108
|
-
case "no_local_passkey_required": break;
|
|
2109
|
-
case "local_unlock_passkey_assertion":
|
|
2110
|
-
await collectFreshLocalPasskeyUnlockCredentialForLogin();
|
|
2111
|
-
break;
|
|
2112
|
-
default: return assertNeverLoginState(noServerSessionPasskeyCredentialPlan);
|
|
2113
|
-
}
|
|
2114
|
-
const statusReads = new WalletSessionStatusReadScope();
|
|
2115
|
-
if (requireThresholdWarmup && localUnlockAuthMethod === SIGNER_AUTH_METHODS.passkey) {
|
|
2116
|
-
const preparedActivation = await preparePasskeyExchangeEcdsaActivation({
|
|
2117
|
-
context,
|
|
2118
|
-
walletIdentity,
|
|
2119
|
-
selection: walletUnlockSelection,
|
|
2120
|
-
ttlMs: signingSessionPolicy.ttlMs,
|
|
2121
|
-
remainingUses: requireLoginUnlockSessionUses(signingSessionPolicy.unlockRemainingUses)
|
|
2122
|
-
});
|
|
2123
|
-
const relayUrl = String(context.configs.network.relayer.url || "").trim();
|
|
2124
|
-
const rpId = String(signingEngine.getRpId() || "").trim();
|
|
2125
|
-
if (!relayUrl || !rpId) throw new Error("[login] passkey wallet unlock requires relayer URL and rpId");
|
|
2126
|
-
const completedUnlock = await completePasskeyWalletUnlock({
|
|
2127
|
-
context,
|
|
2128
|
-
walletIdentity,
|
|
2129
|
-
unlockSubjectId,
|
|
2130
|
-
onEvent,
|
|
2131
|
-
authenticators,
|
|
2132
|
-
signerSlot: baseSignerSlot,
|
|
2133
|
-
remainingUses: requireLoginUnlockSessionUses(signingSessionPolicy.unlockRemainingUses),
|
|
2134
|
-
relayUrl,
|
|
2135
|
-
rpId,
|
|
2136
|
-
expectedOrigin: void 0,
|
|
2137
|
-
activation: preparedActivation,
|
|
2138
|
-
collectCredentialForChallenge: async (challenge) => await collectLocalPasskeyCredentialForChallenge({
|
|
2139
|
-
challengeB64u: challenge.challengeB64u,
|
|
2140
|
-
saveAsLoginCredential: true,
|
|
2141
|
-
credentialIds: challenge.credentialIds
|
|
2142
|
-
})
|
|
2143
|
-
}, statusReads);
|
|
2144
|
-
loginCredential = completedUnlock.credential;
|
|
2145
|
-
completedPasskeyExchangeEcdsaActivation = completedUnlock.activation;
|
|
2146
|
-
completedPasskeyEd25519Session = completedUnlock.result.ed25519Session;
|
|
2147
|
-
completedPasskeyWalletSessionAuthorization = completedUnlock.result.walletSessionAuthorization ?? (completedUnlock.activation ? exactAuthorizationFromPasskeyEcdsaActivation(completedUnlock.activation.sessionActivation) : null);
|
|
2148
|
-
completedPasskeySessionCustody = completedUnlock.custody;
|
|
2149
|
-
await rememberPasskeySessionCustodyForExport({
|
|
2150
|
-
walletId: String(walletIdentity.walletId),
|
|
2151
|
-
unlock: completedUnlock
|
|
2152
|
-
});
|
|
2153
|
-
localWarmupRouteAuthorization = resolveLoginWarmupRouteAuthorization();
|
|
2154
|
-
}
|
|
2155
|
-
if (!loginCredential) throw new Error("[login] successful Passkey unlock omitted its credential");
|
|
2156
|
-
await markPasskeyLoginSelectionUnlocked({
|
|
2157
|
-
context,
|
|
2158
|
-
walletIdentity,
|
|
2159
|
-
credential: loginCredential
|
|
2160
|
-
});
|
|
2161
|
-
if (requireThresholdWarmup) {
|
|
2162
|
-
const authMethodBinding = await readThresholdWarmupAuthMethodBinding({
|
|
2163
|
-
walletId: walletIdentity.walletId,
|
|
2164
|
-
authMethod: localUnlockAuthMethod
|
|
2165
|
-
});
|
|
2166
|
-
const keyFactsInventoryAuthority = resolveUnlockEcdsaKeyFactsInventoryAuthority({
|
|
2167
|
-
completedActivation: completedPasskeyExchangeEcdsaActivation,
|
|
2168
|
-
request: options?.ecdsaKeyFactsInventory,
|
|
2169
|
-
routeAuthorization: localWarmupRouteAuthorization,
|
|
2170
|
-
wantsEcdsaWarmup: resolveLoginUnlockWarmupBranchPlan({
|
|
2171
|
-
subjectSet: walletIdentity.subjectSet,
|
|
2172
|
-
selection: walletUnlockSelection,
|
|
2173
|
-
hasConfiguredEcdsaTargets: listConfiguredThresholdEcdsaPublicationTargets(context.configs.network.chains).length > 0
|
|
2174
|
-
}).wantsEcdsaWarmup
|
|
2175
|
-
});
|
|
2176
|
-
warmupPhase = await warmThresholdSigningSessions(resolveThresholdLoginWarmupPhaseInput({
|
|
2177
|
-
context,
|
|
2178
|
-
signerSlot: baseSignerSlot,
|
|
2179
|
-
authenticators,
|
|
2180
|
-
selection: walletUnlockSelection,
|
|
2181
|
-
subjectSet: walletIdentity.subjectSet,
|
|
2182
|
-
authMethod: localUnlockAuthMethod,
|
|
2183
|
-
authMethodBinding,
|
|
2184
|
-
keyFactsInventoryAuthority,
|
|
2185
|
-
routeAuthorization: localWarmupRouteAuthorization
|
|
2186
|
-
}));
|
|
2187
|
-
if (localUnlockAuthMethod === SIGNER_AUTH_METHODS.passkey) {
|
|
2188
|
-
const authenticatedCredential = loginCredential;
|
|
2189
|
-
if (!authenticatedCredential) throw new Error("[login] passkey threshold warm-up completed without a credential");
|
|
2190
|
-
await assertPasskeyUnlockRuntimePostconditions({
|
|
2191
|
-
context,
|
|
2192
|
-
statusReads,
|
|
2193
|
-
walletIdentity,
|
|
2194
|
-
signersWarmed: warmupPhase.signersWarmed,
|
|
2195
|
-
credential: authenticatedCredential
|
|
2196
|
-
});
|
|
2197
|
-
}
|
|
2198
|
-
}
|
|
2199
|
-
await persistSuccessfulLoginState(baseSignerSlot);
|
|
2200
|
-
recoverNonceLanesAfterUnlock();
|
|
2201
|
-
if (completedPasskeyWalletSessionAuthorization && loginCredential && completedPasskeySessionCustody) {
|
|
2202
|
-
const prfFirstB64u = passkeyPrfFirstB64uFromCredential(loginCredential);
|
|
2203
|
-
if (prfFirstB64u) resumeNearAfterSuccessfulUnlock({
|
|
2204
|
-
context,
|
|
2205
|
-
sessionAuthority: completedPasskeyWalletSessionAuthorization,
|
|
2206
|
-
factor: {
|
|
2207
|
-
kind: "passkey",
|
|
2208
|
-
rpId: signingEngine.getRpId(),
|
|
2209
|
-
credentialIdB64u: passkeyCredentialIdB64uFromAuthentication(loginCredential),
|
|
2210
|
-
prfFirstB64u
|
|
2211
|
-
},
|
|
2212
|
-
ownedFactorSecret: base64UrlDecode(prfFirstB64u).slice().buffer,
|
|
2213
|
-
custodyEnvelope: completedPasskeySessionCustody.envelope
|
|
2214
|
-
});
|
|
2215
|
-
}
|
|
2216
|
-
const baseLoginResult = buildSuccessfulLoginResult({
|
|
2217
|
-
identity: walletIdentity,
|
|
2218
|
-
accountSubject
|
|
2219
|
-
});
|
|
2220
|
-
const loginResult = warmupPhase ? {
|
|
2221
|
-
...baseLoginResult,
|
|
2222
|
-
...warmupPhase.kind === "threshold_login_warmup_ready" ? { signingSession: warmupPhase.signingSession } : {}
|
|
2223
|
-
} : baseLoginResult;
|
|
2224
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
2225
|
-
phase: UnlockEventPhase.STEP_06_SESSION_READY,
|
|
2226
|
-
status: "succeeded",
|
|
2227
|
-
authMethod: loginCredential ? "passkey" : void 0
|
|
2228
|
-
});
|
|
2229
|
-
return await finalizeLoginSuccess({
|
|
2230
|
-
context,
|
|
2231
|
-
authMethod: localUnlockAuthMethod,
|
|
2232
|
-
unlockSubjectId,
|
|
2233
|
-
loginResult,
|
|
2234
|
-
onEvent,
|
|
2235
|
-
afterCall
|
|
2236
|
-
});
|
|
2237
|
-
} catch (err) {
|
|
2238
|
-
console.warn("[login] unlock failed before active session commit", {
|
|
2239
|
-
unlockSubjectId,
|
|
2240
|
-
message: err && typeof err === "object" && "message" in err ? String(err.message || "") : String(err || "")
|
|
2241
|
-
});
|
|
2242
|
-
await clearFailedUnlockSessionState({
|
|
2243
|
-
context,
|
|
2244
|
-
walletId: walletIdentity.walletId
|
|
2245
|
-
});
|
|
2246
|
-
return await finalizeLoginError({
|
|
2247
|
-
unlockSubjectId,
|
|
2248
|
-
message: getUserFriendlyErrorMessage(err, "login") || "Login failed",
|
|
2249
|
-
error: err,
|
|
2250
|
-
cancelled: isUserCancellationError(err),
|
|
2251
|
-
onEvent,
|
|
2252
|
-
onError,
|
|
2253
|
-
afterCall
|
|
2254
|
-
});
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
|
-
async function clearFailedUnlockSessionState(args) {
|
|
2258
|
-
await IndexedDBManager.clearLastProfileSelection().catch(() => void 0);
|
|
2259
|
-
try {
|
|
2260
|
-
args.context.signingEngine.getNonceCoordinator().clearAll();
|
|
2261
|
-
} catch {}
|
|
2262
|
-
try {
|
|
2263
|
-
await args.context.signingEngine.clearVolatileWarmSigningMaterial(args.walletId);
|
|
2264
|
-
} catch {}
|
|
2265
|
-
}
|
|
2266
|
-
async function finalizeLoginSuccess(args) {
|
|
2267
|
-
const { context, authMethod, unlockSubjectId, loginResult, onEvent, afterCall } = args;
|
|
2268
|
-
if (loginResult.success) context.signingEngine.setWalletAuthenticated({
|
|
2269
|
-
kind: "authenticated",
|
|
2270
|
-
walletId: loginResult.walletId,
|
|
2271
|
-
authMethod
|
|
2272
|
-
});
|
|
2273
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
2274
|
-
phase: UnlockEventPhase.STEP_07_COMPLETED,
|
|
2275
|
-
status: "succeeded",
|
|
2276
|
-
data: { ...loginResult.success && loginResult.kind === "near_wallet_unlocked" ? { operationalPublicKey: loginResult.operationalPublicKey ?? "" } : { walletId: loginResult.success ? String(loginResult.walletId) : "" } }
|
|
2277
|
-
});
|
|
2278
|
-
await afterCall?.(true, loginResult);
|
|
2279
|
-
return loginResult;
|
|
2280
|
-
}
|
|
2281
|
-
async function finalizeLoginError(args) {
|
|
2282
|
-
const { message, unlockSubjectId, error, onEvent, onError, afterCall, callOnError = true, callAfterCall = true, cancelled = false } = args;
|
|
2283
|
-
if (callOnError) onError?.(toError(error));
|
|
2284
|
-
emitUnlockEvent(onEvent, unlockSubjectId, {
|
|
2285
|
-
phase: cancelled ? UnlockEventPhase.CANCELLED : UnlockEventPhase.FAILED,
|
|
2286
|
-
status: cancelled ? "cancelled" : "failed",
|
|
2287
|
-
...cancelled ? {} : { message },
|
|
2288
|
-
interaction: {
|
|
2289
|
-
kind: "passkey_assert",
|
|
2290
|
-
overlay: "hide"
|
|
2291
|
-
},
|
|
2292
|
-
error: { message }
|
|
2293
|
-
});
|
|
2294
|
-
if (callAfterCall) await afterCall?.(false);
|
|
2295
|
-
return {
|
|
2296
|
-
success: false,
|
|
2297
|
-
error: message
|
|
2298
|
-
};
|
|
2299
|
-
}
|
|
2300
|
-
function thresholdSessionIdFromPasskeyEcdsaActivation(activation) {
|
|
2301
|
-
return isEcdsaCredentialFreeSessionActivationAuthorization(activation) ? activation.activation.session.threshold_session_id : activation.session.threshold_session_id;
|
|
2302
|
-
}
|
|
2303
|
-
function exactAuthorizationFromPasskeyEcdsaActivation(activation) {
|
|
2304
|
-
if (isEcdsaCredentialFreeSessionActivationAuthorization(activation)) return activation.authorization;
|
|
2305
|
-
return {
|
|
2306
|
-
record: activation.session.wallet_session,
|
|
2307
|
-
operationCredential: activation.session.operation_credential
|
|
2308
|
-
};
|
|
2309
|
-
}
|
|
2310
|
-
function resolveUnlockEcdsaKeyFactsInventoryAuthority(args) {
|
|
2311
|
-
if (!args.wantsEcdsaWarmup) return null;
|
|
2312
|
-
if (args.completedActivation) {
|
|
2313
|
-
let operationCredential;
|
|
2314
|
-
try {
|
|
2315
|
-
const sessionActivation = args.completedActivation.sessionActivation;
|
|
2316
|
-
if (isEcdsaCredentialFreeSessionActivationAuthorization(sessionActivation)) operationCredential = parseWalletSessionOperationCredentialV1(sessionActivation.authorization.operationCredential);
|
|
2317
|
-
else {
|
|
2318
|
-
const response = args.completedActivation.response;
|
|
2319
|
-
if (response.kind !== "router_ab_ecdsa_post_registration_session_activated_v1") throw new Error("completed ECDSA unlock activation branch is invalid");
|
|
2320
|
-
operationCredential = parseWalletSessionOperationCredentialV1(response.session.operation_credential);
|
|
2321
|
-
}
|
|
2322
|
-
} catch {
|
|
2323
|
-
throw new Error("[login] completed ECDSA unlock omitted a valid Wallet Session operation credential");
|
|
2324
|
-
}
|
|
2325
|
-
return {
|
|
2326
|
-
kind: "wallet_session_operation_credential_v1",
|
|
2327
|
-
operationCredential
|
|
2328
|
-
};
|
|
2329
|
-
}
|
|
2330
|
-
const authority = resolveLoginEcdsaKeyFactsInventoryAuthority({
|
|
2331
|
-
request: args.request ?? null,
|
|
2332
|
-
routeAuthorization: args.routeAuthorization
|
|
2333
|
-
});
|
|
2334
|
-
if (authority?.kind === "webauthn") throw new Error("[login] ECDSA warm-up requires the Wallet Session minted by the unlock assertion");
|
|
2335
|
-
return authority;
|
|
2336
|
-
}
|
|
2337
|
-
function assertPasskeyEcdsaExchangeContinuity(args) {
|
|
2338
|
-
const signer = args.continuity.signers.find((candidate) => thresholdEcdsaChainTargetKey(candidate.chainTarget) === args.prepared.targetKey);
|
|
2339
|
-
if (!signer) throw new Error("Passkey ECDSA custody continuity omitted the requested chain target");
|
|
2340
|
-
const capability = signer.walletKey.publicCapability;
|
|
2341
|
-
const receipt = signer.activationReceipt;
|
|
2342
|
-
const activation = receipt.ecdsa_activation;
|
|
2343
|
-
const normalScope = args.response.normal_signing.scope;
|
|
2344
|
-
if (signer.walletKey.walletId !== args.walletId || signer.walletKey.keyHandle !== args.prepared.policy.key_handle || args.response.session.threshold_session_id !== args.prepared.policy.session_policy.threshold_session_id || !sameThresholdRuntimePolicyScope(signer.runtimePolicyScope, args.prepared.policy.session_policy.runtime_policy_scope) || !sameRouterAbEcdsaDerivationPublicCapabilityV1(args.response.public_capability, capability) || !sameRouterAbEcdsaRegistrationActivationReceiptV1(args.activationReceipt, receipt) || capability.context.application_binding_digest_b64u !== activation.context.application_binding_digest_b64u || !sameRouterAbEcdsaDerivationPublicIdentityV1(capability.public_identity, activation.public_identity) || !sameRouterAbMpcMaterialActivationRef(capability.material_activation, activation.material_activation) || !sameRouterAbServerIdentityV1(capability.signer_set.selected_server, activation.signing_worker) || capability.activation_epoch !== activation.activation_epoch || normalScope.context.application_binding_digest_b64u !== activation.context.application_binding_digest_b64u || !sameRouterAbEcdsaDerivationPublicIdentityV1(normalScope.public_identity, activation.public_identity) || !sameRouterAbMpcMaterialActivationRef(normalScope.material_activation, activation.material_activation) || !sameRouterAbServerIdentityV1(normalScope.signing_worker, activation.signing_worker) || normalScope.activation_epoch !== activation.activation_epoch || normalScope.wallet_id !== args.walletId || normalScope.ecdsa_threshold_key_id !== signer.walletKey.ecdsaThresholdKeyId || normalScope.signing_root_id !== signer.walletKey.signingRootId || normalScope.signing_root_version !== signer.walletKey.signingRootVersion) throw new Error("Passkey ECDSA session activation changed custody continuity");
|
|
2345
|
-
}
|
|
2346
|
-
function assertRejoinedPasskeyEcdsaPublicFacts(args) {
|
|
2347
|
-
const identity = args.signer.walletKey.publicCapability.public_identity;
|
|
2348
|
-
if (args.publicFacts.contextBinding32B64u !== identity.context_binding_b64u || args.publicFacts.derivationClientSharePublicKey33B64u !== identity.derivation_client_share_public_key33_b64u || args.publicFacts.relayerPublicKey33B64u !== identity.server_public_key33_b64u || args.publicFacts.groupPublicKey33B64u !== identity.threshold_public_key33_b64u || args.publicFacts.ethereumAddress !== ethereumAddressFromEcdsaIdentityB64u(identity.ethereum_address20_b64u) || args.publicFacts.clientShareRetryCounter !== identity.client_share_retry_counter || args.publicFacts.relayerShareRetryCounter !== identity.server_share_retry_counter) throw new Error("Passkey ECDSA custody rejoin changed registered public identity");
|
|
2349
|
-
}
|
|
2350
|
-
async function rememberPasskeySessionCustodyForExport(args) {
|
|
2351
|
-
const credentialIdB64u = String(args.unlock.credential.rawId || args.unlock.credential.id || "").trim();
|
|
2352
|
-
if (!credentialIdB64u) throw new Error("[login] passkey assertion credential id is missing");
|
|
2353
|
-
await rememberPasskeyCustodySessionEnvelope({
|
|
2354
|
-
walletId: args.walletId,
|
|
2355
|
-
credentialIdB64u,
|
|
2356
|
-
envelope: args.unlock.custody.envelope
|
|
2357
|
-
});
|
|
2358
|
-
}
|
|
2359
|
-
async function preparePasskeyExchangeEcdsaActivation(args) {
|
|
2360
|
-
const configuredTargets = listConfiguredThresholdEcdsaPublicationTargets(args.context.configs.network.chains);
|
|
2361
|
-
if (!resolveLoginUnlockWarmupBranchPlan({
|
|
2362
|
-
subjectSet: args.walletIdentity.subjectSet,
|
|
2363
|
-
selection: args.selection,
|
|
2364
|
-
hasConfiguredEcdsaTargets: configuredTargets.length > 0
|
|
2365
|
-
}).wantsEcdsaWarmup) return null;
|
|
2366
|
-
const target = configuredTargets[0];
|
|
2367
|
-
if (!target) return null;
|
|
2368
|
-
const context = await resolveCanonicalThresholdEcdsaWarmSessionContext(args.context, args.walletIdentity.walletId, void 0, "passkey");
|
|
2369
|
-
const targetKey = thresholdEcdsaChainTargetKey(target.chainTarget);
|
|
2370
|
-
const targetEcdsaKey = context.ecdsaKeys.find((candidate) => candidate.targetKey === targetKey);
|
|
2371
|
-
if (!targetEcdsaKey) throw createThresholdEcdsaDeviceLinkRequiredError(targetKey);
|
|
2372
|
-
const runtimePolicyScope = context.runtimePolicyScope;
|
|
2373
|
-
if (!runtimePolicyScope) throw new Error("[login] passkey ECDSA activation requires runtime policy scope");
|
|
2374
|
-
const thresholdSessionId = requireThresholdLoginEcdsaSessionId(createThresholdLoginWarmSessionId("threshold-ecdsa-login"));
|
|
2375
|
-
const walletSessionMintId = requireThresholdLoginWalletSessionMintId(createThresholdLoginWarmSessionId("wallet-session-mint"));
|
|
2376
|
-
return {
|
|
2377
|
-
targetKey,
|
|
2378
|
-
requiresCustodyRejoin: !targetEcdsaKey.existingRoleLocalMaterial,
|
|
2379
|
-
policy: {
|
|
2380
|
-
kind: "router_ab_ecdsa_post_registration_session_activation_policy_v1",
|
|
2381
|
-
key_handle: targetEcdsaKey.keyHandle,
|
|
2382
|
-
session_policy: {
|
|
2383
|
-
threshold_session_id: thresholdSessionId,
|
|
2384
|
-
wallet_session_mint_id: walletSessionMintId,
|
|
2385
|
-
ttl_ms: args.ttlMs,
|
|
2386
|
-
remaining_uses: args.remainingUses,
|
|
2387
|
-
runtime_policy_scope: runtimePolicyScope
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
};
|
|
2391
|
-
}
|
|
2392
|
-
function passkeyUnlockEd25519SessionRequest(args) {
|
|
2393
|
-
switch (args.walletIdentity.kind) {
|
|
2394
|
-
case "near_ed25519_capable_wallet": return {
|
|
2395
|
-
kind: "requested",
|
|
2396
|
-
remainingUses: args.remainingUses
|
|
2397
|
-
};
|
|
2398
|
-
case "evm_family_ecdsa_only_wallet": return { kind: "not_requested" };
|
|
2399
|
-
default: return assertNeverLoginState(args.walletIdentity);
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2402
|
-
function passkeyWalletUnlockInput(args) {
|
|
2403
|
-
if (args.activation) return {
|
|
2404
|
-
type: "passkey_assertion",
|
|
2405
|
-
challengeId: args.challengeId,
|
|
2406
|
-
walletId: String(args.walletIdentity.walletId),
|
|
2407
|
-
webauthn_authentication: args.credential,
|
|
2408
|
-
ed25519SessionRequest: args.ed25519SessionRequest,
|
|
2409
|
-
expected_origin: args.expectedOrigin,
|
|
2410
|
-
ecdsaSessionPolicy: args.activation.policy
|
|
2411
|
-
};
|
|
2412
|
-
return {
|
|
2413
|
-
type: "passkey_assertion",
|
|
2414
|
-
challengeId: args.challengeId,
|
|
2415
|
-
webauthn_authentication: args.credential,
|
|
2416
|
-
ed25519SessionRequest: args.ed25519SessionRequest,
|
|
2417
|
-
expected_origin: args.expectedOrigin
|
|
2418
|
-
};
|
|
2419
|
-
}
|
|
2420
|
-
async function resolveActivePasskeyWalletSessionAuthority(args) {
|
|
2421
|
-
const authMethod = await IndexedDBManager.getWalletAuthMethodV2(args.authorization.record.authMethodId);
|
|
2422
|
-
if (!authMethod || authMethod.kind !== "passkey" || authMethod.status !== "active" || authMethod.walletId !== args.walletId || authMethod.walletAuthorityId !== args.authorization.record.authorityId) throw new Error("Passkey Wallet Session authorization changed auth-method identity");
|
|
2423
|
-
const authority = await IndexedDBManager.getWalletAuthority(authMethod.walletAuthorityId);
|
|
2424
|
-
if (!authority || authority.state !== "active" || authority.walletId !== args.walletId || authority.authorityId !== args.authorization.record.authorityId || authority.authorityDigestB64u !== args.authorization.record.authorityDigestB64u || authority.revocationEpoch !== args.authorization.record.authorityRevocationEpoch) throw new Error("Passkey Wallet Session authorization changed authority identity");
|
|
2425
|
-
return {
|
|
2426
|
-
reference: await walletAuthAuthorityRefForSelectedPasskeyMethod(authMethod),
|
|
2427
|
-
identity: exactWalletSessionAuthorityIdentity({
|
|
2428
|
-
authority,
|
|
2429
|
-
walletAuthMethodId: authMethod.walletAuthMethodId
|
|
2430
|
-
})
|
|
2431
|
-
};
|
|
2432
|
-
}
|
|
2433
|
-
async function validatePasskeyWalletSessionAuthorization(args) {
|
|
2434
|
-
const credentialIdB64u = passkeyCredentialIdB64uFromAuthentication(args.credential);
|
|
2435
|
-
if (!credentialIdB64u) throw new Error("Passkey Wallet Session adoption requires WebAuthn credential identity");
|
|
2436
|
-
const authMethod = await exactPasskeyWalletAuthMethodForCredential({
|
|
2437
|
-
walletId: args.walletIdentity.walletId,
|
|
2438
|
-
rpId: args.rpId,
|
|
2439
|
-
credentialIdB64u
|
|
2440
|
-
});
|
|
2441
|
-
const authority = await resolveActivePasskeyWalletSessionAuthority({
|
|
2442
|
-
walletId: args.walletIdentity.walletId,
|
|
2443
|
-
authorization: args.authorization
|
|
2444
|
-
});
|
|
2445
|
-
if (args.authorization.record.walletId !== args.walletIdentity.walletId || args.authorization.record.authMethodId !== authMethod.walletAuthMethodId || args.authorization.record.authorityId !== authMethod.walletAuthorityId || authority.reference.walletId !== args.walletIdentity.walletId) throw new Error("Passkey Wallet Session authorization changed auth-method identity");
|
|
2446
|
-
return authority;
|
|
2447
|
-
}
|
|
2448
|
-
function bindPasskeyEcdsaSessionPolicyToUnlockChallenge(policy, challengeId) {
|
|
2449
|
-
return {
|
|
2450
|
-
...policy,
|
|
2451
|
-
session_policy: {
|
|
2452
|
-
...policy.session_policy,
|
|
2453
|
-
wallet_session_mint_id: requireThresholdLoginWalletSessionMintId(challengeId)
|
|
2454
|
-
}
|
|
2455
|
-
};
|
|
2456
|
-
}
|
|
2457
|
-
async function completePasskeyWalletUnlock(args, statusReads) {
|
|
2458
|
-
emitUnlockEvent(args.onEvent, args.unlockSubjectId, {
|
|
2459
|
-
phase: UnlockEventPhase.STEP_03_PASSKEY_CHALLENGE_STARTED,
|
|
2460
|
-
status: "running",
|
|
2461
|
-
authMethod: "passkey"
|
|
2462
|
-
});
|
|
2463
|
-
const challengeResponse = await fetch(joinNormalizedUrl(args.relayUrl, "/wallet/unlock/challenge"), {
|
|
2464
|
-
method: "POST",
|
|
2465
|
-
headers: { "Content-Type": "application/json" },
|
|
2466
|
-
body: JSON.stringify({
|
|
2467
|
-
unlockBackend: "passkey",
|
|
2468
|
-
userId: String(args.walletIdentity.walletId),
|
|
2469
|
-
rpId: args.rpId
|
|
2470
|
-
})
|
|
2471
|
-
});
|
|
2472
|
-
const challengeBodyUnknown = await challengeResponse.json().catch(() => ({}));
|
|
2473
|
-
const challengeBody = isObject(challengeBodyUnknown) ? challengeBodyUnknown : {};
|
|
2474
|
-
const challengeMessage = typeof challengeBody.message === "string" ? challengeBody.message : "";
|
|
2475
|
-
if (!challengeResponse.ok || challengeBody.ok !== true) throw new Error(challengeMessage || `wallet/unlock/challenge failed (HTTP ${challengeResponse.status})`);
|
|
2476
|
-
const challengeId = String(challengeBody.challengeId || "").trim();
|
|
2477
|
-
const challengeB64u = String(challengeBody.challengeB64u || "").trim();
|
|
2478
|
-
if (!challengeId || !challengeB64u) throw new Error("wallet/unlock/challenge returned invalid challenge");
|
|
2479
|
-
const activation = args.activation ? {
|
|
2480
|
-
...args.activation,
|
|
2481
|
-
policy: bindPasskeyEcdsaSessionPolicyToUnlockChallenge(args.activation.policy, challengeId)
|
|
2482
|
-
} : null;
|
|
2483
|
-
const credentialIds = resolveLoginPasskeyPromptCredentialIds({
|
|
2484
|
-
authenticators: args.authenticators,
|
|
2485
|
-
signerSlot: args.signerSlot,
|
|
2486
|
-
serverCredentialIds: parseLoginChallengeCredentialIds(challengeBody.credentialIds)
|
|
2487
|
-
});
|
|
2488
|
-
const credential = await args.collectCredentialForChallenge({
|
|
2489
|
-
challengeB64u,
|
|
2490
|
-
credentialIds
|
|
2491
|
-
});
|
|
2492
|
-
const expectedOrigin = String(args.expectedOrigin ?? (typeof window !== "undefined" ? window.location.origin : "")).trim();
|
|
2493
|
-
if (!expectedOrigin) throw new Error("[login] passkey wallet unlock requires an expected origin");
|
|
2494
|
-
const unlockInput = passkeyWalletUnlockInput({
|
|
2495
|
-
challengeId,
|
|
2496
|
-
credential,
|
|
2497
|
-
ed25519SessionRequest: passkeyUnlockEd25519SessionRequest({
|
|
2498
|
-
walletIdentity: args.walletIdentity,
|
|
2499
|
-
remainingUses: args.remainingUses
|
|
2500
|
-
}),
|
|
2501
|
-
expectedOrigin,
|
|
2502
|
-
walletIdentity: args.walletIdentity,
|
|
2503
|
-
activation
|
|
2504
|
-
});
|
|
2505
|
-
const result = await verifyPasskeyWalletUnlock(args.relayUrl, unlockInput, statusReads);
|
|
2506
|
-
if (!result.success) throw new Error(result.error || "Passkey wallet unlock failed");
|
|
2507
|
-
if (!result.walletCustody) throw new Error("Passkey wallet unlock omitted wallet custody continuity");
|
|
2508
|
-
if (activation && (!result.ecdsaSession || !result.ecdsaActivationReceipt || !result.ecdsaCustody)) throw new Error("Passkey wallet unlock omitted the requested ECDSA activation");
|
|
2509
|
-
const walletSessionAuthorizationToPersist = result.walletSessionAuthorization ?? null;
|
|
2510
|
-
const passkeySessionAuthority = walletSessionAuthorizationToPersist ? await validatePasskeyWalletSessionAuthorization({
|
|
2511
|
-
walletIdentity: args.walletIdentity,
|
|
2512
|
-
rpId: args.rpId,
|
|
2513
|
-
credential,
|
|
2514
|
-
authorization: walletSessionAuthorizationToPersist
|
|
2515
|
-
}) : null;
|
|
2516
|
-
let sessionActivation = null;
|
|
2517
|
-
if (activation && result.ecdsaSession && result.ecdsaActivationReceipt && result.ecdsaCustody && result.ecdsaSession.kind === "router_ab_ecdsa_credential_free_session_activated_v1") {
|
|
2518
|
-
const walletSessionAuthorization = result.walletSessionAuthorization;
|
|
2519
|
-
if (!walletSessionAuthorization) throw new Error("Passkey credential-free activation omitted exact Wallet Session authority");
|
|
2520
|
-
if (!passkeySessionAuthority) throw new Error("Passkey credential-free activation omitted exact Passkey authority");
|
|
2521
|
-
sessionActivation = {
|
|
2522
|
-
kind: "credential_free_ecdsa_session_activation_authorization_v1",
|
|
2523
|
-
activation: result.ecdsaSession,
|
|
2524
|
-
authorization: walletSessionAuthorization
|
|
2525
|
-
};
|
|
2526
|
-
}
|
|
2527
|
-
if (activation && result.ecdsaSession && result.ecdsaActivationReceipt && result.ecdsaCustody) {
|
|
2528
|
-
assertPasskeyEcdsaExchangeContinuity({
|
|
2529
|
-
walletId: String(args.walletIdentity.walletId),
|
|
2530
|
-
prepared: activation,
|
|
2531
|
-
response: result.ecdsaSession,
|
|
2532
|
-
activationReceipt: result.ecdsaActivationReceipt,
|
|
2533
|
-
continuity: result.ecdsaCustody
|
|
2534
|
-
});
|
|
2535
|
-
if (result.ecdsaSession.kind === "router_ab_ecdsa_post_registration_session_activated_v1") sessionActivation = result.ecdsaSession;
|
|
2536
|
-
}
|
|
2537
|
-
const ecdsaSessionAuthority = sessionActivation ? await validatePasskeyWalletSessionAuthorization({
|
|
2538
|
-
walletIdentity: args.walletIdentity,
|
|
2539
|
-
rpId: args.rpId,
|
|
2540
|
-
credential,
|
|
2541
|
-
authorization: exactAuthorizationFromPasskeyEcdsaActivation(sessionActivation)
|
|
2542
|
-
}) : null;
|
|
2543
|
-
if (walletSessionAuthorizationToPersist) await walletSessionAuthorizations.writeExactWithOperationCredential(walletSessionAuthorizationToPersist);
|
|
2544
|
-
if (activation?.requiresCustodyRejoin) {
|
|
2545
|
-
if (!("ecdsaCustody" in result) || !result.ecdsaCustody) throw new Error("Passkey wallet unlock omitted ECDSA custody rejoin continuity");
|
|
2546
|
-
const passkeyPrfFirstB64u = passkeyPrfFirstB64uFromCredential(credential);
|
|
2547
|
-
if (!passkeyPrfFirstB64u) throw new Error("Passkey ECDSA custody rejoin requires WebAuthn PRF.first");
|
|
2548
|
-
const credentialIdB64u = passkeyCredentialIdB64uFromAuthentication(credential);
|
|
2549
|
-
const authority = ecdsaSessionAuthority?.reference ?? passkeySessionAuthority?.reference ?? await exactPasskeyWalletAuthAuthorityRefForCredential({
|
|
2550
|
-
walletId: args.walletIdentity.walletId,
|
|
2551
|
-
rpId: args.rpId,
|
|
2552
|
-
credentialIdB64u
|
|
2553
|
-
});
|
|
2554
|
-
await restorePasskeyEcdsaCustodyLogin({
|
|
2555
|
-
signingEngine: args.context.signingEngine,
|
|
2556
|
-
walletId: String(args.walletIdentity.walletId),
|
|
2557
|
-
custody: result.walletCustody,
|
|
2558
|
-
continuity: result.ecdsaCustody,
|
|
2559
|
-
authority,
|
|
2560
|
-
passkeyPrfFirstB64u
|
|
2561
|
-
});
|
|
2562
|
-
}
|
|
2563
|
-
return {
|
|
2564
|
-
credential,
|
|
2565
|
-
activation: activation && result.ecdsaSession && sessionActivation && ecdsaSessionAuthority ? {
|
|
2566
|
-
...activation,
|
|
2567
|
-
response: result.ecdsaSession,
|
|
2568
|
-
sessionActivation,
|
|
2569
|
-
authorizationIdentity: ecdsaSessionAuthority.identity,
|
|
2570
|
-
activationReceipt: result.ecdsaActivationReceipt,
|
|
2571
|
-
continuity: result.ecdsaCustody
|
|
2572
|
-
} : null,
|
|
2573
|
-
custody: result.walletCustody,
|
|
2574
|
-
result
|
|
2575
|
-
};
|
|
2576
|
-
}
|
|
2577
|
-
var LoginWarmupDeferred = class {
|
|
2578
|
-
constructor() {
|
|
2579
|
-
this.settled = false;
|
|
2580
|
-
this.promise = new Promise(this.capturePromise.bind(this));
|
|
2581
|
-
}
|
|
2582
|
-
resolve(value) {
|
|
2583
|
-
if (this.settled) return;
|
|
2584
|
-
this.settled = true;
|
|
2585
|
-
this.resolvePromise(value);
|
|
2586
|
-
}
|
|
2587
|
-
reject(error) {
|
|
2588
|
-
if (this.settled) return;
|
|
2589
|
-
this.settled = true;
|
|
2590
|
-
this.rejectPromise(toError(error));
|
|
2591
|
-
}
|
|
2592
|
-
async wait() {
|
|
2593
|
-
return await this.promise;
|
|
2594
|
-
}
|
|
2595
|
-
capturePromise(resolve, reject) {
|
|
2596
|
-
this.resolvePromise = resolve;
|
|
2597
|
-
this.rejectPromise = reject;
|
|
2598
|
-
}
|
|
2599
|
-
};
|
|
2600
|
-
async function stageMintedLoginEd25519WalletSessionAuthority(context, minted) {
|
|
2601
|
-
context.sharedState.ed25519.thresholdSessionId = String(minted.thresholdSessionId);
|
|
2602
|
-
context.sharedState.ed25519.authorizationId = minted.authorizationId;
|
|
2603
|
-
context.sharedState.ed25519.walletSessionId = minted.walletSessionId;
|
|
2604
|
-
context.sharedState.ed25519.quotaId = minted.quotaId;
|
|
2605
|
-
context.sharedState.ed25519.operationCredential = minted.operationCredential;
|
|
2606
|
-
context.sharedState.ed25519.expiresAtMs = minted.expiresAtMs;
|
|
2607
|
-
context.sharedState.ed25519.remainingUses = minted.remainingUses;
|
|
2608
|
-
context.sharedState.ed25519.runtimePolicyScope = minted.runtimePolicyScope;
|
|
2609
|
-
context.authorityDeferred?.resolve(minted);
|
|
2610
|
-
}
|
|
2611
|
-
function rejectLoginWarmupEd25519Deferreds(authorityDeferred, error) {
|
|
2612
|
-
authorityDeferred?.reject(error);
|
|
2613
|
-
}
|
|
2614
|
-
function createActiveLoginSigningSessionStatus(args) {
|
|
2615
|
-
return {
|
|
2616
|
-
sessionId: String(args.session.thresholdSessionId),
|
|
2617
|
-
status: "active",
|
|
2618
|
-
authMethod: args.authMethod,
|
|
2619
|
-
...args.authMethod === SIGNER_AUTH_METHODS.emailOtp ? { retention: "session" } : {},
|
|
2620
|
-
remainingUses: args.session.remainingUses,
|
|
2621
|
-
expiresAtMs: args.session.expiresAtMs
|
|
2622
|
-
};
|
|
2623
|
-
}
|
|
2624
|
-
function isWalletSessionReconnectEcdsaRouteAuth(auth) {
|
|
2625
|
-
return auth?.kind === "opaque_wallet_session_operation_credential_v1";
|
|
2626
|
-
}
|
|
2627
|
-
function publicCapabilityFromThresholdEcdsaBootstrap(bootstrap) {
|
|
2628
|
-
const backendBinding = bootstrap.thresholdEcdsaKeyRef.backendBinding;
|
|
2629
|
-
if (!backendBinding) return void 0;
|
|
2630
|
-
switch (backendBinding.materialKind) {
|
|
2631
|
-
case "role_local_worker_handle":
|
|
2632
|
-
case "role_local_durable_sealed_ref":
|
|
2633
|
-
case "role_local_durable_public_anchor": return backendBinding.publicFacts.publicCapability;
|
|
2634
|
-
case "role_local_ready_state_blob": return backendBinding.ecdsaRoleLocalReadyRecord.publicFacts.publicCapability;
|
|
2635
|
-
case "metadata_only": return;
|
|
2636
|
-
}
|
|
2637
|
-
}
|
|
2638
|
-
function sharedEcdsaActivationKey(capability) {
|
|
2639
|
-
return JSON.stringify(capability);
|
|
2640
|
-
}
|
|
2641
|
-
function preauthorizedEcdsaActivationFromBootstrap(bootstrap) {
|
|
2642
|
-
const publicCapability = publicCapabilityFromThresholdEcdsaBootstrap(bootstrap);
|
|
2643
|
-
if (!publicCapability) throw new Error("[login] ECDSA bootstrap is missing its public capability");
|
|
2644
|
-
const session = bootstrap.session;
|
|
2645
|
-
const normalSigning = bootstrap.thresholdEcdsaKeyRef.routerAbEcdsaDerivationNormalSigning;
|
|
2646
|
-
if (!normalSigning) throw new Error("[login] ECDSA bootstrap is missing normal-signing state");
|
|
2647
|
-
return {
|
|
2648
|
-
kind: "router_ab_ecdsa_post_registration_session_activated_v1",
|
|
2649
|
-
public_capability: publicCapability,
|
|
2650
|
-
session: {
|
|
2651
|
-
authorization_session_id: session.authorizationSessionId,
|
|
2652
|
-
authorization_id: session.authorizationId,
|
|
2653
|
-
threshold_session_id: requireThresholdLoginEcdsaSessionId(session.thresholdSessionId),
|
|
2654
|
-
wallet_session_id: session.walletSessionId,
|
|
2655
|
-
quota_id: session.quotaId,
|
|
2656
|
-
expires_at_ms: session.expiresAtMs,
|
|
2657
|
-
remaining_uses: session.remainingUses,
|
|
2658
|
-
wallet_session: session.walletSession,
|
|
2659
|
-
operation_credential: session.operationCredential
|
|
2660
|
-
},
|
|
2661
|
-
normal_signing: normalSigning
|
|
2662
|
-
};
|
|
2663
|
-
}
|
|
2664
|
-
function sameEd25519ParticipantIds(left, right) {
|
|
2665
|
-
return left.length === right.length && left.every((participantId, index) => participantId === right[index]);
|
|
2666
|
-
}
|
|
2667
|
-
function sameRouterAbEd25519NormalSigningState(left, right) {
|
|
2668
|
-
return left.kind === right.kind && left.signingWorkerId === right.signingWorkerId;
|
|
2669
|
-
}
|
|
2670
|
-
function sameThresholdRuntimePolicyScope(left, right) {
|
|
2671
|
-
return left.orgId === right.orgId && left.projectId === right.projectId && left.envId === right.envId && left.signingRootVersion === right.signingRootVersion;
|
|
2672
|
-
}
|
|
2673
|
-
function mergeThresholdEcdsaWarmSessionContexts(args) {
|
|
2674
|
-
if (args.current.runtimePolicyScope && args.incoming.runtimePolicyScope && !sameThresholdRuntimePolicyScope(args.current.runtimePolicyScope, args.incoming.runtimePolicyScope)) throw new Error(`[login] threshold ECDSA ${args.source} has a conflicting runtime policy scope`);
|
|
2675
|
-
return mergeCanonicalThresholdEcdsaWarmSessionContexts(args.current, args.incoming);
|
|
2676
|
-
}
|
|
2677
|
-
/** Public capability and authority are the manifest's half of the capability
|
|
2678
|
-
* split; the sealed record is only correlated runtime evidence. A persisted
|
|
2679
|
-
* capability on the configured target is used directly; otherwise the exact
|
|
2680
|
-
* manifest is resolved. There is deliberately no composite-record fallback --
|
|
2681
|
-
* absent canonical state is device-link-required, not a silent miss. */
|
|
2682
|
-
async function resolvePersistedEcdsaPublicCapabilityForLogin(args) {
|
|
2683
|
-
if (args.targetEcdsaKey.publicCapability.kind === "persisted_public_capability") {
|
|
2684
|
-
const publicCapability = args.targetEcdsaKey.publicCapability.value;
|
|
2685
|
-
if (String(publicCapability.client_id) !== String(args.walletId)) throw new Error(`[login] threshold ECDSA persisted public capability wallet mismatch for ${thresholdEcdsaChainTargetKey(args.chainTarget)}`);
|
|
2686
|
-
return publicCapability;
|
|
2687
|
-
}
|
|
2688
|
-
const resolved = await resolveBrowserActiveEcdsaCapabilityRuntime({
|
|
2689
|
-
walletId: args.walletId,
|
|
2690
|
-
chainTarget: args.chainTarget
|
|
2691
|
-
});
|
|
2692
|
-
if (resolved.kind !== "resolved") throw createThresholdEcdsaDeviceLinkRequiredError(thresholdEcdsaChainTargetKey(args.chainTarget));
|
|
2693
|
-
const publicFacts = resolved.manifest.durableMaterial.roleLocalPublicFacts;
|
|
2694
|
-
if (String(publicFacts.keyHandle) !== String(args.targetEcdsaKey.keyHandle) || String(publicFacts.walletId) !== String(args.walletId)) throw createThresholdEcdsaDeviceLinkRequiredError(thresholdEcdsaChainTargetKey(args.chainTarget));
|
|
2695
|
-
return publicFacts.publicCapability;
|
|
2696
|
-
}
|
|
2697
|
-
function buildThresholdLoginWarmSignerSelection(signersToWarm) {
|
|
2698
|
-
const normalized = [];
|
|
2699
|
-
for (const signer of signersToWarm) {
|
|
2700
|
-
if (signer !== "ed25519" && signer !== "ecdsa") continue;
|
|
2701
|
-
if (normalized.includes(signer)) continue;
|
|
2702
|
-
normalized.push(signer);
|
|
2703
|
-
}
|
|
2704
|
-
return normalized;
|
|
2705
|
-
}
|
|
2706
|
-
async function runThresholdLoginWarmupTask(task) {
|
|
2707
|
-
try {
|
|
2708
|
-
await task.run();
|
|
2709
|
-
return {
|
|
2710
|
-
kind: "succeeded",
|
|
2711
|
-
task
|
|
2712
|
-
};
|
|
2713
|
-
} catch (error) {
|
|
2714
|
-
task.onFailure?.(error);
|
|
2715
|
-
return {
|
|
2716
|
-
kind: "failed",
|
|
2717
|
-
task,
|
|
2718
|
-
error: toError(error)
|
|
2719
|
-
};
|
|
2720
|
-
}
|
|
2721
|
-
}
|
|
2722
|
-
async function runThresholdLoginWarmupTasks(tasks) {
|
|
2723
|
-
const pendingBySigner = /* @__PURE__ */ new Map();
|
|
2724
|
-
for (const task of tasks) pendingBySigner.set(task.signer, task);
|
|
2725
|
-
const completed = /* @__PURE__ */ new Set();
|
|
2726
|
-
while (pendingBySigner.size > 0) {
|
|
2727
|
-
const ready = [];
|
|
2728
|
-
for (const task of pendingBySigner.values()) if (task.dependencies.every((dep) => completed.has(dep))) ready.push(task);
|
|
2729
|
-
if (ready.length === 0) throw new Error("[login] threshold warm-up task dependency graph is unsatisfied");
|
|
2730
|
-
const outcomes = await Promise.all(ready.map(runThresholdLoginWarmupTask));
|
|
2731
|
-
let firstFailure = null;
|
|
2732
|
-
for (const outcome of outcomes) switch (outcome.kind) {
|
|
2733
|
-
case "succeeded":
|
|
2734
|
-
completed.add(outcome.task.signer);
|
|
2735
|
-
pendingBySigner.delete(outcome.task.signer);
|
|
2736
|
-
break;
|
|
2737
|
-
case "failed":
|
|
2738
|
-
firstFailure ??= outcome.error;
|
|
2739
|
-
break;
|
|
2740
|
-
default: return assertNeverLoginState(outcome);
|
|
2741
|
-
}
|
|
2742
|
-
if (firstFailure) throw firstFailure;
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
2745
|
-
function resolveThresholdLoginWarmEcdsaBootstrapIdentity(args) {
|
|
2746
|
-
args.routeAuthorization.kind;
|
|
2747
|
-
if (args.credentialState.kind === "available") return {};
|
|
2748
|
-
throw new Error("[login] threshold ECDSA warm-up requires route authorization");
|
|
2749
|
-
}
|
|
2750
|
-
function thresholdLoginWarmupErrorMessage(error) {
|
|
2751
|
-
return String((error && typeof error === "object" && "message" in error ? error.message : error) || "");
|
|
2752
|
-
}
|
|
2753
|
-
function assertNeverLoginState(value) {
|
|
2754
|
-
throw new Error(`[login] unexpected state: ${String(value)}`);
|
|
2755
|
-
}
|
|
2756
|
-
async function bootstrapLoginEcdsaSession(args) {
|
|
2757
|
-
switch (args.runtimeScopeBootstrapState.kind) {
|
|
2758
|
-
case "available": return await args.signingEngine.bootstrapEcdsaSession({
|
|
2759
|
-
...args.request,
|
|
2760
|
-
runtimeScopeBootstrap: args.runtimeScopeBootstrapState.runtimeScopeBootstrap
|
|
2761
|
-
});
|
|
2762
|
-
case "unavailable": return await args.signingEngine.bootstrapEcdsaSession(args.request);
|
|
2763
|
-
default: return assertNeverLoginState(args.runtimeScopeBootstrapState);
|
|
2764
|
-
}
|
|
2765
|
-
}
|
|
2766
|
-
function requireLoginWarmEd25519OperationCredential(session) {
|
|
2767
|
-
if ("operationCredential" in session) return session.operationCredential;
|
|
2768
|
-
throw new Error("[login] wallet custody Ed25519 activation requires the exact issued operation credential");
|
|
2769
|
-
}
|
|
2770
|
-
async function ensurePasskeyEd25519OwnerProfile(input) {
|
|
2771
|
-
const existing = await input.signingEngine.getUserBySignerSlot(input.walletBinding.nearAccountId, input.signerSlot).catch(() => null);
|
|
2772
|
-
if (existing) {
|
|
2773
|
-
if (existing.walletId !== String(input.walletBinding.walletId) || existing.nearEd25519SigningKeyId !== String(input.walletBinding.nearEd25519SigningKeyId) || existing.signerSlot !== input.signerSlot) throw new Error("[login] local Ed25519 owner profile identity is invalid");
|
|
2774
|
-
return;
|
|
2775
|
-
}
|
|
2776
|
-
await input.signingEngine.storeUserData({
|
|
2777
|
-
walletId: String(input.walletBinding.walletId),
|
|
2778
|
-
nearAccountId: input.walletBinding.nearAccountId,
|
|
2779
|
-
nearEd25519SigningKeyId: String(input.walletBinding.nearEd25519SigningKeyId),
|
|
2780
|
-
signerSlot: input.signerSlot,
|
|
2781
|
-
operationalPublicKey: `ed25519:${base58Encode(input.registeredPublicKey)}`,
|
|
2782
|
-
passkeyCredential: {
|
|
2783
|
-
id: input.credentialIdB64u,
|
|
2784
|
-
rawId: input.credentialIdB64u
|
|
2785
|
-
},
|
|
2786
|
-
lastUpdated: Date.now(),
|
|
2787
|
-
version: 2
|
|
2788
|
-
});
|
|
2789
|
-
}
|
|
2790
|
-
function walletCustodyLoginActivationFacts(custody, thresholdSessionId) {
|
|
2791
|
-
const capability = custody.ed25519.capability;
|
|
2792
|
-
const continuity = capability.registrationContinuity;
|
|
2793
|
-
return {
|
|
2794
|
-
materialActivation: capability.materialActivation,
|
|
2795
|
-
lifecycleId: capability.lifecycle.lifecycleId,
|
|
2796
|
-
signingRootVersion: capability.lifecycle.rootShareEpoch,
|
|
2797
|
-
signingRootId: capability.applicationBinding.signing_root_id,
|
|
2798
|
-
signerSetId: capability.lifecycle.signerSetId,
|
|
2799
|
-
thresholdSessionId,
|
|
2800
|
-
activationTranscriptB64u: base64UrlEncode(Uint8Array.from(continuity.activationTranscript)),
|
|
2801
|
-
activationCapabilityBindingB64u: base64UrlEncode(Uint8Array.from(capability.activeCapabilityBinding))
|
|
2802
|
-
};
|
|
2803
|
-
}
|
|
2804
|
-
function assertWalletCustodyLoginIdentity(input) {
|
|
2805
|
-
const ed25519 = input.custody.ed25519;
|
|
2806
|
-
const capability = ed25519.capability;
|
|
2807
|
-
if (ed25519.nearAccountId !== String(input.walletBinding.nearAccountId) || ed25519.nearEd25519SigningKeyId !== String(input.walletBinding.nearEd25519SigningKeyId) || ed25519.signerSlot !== input.signerSlot || capability.applicationBinding.wallet_id !== String(input.walletBinding.walletId) || capability.applicationBinding.near_ed25519_signing_key_id !== String(input.walletBinding.nearEd25519SigningKeyId) || capability.applicationBinding.key_creation_signer_slot !== input.signerSlot || capability.nearAccountId !== input.walletBinding.nearAccountId || capability.lifecycle.accountId !== String(input.walletBinding.walletId) || capability.lifecycle.signingWorkerId !== ed25519.relayerKeyId) throw new Error("[login] wallet custody identity does not match the selected signing lane");
|
|
2808
|
-
}
|
|
2809
|
-
async function openAndActivatePasskeyEd25519CustodyLogin(input) {
|
|
2810
|
-
assertWalletCustodyLoginIdentity(input);
|
|
2811
|
-
const capability = input.custody.ed25519.capability;
|
|
2812
|
-
const cached = await input.signingEngine.loadWalletCustodyEd25519Material({
|
|
2813
|
-
nearAccountId: String(input.walletBinding.nearAccountId),
|
|
2814
|
-
signerSlot: input.signerSlot,
|
|
2815
|
-
expectedRegisteredPublicKeyB64u: base64UrlEncode(Uint8Array.from(capability.registeredPublicKey))
|
|
2816
|
-
});
|
|
2817
|
-
const thresholdSessionId = parseThresholdEd25519SessionId(input.walletSession.thresholdSessionId);
|
|
2818
|
-
if (!thresholdSessionId.ok) throw new Error("[login] wallet custody returned an invalid threshold session identity");
|
|
2819
|
-
const activation = walletCustodyLoginActivationFacts(input.custody, thresholdSessionId.value);
|
|
2820
|
-
const envelope = walletCustodyCacheEnvelopeFromRecordV1(input.custody.envelope);
|
|
2821
|
-
let activeClient = null;
|
|
2822
|
-
let rejoinSecret = null;
|
|
2823
|
-
let openSecret = null;
|
|
2824
|
-
try {
|
|
2825
|
-
if (cached.kind === "found") {
|
|
2826
|
-
openSecret = base64UrlDecode(input.passkeyPrfFirstB64u);
|
|
2827
|
-
activeClient = await openWalletCustodyEd25519ActiveClientV1({
|
|
2828
|
-
material: cached.material,
|
|
2829
|
-
activation,
|
|
2830
|
-
envelope,
|
|
2831
|
-
ownedFactorSecret: openSecret
|
|
2832
|
-
});
|
|
2833
|
-
} else {
|
|
2834
|
-
const custodyWire = joinCustodyWireFromEnvelopeRecord(input.custody.envelope);
|
|
2835
|
-
if (!custodyWire.ok) throw new Error(custodyWire.reason);
|
|
2836
|
-
rejoinSecret = base64UrlDecode(input.passkeyPrfFirstB64u);
|
|
2837
|
-
openSecret = base64UrlDecode(input.passkeyPrfFirstB64u);
|
|
2838
|
-
const rejoined = await input.signingEngine.rejoinWalletCustodyNearEd25519KeySet({
|
|
2839
|
-
walletId: String(input.walletBinding.walletId),
|
|
2840
|
-
custodyJson: custodyWire.custodyJson,
|
|
2841
|
-
factorSecret: rejoinSecret.buffer,
|
|
2842
|
-
nearEd25519SigningKeyId: String(input.walletBinding.nearEd25519SigningKeyId),
|
|
2843
|
-
recoveryBasis: capability,
|
|
2844
|
-
routerOrigin: new URL(input.relayerUrl).origin,
|
|
2845
|
-
walletSessionToken: requireLoginWarmEd25519OperationCredential(input.walletSession).token
|
|
2846
|
-
});
|
|
2847
|
-
const materialBinding = {
|
|
2848
|
-
kind: WALLET_CUSTODY_ED25519_MATERIAL_KEY_KIND,
|
|
2849
|
-
applicationBindingDigestB64u: rejoined.localMaterial.applicationBindingDigestB64u,
|
|
2850
|
-
registeredPublicKeyB64u: base64UrlEncode(rejoined.metadata.registeredPublicKey),
|
|
2851
|
-
participantIds: rejoined.metadata.participantIds,
|
|
2852
|
-
stateEpoch: String(rejoined.metadata.stateEpoch),
|
|
2853
|
-
walletId: String(input.walletBinding.walletId),
|
|
2854
|
-
nearAccountId: String(input.walletBinding.nearAccountId),
|
|
2855
|
-
nearEd25519SigningKeyId: String(input.walletBinding.nearEd25519SigningKeyId),
|
|
2856
|
-
signerSlot: input.signerSlot,
|
|
2857
|
-
signingWorkerId: input.custody.ed25519.relayerKeyId,
|
|
2858
|
-
signingWorkerVerifyingShareB64u: base64UrlEncode(rejoined.metadata.signingWorkerVerifyingShare)
|
|
2859
|
-
};
|
|
2860
|
-
const sealed = {
|
|
2861
|
-
ciphertextB64u: rejoined.localMaterial.b64u,
|
|
2862
|
-
nonceB64u: rejoined.localMaterial.nonceB64u
|
|
2863
|
-
};
|
|
2864
|
-
try {
|
|
2865
|
-
await input.signingEngine.persistWalletCustodyEd25519Material({
|
|
2866
|
-
binding: materialBinding,
|
|
2867
|
-
sealed
|
|
2868
|
-
});
|
|
2869
|
-
} catch (error) {
|
|
2870
|
-
console.warn("[login] wallet custody cache write failed; continuing with verified material", { error });
|
|
2871
|
-
}
|
|
2872
|
-
activeClient = await openWalletCustodyEd25519ActiveClientV1({
|
|
2873
|
-
material: {
|
|
2874
|
-
binding: materialBinding,
|
|
2875
|
-
sealed
|
|
2876
|
-
},
|
|
2877
|
-
activation: walletCustodyActivationFactsFromActiveClientMetadataV1(rejoined.metadata),
|
|
2878
|
-
envelope,
|
|
2879
|
-
ownedFactorSecret: openSecret
|
|
2880
|
-
});
|
|
2881
|
-
}
|
|
2882
|
-
if (!activeClient) throw new Error("[login] wallet custody produced no active client");
|
|
2883
|
-
const recoveredThresholdSessionId = parseThresholdEd25519SessionId(activeClient.metadata().scope.threshold_session_id);
|
|
2884
|
-
if (!recoveredThresholdSessionId.ok) throw new Error("[login] wallet custody returned an invalid threshold session identity");
|
|
2885
|
-
if (recoveredThresholdSessionId.value !== input.walletSession.thresholdSessionId) throw new Error("[login] wallet custody changed the threshold session identity");
|
|
2886
|
-
const envelopeFactor = input.custody.envelope.factor;
|
|
2887
|
-
if (envelopeFactor.kind !== "passkey") throw new Error("[login] wallet custody returned a different factor authority");
|
|
2888
|
-
await ensurePasskeyEd25519OwnerProfile({
|
|
2889
|
-
signingEngine: input.signingEngine,
|
|
2890
|
-
walletBinding: input.walletBinding,
|
|
2891
|
-
signerSlot: input.signerSlot,
|
|
2892
|
-
credentialIdB64u: envelopeFactor.credentialIdB64u,
|
|
2893
|
-
registeredPublicKey: activeClient.metadata().registeredPublicKey
|
|
2894
|
-
});
|
|
2895
|
-
await persistPasskeyEd25519YaoSignerMaterialV1({
|
|
2896
|
-
store: IndexedDBManager,
|
|
2897
|
-
activeClient,
|
|
2898
|
-
identity: {
|
|
2899
|
-
walletId: String(input.walletBinding.walletId),
|
|
2900
|
-
nearAccountId: String(input.walletBinding.nearAccountId),
|
|
2901
|
-
nearEd25519SigningKeyId: String(input.walletBinding.nearEd25519SigningKeyId),
|
|
2902
|
-
thresholdSessionId: recoveredThresholdSessionId.value,
|
|
2903
|
-
signerSlot: input.signerSlot,
|
|
2904
|
-
rpId: envelopeFactor.rpId,
|
|
2905
|
-
credentialIdB64u: envelopeFactor.credentialIdB64u,
|
|
2906
|
-
signingRootId: capability.applicationBinding.signing_root_id,
|
|
2907
|
-
signingRootVersion: capability.lifecycle.rootShareEpoch,
|
|
2908
|
-
signingWorkerId: input.custody.ed25519.relayerKeyId
|
|
2909
|
-
},
|
|
2910
|
-
stableServerScope: {
|
|
2911
|
-
relayerKeyId: input.custody.ed25519.relayerKeyId,
|
|
2912
|
-
participantIds: input.custody.ed25519.participantIds,
|
|
2913
|
-
runtimePolicyScope: capability.runtimePolicyScope,
|
|
2914
|
-
routerAbNormalSigning: input.routerAbNormalSigning
|
|
2915
|
-
},
|
|
2916
|
-
passkeyPrfFirstB64u: input.passkeyPrfFirstB64u
|
|
2917
|
-
});
|
|
2918
|
-
const activated = await input.signingEngine.activateVerifiedNearEd25519YaoMaterial({
|
|
2919
|
-
activeClient,
|
|
2920
|
-
facts: {
|
|
2921
|
-
thresholdSessionId: recoveredThresholdSessionId.value,
|
|
2922
|
-
signer: nearEd25519SignerBindingFromBoundaryFields({
|
|
2923
|
-
walletId: input.walletBinding.walletId,
|
|
2924
|
-
nearAccountId: input.walletBinding.nearAccountId,
|
|
2925
|
-
nearEd25519SigningKeyId: input.walletBinding.nearEd25519SigningKeyId,
|
|
2926
|
-
signerSlot: input.signerSlot
|
|
2927
|
-
}),
|
|
2928
|
-
signingRootId: capability.applicationBinding.signing_root_id,
|
|
2929
|
-
signingRootVersion: capability.lifecycle.rootShareEpoch,
|
|
2930
|
-
routerAbNormalSigning: input.routerAbNormalSigning,
|
|
2931
|
-
runtimePolicyScope: capability.runtimePolicyScope,
|
|
2932
|
-
relayerUrl: input.relayerUrl
|
|
2933
|
-
}
|
|
2934
|
-
});
|
|
2935
|
-
const signingWalletSession = buildRouterAbEd25519SigningWalletSession({
|
|
2936
|
-
walletId: String(input.walletBinding.walletId),
|
|
2937
|
-
nearAccountId: String(input.walletBinding.nearAccountId),
|
|
2938
|
-
nearEd25519SigningKeyId: String(input.walletBinding.nearEd25519SigningKeyId),
|
|
2939
|
-
walletSessionId: input.walletSession.walletSessionId,
|
|
2940
|
-
authorizationId: input.walletSession.authorizationId,
|
|
2941
|
-
quotaId: input.walletSession.quotaId,
|
|
2942
|
-
thresholdSessionId: recoveredThresholdSessionId.value,
|
|
2943
|
-
remainingUses: input.walletSession.remainingUses,
|
|
2944
|
-
expiresAtMs: input.walletSession.expiresAtMs,
|
|
2945
|
-
runtimePolicyScope: input.walletSession.runtimePolicyScope,
|
|
2946
|
-
signingRootId: capability.applicationBinding.signing_root_id,
|
|
2947
|
-
signingRootVersion: capability.lifecycle.rootShareEpoch,
|
|
2948
|
-
routerAbNormalSigning: input.routerAbNormalSigning,
|
|
2949
|
-
walletSessionToken: requireLoginWarmEd25519OperationCredential(input.walletSession).token,
|
|
2950
|
-
nowMs: Math.min(Date.now(), input.walletSession.expiresAtMs - 1)
|
|
2951
|
-
});
|
|
2952
|
-
if (!signingWalletSession.ok) throw new Error(`[login] wallet custody returned an unusable Ed25519 Wallet Session: ${signingWalletSession.reason}`);
|
|
2953
|
-
const session = buildPasskeyRouterAbEd25519WalletSessionState({
|
|
2954
|
-
walletId: input.walletBinding.walletId,
|
|
2955
|
-
nearAccountId: input.walletBinding.nearAccountId,
|
|
2956
|
-
nearEd25519SigningKeyId: input.walletBinding.nearEd25519SigningKeyId,
|
|
2957
|
-
signerSlot: input.signerSlot,
|
|
2958
|
-
rpId: toRpId(envelopeFactor.rpId),
|
|
2959
|
-
credentialIdB64u: envelopeFactor.credentialIdB64u,
|
|
2960
|
-
relayerUrl: input.relayerUrl,
|
|
2961
|
-
authority: input.authority,
|
|
2962
|
-
signingWalletSession: signingWalletSession.value
|
|
2963
|
-
});
|
|
2964
|
-
await persistPasskeyEd25519YaoSessionForRefresh({
|
|
2965
|
-
persistence: input.signingEngine,
|
|
2966
|
-
session,
|
|
2967
|
-
prfFirstB64u: input.passkeyPrfFirstB64u,
|
|
2968
|
-
ed25519Restore: buildPasskeyEd25519RestoreMetadata({
|
|
2969
|
-
rpId: envelopeFactor.rpId,
|
|
2970
|
-
nearAccountId: String(input.walletBinding.nearAccountId),
|
|
2971
|
-
nearEd25519SigningKeyId: String(input.walletBinding.nearEd25519SigningKeyId),
|
|
2972
|
-
relayerKeyId: input.custody.ed25519.relayerKeyId,
|
|
2973
|
-
participantIds: input.custody.ed25519.participantIds,
|
|
2974
|
-
runtimePolicyScope: input.walletSession.runtimePolicyScope,
|
|
2975
|
-
signerSlot: input.signerSlot,
|
|
2976
|
-
routerAbNormalSigning: input.routerAbNormalSigning,
|
|
2977
|
-
credentialIdB64u: envelopeFactor.credentialIdB64u,
|
|
2978
|
-
materialActivation: activated.materialActivation
|
|
2979
|
-
}),
|
|
2980
|
-
materialActivation: activated.materialActivation
|
|
2981
|
-
});
|
|
2982
|
-
await input.signingEngine.establishUnlockedWalletEd25519ExportRootCapabilityV1({
|
|
2983
|
-
existingEnvelope: input.custody.envelope,
|
|
2984
|
-
passkeyPrfFirstB64u: input.passkeyPrfFirstB64u,
|
|
2985
|
-
walletId: String(input.walletBinding.walletId),
|
|
2986
|
-
walletAuthMethodId: String(input.authority.walletAuthMethodId),
|
|
2987
|
-
walletSessionId: String(input.walletSession.walletSessionId),
|
|
2988
|
-
expiresAtMs: input.walletSession.expiresAtMs
|
|
2989
|
-
});
|
|
2990
|
-
} catch (error) {
|
|
2991
|
-
activeClient?.dispose();
|
|
2992
|
-
throw error;
|
|
2993
|
-
} finally {
|
|
2994
|
-
rejoinSecret?.fill(0);
|
|
2995
|
-
openSecret?.fill(0);
|
|
2996
|
-
}
|
|
2997
|
-
}
|
|
2998
|
-
function ethereumAddressFromEcdsaIdentityB64u(value) {
|
|
2999
|
-
const bytes = base64UrlDecode(value);
|
|
3000
|
-
if (bytes.length !== 20) throw new Error("[login] ECDSA custody address is invalid");
|
|
3001
|
-
let hex = "0x";
|
|
3002
|
-
for (const byte of bytes) hex += byte.toString(16).padStart(2, "0");
|
|
3003
|
-
return hex;
|
|
3004
|
-
}
|
|
3005
|
-
function nonEmptyEcdsaCustodyChainTargets(signers) {
|
|
3006
|
-
const [first, ...rest] = signers;
|
|
3007
|
-
if (!first) throw new Error("[login] passkey ECDSA custody continuity is empty");
|
|
3008
|
-
return [first.chainTarget, ...rest.map((signer) => signer.chainTarget)];
|
|
3009
|
-
}
|
|
3010
|
-
async function restorePasskeyEcdsaCustodyLogin(input) {
|
|
3011
|
-
const first = input.continuity.signers[0];
|
|
3012
|
-
if (!first) throw new Error("[login] passkey ECDSA custody continuity is empty");
|
|
3013
|
-
if (first.walletKey.walletId !== input.walletId) throw new Error("[login] passkey ECDSA custody continuity changed wallet identity");
|
|
3014
|
-
for (const signer of input.continuity.signers) if (signer.walletKey.walletId !== first.walletKey.walletId || signer.walletKey.keyHandle !== first.walletKey.keyHandle || signer.walletKey.ecdsaThresholdKeyId !== first.walletKey.ecdsaThresholdKeyId || signer.walletKey.signingRootId !== first.walletKey.signingRootId || signer.walletKey.signingRootVersion !== first.walletKey.signingRootVersion || signer.walletKey.relayerKeyId !== first.walletKey.relayerKeyId || !sameRouterAbEcdsaDerivationPublicCapabilityV1(signer.walletKey.publicCapability, first.walletKey.publicCapability) || !sameRouterAbEcdsaRegistrationActivationReceiptV1(signer.activationReceipt, first.activationReceipt) || !sameThresholdRuntimePolicyScope(signer.runtimePolicyScope, first.runtimePolicyScope)) throw new Error("[login] passkey ECDSA custody continuity conflicts across targets");
|
|
3015
|
-
const custodyWire = joinCustodyWireFromEnvelopeRecord(input.custody.envelope);
|
|
3016
|
-
if (!custodyWire.ok) throw new Error(custodyWire.reason);
|
|
3017
|
-
const factorSecret = base64UrlDecode(input.passkeyPrfFirstB64u);
|
|
3018
|
-
try {
|
|
3019
|
-
const rejoined = await input.signingEngine.rejoinWalletCustodyEvmFamilyKeySet({
|
|
3020
|
-
walletId: input.walletId,
|
|
3021
|
-
custodyJson: custodyWire.custodyJson,
|
|
3022
|
-
factorSecret: factorSecret.buffer,
|
|
3023
|
-
evmFamilySigningKeySlotId: deriveEvmFamilySigningKeySlotId({
|
|
3024
|
-
walletId: input.walletId,
|
|
3025
|
-
signingRootId: first.walletKey.signingRootId,
|
|
3026
|
-
signingRootVersion: first.walletKey.signingRootVersion
|
|
3027
|
-
}),
|
|
3028
|
-
applicationBindingDigestB64u: first.walletKey.publicCapability.context.application_binding_digest_b64u,
|
|
3029
|
-
registeredClientRootPublicKey33B64u: first.walletKey.derivationClientSharePublicKey33B64u,
|
|
3030
|
-
relayerPublicIdentityJson: JSON.stringify({
|
|
3031
|
-
relayerKeyId: first.walletKey.relayerKeyId,
|
|
3032
|
-
relayerPublicKey33B64u: first.activationReceipt.ecdsa_activation.public_identity.server_public_key33_b64u,
|
|
3033
|
-
groupPublicKey33B64u: first.activationReceipt.ecdsa_activation.public_identity.threshold_public_key33_b64u,
|
|
3034
|
-
ethereumAddress: ethereumAddressFromEcdsaIdentityB64u(first.activationReceipt.ecdsa_activation.public_identity.ethereum_address20_b64u),
|
|
3035
|
-
relayerShareRetryCounter: first.activationReceipt.ecdsa_activation.public_identity.server_share_retry_counter
|
|
3036
|
-
})
|
|
3037
|
-
});
|
|
3038
|
-
assertRejoinedPasskeyEcdsaPublicFacts({
|
|
3039
|
-
publicFacts: rejoined.publicFacts,
|
|
3040
|
-
signer: first
|
|
3041
|
-
});
|
|
3042
|
-
await input.signingEngine.restoreWalletCustodyEcdsaContinuity({
|
|
3043
|
-
authority: input.authority,
|
|
3044
|
-
chainTargets: nonEmptyEcdsaCustodyChainTargets(input.continuity.signers),
|
|
3045
|
-
walletId: first.walletKey.walletId,
|
|
3046
|
-
keyHandle: first.walletKey.keyHandle,
|
|
3047
|
-
ecdsaThresholdKeyId: first.walletKey.ecdsaThresholdKeyId,
|
|
3048
|
-
signingRootId: first.walletKey.signingRootId,
|
|
3049
|
-
signingRootVersion: first.walletKey.signingRootVersion,
|
|
3050
|
-
relayerKeyId: first.walletKey.relayerKeyId,
|
|
3051
|
-
participantIds: first.walletKey.participantIds,
|
|
3052
|
-
publicCapability: first.walletKey.publicCapability,
|
|
3053
|
-
activationReceipt: first.activationReceipt,
|
|
3054
|
-
runtimePolicyScope: first.runtimePolicyScope,
|
|
3055
|
-
readyStateBlobB64u: rejoined.readyStateBlobB64u,
|
|
3056
|
-
publicFacts: rejoined.publicFacts
|
|
3057
|
-
});
|
|
3058
|
-
} finally {
|
|
3059
|
-
factorSecret.fill(0);
|
|
3060
|
-
}
|
|
3061
|
-
}
|
|
3062
|
-
async function primeThresholdLoginWarmSigners(args) {
|
|
3063
|
-
const signersToWarm = buildThresholdLoginWarmSignerSelection(args.signersToWarm);
|
|
3064
|
-
const credential = args.credentialState.kind === "available" ? args.credentialState.credential : void 0;
|
|
3065
|
-
const localPasskeyCredentialIdB64u = args.credentialState.localPasskeyCredentialIdB64u;
|
|
3066
|
-
const runtimeScopeBootstrap = args.runtimeScopeBootstrapState.kind === "available" ? args.runtimeScopeBootstrapState.runtimeScopeBootstrap : null;
|
|
3067
|
-
const initialCanonicalEcdsaContext = args.ecdsaContext;
|
|
3068
|
-
const sharedState = {
|
|
3069
|
-
activeCanonicalEcdsaContext: initialCanonicalEcdsaContext,
|
|
3070
|
-
ed25519: {
|
|
3071
|
-
thresholdSessionId: "",
|
|
3072
|
-
authorizationId: null,
|
|
3073
|
-
walletSessionId: null,
|
|
3074
|
-
quotaId: null,
|
|
3075
|
-
operationCredential: null,
|
|
3076
|
-
expiresAtMs: 0,
|
|
3077
|
-
remainingUses: 0,
|
|
3078
|
-
runtimePolicyScope: null
|
|
3079
|
-
}
|
|
3080
|
-
};
|
|
3081
|
-
const authorityDeferred = args.ecdsaDependency.kind === "ed25519_wallet_session_authority" ? new LoginWarmupDeferred() : null;
|
|
3082
|
-
const ecdsaThresholdSessionState = { generatedThresholdSessionId: args.passkeyExchangeEcdsaActivation?.policy.session_policy.threshold_session_id || "" };
|
|
3083
|
-
const unlockRemainingUses = args.unlockRemainingUses;
|
|
3084
|
-
const ecdsaBootstraps = [];
|
|
3085
|
-
let ed25519Session = null;
|
|
3086
|
-
let ecdsaAuthorizedEd25519Mint = null;
|
|
3087
|
-
const tasks = [];
|
|
3088
|
-
if (signersToWarm.includes("ed25519")) tasks.push({
|
|
3089
|
-
signer: "ed25519",
|
|
3090
|
-
dependencies: args.ed25519DependsOnEcdsa ? ["ecdsa"] : [],
|
|
3091
|
-
onFailure: authorityDeferred ? rejectLoginWarmupEd25519Deferreds.bind(void 0, authorityDeferred) : null,
|
|
3092
|
-
run: async () => {
|
|
3093
|
-
const walletBinding = requireNearLoginWalletBinding(args.walletIdentity);
|
|
3094
|
-
const ecdsaMint = ecdsaAuthorizedEd25519Mint;
|
|
3095
|
-
const ed25519SessionAuthority = bindLoginEd25519SessionAuthorityToAuthenticatedCredential({
|
|
3096
|
-
authority: requireRequestedLoginEd25519SessionAuthority(args.ed25519SessionAuthority),
|
|
3097
|
-
walletId: walletBinding.walletId,
|
|
3098
|
-
rpId: args.context.signingEngine.getRpId(),
|
|
3099
|
-
credentialIdB64u: localPasskeyCredentialIdB64u
|
|
3100
|
-
});
|
|
3101
|
-
const ed25519ProvisioningIdentity = resolveLoginWarmEd25519ProvisioningIdentity({
|
|
3102
|
-
mintPlan: args.ed25519MintPlan,
|
|
3103
|
-
ecdsaMint,
|
|
3104
|
-
walletBinding,
|
|
3105
|
-
signerSlot: args.signerSlot,
|
|
3106
|
-
authority: ed25519SessionAuthority
|
|
3107
|
-
});
|
|
3108
|
-
const provisionScope = resolveLoginEd25519ProvisionScope({
|
|
3109
|
-
mintPlan: args.ed25519MintPlan,
|
|
3110
|
-
fallback: {
|
|
3111
|
-
relayerKeyId: args.relayerKeyId,
|
|
3112
|
-
participantIds: args.participantIds,
|
|
3113
|
-
runtimePolicyScope: initialCanonicalEcdsaContext.runtimePolicyScope ?? null,
|
|
3114
|
-
routerAbNormalSigning: createRouterAbNormalSigningPolicy(args.context.configs)
|
|
3115
|
-
}
|
|
3116
|
-
});
|
|
3117
|
-
const sharedEd25519ConnectArgs = {
|
|
3118
|
-
relayerUrl: args.relayerUrl,
|
|
3119
|
-
relayerKeyId: provisionScope.relayerKeyId,
|
|
3120
|
-
runtimePolicyScope: provisionScope.runtimePolicyScope || void 0,
|
|
3121
|
-
routerAbNormalSigning: provisionScope.routerAbNormalSigning,
|
|
3122
|
-
runtimeScopeBootstrap: runtimeScopeBootstrap || void 0,
|
|
3123
|
-
participantIds: provisionScope.participantIds,
|
|
3124
|
-
ttlMs: args.ttlMs,
|
|
3125
|
-
remainingUses: unlockRemainingUses,
|
|
3126
|
-
onWalletSessionAuthorityReady: stageMintedLoginEd25519WalletSessionAuthority.bind(void 0, {
|
|
3127
|
-
sharedState,
|
|
3128
|
-
authorityDeferred
|
|
3129
|
-
})
|
|
3130
|
-
};
|
|
3131
|
-
const commonEd25519ConnectArgs = ed25519ProvisioningIdentity.kind === "fresh_ed25519_provisioning" ? {
|
|
3132
|
-
...ed25519ProvisioningIdentity,
|
|
3133
|
-
walletId: String(walletBinding.walletId),
|
|
3134
|
-
nearAccountId: walletBinding.nearAccountId,
|
|
3135
|
-
nearEd25519SigningKeyId: walletBinding.nearEd25519SigningKeyId,
|
|
3136
|
-
signerSlot: args.signerSlot,
|
|
3137
|
-
...sharedEd25519ConnectArgs
|
|
3138
|
-
} : {
|
|
3139
|
-
...ed25519ProvisioningIdentity,
|
|
3140
|
-
...sharedEd25519ConnectArgs
|
|
3141
|
-
};
|
|
3142
|
-
let connected;
|
|
3143
|
-
switch (ed25519SessionAuthority.kind) {
|
|
3144
|
-
case "email_otp":
|
|
3145
|
-
connected = await args.signingEngine.connectEd25519Session({
|
|
3146
|
-
...commonEd25519ConnectArgs,
|
|
3147
|
-
source: "email_otp",
|
|
3148
|
-
authority: ed25519SessionAuthority.authority,
|
|
3149
|
-
emailOtpAuthContext: ed25519SessionAuthority.emailOtpAuthContext,
|
|
3150
|
-
materialActivation: void 0
|
|
3151
|
-
});
|
|
3152
|
-
break;
|
|
3153
|
-
case "passkey":
|
|
3154
|
-
if (!args.passkeyUnlockEd25519Session) throw new Error("[login] verified wallet unlock omitted its Ed25519 Wallet Session");
|
|
3155
|
-
if (args.ed25519MintPlan.kind !== "wallet_custody") throw new Error("[login] verified unlock Ed25519 session requires wallet custody");
|
|
3156
|
-
connected = passkeyUnlockEd25519Connection({
|
|
3157
|
-
session: args.passkeyUnlockEd25519Session,
|
|
3158
|
-
walletBinding,
|
|
3159
|
-
signerSlot: args.signerSlot,
|
|
3160
|
-
custody: args.ed25519MintPlan.custody,
|
|
3161
|
-
provisionScope,
|
|
3162
|
-
credential,
|
|
3163
|
-
remainingUses: unlockRemainingUses,
|
|
3164
|
-
unlockAuthorization: args.passkeyUnlockWalletSessionAuthorization
|
|
3165
|
-
});
|
|
3166
|
-
break;
|
|
3167
|
-
default: return assertNeverLoginState(ed25519SessionAuthority);
|
|
3168
|
-
}
|
|
3169
|
-
if (!connected.ok) {
|
|
3170
|
-
const details = String(connected.message || connected.code || "Failed to connect threshold Ed25519 session");
|
|
3171
|
-
throw new Error(`[login] threshold Ed25519 warm-up failed: ${details}`);
|
|
3172
|
-
}
|
|
3173
|
-
ed25519Session = connected;
|
|
3174
|
-
if (!connected.thresholdSessionId) throw new Error("[login] threshold Ed25519 warm-up did not return a thresholdSessionId");
|
|
3175
|
-
const connectedAuthority = ed25519SessionAuthority.kind === "passkey" ? await exactPasskeyWalletAuthAuthorityRefForCredential({
|
|
3176
|
-
walletId: walletBinding.walletId,
|
|
3177
|
-
rpId: args.context.signingEngine.getRpId(),
|
|
3178
|
-
credentialIdB64u: passkeyCredentialIdB64uFromAuthentication(credential || void 0) || localPasskeyCredentialIdB64u
|
|
3179
|
-
}) : await walletAuthAuthorityRef({ authority: ed25519SessionAuthority.authority.authority });
|
|
3180
|
-
if (args.ed25519MintPlan.kind === "wallet_custody") {
|
|
3181
|
-
if (ed25519SessionAuthority.kind !== "passkey") throw new Error("[login] wallet custody requires passkey authority");
|
|
3182
|
-
const expectedMaterialActivation = resolveLoginPasskeyMaterialActivation(ed25519ProvisioningIdentity, args.ed25519MintPlan);
|
|
3183
|
-
const passkeyPrfFirstB64u = credential ? passkeyPrfFirstB64uFromCredential(credential) : "";
|
|
3184
|
-
if (!passkeyPrfFirstB64u) throw new Error("[login] wallet custody requires WebAuthn PRF.first");
|
|
3185
|
-
await args.signingEngine.withExactEd25519MaterialOwner({
|
|
3186
|
-
materialActivation: expectedMaterialActivation,
|
|
3187
|
-
nearAccountId: walletBinding.nearAccountId,
|
|
3188
|
-
task: openAndActivatePasskeyEd25519CustodyLogin.bind(void 0, {
|
|
3189
|
-
signingEngine: args.signingEngine,
|
|
3190
|
-
custody: args.ed25519MintPlan.custody,
|
|
3191
|
-
walletBinding,
|
|
3192
|
-
signerSlot: args.signerSlot,
|
|
3193
|
-
passkeyPrfFirstB64u,
|
|
3194
|
-
walletSession: connected,
|
|
3195
|
-
authority: connectedAuthority,
|
|
3196
|
-
routerAbNormalSigning: provisionScope.routerAbNormalSigning,
|
|
3197
|
-
relayerUrl: args.relayerUrl
|
|
3198
|
-
})
|
|
3199
|
-
});
|
|
3200
|
-
}
|
|
3201
|
-
}
|
|
3202
|
-
});
|
|
3203
|
-
if (signersToWarm.includes("ecdsa")) tasks.push({
|
|
3204
|
-
signer: "ecdsa",
|
|
3205
|
-
dependencies: [],
|
|
3206
|
-
onFailure: null,
|
|
3207
|
-
run: async () => {
|
|
3208
|
-
await authorityDeferred?.promise;
|
|
3209
|
-
let bootstrapIdentity = null;
|
|
3210
|
-
let consumedPasskeyExchangeActivation = false;
|
|
3211
|
-
const activationByMaterial = /* @__PURE__ */ new Map();
|
|
3212
|
-
const configuredEcdsaTargets = listConfiguredThresholdEcdsaPublicationTargets(args.context.configs.network.chains);
|
|
3213
|
-
const completeActiveContextFromConfiguredTargets = (source) => {
|
|
3214
|
-
const completion = buildConfiguredTargetKeyCompletion({
|
|
3215
|
-
context: sharedState.activeCanonicalEcdsaContext,
|
|
3216
|
-
configuredTargets: configuredEcdsaTargets
|
|
3217
|
-
});
|
|
3218
|
-
if (completion.kind === "complete_configured_target_keys") {
|
|
3219
|
-
sharedState.activeCanonicalEcdsaContext = completion.context;
|
|
3220
|
-
return;
|
|
3221
|
-
}
|
|
3222
|
-
if (completion.kind === "missing_configured_target_keys") return;
|
|
3223
|
-
requireCompleteConfiguredTargetKeyContext({
|
|
3224
|
-
completion,
|
|
3225
|
-
source
|
|
3226
|
-
});
|
|
3227
|
-
};
|
|
3228
|
-
const rememberEcdsaAuthorizedEd25519Mint = (bootstrap) => {
|
|
3229
|
-
if (ecdsaAuthorizedEd25519Mint) return;
|
|
3230
|
-
const operationCredential = bootstrap.session.operationCredential;
|
|
3231
|
-
const passkeyPrfFirstB64u = credential ? passkeyPrfFirstB64uFromCredential(credential) : "";
|
|
3232
|
-
const passkeyCredentialIdB64u = passkeyCredentialIdB64uFromAuthentication(credential || void 0) || localPasskeyCredentialIdB64u;
|
|
3233
|
-
if (!operationCredential.token || !passkeyPrfFirstB64u || !passkeyCredentialIdB64u) return;
|
|
3234
|
-
ecdsaAuthorizedEd25519Mint = {
|
|
3235
|
-
operationCredential,
|
|
3236
|
-
passkeyPrfFirstB64u,
|
|
3237
|
-
passkeyCredentialIdB64u,
|
|
3238
|
-
quotaId: bootstrap.session.quotaId
|
|
3239
|
-
};
|
|
3240
|
-
};
|
|
3241
|
-
const resolveCurrentBootstrapIdentity = () => {
|
|
3242
|
-
if (sharedState.ed25519.operationCredential) return { routeAuth: sharedState.ed25519.operationCredential };
|
|
3243
|
-
const operationCredential = ecdsaAuthorizedEd25519Mint?.operationCredential;
|
|
3244
|
-
if (operationCredential) return { routeAuth: operationCredential };
|
|
3245
|
-
if (bootstrapIdentity) return bootstrapIdentity;
|
|
3246
|
-
bootstrapIdentity = resolveThresholdLoginWarmEcdsaBootstrapIdentity({
|
|
3247
|
-
credentialState: args.credentialState,
|
|
3248
|
-
routeAuthorization: args.routeAuthorization
|
|
3249
|
-
});
|
|
3250
|
-
return bootstrapIdentity;
|
|
3251
|
-
};
|
|
3252
|
-
const bootstrapTarget = async (target, targetEcdsaKey) => {
|
|
3253
|
-
if (!targetEcdsaKey.key) throw new Error("[login] threshold ECDSA warm-up requires configured target key identity");
|
|
3254
|
-
const publicCapability = await resolvePersistedEcdsaPublicCapabilityForLogin({
|
|
3255
|
-
walletId: args.walletIdentity.walletId,
|
|
3256
|
-
chainTarget: target.chainTarget,
|
|
3257
|
-
targetEcdsaKey
|
|
3258
|
-
});
|
|
3259
|
-
const reusedMaterialActivation = activationByMaterial.get(sharedEcdsaActivationKey(publicCapability));
|
|
3260
|
-
const exchangeActivation = args.passkeyExchangeEcdsaActivation;
|
|
3261
|
-
const matchingExchangeActivation = exchangeActivation && !consumedPasskeyExchangeActivation && exchangeActivation.targetKey === thresholdEcdsaChainTargetKey(target.chainTarget) ? exchangeActivation : null;
|
|
3262
|
-
const preauthorized = matchingExchangeActivation ? {
|
|
3263
|
-
sessionActivation: matchingExchangeActivation.sessionActivation,
|
|
3264
|
-
authorizationIdentity: matchingExchangeActivation.authorizationIdentity
|
|
3265
|
-
} : reusedMaterialActivation ?? null;
|
|
3266
|
-
const thresholdSessionId = preauthorized ? thresholdSessionIdFromPasskeyEcdsaActivation(preauthorized.sessionActivation) : resolveThresholdLoginWarmEcdsaThresholdSessionId({ sharedState: ecdsaThresholdSessionState });
|
|
3267
|
-
const runtimePolicyScope = sharedState.activeCanonicalEcdsaContext.runtimePolicyScope;
|
|
3268
|
-
if (!runtimePolicyScope) throw new Error("[login] ECDSA session lane requires runtimePolicyScope");
|
|
3269
|
-
const lanePolicy = buildEvmFamilyEcdsaSessionLanePolicy({
|
|
3270
|
-
chainTarget: target.chainTarget,
|
|
3271
|
-
thresholdSessionId,
|
|
3272
|
-
ttlMs: args.ttlMs,
|
|
3273
|
-
remainingUses: unlockRemainingUses,
|
|
3274
|
-
runtimePolicyScope
|
|
3275
|
-
});
|
|
3276
|
-
const existingRoleLocalMaterial = targetEcdsaKey.existingRoleLocalMaterial;
|
|
3277
|
-
if (!existingRoleLocalMaterial) throw createThresholdEcdsaDeviceLinkRequiredError(thresholdEcdsaChainTargetKey(target.chainTarget));
|
|
3278
|
-
if (!localPasskeyCredentialIdB64u) throw new Error("[login] ECDSA role-local activation requires passkey identity");
|
|
3279
|
-
const authorizationAuthority = existingRoleLocalMaterial.authority;
|
|
3280
|
-
if (preauthorized) {
|
|
3281
|
-
if (matchingExchangeActivation) consumedPasskeyExchangeActivation = true;
|
|
3282
|
-
return await bootstrapLoginEcdsaSession({
|
|
3283
|
-
signingEngine: args.signingEngine,
|
|
3284
|
-
runtimeScopeBootstrapState: args.runtimeScopeBootstrapState,
|
|
3285
|
-
request: {
|
|
3286
|
-
kind: "passkey_preauthorized_ecdsa_bootstrap",
|
|
3287
|
-
source: "login",
|
|
3288
|
-
relayerUrl: args.relayerUrl,
|
|
3289
|
-
keyHandle: toEvmFamilyEcdsaKeyHandle(targetEcdsaKey.keyHandle),
|
|
3290
|
-
key: targetEcdsaKey.key,
|
|
3291
|
-
lanePolicy,
|
|
3292
|
-
publicCapability,
|
|
3293
|
-
existingRoleLocalMaterial,
|
|
3294
|
-
authorizationAuthority,
|
|
3295
|
-
authorizationIdentity: preauthorized.authorizationIdentity,
|
|
3296
|
-
passkeyCredentialIdB64u: localPasskeyCredentialIdB64u,
|
|
3297
|
-
sessionActivation: preauthorized.sessionActivation
|
|
3298
|
-
}
|
|
3299
|
-
});
|
|
3300
|
-
}
|
|
3301
|
-
const reconnectRouteAuth = resolveCurrentBootstrapIdentity().routeAuth;
|
|
3302
|
-
if (!isWalletSessionReconnectEcdsaRouteAuth(reconnectRouteAuth)) throw new Error("[login] ECDSA role-local activation requires a verified Wallet Session");
|
|
3303
|
-
return await bootstrapLoginEcdsaSession({
|
|
3304
|
-
signingEngine: args.signingEngine,
|
|
3305
|
-
runtimeScopeBootstrapState: args.runtimeScopeBootstrapState,
|
|
3306
|
-
request: {
|
|
3307
|
-
kind: "wallet_session_reconnect_ecdsa_bootstrap",
|
|
3308
|
-
source: "login",
|
|
3309
|
-
relayerUrl: args.relayerUrl,
|
|
3310
|
-
keyHandle: toEvmFamilyEcdsaKeyHandle(targetEcdsaKey.keyHandle),
|
|
3311
|
-
key: targetEcdsaKey.key,
|
|
3312
|
-
lanePolicy,
|
|
3313
|
-
publicCapability,
|
|
3314
|
-
existingRoleLocalMaterial,
|
|
3315
|
-
authorizationAuthority,
|
|
3316
|
-
passkeyCredentialIdB64u: localPasskeyCredentialIdB64u,
|
|
3317
|
-
routeAuth: reconnectRouteAuth
|
|
3318
|
-
}
|
|
3319
|
-
});
|
|
3320
|
-
};
|
|
3321
|
-
const bootstrapConfiguredTargets = async () => {
|
|
3322
|
-
completeActiveContextFromConfiguredTargets("login ECDSA warm-up preflight");
|
|
3323
|
-
const orderedConfiguredEcdsaTargets = [];
|
|
3324
|
-
const preauthorizedTargetKey = args.passkeyExchangeEcdsaActivation?.targetKey || null;
|
|
3325
|
-
if (preauthorizedTargetKey) {
|
|
3326
|
-
for (const target of configuredEcdsaTargets) if (thresholdEcdsaChainTargetKey(target.chainTarget) === preauthorizedTargetKey) orderedConfiguredEcdsaTargets.push(target);
|
|
3327
|
-
}
|
|
3328
|
-
for (const target of configuredEcdsaTargets) if (thresholdEcdsaChainTargetKey(target.chainTarget) !== preauthorizedTargetKey) orderedConfiguredEcdsaTargets.push(target);
|
|
3329
|
-
for (const target of orderedConfiguredEcdsaTargets) {
|
|
3330
|
-
const targetKey = thresholdEcdsaChainTargetKey(target.chainTarget);
|
|
3331
|
-
const targetEcdsaKey = sharedState.activeCanonicalEcdsaContext.ecdsaKeys.find((key) => key.targetKey === targetKey);
|
|
3332
|
-
const keyHandle = String(targetEcdsaKey?.keyHandle || "").trim();
|
|
3333
|
-
if (!targetEcdsaKey?.key || !keyHandle) throw createThresholdEcdsaDeviceLinkRequiredError(targetKey);
|
|
3334
|
-
const bootstrap = await bootstrapTarget(target, targetEcdsaKey);
|
|
3335
|
-
ecdsaBootstraps.push(bootstrap);
|
|
3336
|
-
scheduleEcdsaSessionPresignaturePrefill({
|
|
3337
|
-
statusReads: args.statusReads,
|
|
3338
|
-
trigger: "unlock",
|
|
3339
|
-
signingEngine: args.signingEngine,
|
|
3340
|
-
walletId: args.walletIdentity.walletId,
|
|
3341
|
-
chainTarget: target.chainTarget
|
|
3342
|
-
});
|
|
3343
|
-
rememberEcdsaAuthorizedEd25519Mint(bootstrap);
|
|
3344
|
-
const activation = preauthorizedEcdsaActivationFromBootstrap(bootstrap);
|
|
3345
|
-
const activationKey = sharedEcdsaActivationKey(activation.public_capability);
|
|
3346
|
-
if (!activationByMaterial.has(activationKey)) {
|
|
3347
|
-
const activationAuthority = await resolveActivePasskeyWalletSessionAuthority({
|
|
3348
|
-
walletId: args.walletIdentity.walletId,
|
|
3349
|
-
authorization: {
|
|
3350
|
-
record: bootstrap.session.walletSession,
|
|
3351
|
-
operationCredential: bootstrap.session.operationCredential
|
|
3352
|
-
}
|
|
3353
|
-
});
|
|
3354
|
-
activationByMaterial.set(activationKey, {
|
|
3355
|
-
sessionActivation: activation,
|
|
3356
|
-
authorizationIdentity: activationAuthority.identity
|
|
3357
|
-
});
|
|
3358
|
-
}
|
|
3359
|
-
if (String(bootstrap.thresholdEcdsaKeyRef?.keyHandle || "").trim() !== targetEcdsaKey.keyHandle) throw new Error(`[login] threshold ECDSA warm-up returned a different keyHandle for ${targetKey}`);
|
|
3360
|
-
}
|
|
3361
|
-
if (args.passkeyExchangeEcdsaActivation && !consumedPasskeyExchangeActivation) throw new Error("[login] passkey exchange ECDSA activation did not match a configured target");
|
|
3362
|
-
};
|
|
3363
|
-
try {
|
|
3364
|
-
await bootstrapConfiguredTargets();
|
|
3365
|
-
} catch (error) {
|
|
3366
|
-
const details = thresholdLoginWarmupErrorMessage(error) || "Failed to bootstrap threshold ECDSA session";
|
|
3367
|
-
throw new Error(`[login] threshold ECDSA warm-up failed: ${details}`);
|
|
3368
|
-
}
|
|
3369
|
-
}
|
|
3370
|
-
});
|
|
3371
|
-
await runThresholdLoginWarmupTasks(tasks);
|
|
3372
|
-
return {
|
|
3373
|
-
ecdsaBootstraps,
|
|
3374
|
-
ed25519Session
|
|
3375
|
-
};
|
|
3376
|
-
}
|
|
3377
|
-
async function getWalletSession(context, walletId) {
|
|
3378
|
-
let currentAuthentication = context.signingEngine.readWalletAuthenticationState();
|
|
3379
|
-
const requestedWalletId = walletId ?? (currentAuthentication.kind !== "signed_out" ? currentAuthentication.walletId : void 0);
|
|
3380
|
-
let requestedWalletIdValue = null;
|
|
3381
|
-
let requestedAuthenticationRead = null;
|
|
3382
|
-
if (requestedWalletId !== void 0) {
|
|
3383
|
-
const parsedRequestedWalletId = parseWalletId(String(requestedWalletId));
|
|
3384
|
-
if (parsedRequestedWalletId.ok) {
|
|
3385
|
-
requestedWalletIdValue = parsedRequestedWalletId.value;
|
|
3386
|
-
requestedAuthenticationRead = await readExactWalletSessionAuthentication({
|
|
3387
|
-
walletId: parsedRequestedWalletId.value,
|
|
3388
|
-
ports: browserExactWalletSessionReadPorts
|
|
3389
|
-
});
|
|
3390
|
-
if (requestedAuthenticationRead.kind === "upgrade_required") throw new WalletSessionAuthorizationUpgradeRequiredError("[WalletSession] Wallet Session authorization requires a newer client");
|
|
3391
|
-
if (requestedAuthenticationRead.kind === "missing") currentAuthentication = { kind: "signed_out" };
|
|
3392
|
-
}
|
|
3393
|
-
}
|
|
3394
|
-
let readResolution = await resolveWalletCapabilitySubjectResolution(requestedWalletId);
|
|
3395
|
-
if (readResolution.kind === "no_session_for_wallet") {
|
|
3396
|
-
const linkedSubjectSet = await resolveLinkedDeviceUnlockSubjectSet(String(readResolution.walletId));
|
|
3397
|
-
if (linkedSubjectSet) readResolution = {
|
|
3398
|
-
kind: "resolved",
|
|
3399
|
-
walletId: readResolution.walletId,
|
|
3400
|
-
subjectSet: linkedSubjectSet,
|
|
3401
|
-
source: "local_wallet_authority"
|
|
3402
|
-
};
|
|
3403
|
-
}
|
|
3404
|
-
let didReconcileEcdsaActivation = false;
|
|
3405
|
-
if (readResolution.kind === "no_session_request") return buildAnonymousWalletSession();
|
|
3406
|
-
if (readResolution.kind === "no_session_for_wallet") {
|
|
3407
|
-
const journalSelectors = await resolveEcdsaActivationJournalSelectors(readResolution.walletId);
|
|
3408
|
-
if (journalSelectors.kind !== "resolved") return await buildCapabilityUnresolvableWalletSession({
|
|
3409
|
-
context,
|
|
3410
|
-
walletId: readResolution.walletId,
|
|
3411
|
-
reason: "activation_reconciliation_failed"
|
|
3412
|
-
});
|
|
3413
|
-
if (journalSelectors.selectors.length > 0) {
|
|
3414
|
-
didReconcileEcdsaActivation = true;
|
|
3415
|
-
const reconciliation = await reconcileCanonicalEcdsaActivationSelectors({
|
|
3416
|
-
workerCtx: context.signingEngine.getSignerWorkerContext(),
|
|
3417
|
-
selectors: journalSelectors.selectors
|
|
3418
|
-
});
|
|
3419
|
-
if (reconciliation.didFinalize) readResolution = await resolveWalletCapabilitySubjectResolution(readResolution.walletId);
|
|
3420
|
-
if (readResolution.kind === "no_session_for_wallet" && reconciliation.kind !== "settled") return await buildCapabilityUnresolvableWalletSession({
|
|
3421
|
-
context,
|
|
3422
|
-
walletId: readResolution.walletId,
|
|
3423
|
-
reason: reconciliation.kind === "pending" ? "activation_reconciliation_pending" : "activation_reconciliation_failed"
|
|
3424
|
-
});
|
|
3425
|
-
}
|
|
3426
|
-
}
|
|
3427
|
-
if (readResolution.kind === "no_session_for_wallet") return await buildCapabilityUnresolvableWalletSession({
|
|
3428
|
-
context,
|
|
3429
|
-
walletId: readResolution.walletId,
|
|
3430
|
-
reason: readResolution.reason
|
|
3431
|
-
});
|
|
3432
|
-
if (readResolution.kind === "no_session_request") return buildAnonymousWalletSession();
|
|
3433
|
-
if (readResolution.kind === "unresolvable_profile") {
|
|
3434
|
-
console.warn("[WalletSession] wallet session profile is unresolvable", {
|
|
3435
|
-
profileId: readResolution.profileId,
|
|
3436
|
-
reason: readResolution.reason
|
|
3437
|
-
});
|
|
3438
|
-
return buildAnonymousWalletSession();
|
|
3439
|
-
}
|
|
3440
|
-
if (readResolution.kind === "unresolvable") {
|
|
3441
|
-
console.warn("[WalletSession] wallet session identity is unresolvable", {
|
|
3442
|
-
walletId: String(readResolution.walletId),
|
|
3443
|
-
reason: readResolution.reason
|
|
3444
|
-
});
|
|
3445
|
-
return await buildCapabilityUnresolvableWalletSession({
|
|
3446
|
-
context,
|
|
3447
|
-
walletId: readResolution.walletId,
|
|
3448
|
-
reason: readResolution.reason
|
|
3449
|
-
});
|
|
3450
|
-
}
|
|
3451
|
-
const activeEcdsaSelectors = ecdsaActivationSelectorsFromSubjectSet(readResolution.subjectSet);
|
|
3452
|
-
if (!didReconcileEcdsaActivation && activeEcdsaSelectors.length > 0) reportNonSettledEcdsaActivationReconciliation(await reconcileCanonicalEcdsaActivationSelectors({
|
|
3453
|
-
workerCtx: context.signingEngine.getSignerWorkerContext(),
|
|
3454
|
-
selectors: activeEcdsaSelectors
|
|
3455
|
-
}));
|
|
3456
|
-
await context.signingEngine.assertSealedRefreshStartupParity().catch((error) => {
|
|
3457
|
-
console.warn("[WalletSession] sealed refresh startup parity check failed during session read; continuing with cached login state", error instanceof Error ? error.message : String(error || "unknown error"));
|
|
3458
|
-
});
|
|
3459
|
-
const [appIdentity, availableLanes] = await Promise.all([resolveWalletSessionAppIdentity(context, readResolution), readExactWalletSessionAvailableLanes(context, readResolution.walletId)]);
|
|
3460
|
-
const restoredAuthenticationRead = requestedAuthenticationRead && requestedWalletIdValue && String(requestedWalletIdValue) === String(readResolution.walletId) ? requestedAuthenticationRead : await readExactWalletSessionAuthentication({
|
|
3461
|
-
walletId: readResolution.walletId,
|
|
3462
|
-
ports: browserExactWalletSessionReadPorts
|
|
3463
|
-
});
|
|
3464
|
-
let authentication = { kind: "signed_out" };
|
|
3465
|
-
switch (restoredAuthenticationRead.kind) {
|
|
3466
|
-
case "authenticated":
|
|
3467
|
-
if (await setRestoredWalletAuthenticationIfUnlocked(context, restoredAuthenticationRead.state)) authentication = restoredAuthenticationRead.state;
|
|
3468
|
-
break;
|
|
3469
|
-
case "missing": break;
|
|
3470
|
-
case "upgrade_required": throw new WalletSessionAuthorizationUpgradeRequiredError("[WalletSession] Wallet Session authorization requires a newer client");
|
|
3471
|
-
}
|
|
3472
|
-
const capabilityProjection = buildWalletSessionCapabilityProjection({
|
|
3473
|
-
subjectSet: authentication.kind === "authenticated" && restoredAuthenticationRead.kind === "authenticated" ? scopeSubjectSetToWalletAuthMethod(readResolution.subjectSet, restoredAuthenticationRead.walletAuthMethodId) : readResolution.subjectSet,
|
|
3474
|
-
availableLanes,
|
|
3475
|
-
configuredEcdsaTargets: listConfiguredThresholdEcdsaPublicationTargets(context.configs.network.chains).map((target) => target.chainTarget)
|
|
3476
|
-
});
|
|
3477
|
-
return {
|
|
3478
|
-
appIdentity,
|
|
3479
|
-
authentication,
|
|
3480
|
-
capabilityProjection,
|
|
3481
|
-
nonceDiagnostics: readWalletSessionNonceDiagnostics(context, appIdentity.nearAccountId)
|
|
3482
|
-
};
|
|
3483
|
-
}
|
|
3484
|
-
function scopeSubjectSetToWalletAuthMethod(subjectSet, walletAuthMethodId) {
|
|
3485
|
-
const [first, ...rest] = subjectSet.subjects.filter((subject) => subject.kind !== "evm_family_ecdsa_wallet" || String(subject.authority.walletAuthMethodId) === String(walletAuthMethodId));
|
|
3486
|
-
if (!first) return subjectSet;
|
|
3487
|
-
return {
|
|
3488
|
-
...subjectSet,
|
|
3489
|
-
subjects: [first, ...rest]
|
|
3490
|
-
};
|
|
3491
|
-
}
|
|
3492
|
-
/**
|
|
3493
|
-
* A restore read races the user's lock: the read observes an unlocked
|
|
3494
|
-
* selection, the lock lands while its network validation runs, and the stale
|
|
3495
|
-
* result would re-authenticate a wallet the user just locked. Re-checking the
|
|
3496
|
-
* durable lock right before the runtime write keeps the lock decisive over
|
|
3497
|
-
* any in-flight restore.
|
|
3498
|
-
*/
|
|
3499
|
-
async function setRestoredWalletAuthenticationIfUnlocked(context, state) {
|
|
3500
|
-
let lockedOut = false;
|
|
3501
|
-
try {
|
|
3502
|
-
const selected = await IndexedDBManager.resolveSelectedWalletAuthority(String(state.walletId));
|
|
3503
|
-
lockedOut = selected.kind !== "resolved" || selected.selection.lockState !== "unlocked";
|
|
3504
|
-
} catch {
|
|
3505
|
-
lockedOut = true;
|
|
3506
|
-
}
|
|
3507
|
-
if (lockedOut) return false;
|
|
3508
|
-
context.signingEngine.setWalletAuthenticated(state);
|
|
3509
|
-
return true;
|
|
3510
|
-
}
|
|
3511
|
-
async function buildCapabilityUnresolvableWalletSession(args) {
|
|
3512
|
-
const [appIdentity, exactAuthenticationRead] = await Promise.all([resolveWalletSessionAppIdentityForWallet(args.context, args.walletId), readExactWalletSessionAuthentication({
|
|
3513
|
-
walletId: args.walletId,
|
|
3514
|
-
ports: browserExactWalletSessionReadPorts
|
|
3515
|
-
})]);
|
|
3516
|
-
let authentication = { kind: "signed_out" };
|
|
3517
|
-
switch (exactAuthenticationRead.kind) {
|
|
3518
|
-
case "authenticated":
|
|
3519
|
-
if (await setRestoredWalletAuthenticationIfUnlocked(args.context, exactAuthenticationRead.state)) authentication = exactAuthenticationRead.state;
|
|
3520
|
-
break;
|
|
3521
|
-
case "missing": break;
|
|
3522
|
-
case "upgrade_required": throw new WalletSessionAuthorizationUpgradeRequiredError("[WalletSession] Wallet Session authorization requires a newer client");
|
|
3523
|
-
}
|
|
3524
|
-
return {
|
|
3525
|
-
appIdentity,
|
|
3526
|
-
authentication,
|
|
3527
|
-
capabilityProjection: {
|
|
3528
|
-
kind: "unresolvable",
|
|
3529
|
-
reason: args.reason
|
|
3530
|
-
},
|
|
3531
|
-
nonceDiagnostics: readWalletSessionNonceDiagnostics(args.context, appIdentity.nearAccountId)
|
|
3532
|
-
};
|
|
3533
|
-
}
|
|
3534
|
-
function readExactWalletSessionAvailableLanes(context, walletId) {
|
|
3535
|
-
return context.signingEngine.readPersistedAvailableSigningLanes({ walletId }).then((lanes) => ({
|
|
3536
|
-
kind: "available",
|
|
3537
|
-
lanes
|
|
3538
|
-
})).catch(() => ({ kind: "unavailable" }));
|
|
3539
|
-
}
|
|
3540
|
-
function readWalletSessionNonceDiagnostics(context, nearAccountId) {
|
|
3541
|
-
const accountId = String(nearAccountId || "").trim();
|
|
3542
|
-
if (!accountId) return null;
|
|
3543
|
-
try {
|
|
3544
|
-
return context.signingEngine.getNonceCoordinator().getDiagnostics({
|
|
3545
|
-
accountId,
|
|
3546
|
-
emitMetrics: true
|
|
3547
|
-
});
|
|
3548
|
-
} catch {
|
|
3549
|
-
return null;
|
|
3550
|
-
}
|
|
3551
|
-
}
|
|
3552
|
-
function normalizeEvmOwnerAddress(value) {
|
|
3553
|
-
const candidate = String(value || "").trim().toLowerCase();
|
|
3554
|
-
return /^0x[0-9a-f]{40}$/.test(candidate) ? candidate : "";
|
|
3555
|
-
}
|
|
3556
|
-
async function readProfileContinuityThresholdEcdsaWalletKeys(context, walletId) {
|
|
3557
|
-
const configuredTargets = listConfiguredThresholdEcdsaPublicationTargets(context.configs.network.chains).map((target) => target.chainTarget);
|
|
3558
|
-
if (!configuredTargets.length) return [];
|
|
3559
|
-
const walletSigners = await IndexedDBManager.listAccountSignersByProfile({
|
|
3560
|
-
profileId: String(walletId),
|
|
3561
|
-
status: "active"
|
|
3562
|
-
}).catch(() => []);
|
|
3563
|
-
const walletKeys = [];
|
|
3564
|
-
for (const signer of walletSigners) {
|
|
3565
|
-
const parsed = parseActiveEcdsaSignerRecordForUnlock({
|
|
3566
|
-
walletId,
|
|
3567
|
-
configuredTargets,
|
|
3568
|
-
signer
|
|
3569
|
-
});
|
|
3570
|
-
if (parsed.kind === "active_ecdsa_signer_record") walletKeys.push(parsed.walletKey);
|
|
3571
|
-
}
|
|
3572
|
-
return walletKeys;
|
|
3573
|
-
}
|
|
3574
|
-
async function resolveProfileContinuityThresholdEcdsaEthereumAddress(context, walletId) {
|
|
3575
|
-
const addresses = [...new Set((await readProfileContinuityThresholdEcdsaWalletKeys(context, walletId)).map((walletKey) => normalizeEvmOwnerAddress(walletKey.keyFacts.thresholdOwnerAddress)).filter(Boolean))];
|
|
3576
|
-
if (addresses.length === 1) return addresses[0];
|
|
3577
|
-
if (addresses.length > 1) console.warn("[WalletSession] conflicting profile threshold ECDSA addresses", {
|
|
3578
|
-
walletId: String(walletId),
|
|
3579
|
-
addresses
|
|
3580
|
-
});
|
|
3581
|
-
return null;
|
|
3582
|
-
}
|
|
3583
|
-
function resolveThresholdLoginWarmSigners(args) {
|
|
3584
|
-
if (args.selection.mode === "ed25519_only") return ["ed25519"];
|
|
3585
|
-
if (!args.configuredEcdsaTargets.length) return args.selection.mode === "ecdsa_only" ? [] : ["ed25519"];
|
|
3586
|
-
const keyIdsByTarget = new Set((args.canonicalEcdsaContext?.ecdsaKeys || []).map((key) => key.targetKey));
|
|
3587
|
-
if (keyIdsByTarget.size === 0) throw new Error("[login] threshold ECDSA warm-up missing canonical key identity");
|
|
3588
|
-
const missingTargets = args.configuredEcdsaTargets.map((target) => thresholdEcdsaChainTargetKey(target.chainTarget)).filter((targetKey) => !keyIdsByTarget.has(targetKey));
|
|
3589
|
-
if (missingTargets.length) throw new Error(`[login] threshold ECDSA warm-up missing configured-target key ids for ${missingTargets.join(", ")}`);
|
|
3590
|
-
return args.selection.mode === "ecdsa_only" ? ["ecdsa"] : ["ed25519", "ecdsa"];
|
|
3591
|
-
}
|
|
3592
|
-
function resolveThresholdLoginWarmupPlan(args) {
|
|
3593
|
-
const configuredTargetKeyCompletion = buildConfiguredTargetKeyCompletion({
|
|
3594
|
-
context: args.storedCanonicalEcdsaContext,
|
|
3595
|
-
configuredTargets: args.selectedEcdsaTargets
|
|
3596
|
-
});
|
|
3597
|
-
const ecdsaContext = requireCompleteConfiguredTargetKeyContext({
|
|
3598
|
-
completion: configuredTargetKeyCompletion,
|
|
3599
|
-
source: "stored ECDSA key facts"
|
|
3600
|
-
});
|
|
3601
|
-
let signersToWarm = resolveThresholdLoginWarmSigners({
|
|
3602
|
-
selection: args.selection,
|
|
3603
|
-
configuredEcdsaTargets: args.selectedEcdsaTargets,
|
|
3604
|
-
canonicalEcdsaContext: ecdsaContext
|
|
3605
|
-
});
|
|
3606
|
-
if (args.wantsEd25519Warmup && !signersToWarm.includes("ed25519")) signersToWarm = ["ed25519", ...signersToWarm];
|
|
3607
|
-
const ed25519DependsOnEcdsa = false;
|
|
3608
|
-
const ecdsaDependsOnEd25519 = signersToWarm.includes("ed25519") && signersToWarm.includes("ecdsa");
|
|
3609
|
-
if (!signersToWarm.length) throw new Error("[login] ECDSA unlock requested with no configured ECDSA targets");
|
|
3610
|
-
return {
|
|
3611
|
-
kind: "threshold_login_warmup_plan_ready",
|
|
3612
|
-
storedCanonicalEcdsaContext: args.storedCanonicalEcdsaContext,
|
|
3613
|
-
configuredTargetKeyCompletion,
|
|
3614
|
-
ecdsaContext,
|
|
3615
|
-
signersToWarm,
|
|
3616
|
-
ed25519DependsOnEcdsa,
|
|
3617
|
-
ecdsaDependsOnEd25519
|
|
3618
|
-
};
|
|
3619
|
-
}
|
|
3620
|
-
function createThresholdLoginWarmSessionId(prefix) {
|
|
3621
|
-
return secureRandomId(prefix, 32, "threshold login warm session IDs");
|
|
3622
|
-
}
|
|
3623
|
-
function requireThresholdLoginEcdsaSessionId(value) {
|
|
3624
|
-
const parsed = parseThresholdEcdsaSessionId(value);
|
|
3625
|
-
if (!parsed.ok) throw new Error("[login] failed to create threshold ECDSA session identity");
|
|
3626
|
-
return parsed.value;
|
|
3627
|
-
}
|
|
3628
|
-
function requireThresholdLoginWalletSessionMintId(value) {
|
|
3629
|
-
const parsed = parseWalletSessionMintId(value);
|
|
3630
|
-
if (!parsed.ok) throw new Error("[login] failed to create Wallet Session mint identity");
|
|
3631
|
-
return parsed.value;
|
|
3632
|
-
}
|
|
3633
|
-
function requireLoginUnlockSessionUses(remainingUses) {
|
|
3634
|
-
if (remainingUses == null || remainingUses <= 0) throw new Error("[login] unlock warm-up requires positive unlock session uses");
|
|
3635
|
-
return remainingUses;
|
|
3636
|
-
}
|
|
3637
|
-
function createThresholdEcdsaDeviceLinkRequiredError(targetKey) {
|
|
3638
|
-
const error = /* @__PURE__ */ new Error(`[login] device_link_required: local threshold ECDSA material is unavailable for ${targetKey}`);
|
|
3639
|
-
error.code = "device_link_required";
|
|
3640
|
-
return error;
|
|
3641
|
-
}
|
|
3642
|
-
function createThresholdEd25519DeviceLinkRequiredError() {
|
|
3643
|
-
const error = /* @__PURE__ */ new Error("[login] device_link_required: local threshold Ed25519 material is unavailable");
|
|
3644
|
-
error.code = "device_link_required";
|
|
3645
|
-
return error;
|
|
3646
|
-
}
|
|
3647
|
-
function resolveThresholdLoginWarmEcdsaThresholdSessionId(input) {
|
|
3648
|
-
const current = String(input.sharedState.generatedThresholdSessionId || "").trim();
|
|
3649
|
-
if (current) return current;
|
|
3650
|
-
const generated = createThresholdLoginWarmSessionId("threshold-ecdsa-login");
|
|
3651
|
-
input.sharedState.generatedThresholdSessionId = generated;
|
|
3652
|
-
return generated;
|
|
3653
|
-
}
|
|
3654
|
-
async function resolveWalletEcdsaKeyFactsInventoryWithWebAuthn(args) {
|
|
3655
|
-
if (!args.collectCredential) throw new Error("[login] WebAuthn ECDSA key-facts inventory requires a credential collector");
|
|
3656
|
-
const serverNonceB64u = createLocalUnlockChallengeB64u();
|
|
3657
|
-
const expectedChallengeDigestB64u = await computeWalletEcdsaKeyFactsInventoryChallengeDigestB64u({
|
|
3658
|
-
walletId: args.walletId,
|
|
3659
|
-
rpId: args.rpId,
|
|
3660
|
-
keyTargets: args.keyTargets,
|
|
3661
|
-
serverNonceB64u,
|
|
3662
|
-
...args.runtimePolicyScope ? { runtimePolicyScope: args.runtimePolicyScope } : {}
|
|
3663
|
-
});
|
|
3664
|
-
const credential = await args.collectCredential(expectedChallengeDigestB64u);
|
|
3665
|
-
return await fetchWalletEcdsaKeyFactsInventoryWithWebAuthn({
|
|
3666
|
-
relayerUrl: args.relayerUrl,
|
|
3667
|
-
walletId: args.walletId,
|
|
3668
|
-
rpId: args.rpId,
|
|
3669
|
-
credential,
|
|
3670
|
-
keyTargets: args.keyTargets,
|
|
3671
|
-
serverNonceB64u,
|
|
3672
|
-
expectedChallengeDigestB64u,
|
|
3673
|
-
...args.runtimePolicyScope ? { runtimePolicyScope: args.runtimePolicyScope } : {}
|
|
3674
|
-
});
|
|
3675
|
-
}
|
|
3676
|
-
async function resolveWalletEcdsaKeyFactsInventoryForLogin(args) {
|
|
3677
|
-
const relayerUrl = String(args.relayerUrl || "").trim();
|
|
3678
|
-
const rpId = String(args.rpId || "").trim();
|
|
3679
|
-
if (!relayerUrl || !rpId) throw new Error("[login] threshold ECDSA key-facts inventory requires relayerUrl and rpId");
|
|
3680
|
-
if (args.authority?.kind === "wallet_session_operation_credential_v1") return await fetchWalletEcdsaKeyFactsInventoryWithOperationCredential({
|
|
3681
|
-
relayerUrl,
|
|
3682
|
-
walletId: args.walletId,
|
|
3683
|
-
rpId,
|
|
3684
|
-
operationCredential: args.authority.operationCredential,
|
|
3685
|
-
keyTargets: args.keyTargets
|
|
3686
|
-
});
|
|
3687
|
-
return await resolveWalletEcdsaKeyFactsInventoryWithWebAuthn({
|
|
3688
|
-
walletId: args.walletId,
|
|
3689
|
-
relayerUrl,
|
|
3690
|
-
rpId,
|
|
3691
|
-
keyTargets: args.keyTargets,
|
|
3692
|
-
...args.runtimePolicyScope ? { runtimePolicyScope: args.runtimePolicyScope } : {},
|
|
3693
|
-
collectCredential: args.collectWebAuthnInventoryCredential
|
|
3694
|
-
});
|
|
3695
|
-
}
|
|
3696
|
-
function authenticatedInventorySignerMatch(args) {
|
|
3697
|
-
const parsed = parseActiveEcdsaSignerRecordForUnlock({
|
|
3698
|
-
walletId: args.walletId,
|
|
3699
|
-
configuredTargets: args.configuredTargets,
|
|
3700
|
-
signer: args.signer
|
|
3701
|
-
});
|
|
3702
|
-
switch (parsed.kind) {
|
|
3703
|
-
case "active_ecdsa_signer_record": return parsed.targetKey === thresholdEcdsaChainTargetKey(args.record.walletKey.chainTarget) && String(parsed.walletKey.keyHandle) === String(args.record.walletKey.keyHandle);
|
|
3704
|
-
case "key_facts_inventory_required": return parsed.targetKey === thresholdEcdsaChainTargetKey(args.record.walletKey.chainTarget) && parsed.keyHandle === String(args.record.walletKey.keyHandle);
|
|
3705
|
-
case "blocked":
|
|
3706
|
-
case "skipped": return false;
|
|
3707
|
-
}
|
|
3708
|
-
return false;
|
|
3709
|
-
}
|
|
3710
|
-
function repairedEcdsaSignerMetadata(args) {
|
|
3711
|
-
const walletKey = args.record.walletKey;
|
|
3712
|
-
const keyFacts = walletKey.keyFacts;
|
|
3713
|
-
const targetKey = thresholdEcdsaChainTargetKey(walletKey.chainTarget);
|
|
3714
|
-
return {
|
|
3715
|
-
...args.signer.metadata || {},
|
|
3716
|
-
accountModel: "threshold-ecdsa",
|
|
3717
|
-
accountAddress: args.record.accountAddress,
|
|
3718
|
-
ownerAddress: args.record.ownerAddress,
|
|
3719
|
-
thresholdOwnerAddress: keyFacts.thresholdOwnerAddress,
|
|
3720
|
-
keyScope: keyFacts.keyScope,
|
|
3721
|
-
keyHandle: walletKey.keyHandle,
|
|
3722
|
-
walletId: walletKey.walletId,
|
|
3723
|
-
ecdsaThresholdKeyId: keyFacts.ecdsaThresholdKeyId,
|
|
3724
|
-
signingRootId: keyFacts.signingRootId,
|
|
3725
|
-
signingRootVersion: keyFacts.signingRootVersion,
|
|
3726
|
-
publicCapability: args.record.publicCapability,
|
|
3727
|
-
thresholdEcdsaPublicKeyB64u: keyFacts.thresholdEcdsaPublicKeyB64u,
|
|
3728
|
-
participantIds: [...keyFacts.participantIds],
|
|
3729
|
-
chainTarget: walletKey.chainTarget,
|
|
3730
|
-
targetMembership: {
|
|
3731
|
-
targetKey,
|
|
3732
|
-
chainTarget: walletKey.chainTarget
|
|
3733
|
-
},
|
|
3734
|
-
sharedEvmFamilyKey: {
|
|
3735
|
-
walletId: walletKey.walletId,
|
|
3736
|
-
keyScope: keyFacts.keyScope,
|
|
3737
|
-
keyHandle: walletKey.keyHandle,
|
|
3738
|
-
ecdsaThresholdKeyId: keyFacts.ecdsaThresholdKeyId,
|
|
3739
|
-
signingRootId: keyFacts.signingRootId,
|
|
3740
|
-
signingRootVersion: keyFacts.signingRootVersion,
|
|
3741
|
-
participantIds: [...keyFacts.participantIds],
|
|
3742
|
-
thresholdOwnerAddress: keyFacts.thresholdOwnerAddress,
|
|
3743
|
-
thresholdEcdsaPublicKeyB64u: keyFacts.thresholdEcdsaPublicKeyB64u
|
|
3744
|
-
},
|
|
3745
|
-
chainId: walletKey.chainTarget.chainId
|
|
3746
|
-
};
|
|
3747
|
-
}
|
|
3748
|
-
async function persistAuthenticatedEcdsaInventoryProfileRepairs(args) {
|
|
3749
|
-
for (const record of args.records) {
|
|
3750
|
-
const matchingSigners = args.walletSigners.filter((signer) => authenticatedInventorySignerMatch({
|
|
3751
|
-
walletId: args.walletId,
|
|
3752
|
-
configuredTargets: args.configuredTargets,
|
|
3753
|
-
signer,
|
|
3754
|
-
record
|
|
3755
|
-
}));
|
|
3756
|
-
if (matchingSigners.length !== 1) throw new Error(`[login] authenticated ECDSA key inventory could not identify one profile signer for ${thresholdEcdsaChainTargetKey(record.walletKey.chainTarget)}`);
|
|
3757
|
-
const signer = matchingSigners[0];
|
|
3758
|
-
if (String(record.walletKey.walletId) !== String(args.walletId) || record.accountAddress !== signer.accountAddress || record.ownerAddress !== signer.accountAddress || String(record.walletKey.keyFacts.thresholdOwnerAddress) !== signer.accountAddress) throw new Error(`[login] authenticated ECDSA key inventory profile identity mismatch for ${thresholdEcdsaChainTargetKey(record.walletKey.chainTarget)}`);
|
|
3759
|
-
await args.store.activateAccountSigner({
|
|
3760
|
-
account: {
|
|
3761
|
-
profileId: signer.profileId,
|
|
3762
|
-
chainIdKey: signer.chainIdKey,
|
|
3763
|
-
accountAddress: signer.accountAddress,
|
|
3764
|
-
accountModel: "threshold-ecdsa"
|
|
3765
|
-
},
|
|
3766
|
-
signer: {
|
|
3767
|
-
signerId: signer.signerId,
|
|
3768
|
-
signerType: signer.signerType,
|
|
3769
|
-
signerKind: signer.signerKind,
|
|
3770
|
-
signerAuthMethod: signer.signerAuthMethod,
|
|
3771
|
-
signerSource: signer.signerSource,
|
|
3772
|
-
metadata: repairedEcdsaSignerMetadata({
|
|
3773
|
-
signer,
|
|
3774
|
-
record
|
|
3775
|
-
})
|
|
3776
|
-
},
|
|
3777
|
-
activationPolicy: { mode: "allocate_next_free" },
|
|
3778
|
-
preferredSlot: signer.signerSlot,
|
|
3779
|
-
selectAsActive: false,
|
|
3780
|
-
mutation: { routeThroughOutbox: false }
|
|
3781
|
-
});
|
|
3782
|
-
}
|
|
3783
|
-
}
|
|
3784
|
-
function buildCanonicalThresholdEcdsaWarmSessionContext(ecdsaKeys, runtimePolicyScope) {
|
|
3785
|
-
if (runtimePolicyScope) return {
|
|
3786
|
-
ecdsaKeys,
|
|
3787
|
-
runtimePolicyScope
|
|
3788
|
-
};
|
|
3789
|
-
return { ecdsaKeys };
|
|
3790
|
-
}
|
|
3791
|
-
function buildProfileContinuityEcdsaInventoryInput(args) {
|
|
3792
|
-
const keyFactsInventoryAuthority = args.input?.keyFactsInventoryAuthority || null;
|
|
3793
|
-
const keyFactsInventoryRequested = args.input?.keyFactsInventoryRequested === true;
|
|
3794
|
-
const relayerUrl = args.input?.relayerUrl || "";
|
|
3795
|
-
const rpId = args.input?.rpId || "";
|
|
3796
|
-
const collectWebAuthnInventoryCredential = args.input?.collectWebAuthnInventoryCredential;
|
|
3797
|
-
if (args.runtimePolicyScope) return {
|
|
3798
|
-
kind: "runtime_policy_scoped",
|
|
3799
|
-
keyFactsInventoryAuthority,
|
|
3800
|
-
keyFactsInventoryRequested,
|
|
3801
|
-
relayerUrl,
|
|
3802
|
-
rpId,
|
|
3803
|
-
runtimePolicyScope: args.runtimePolicyScope,
|
|
3804
|
-
collectWebAuthnInventoryCredential
|
|
3805
|
-
};
|
|
3806
|
-
return {
|
|
3807
|
-
kind: "runtime_policy_unscoped",
|
|
3808
|
-
keyFactsInventoryAuthority,
|
|
3809
|
-
keyFactsInventoryRequested,
|
|
3810
|
-
relayerUrl,
|
|
3811
|
-
rpId,
|
|
3812
|
-
collectWebAuthnInventoryCredential
|
|
3813
|
-
};
|
|
3814
|
-
}
|
|
3815
|
-
async function resolveProfileContinuityEcdsaWarmKeys(walletId, configuredTargets, keyFactsInventoryInput) {
|
|
3816
|
-
const configuredChainTargets = configuredTargets.map((target) => target.chainTarget);
|
|
3817
|
-
const walletSigners = await IndexedDBManager.listAccountSignersByProfile({
|
|
3818
|
-
profileId: String(walletId),
|
|
3819
|
-
status: "active"
|
|
3820
|
-
}).catch(() => []);
|
|
3821
|
-
const activeSignerRecords = [];
|
|
3822
|
-
const keyFactsInventoryRequiredRecords = [];
|
|
3823
|
-
const blockedRecords = [];
|
|
3824
|
-
for (const signer of walletSigners) {
|
|
3825
|
-
const parsed = parseActiveEcdsaSignerRecordForUnlock({
|
|
3826
|
-
walletId,
|
|
3827
|
-
configuredTargets: configuredChainTargets,
|
|
3828
|
-
signer
|
|
3829
|
-
});
|
|
3830
|
-
switch (parsed.kind) {
|
|
3831
|
-
case "active_ecdsa_signer_record":
|
|
3832
|
-
activeSignerRecords.push(parsed);
|
|
3833
|
-
break;
|
|
3834
|
-
case "key_facts_inventory_required":
|
|
3835
|
-
keyFactsInventoryRequiredRecords.push(parsed);
|
|
3836
|
-
break;
|
|
3837
|
-
case "blocked":
|
|
3838
|
-
blockedRecords.push(parsed);
|
|
3839
|
-
break;
|
|
3840
|
-
case "skipped": break;
|
|
3841
|
-
default:
|
|
3842
|
-
}
|
|
3843
|
-
}
|
|
3844
|
-
if (!activeSignerRecords.length && !keyFactsInventoryRequiredRecords.length && !blockedRecords.length) return [];
|
|
3845
|
-
const plan = planUnlockEcdsaWarmup({
|
|
3846
|
-
selection: {
|
|
3847
|
-
mode: "ecdsa_only",
|
|
3848
|
-
ecdsa: true
|
|
3849
|
-
},
|
|
3850
|
-
configuredTargets: configuredChainTargets,
|
|
3851
|
-
activeSignerRecords,
|
|
3852
|
-
keyFactsInventoryRequiredRecords,
|
|
3853
|
-
blockedRecords,
|
|
3854
|
-
runtimeConfig: {
|
|
3855
|
-
explicitKeyFactsInventoryMode: keyFactsInventoryInput?.keyFactsInventoryRequested === true,
|
|
3856
|
-
allowAuthenticatedKeyFactsInventory: Boolean(keyFactsInventoryInput?.keyFactsInventoryAuthority)
|
|
3857
|
-
}
|
|
3858
|
-
});
|
|
3859
|
-
switch (plan.kind) {
|
|
3860
|
-
case "ready": {
|
|
3861
|
-
const missingCapabilityTargets = plan.readyTargets.filter((target) => target.publicCapability.kind === "missing_public_capability");
|
|
3862
|
-
const repairedCapabilities = /* @__PURE__ */ new Map();
|
|
3863
|
-
let repairedInventoryRecords = [];
|
|
3864
|
-
if (missingCapabilityTargets.length) {
|
|
3865
|
-
const inventory = await resolveWalletEcdsaKeyFactsInventoryForLogin({
|
|
3866
|
-
walletId,
|
|
3867
|
-
relayerUrl: keyFactsInventoryInput?.relayerUrl || "",
|
|
3868
|
-
rpId: keyFactsInventoryInput?.rpId || "",
|
|
3869
|
-
keyTargets: missingCapabilityTargets.map((target) => ({
|
|
3870
|
-
keyHandle: target.walletKey.keyHandle,
|
|
3871
|
-
chainTarget: target.chainTarget
|
|
3872
|
-
})),
|
|
3873
|
-
authority: keyFactsInventoryInput?.keyFactsInventoryAuthority || null,
|
|
3874
|
-
...keyFactsInventoryInput?.runtimePolicyScope ? { runtimePolicyScope: keyFactsInventoryInput.runtimePolicyScope } : {},
|
|
3875
|
-
collectWebAuthnInventoryCredential: keyFactsInventoryInput?.collectWebAuthnInventoryCredential
|
|
3876
|
-
});
|
|
3877
|
-
repairedInventoryRecords = inventory.records;
|
|
3878
|
-
for (const record of inventory.records) repairedCapabilities.set(thresholdEcdsaChainTargetKey(record.walletKey.chainTarget), record.publicCapability);
|
|
3879
|
-
}
|
|
3880
|
-
const canonicalKeys = collectConfiguredTargetThresholdEcdsaWarmKeys({
|
|
3881
|
-
source: "profile continuity",
|
|
3882
|
-
keys: plan.readyTargets.map((target) => configuredTargetThresholdEcdsaWarmKey({
|
|
3883
|
-
chainTarget: target.chainTarget,
|
|
3884
|
-
keyHandle: target.walletKey.keyHandle,
|
|
3885
|
-
key: evmFamilyEcdsaWalletKeyToIdentity(target.walletKey),
|
|
3886
|
-
publicCapability: target.publicCapability.kind === "persisted_public_capability" ? target.publicCapability.value : repairedCapabilities.get(target.targetKey)
|
|
3887
|
-
}))
|
|
3888
|
-
});
|
|
3889
|
-
const unresolvedCapabilities = canonicalKeys.filter((key) => key.publicCapability.kind === "missing_public_capability").map((key) => key.targetKey);
|
|
3890
|
-
if (unresolvedCapabilities.length) throw new Error(`[login] authenticated ECDSA key inventory did not return public capabilities for ${unresolvedCapabilities.join(", ")}`);
|
|
3891
|
-
await persistAuthenticatedEcdsaInventoryProfileRepairs({
|
|
3892
|
-
store: IndexedDBManager,
|
|
3893
|
-
walletId,
|
|
3894
|
-
configuredTargets: configuredChainTargets,
|
|
3895
|
-
walletSigners,
|
|
3896
|
-
records: repairedInventoryRecords
|
|
3897
|
-
});
|
|
3898
|
-
return canonicalKeys;
|
|
3899
|
-
}
|
|
3900
|
-
case "no_configured_ecdsa_targets": return [];
|
|
3901
|
-
case "awaiting_authenticated_key_facts_inventory": {
|
|
3902
|
-
const keyFactsInventoryAuthority = keyFactsInventoryInput?.keyFactsInventoryAuthority;
|
|
3903
|
-
if (!keyFactsInventoryAuthority) throw new Error("[login] threshold ECDSA key-facts inventory requires authenticated inventory authority");
|
|
3904
|
-
const inventory = await resolveWalletEcdsaKeyFactsInventoryForLogin({
|
|
3905
|
-
walletId,
|
|
3906
|
-
relayerUrl: keyFactsInventoryInput.relayerUrl,
|
|
3907
|
-
rpId: keyFactsInventoryInput.rpId,
|
|
3908
|
-
keyTargets: plan.keyTargets,
|
|
3909
|
-
authority: keyFactsInventoryAuthority,
|
|
3910
|
-
...keyFactsInventoryInput.runtimePolicyScope ? { runtimePolicyScope: keyFactsInventoryInput.runtimePolicyScope } : {},
|
|
3911
|
-
collectWebAuthnInventoryCredential: keyFactsInventoryInput.collectWebAuthnInventoryCredential
|
|
3912
|
-
});
|
|
3913
|
-
const inventoriedCompletion = buildConfiguredTargetKeyCompletion({
|
|
3914
|
-
context: { ecdsaKeys: collectConfiguredTargetThresholdEcdsaWarmKeys({
|
|
3915
|
-
source: "profile continuity inventory",
|
|
3916
|
-
keys: inventory.records.map((record) => configuredTargetThresholdEcdsaWarmKey({
|
|
3917
|
-
chainTarget: record.walletKey.chainTarget,
|
|
3918
|
-
keyHandle: record.walletKey.keyHandle,
|
|
3919
|
-
key: evmFamilyEcdsaWalletKeyToIdentity(record.walletKey),
|
|
3920
|
-
publicCapability: record.publicCapability
|
|
3921
|
-
}))
|
|
3922
|
-
}) },
|
|
3923
|
-
configuredTargets
|
|
3924
|
-
});
|
|
3925
|
-
if (inventoriedCompletion.kind !== "complete_configured_target_keys") throw new Error("[login] threshold ECDSA key-facts inventory returned incomplete key facts");
|
|
3926
|
-
await persistAuthenticatedEcdsaInventoryProfileRepairs({
|
|
3927
|
-
store: IndexedDBManager,
|
|
3928
|
-
walletId,
|
|
3929
|
-
configuredTargets: configuredChainTargets,
|
|
3930
|
-
walletSigners,
|
|
3931
|
-
records: inventory.records
|
|
3932
|
-
});
|
|
3933
|
-
return inventoriedCompletion.context.ecdsaKeys;
|
|
3934
|
-
}
|
|
3935
|
-
case "key_facts_inventory_required": {
|
|
3936
|
-
const targets = plan.keyFactsInventoryRequiredRecords.map((record) => record.targetKey).join(", ");
|
|
3937
|
-
if (keyFactsInventoryInput?.keyFactsInventoryRequested) throw new Error(`[login] threshold ECDSA key-facts inventory requires authenticated inventory authority for ${targets}`);
|
|
3938
|
-
throw new Error(`[login] threshold ECDSA warm-up requires complete local key facts for ${targets}; run explicit authenticated ECDSA key-facts inventory before unlock`);
|
|
3939
|
-
}
|
|
3940
|
-
case "blocked": {
|
|
3941
|
-
const reasons = plan.blockedRecords.map((record) => `${record.targetKey || "unknown"}:${record.reason}`).join(", ");
|
|
3942
|
-
throw new Error(`[login] threshold ECDSA warm-up requires complete local key facts before unlock; run explicit authenticated ECDSA key-facts inventory before unlock; blocked profile signer records: ${reasons}`);
|
|
3943
|
-
}
|
|
3944
|
-
}
|
|
3945
|
-
return [];
|
|
3946
|
-
}
|
|
3947
|
-
async function resolveCanonicalThresholdEcdsaWarmSessionContext(context, walletId, keyFactsInventoryInput, authMethod) {
|
|
3948
|
-
const configuredTargets = listConfiguredThresholdEcdsaPublicationTargets(context.configs.network.chains);
|
|
3949
|
-
const storedKeys = [];
|
|
3950
|
-
let runtimePolicyScope;
|
|
3951
|
-
let canonicalContext = buildCanonicalThresholdEcdsaWarmSessionContext(collectConfiguredTargetThresholdEcdsaWarmKeys({
|
|
3952
|
-
source: "stored",
|
|
3953
|
-
keys: storedKeys
|
|
3954
|
-
}), runtimePolicyScope);
|
|
3955
|
-
const capabilities = await listBrowserCanonicalEcdsaSigningCapabilitiesForWallet({
|
|
3956
|
-
walletId,
|
|
3957
|
-
chainTargets: configuredTargets.map((target) => target.chainTarget),
|
|
3958
|
-
...authMethod ? { authMethod } : {}
|
|
3959
|
-
});
|
|
3960
|
-
const availableLaneKeys = [];
|
|
3961
|
-
let availableLaneRuntimePolicyScope;
|
|
3962
|
-
for (const capability of capabilities) {
|
|
3963
|
-
const manifest = capability.manifest;
|
|
3964
|
-
for (const { chainTarget: target } of configuredTargets) {
|
|
3965
|
-
if (!manifest.signer.scope.targetMemberships.some((membership) => thresholdEcdsaChainTargetKey(membership) === thresholdEcdsaChainTargetKey(target))) continue;
|
|
3966
|
-
const publicFacts = manifest.durableMaterial.roleLocalPublicFacts;
|
|
3967
|
-
const keyHandle = String(publicFacts.keyHandle);
|
|
3968
|
-
const publicCapability = publicFacts.publicCapability;
|
|
3969
|
-
const existingRoleLocalMaterial = capability.material;
|
|
3970
|
-
const laneRuntimePolicyScope = manifest.durableMaterial.runtimePolicyScope;
|
|
3971
|
-
const signingRootBinding = resolveThresholdSigningRootBindingFromRuntimePolicyScope({ runtimePolicyScope: laneRuntimePolicyScope });
|
|
3972
|
-
if (String(signingRootBinding.signingRootId) !== String(manifest.signer.signingRootId) || String(signingRootBinding.signingRootVersion) !== String(manifest.signer.signingRootVersion)) throw new Error(`[login] threshold ECDSA canonical runtime policy scope mismatch for ${thresholdEcdsaChainTargetKey(target)}`);
|
|
3973
|
-
if (availableLaneRuntimePolicyScope && laneRuntimePolicyScope && !sameThresholdRuntimePolicyScope(availableLaneRuntimePolicyScope, laneRuntimePolicyScope)) throw new Error("[login] threshold ECDSA durable lanes have conflicting runtime policy scopes");
|
|
3974
|
-
if (!availableLaneRuntimePolicyScope && laneRuntimePolicyScope) availableLaneRuntimePolicyScope = laneRuntimePolicyScope;
|
|
3975
|
-
availableLaneKeys.push(configuredTargetThresholdEcdsaWarmKey({
|
|
3976
|
-
chainTarget: target,
|
|
3977
|
-
keyHandle,
|
|
3978
|
-
key: buildBaseEvmFamilyEcdsaKeyIdentity({
|
|
3979
|
-
walletId: manifest.signer.walletId,
|
|
3980
|
-
ecdsaThresholdKeyId: manifest.durableMaterial.roleLocalBinding.ecdsaThresholdKeyId,
|
|
3981
|
-
signingRootId: manifest.signer.signingRootId,
|
|
3982
|
-
signingRootVersion: manifest.signer.signingRootVersion,
|
|
3983
|
-
participantIds: manifest.signer.registeredPublicFacts.participantIds,
|
|
3984
|
-
thresholdOwnerAddress: manifest.signer.registeredPublicFacts.thresholdOwnerAddress
|
|
3985
|
-
}),
|
|
3986
|
-
publicCapability,
|
|
3987
|
-
existingRoleLocalMaterial
|
|
3988
|
-
}));
|
|
3989
|
-
}
|
|
3990
|
-
}
|
|
3991
|
-
const exactAvailableLaneKeys = collectConfiguredTargetThresholdEcdsaWarmKeys({
|
|
3992
|
-
source: "available lane",
|
|
3993
|
-
keys: availableLaneKeys
|
|
3994
|
-
});
|
|
3995
|
-
canonicalContext = mergeThresholdEcdsaWarmSessionContexts({
|
|
3996
|
-
current: canonicalContext,
|
|
3997
|
-
incoming: buildCanonicalThresholdEcdsaWarmSessionContext(exactAvailableLaneKeys, availableLaneRuntimePolicyScope),
|
|
3998
|
-
source: "durable lanes"
|
|
3999
|
-
});
|
|
4000
|
-
const configuredTargetCompletion = buildConfiguredTargetKeyCompletion({
|
|
4001
|
-
context: canonicalContext,
|
|
4002
|
-
configuredTargets
|
|
4003
|
-
});
|
|
4004
|
-
if (configuredTargetCompletion.kind === "complete_configured_target_keys") return configuredTargetCompletion.context;
|
|
4005
|
-
const missingTargets = new Set(configuredTargetCompletion.missingTargets);
|
|
4006
|
-
const profileEcdsaThresholdKeys = await resolveProfileContinuityEcdsaWarmKeys(walletId, configuredTargets.filter((target) => missingTargets.has(thresholdEcdsaChainTargetKey(target.chainTarget))), buildProfileContinuityEcdsaInventoryInput({
|
|
4007
|
-
input: keyFactsInventoryInput,
|
|
4008
|
-
runtimePolicyScope: canonicalContext.runtimePolicyScope
|
|
4009
|
-
}));
|
|
4010
|
-
canonicalContext = mergeThresholdEcdsaWarmSessionContexts({
|
|
4011
|
-
current: canonicalContext,
|
|
4012
|
-
incoming: { ecdsaKeys: profileEcdsaThresholdKeys },
|
|
4013
|
-
source: "profile continuity"
|
|
4014
|
-
});
|
|
4015
|
-
return canonicalContext;
|
|
4016
|
-
}
|
|
4017
|
-
async function resolveProfileContinuityThresholdEcdsaPublicKeyB64u(context, walletId) {
|
|
4018
|
-
const publicKeys = [...new Set((await readProfileContinuityThresholdEcdsaWalletKeys(context, walletId)).map((walletKey) => String(walletKey.keyFacts.thresholdEcdsaPublicKeyB64u || "").trim()).filter(Boolean))];
|
|
4019
|
-
if (publicKeys.length === 1) return publicKeys[0];
|
|
4020
|
-
if (publicKeys.length > 1) console.warn("[WalletSession] conflicting profile threshold ECDSA public keys", {
|
|
4021
|
-
walletId: String(walletId),
|
|
4022
|
-
publicKeyCount: publicKeys.length
|
|
4023
|
-
});
|
|
4024
|
-
return null;
|
|
4025
|
-
}
|
|
4026
|
-
async function resolveThresholdEcdsaLoginMetadata(context, walletId) {
|
|
4027
|
-
const [profileAddress, profilePublicKey] = await Promise.all([resolveProfileContinuityThresholdEcdsaEthereumAddress(context, walletId), resolveProfileContinuityThresholdEcdsaPublicKeyB64u(context, walletId)]);
|
|
4028
|
-
if (profileAddress && profilePublicKey) return {
|
|
4029
|
-
ethereumAddress: profileAddress,
|
|
4030
|
-
thresholdEcdsaPublicKeyB64u: profilePublicKey
|
|
4031
|
-
};
|
|
4032
|
-
const capabilities = await listBrowserCanonicalEcdsaSigningCapabilitiesForWallet({
|
|
4033
|
-
walletId,
|
|
4034
|
-
chainTargets: listConfiguredThresholdEcdsaPublicationTargets(context.configs.network.chains).map((target) => target.chainTarget)
|
|
4035
|
-
});
|
|
4036
|
-
const addresses = /* @__PURE__ */ new Set();
|
|
4037
|
-
const publicKeys = /* @__PURE__ */ new Set();
|
|
4038
|
-
for (const capability of capabilities) {
|
|
4039
|
-
const facts = capability.manifest.signer.registeredPublicFacts;
|
|
4040
|
-
addresses.add(normalizeEvmOwnerAddress(facts.thresholdOwnerAddress));
|
|
4041
|
-
publicKeys.add(facts.publicKeyB64u);
|
|
4042
|
-
}
|
|
4043
|
-
return {
|
|
4044
|
-
ethereumAddress: profileAddress ?? (addresses.size === 1 ? [...addresses][0] : null),
|
|
4045
|
-
thresholdEcdsaPublicKeyB64u: profilePublicKey ?? (publicKeys.size === 1 ? [...publicKeys][0] : null)
|
|
4046
|
-
};
|
|
4047
|
-
}
|
|
4048
|
-
function failedCapabilityLane(reason) {
|
|
4049
|
-
return {
|
|
4050
|
-
kind: "failed",
|
|
4051
|
-
reason
|
|
4052
|
-
};
|
|
4053
|
-
}
|
|
4054
|
-
function persistenceUnavailableCapabilityLane() {
|
|
4055
|
-
return {
|
|
4056
|
-
kind: "failed",
|
|
4057
|
-
reason: "persistence_unavailable"
|
|
4058
|
-
};
|
|
4059
|
-
}
|
|
4060
|
-
function parseExactAvailableLaneReadiness(lane) {
|
|
4061
|
-
switch (lane.state) {
|
|
4062
|
-
case "ready": return { kind: "ready" };
|
|
4063
|
-
case "restorable": return {
|
|
4064
|
-
kind: "pending",
|
|
4065
|
-
resume: "restore_material"
|
|
4066
|
-
};
|
|
4067
|
-
case "deferred": return {
|
|
4068
|
-
kind: "pending",
|
|
4069
|
-
resume: "resolve_deferred_state"
|
|
4070
|
-
};
|
|
4071
|
-
case "expired": return {
|
|
4072
|
-
kind: "authorization_required",
|
|
4073
|
-
requirement: "wallet_session_expired"
|
|
4074
|
-
};
|
|
4075
|
-
case "exhausted": return {
|
|
4076
|
-
kind: "authorization_required",
|
|
4077
|
-
requirement: "wallet_session_exhausted"
|
|
4078
|
-
};
|
|
4079
|
-
}
|
|
4080
|
-
throw new Error("[SeamsWeb] unsupported capability lane readiness");
|
|
4081
|
-
}
|
|
4082
|
-
function invalidLaneReasonForCurve(snapshot, curve) {
|
|
4083
|
-
const diagnostic = snapshot.diagnostics?.invalidLanes.find((candidate) => candidate.curve === curve);
|
|
4084
|
-
if (!diagnostic) return null;
|
|
4085
|
-
return diagnostic.reason === "ambiguous_material" || diagnostic.reason === "conflicting_key_material" ? "ambiguous_lane" : "malformed";
|
|
4086
|
-
}
|
|
4087
|
-
function invalidEcdsaLaneReasonForTarget(snapshot, chainTarget) {
|
|
4088
|
-
const targetKey = thresholdEcdsaChainTargetKey(chainTarget);
|
|
4089
|
-
const diagnostic = snapshot.diagnostics?.invalidLanes.find((candidate) => candidate.curve === "ecdsa" && (candidate.targetKey === void 0 || candidate.targetKey === targetKey));
|
|
4090
|
-
if (!diagnostic) return null;
|
|
4091
|
-
return diagnostic.reason === "ambiguous_material" || diagnostic.reason === "conflicting_key_material" ? "ambiguous_lane" : "malformed";
|
|
4092
|
-
}
|
|
4093
|
-
function nearSubjectMatchesLane(subject, lane) {
|
|
4094
|
-
return String(lane.walletId) === String(subject.walletId) && String(lane.nearAccountId) === String(subject.nearAccountId) && String(lane.nearEd25519SigningKeyId) === String(subject.nearEd25519SigningKeyId) && lane.signerSlot === subject.signerSlot;
|
|
4095
|
-
}
|
|
4096
|
-
function ecdsaSubjectMatchesLane(subject, lane) {
|
|
4097
|
-
return String(lane.key.walletId) === String(subject.walletId) && String(lane.key.ecdsaThresholdKeyId) === String(subject.ecdsaThresholdKeyId);
|
|
4098
|
-
}
|
|
4099
|
-
function nearCapabilityReadiness(args) {
|
|
4100
|
-
if (args.availableLanes.kind === "unavailable") return {
|
|
4101
|
-
kind: "near_ed25519",
|
|
4102
|
-
subject: args.subject,
|
|
4103
|
-
lane: persistenceUnavailableCapabilityLane()
|
|
4104
|
-
};
|
|
4105
|
-
const snapshot = args.availableLanes.lanes;
|
|
4106
|
-
if (String(snapshot.walletId) !== String(args.subject.walletId)) return {
|
|
4107
|
-
kind: "near_ed25519",
|
|
4108
|
-
subject: args.subject,
|
|
4109
|
-
lane: failedCapabilityLane("identity_mismatch")
|
|
4110
|
-
};
|
|
4111
|
-
const invalidReason = invalidLaneReasonForCurve(snapshot, "ed25519");
|
|
4112
|
-
if (invalidReason) return {
|
|
4113
|
-
kind: "near_ed25519",
|
|
4114
|
-
subject: args.subject,
|
|
4115
|
-
lane: failedCapabilityLane(invalidReason)
|
|
4116
|
-
};
|
|
4117
|
-
const lane = snapshot.lanes.ed25519.near;
|
|
4118
|
-
if (!isConcreteAvailableSigningLane(lane)) return {
|
|
4119
|
-
kind: "near_ed25519",
|
|
4120
|
-
subject: args.subject,
|
|
4121
|
-
lane: failedCapabilityLane("missing")
|
|
4122
|
-
};
|
|
4123
|
-
return {
|
|
4124
|
-
kind: "near_ed25519",
|
|
4125
|
-
subject: args.subject,
|
|
4126
|
-
lane: nearSubjectMatchesLane(args.subject, lane) ? parseExactAvailableLaneReadiness(lane) : failedCapabilityLane("identity_mismatch")
|
|
4127
|
-
};
|
|
4128
|
-
}
|
|
4129
|
-
function ecdsaCapabilityLaneReadinessForTarget(args) {
|
|
4130
|
-
if (args.availableLanes.kind === "unavailable") return persistenceUnavailableCapabilityLane();
|
|
4131
|
-
const snapshot = args.availableLanes.lanes;
|
|
4132
|
-
if (String(snapshot.walletId) !== String(args.subject.walletId)) return failedCapabilityLane("identity_mismatch");
|
|
4133
|
-
const invalidReason = invalidEcdsaLaneReasonForTarget(snapshot, args.chainTarget);
|
|
4134
|
-
if (invalidReason) return failedCapabilityLane(invalidReason);
|
|
4135
|
-
const lane = ecdsaAvailableLaneForTarget(snapshot, args.chainTarget);
|
|
4136
|
-
if (!isConcreteAvailableSigningLane(lane)) return failedCapabilityLane("missing");
|
|
4137
|
-
if (!ecdsaSubjectMatchesLane(args.subject, lane)) return failedCapabilityLane("identity_mismatch");
|
|
4138
|
-
if (lane.source === "canonical_capability" && !lane.authorization) return {
|
|
4139
|
-
kind: "authorization_required",
|
|
4140
|
-
requirement: "same_method_step_up"
|
|
4141
|
-
};
|
|
4142
|
-
return parseExactAvailableLaneReadiness(lane);
|
|
4143
|
-
}
|
|
4144
|
-
function ecdsaCapabilityReadiness(args) {
|
|
4145
|
-
const [firstTarget, ...remainingTargets] = args.configuredTargets;
|
|
4146
|
-
if (!firstTarget) return {
|
|
4147
|
-
kind: "evm_family_ecdsa",
|
|
4148
|
-
subject: args.subject,
|
|
4149
|
-
targets: { kind: "no_configured_target" }
|
|
4150
|
-
};
|
|
4151
|
-
return {
|
|
4152
|
-
kind: "evm_family_ecdsa",
|
|
4153
|
-
subject: args.subject,
|
|
4154
|
-
targets: {
|
|
4155
|
-
kind: "configured_targets",
|
|
4156
|
-
lanes: [{
|
|
4157
|
-
chainTarget: firstTarget,
|
|
4158
|
-
readiness: ecdsaCapabilityLaneReadinessForTarget({
|
|
4159
|
-
subject: args.subject,
|
|
4160
|
-
availableLanes: args.availableLanes,
|
|
4161
|
-
chainTarget: firstTarget
|
|
4162
|
-
})
|
|
4163
|
-
}, ...remainingTargets.map((chainTarget) => ({
|
|
4164
|
-
chainTarget,
|
|
4165
|
-
readiness: ecdsaCapabilityLaneReadinessForTarget({
|
|
4166
|
-
subject: args.subject,
|
|
4167
|
-
availableLanes: args.availableLanes,
|
|
4168
|
-
chainTarget
|
|
4169
|
-
})
|
|
4170
|
-
}))]
|
|
4171
|
-
}
|
|
4172
|
-
};
|
|
4173
|
-
}
|
|
4174
|
-
function buildWalletSessionCapabilityProjection(args) {
|
|
4175
|
-
const capabilities = args.subjectSet.subjects.map((subject) => {
|
|
4176
|
-
switch (subject.kind) {
|
|
4177
|
-
case "near_ed25519_wallet": return nearCapabilityReadiness({
|
|
4178
|
-
subject,
|
|
4179
|
-
availableLanes: args.availableLanes
|
|
4180
|
-
});
|
|
4181
|
-
case "evm_family_ecdsa_wallet": return ecdsaCapabilityReadiness({
|
|
4182
|
-
subject,
|
|
4183
|
-
availableLanes: args.availableLanes,
|
|
4184
|
-
configuredTargets: args.configuredEcdsaTargets
|
|
4185
|
-
});
|
|
4186
|
-
}
|
|
4187
|
-
return assertNeverLoginState(subject);
|
|
4188
|
-
});
|
|
4189
|
-
const firstCapability = capabilities[0];
|
|
4190
|
-
if (!firstCapability) throw new Error("[WalletSession] resolved capability subjects must be non-empty");
|
|
4191
|
-
return {
|
|
4192
|
-
kind: "resolved",
|
|
4193
|
-
subjectSet: args.subjectSet,
|
|
4194
|
-
capabilities: [firstCapability, ...capabilities.slice(1)]
|
|
4195
|
-
};
|
|
4196
|
-
}
|
|
4197
|
-
function selectNearOperationalPublicKeyForLogin(userData) {
|
|
4198
|
-
return userData ? userData.operationalPublicKey : null;
|
|
4199
|
-
}
|
|
4200
|
-
function userMatchesNearWalletSubject(user, subject) {
|
|
4201
|
-
return Boolean(user && String(user.walletId) === String(subject.walletId) && String(user.nearAccountId) === String(subject.nearAccountId) && user.signerSlot === subject.signerSlot);
|
|
4202
|
-
}
|
|
4203
|
-
async function resolveExactNearWalletUser(signingEngine, subject) {
|
|
4204
|
-
const lastUser = await signingEngine.getLastUser().catch(() => null);
|
|
4205
|
-
if (userMatchesNearWalletSubject(lastUser, subject)) return lastUser;
|
|
4206
|
-
const projected = await getNearAccountProjection(IndexedDBManager, subject.nearAccountId, subject.signerSlot).catch(() => null);
|
|
4207
|
-
if (userMatchesNearWalletSubject(projected, subject)) return projected;
|
|
4208
|
-
const stored = await signingEngine.getUserBySignerSlot(subject.nearAccountId, subject.signerSlot).catch(() => null);
|
|
4209
|
-
return userMatchesNearWalletSubject(stored, subject) ? stored : null;
|
|
4210
|
-
}
|
|
4211
|
-
function nearWalletSubjectsEqual(left, right) {
|
|
4212
|
-
return left.walletId === right.walletId && left.nearAccountId === right.nearAccountId && left.nearEd25519SigningKeyId === right.nearEd25519SigningKeyId && left.signerSlot === right.signerSlot;
|
|
4213
|
-
}
|
|
4214
|
-
async function resolveLinkedNearOperationalPublicKey(subject) {
|
|
4215
|
-
const parsedWalletId = parseWalletId(String(subject.walletId));
|
|
4216
|
-
if (!parsedWalletId.ok) return null;
|
|
4217
|
-
const walletId = parsedWalletId.value;
|
|
4218
|
-
let resolved;
|
|
4219
|
-
try {
|
|
4220
|
-
resolved = await IndexedDBManager.resolveSelectedWalletAuthority(String(walletId));
|
|
4221
|
-
} catch {
|
|
4222
|
-
return null;
|
|
4223
|
-
}
|
|
4224
|
-
if (resolved.kind !== "resolved") return null;
|
|
4225
|
-
const { selection, authMethod, authority } = resolved;
|
|
4226
|
-
if (linkedDeviceUnlockIdentityMismatchLabels({
|
|
4227
|
-
walletId,
|
|
4228
|
-
selection,
|
|
4229
|
-
authMethod,
|
|
4230
|
-
authority
|
|
4231
|
-
}).length > 0 || authMethod.status !== "active" || authority.state !== "active" || authority.provenance.kind !== "device_link") return null;
|
|
4232
|
-
const resolvedSubject = await resolveLinkedDeviceNearUnlockSubject({
|
|
4233
|
-
walletId,
|
|
4234
|
-
authMethod,
|
|
4235
|
-
authority,
|
|
4236
|
-
signerMaterials: resolved.signerMaterials
|
|
4237
|
-
});
|
|
4238
|
-
if (resolvedSubject.kind !== "resolved" || !nearWalletSubjectsEqual(resolvedSubject.subject, subject)) return null;
|
|
4239
|
-
const activation = authority.signerActivations.ed25519;
|
|
4240
|
-
if (!activation) return null;
|
|
4241
|
-
return `ed25519:${base58Encode(base64UrlDecode(activation.signer.registeredPublicKeyB64u))}`;
|
|
4242
|
-
}
|
|
4243
|
-
async function resolveWalletSessionAppIdentityForWallet(context, walletId) {
|
|
4244
|
-
const [authMethods, thresholdMetadata] = await Promise.all([readWalletAuthMethodBindingsForSession(walletId), resolveThresholdEcdsaLoginMetadata(context, walletId).catch(() => ({
|
|
4245
|
-
ethereumAddress: null,
|
|
4246
|
-
thresholdEcdsaPublicKeyB64u: null
|
|
4247
|
-
}))]);
|
|
4248
|
-
return {
|
|
4249
|
-
kind: "resolved",
|
|
4250
|
-
walletId,
|
|
4251
|
-
nearAccountId: null,
|
|
4252
|
-
nearOperationalPublicKey: null,
|
|
4253
|
-
userData: null,
|
|
4254
|
-
authMethods,
|
|
4255
|
-
thresholdEcdsaEthereumAddress: thresholdMetadata.ethereumAddress,
|
|
4256
|
-
thresholdEcdsaPublicKeyB64u: thresholdMetadata.thresholdEcdsaPublicKeyB64u
|
|
4257
|
-
};
|
|
4258
|
-
}
|
|
4259
|
-
async function resolveWalletSessionAppIdentity(context, readResolution) {
|
|
4260
|
-
const resolvedWalletId = readResolution.walletId;
|
|
4261
|
-
const nearSubject = selectNearEd25519WalletSubject(readResolution.subjectSet);
|
|
4262
|
-
const resolvedNearAccountId = nearSubject?.nearAccountId || null;
|
|
4263
|
-
const [userData, base] = await Promise.all([nearSubject ? resolveExactNearWalletUser(context.signingEngine, nearSubject) : null, resolveWalletSessionAppIdentityForWallet(context, resolvedWalletId)]);
|
|
4264
|
-
const nearOperationalPublicKey = selectNearOperationalPublicKeyForLogin(userData) || (nearSubject ? await resolveLinkedNearOperationalPublicKey(nearSubject) : null);
|
|
4265
|
-
return {
|
|
4266
|
-
...base,
|
|
4267
|
-
nearAccountId: resolvedNearAccountId,
|
|
4268
|
-
nearOperationalPublicKey,
|
|
4269
|
-
userData
|
|
4270
|
-
};
|
|
4271
|
-
}
|
|
4272
|
-
/**
|
|
4273
|
-
* List recently used accounts from IndexedDB.
|
|
4274
|
-
*
|
|
4275
|
-
* Used for account picker UIs and initial app bootstrap state.
|
|
4276
|
-
*/
|
|
4277
|
-
async function getRecentUnlocks(context) {
|
|
4278
|
-
const [allUsersData, selections, lastUsedUser] = await Promise.all([
|
|
4279
|
-
context.signingEngine.getAllUsers(),
|
|
4280
|
-
IndexedDBManager.listWalletSelections(),
|
|
4281
|
-
context.signingEngine.getLastUser()
|
|
4282
|
-
]);
|
|
4283
|
-
const linkedAccounts = (await Promise.all(selections.map(recentUnlockAccountFromLinkedDeviceSelection))).filter((account) => account !== null);
|
|
4284
|
-
const accountsByWalletAuthMethod = /* @__PURE__ */ new Map();
|
|
4285
|
-
for (const user of allUsersData) {
|
|
4286
|
-
const account = recentUnlockAccountFromUser(user);
|
|
4287
|
-
accountsByWalletAuthMethod.set(recentUnlockAccountKey(account), account);
|
|
4288
|
-
}
|
|
4289
|
-
for (const account of linkedAccounts) accountsByWalletAuthMethod.set(recentUnlockAccountKey(account), account);
|
|
4290
|
-
const accounts = [...accountsByWalletAuthMethod.values()];
|
|
4291
|
-
const walletIds = [...new Set([...accounts.map((account) => account.walletId), ...selections.map((selection) => String(selection.walletId))])];
|
|
4292
|
-
const accountIds = [...new Set(accounts.map((account) => account.nearAccountId))];
|
|
4293
|
-
const legacyLastUsedAccount = lastUsedUser ? recentUnlockAccountFromUser(lastUsedUser) : null;
|
|
4294
|
-
return {
|
|
4295
|
-
walletIds,
|
|
4296
|
-
accountIds,
|
|
4297
|
-
accounts,
|
|
4298
|
-
lastUsedAccount: latestRecentUnlockAccount([...linkedAccounts, ...legacyLastUsedAccount ? [legacyLastUsedAccount] : []])
|
|
4299
|
-
};
|
|
4300
|
-
}
|
|
4301
|
-
async function lock(context) {
|
|
4302
|
-
const { signingEngine } = context;
|
|
4303
|
-
const authentication = signingEngine.readWalletAuthenticationState();
|
|
4304
|
-
let failure;
|
|
4305
|
-
let failed = false;
|
|
4306
|
-
let authenticationCleared = false;
|
|
4307
|
-
if (authentication.kind === "authenticated") {
|
|
4308
|
-
try {
|
|
4309
|
-
await signingEngine.advanceWalletLockGeneration(authentication.walletId);
|
|
4310
|
-
} catch (error) {
|
|
4311
|
-
failure = error;
|
|
4312
|
-
failed = true;
|
|
4313
|
-
}
|
|
4314
|
-
try {
|
|
4315
|
-
await signingEngine.retireActiveWalletSessionAuthorizationForLock(authentication.walletId);
|
|
4316
|
-
} catch (error) {
|
|
4317
|
-
if (!failed) {
|
|
4318
|
-
failure = error;
|
|
4319
|
-
failed = true;
|
|
4320
|
-
}
|
|
4321
|
-
}
|
|
4322
|
-
}
|
|
4323
|
-
try {
|
|
4324
|
-
authenticationCleared = signingEngine.clearWalletAuthenticationIfCurrent(authentication);
|
|
4325
|
-
} catch (error) {
|
|
4326
|
-
if (!failed) {
|
|
4327
|
-
failure = error;
|
|
4328
|
-
failed = true;
|
|
4329
|
-
}
|
|
4330
|
-
}
|
|
4331
|
-
if (authenticationCleared) {
|
|
4332
|
-
try {
|
|
4333
|
-
signingEngine.getNonceCoordinator().clearAll();
|
|
4334
|
-
} catch {}
|
|
4335
|
-
try {
|
|
4336
|
-
signingEngine.clearThresholdEcdsaSigningQueue();
|
|
4337
|
-
} catch {}
|
|
4338
|
-
}
|
|
4339
|
-
try {
|
|
4340
|
-
await signingEngine.clearVolatileWarmSigningMaterial(authentication.kind === "authenticated" ? authentication.walletId : void 0);
|
|
4341
|
-
} catch (error) {
|
|
4342
|
-
if (!failed) {
|
|
4343
|
-
failure = error;
|
|
4344
|
-
failed = true;
|
|
4345
|
-
}
|
|
4346
|
-
}
|
|
4347
|
-
if (failed) throw failure;
|
|
4348
|
-
}
|
|
4349
|
-
async function logout(context) {
|
|
4350
|
-
const authentication = context.signingEngine.readWalletAuthenticationState();
|
|
4351
|
-
const cleanupTarget = authentication.kind === "authenticated" ? {
|
|
4352
|
-
kind: "wallet",
|
|
4353
|
-
walletId: authentication.walletId
|
|
4354
|
-
} : null;
|
|
4355
|
-
let failure;
|
|
4356
|
-
let failed = false;
|
|
4357
|
-
try {
|
|
4358
|
-
await lock(context);
|
|
4359
|
-
} catch (error) {
|
|
4360
|
-
failure = error;
|
|
4361
|
-
failed = true;
|
|
4362
|
-
}
|
|
4363
|
-
if (cleanupTarget) try {
|
|
4364
|
-
await context.signingEngine.deleteDurableEcdsaPresignatures(cleanupTarget);
|
|
4365
|
-
} catch (error) {
|
|
4366
|
-
if (!failed) failure = error;
|
|
4367
|
-
failed = true;
|
|
4368
|
-
}
|
|
4369
|
-
if (failed) throw failure;
|
|
4370
|
-
}
|
|
4371
|
-
async function resumeNearAfterSuccessfulUnlock(args) {
|
|
4372
|
-
try {
|
|
4373
|
-
await (await import("../registration/registration.js")).resumeNearRegistrationAfterUnlock(args);
|
|
4374
|
-
} catch (error) {
|
|
4375
|
-
console.warn("[login] NEAR continuation could not start", error instanceof Error ? error.message : "module unavailable");
|
|
4376
|
-
} finally {
|
|
4377
|
-
new Uint8Array(args.ownedFactorSecret).fill(0);
|
|
4378
|
-
}
|
|
4379
|
-
}
|
|
4380
|
-
//#endregion
|
|
4381
|
-
export { activateLinkedDeviceSignerRuntimesAfterLink, getRecentUnlocks, getWalletSession, lock, logout, resolveExactLinkedEmailOtpAuthority, resolveLinkedDeviceEmailOtpAuthoritySelection, unlockLinkedDeviceEmailOtpWallet, unlockResolvedWalletSubjectSet };
|
|
4382
|
-
|
|
4383
|
-
//# sourceMappingURL=login.js.map
|