@seams/wallet 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/.build-inputs.sha256 +1 -1
  2. package/dist/esm/SeamsWeb/index.js +1 -1
  3. package/dist/esm/SeamsWeb/walletIframe/client/inboundMessages.js +1 -1
  4. package/dist/esm/SeamsWeb/walletIframe/client/router.js +10 -4
  5. package/dist/esm/SeamsWeb/walletIframe/coordinator.js +23 -1
  6. package/dist/esm/SeamsWeb/walletIframe/host/ui/auth-menu/AuthMenuSurface.js +33 -6
  7. package/dist/esm/SeamsWeb/walletIframe/host/ui/auth-menu/icons.js +37 -1
  8. package/dist/esm/SeamsWeb/walletIframe/host/ui/auth-menu/presentation.js +1 -0
  9. package/dist/esm/core/browser/walletIframe/events.js +6 -0
  10. package/dist/esm/core/signingEngine/uiConfirm/ui/appearance.js +27 -0
  11. package/dist/esm/core/signingEngine/uiConfirm/ui/export-private-key-reveal.js +155 -0
  12. package/dist/esm/core/signingEngine/uiConfirm/ui/export-viewer-host.js +209 -0
  13. package/dist/esm/core/signingEngine/uiConfirm/ui/preact/ExportPrivateKeySurface.js +319 -0
  14. package/dist/esm/core/signingEngine/uiConfirm/ui/preact/mountExportPrivateKeySurface.js +92 -0
  15. package/dist/esm/core/signingEngine/uiConfirm/ui/surface-measurement-binding.js +12 -0
  16. package/dist/esm/core/ui/messages.js +4 -0
  17. package/dist/esm/index.js +1 -1
  18. package/dist/esm/react/components/AccountMenuButton/AccountMenuButtonView.js +1 -1
  19. package/dist/esm/react/components/AccountMenuButton/ExportKeysSection.css +20 -0
  20. package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.css +9 -3
  21. package/dist/esm/react/components/AccountMenuButton/UserAccountButton.css +1 -0
  22. package/dist/esm/react/components/AccountMenuButton/Web3AuthProfileButton.css +15 -0
  23. package/dist/esm/react/styles/styles.css +36 -0
  24. package/dist/esm/sdk/{ConfirmationDrawer-mu3iThxX.js → ConfirmationDrawer-DCw0m-Iv.js} +1 -1
  25. package/dist/{public/sdk/adapters-u7LVXthY.js → esm/sdk/adapters-BNmcyf9K.js} +1 -1
  26. package/dist/esm/sdk/appearance-token-vars-DxBm_cKA.js +2 -0
  27. package/dist/{public/sdk/export-viewer-host-ivf9LlBo.js → esm/sdk/export-viewer-host-DsdzagKK.js} +1 -1
  28. package/dist/esm/sdk/{exportKeypairOperation-Gw7L5Htj.js → exportKeypairOperation-BwW_E4Lt.js} +1 -1
  29. package/dist/esm/sdk/{host-B-2QXolt.js → host-DMR4KDy9.js} +1 -1
  30. package/dist/esm/sdk/{localOnly-BKpUHtHa.js → localOnly-DO191vDh.js} +1 -1
  31. package/dist/esm/sdk/{mountExportPrivateKeySurface-C8pUK6PQ.js → mountExportPrivateKeySurface-DQzFzhNu.js} +1 -1
  32. package/dist/esm/sdk/{mountRecoveryCodeBackupSurface-DUudF89t.js → mountRecoveryCodeBackupSurface-B1D0ovqx.js} +1 -1
  33. package/dist/esm/sdk/{pendingWalletRecoveryCodeBackup-7tBjuSe7.js → pendingWalletRecoveryCodeBackup-DOeIn_Qj.js} +1 -1
  34. package/dist/esm/sdk/{registration-CWpOVwhj.js → registration-DknFwoqn.js} +1 -1
  35. package/dist/esm/sdk/{registration-D2OEgY7O.js → registration-sQndIWRF.js} +1 -1
  36. package/dist/esm/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
  37. package/dist/esm/sdk/runtime-auth-BxG-J-BB.js +1 -0
  38. package/dist/esm/sdk/{runtime-device-link-vhRhB-wS.js → runtime-device-link-Dn_5hPCq.js} +1 -1
  39. package/dist/{public/sdk/runtime-ecdsa-tempo-BXWgFVBa.js → esm/sdk/runtime-ecdsa-tempo-lTFTb9Rh.js} +1 -1
  40. package/dist/esm/sdk/{runtime-email-otp-BlAaSKtk.js → runtime-email-otp-CPqTCH8Q.js} +1 -1
  41. package/dist/esm/sdk/{runtime-export-B4FuHhcH.js → runtime-export-Brz53_oi.js} +1 -1
  42. package/dist/esm/sdk/{runtime-near-BnWOpEpA.js → runtime-near-Da_xFUXx.js} +1 -1
  43. package/dist/esm/sdk/{runtime-preferences-COm-LTiu.js → runtime-preferences-riUZGaTs.js} +1 -1
  44. package/dist/esm/sdk/{runtime-recovery-BJTo5Idi.js → runtime-recovery-CTj4nDAM.js} +1 -1
  45. package/dist/esm/sdk/{runtime-recovery-codes-CEOjdUHV.js → runtime-recovery-codes-D8T9LQ7-.js} +1 -1
  46. package/dist/esm/sdk/{shared-BKPGtAps.js → shared-hx7KVyeq.js} +1 -1
  47. package/dist/esm/sdk/tx-confirm-ui.js +4 -0
  48. package/dist/esm/sdk/wallet-iframe-host-ecdsa.js +1 -1
  49. package/dist/esm/sdk/wallet-iframe-host-full.js +1 -1
  50. package/dist/esm/sdk/wallet-iframe-host-near.js +1 -1
  51. package/dist/esm/sdk/wallet-iframe-host-runtime.js +1 -1
  52. package/dist/esm/sdk/wallet-ui.css +1 -1
  53. package/dist/esm/wasm/router_ab_ed25519_yao_client/pkg/router_ab_ed25519_yao_client_bg.wasm +0 -0
  54. package/dist/public/headers.manifest.json +1 -1
  55. package/dist/public/sdk/{ConfirmationDrawer-mu3iThxX.js → ConfirmationDrawer-DCw0m-Iv.js} +1 -1
  56. package/dist/{esm/sdk/adapters-u7LVXthY.js → public/sdk/adapters-BNmcyf9K.js} +1 -1
  57. package/dist/public/sdk/appearance-token-vars-DxBm_cKA.js +2 -0
  58. package/dist/{esm/sdk/export-viewer-host-ivf9LlBo.js → public/sdk/export-viewer-host-DsdzagKK.js} +1 -1
  59. package/dist/public/sdk/{exportKeypairOperation-Gw7L5Htj.js → exportKeypairOperation-BwW_E4Lt.js} +1 -1
  60. package/dist/public/sdk/{host-B-2QXolt.js → host-DMR4KDy9.js} +1 -1
  61. package/dist/public/sdk/{localOnly-BKpUHtHa.js → localOnly-DO191vDh.js} +1 -1
  62. package/dist/public/sdk/{mountExportPrivateKeySurface-C8pUK6PQ.js → mountExportPrivateKeySurface-DQzFzhNu.js} +1 -1
  63. package/dist/public/sdk/{mountRecoveryCodeBackupSurface-DUudF89t.js → mountRecoveryCodeBackupSurface-B1D0ovqx.js} +1 -1
  64. package/dist/public/sdk/{pendingWalletRecoveryCodeBackup-7tBjuSe7.js → pendingWalletRecoveryCodeBackup-DOeIn_Qj.js} +1 -1
  65. package/dist/public/sdk/{registration-CWpOVwhj.js → registration-DknFwoqn.js} +1 -1
  66. package/dist/public/sdk/{registration-D2OEgY7O.js → registration-sQndIWRF.js} +1 -1
  67. package/dist/public/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
  68. package/dist/public/sdk/runtime-auth-BxG-J-BB.js +1 -0
  69. package/dist/public/sdk/{runtime-device-link-vhRhB-wS.js → runtime-device-link-Dn_5hPCq.js} +1 -1
  70. package/dist/{esm/sdk/runtime-ecdsa-tempo-BXWgFVBa.js → public/sdk/runtime-ecdsa-tempo-lTFTb9Rh.js} +1 -1
  71. package/dist/public/sdk/{runtime-email-otp-BlAaSKtk.js → runtime-email-otp-CPqTCH8Q.js} +1 -1
  72. package/dist/public/sdk/{runtime-export-B4FuHhcH.js → runtime-export-Brz53_oi.js} +1 -1
  73. package/dist/public/sdk/{runtime-near-BnWOpEpA.js → runtime-near-Da_xFUXx.js} +1 -1
  74. package/dist/public/sdk/{runtime-preferences-COm-LTiu.js → runtime-preferences-riUZGaTs.js} +1 -1
  75. package/dist/public/sdk/{runtime-recovery-BJTo5Idi.js → runtime-recovery-CTj4nDAM.js} +1 -1
  76. package/dist/public/sdk/{runtime-recovery-codes-CEOjdUHV.js → runtime-recovery-codes-D8T9LQ7-.js} +1 -1
  77. package/dist/public/sdk/{shared-BKPGtAps.js → shared-hx7KVyeq.js} +1 -1
  78. package/dist/public/sdk/tx-confirm-ui.js +4 -0
  79. package/dist/public/sdk/wallet-iframe-host-ecdsa.js +1 -1
  80. package/dist/public/sdk/wallet-iframe-host-full.js +1 -1
  81. package/dist/public/sdk/wallet-iframe-host-near.js +1 -1
  82. package/dist/public/sdk/wallet-iframe-host-runtime.js +1 -1
  83. package/dist/public/sdk/wallet-ui.css +1 -1
  84. package/dist/public/sdk/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
  85. package/dist/public/sdk/workers/wallet_custody_ceremony_bg.wasm +0 -0
  86. package/dist/public/wallet-assets.manifest.json +46 -46
  87. package/dist/public/wallet-service/index.html +4 -4
  88. package/dist/types/wallet/src/SeamsWeb/walletIframe/coordinator.d.ts +2 -1
  89. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/auth-menu/domain.d.ts +20 -3
  90. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/auth-menu/session.d.ts +3 -0
  91. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/ui/auth-menu/AuthMenuSurface.d.ts +1 -0
  92. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/ui/auth-menu/icons.d.ts +2 -0
  93. package/dist/types/wallet/src/core/ui/messages.d.ts +1 -1
  94. package/dist/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
  95. package/dist/workers/wallet_custody_ceremony_bg.wasm +0 -0
  96. package/package.json +1 -1
  97. package/dist/esm/sdk/appearance-token-vars-CzBVbO39.js +0 -2
  98. package/dist/esm/sdk/runtime-auth-jtyQAuxZ.js +0 -1
  99. package/dist/public/sdk/appearance-token-vars-CzBVbO39.js +0 -2
  100. package/dist/public/sdk/runtime-auth-jtyQAuxZ.js +0 -1
@@ -1 +1 @@
1
- e649c8908736a93bde3821845b8137669c1ba4c470574d41e3194f38382c0692
1
+ 3ab69e5e65a9a0b43534f8b63d088ec3e73f7bed3dc1442443dab684d53c1500
@@ -1,6 +1,6 @@
1
1
  import { BrowserCapabilityUnavailableError } from "./publicApi/capabilitySelection.js";
2
2
  import { LinkDeviceEventPhase } from "../core/types/sdkSentEvents.js";
3
- import { SeamsWeb } from "./SeamsWeb.js";
4
3
  import { buildHostedAuthMenuOpenRequest, hostedAuthMenuExternalAuthRequestIdFromBoundary, hostedAuthMenuSessionIdFromBoundary } from "./walletIframe/shared/messages.js";
4
+ import { SeamsWeb } from "./SeamsWeb.js";
5
5
  import { DeviceLinkingError, DeviceLinkingErrorCode } from "../core/types/linkDevice.js";
6
6
  export { BrowserCapabilityUnavailableError, DeviceLinkingError, DeviceLinkingErrorCode, LinkDeviceEventPhase, SeamsWeb, buildHostedAuthMenuOpenRequest, hostedAuthMenuExternalAuthRequestIdFromBoundary, hostedAuthMenuSessionIdFromBoundary };
@@ -1,7 +1,7 @@
1
1
  import { isObject } from "../../../shared-ts/src/utils/validation.js";
2
2
  import { isWalletFlowEvent, parseSdkLifecycleEvent } from "../../../core/types/sdkSentEvents.js";
3
- import { parseWalletIframeExactSessionSnapshot, parseWalletIframeSessionRevision } from "../shared/exactSessionState.js";
4
3
  import { isDeviceLinkEmailOtpBaseFactorSelectionProgressV1, isDeviceLinkTargetFactorActivationProgressV1, isRegistrationTimingSpanV1, parseHostedAuthMenuErrorEvent, parseHostedAuthMenuExternalAuthRequest, parseWalletIframeSurfaceMeasurement } from "../shared/messages.js";
4
+ import { parseWalletIframeExactSessionSnapshot, parseWalletIframeSessionRevision } from "../shared/exactSessionState.js";
5
5
  import { parseTransactionReviewState } from "../shared/transactionReview.js";
6
6
  //#region src/SeamsWeb/walletIframe/client/inboundMessages.ts
7
7
  function rawClientMessageObject(value) {
@@ -12,6 +12,8 @@ import "../../../shared-ts/src/device-linking/index.js";
12
12
  import { AccountSyncEventPhase, KeyExportEventPhase, LinkDeviceEventPhase, RegistrationEventPhase, SigningEventPhase, UnlockEventPhase, classifyLinkDeviceFlowEvent, createAccountSyncFlowEvent, createKeyExportFlowEvent, createLinkDeviceFlowEvent, createRegistrationFlowEvent, createSigningFlowEvent, createUnlockFlowEvent, isWalletFlowEvent, parseNearProvisioningState } from "../../../core/types/sdkSentEvents.js";
13
13
  import { requireTempoFeeTokenPreferenceSigningRequest } from "../../../core/signingEngine/chains/tempo/feeToken.js";
14
14
  import { buildPMUnlockPayload } from "../shared/unlockOptions.js";
15
+ import { walletIframeSurfaceIdFromBoundary } from "../../../core/types/walletIframeIdentity.js";
16
+ import { HOSTED_AUTH_MENU_ERROR_EVENT, buildHostedAuthMenuCancelPayload, buildPMRedeemHostedWalletSeamsSessionPayload, hostedAuthMenuSessionIdFromBoundary, isDeviceLinkEmailOtpBaseFactorSelectionProgressV1, isDeviceLinkTargetFactorActivationProgressV1, isRegistrationTimingSpanV1, parseHostedAuthMenuErrorEvent, parseHostedAuthMenuExternalAuthRequest, parseHostedAuthMenuExternalAuthResolution, parseHostedAuthMenuOpenRequest, parseHostedAuthMenuOutcome, parseWalletIframeSurfaceMeasurement } from "../shared/messages.js";
15
17
  import { replaceWalletHostAppearance } from "../shared/configuration.js";
16
18
  import { anchorWalletIframeModalGeometry, isWalletIframeModalGeometry, resolveWalletIframeSurfaceGeometry } from "./surface/geometry.js";
17
19
  import OverlayController from "./overlay/overlay-controller.js";
@@ -19,8 +21,6 @@ import { walletIdFromString } from "../../../shared-ts/src/utils/registrationIds
19
21
  import { WalletIframeSessionExpiredRequestError, exactSessionIdentitiesMatch, parseWalletIframeExactSessionLockResult, parseWalletIframeExactSessionSnapshot, parseWalletSessionFromBoundary } from "../shared/exactSessionState.js";
20
22
  import { parseExactEcdsaSigningLaneIdentity, parseExactEd25519ExportMaterialIdentity } from "../../../core/signingEngine/session/identity/exactSigningLaneIdentity.js";
21
23
  import { resolveRuntimeAppearance } from "../shared/facadeBoundary.js";
22
- import { walletIframeSurfaceIdFromBoundary } from "../../../core/types/walletIframeIdentity.js";
23
- import { HOSTED_AUTH_MENU_ERROR_EVENT, buildHostedAuthMenuCancelPayload, buildPMRedeemHostedWalletSeamsSessionPayload, hostedAuthMenuSessionIdFromBoundary, isDeviceLinkEmailOtpBaseFactorSelectionProgressV1, isDeviceLinkTargetFactorActivationProgressV1, isRegistrationTimingSpanV1, parseHostedAuthMenuErrorEvent, parseHostedAuthMenuExternalAuthRequest, parseHostedAuthMenuExternalAuthResolution, parseHostedAuthMenuOpenRequest, parseHostedAuthMenuOutcome, parseWalletIframeSurfaceMeasurement } from "../shared/messages.js";
24
24
  import { TransactionReviewError, assertTransactionReviewValid, parseTransactionReviewState, reviewedConfirmationConfig, sameTransactionReviewIdentity, transactionReviewCancellationCode } from "../shared/transactionReview.js";
25
25
  import { needsExplicitActivation } from "../../../utils/deviceDetection.js";
26
26
  import { TransactionReviewReservation } from "./transactionReviewReservation.js";
@@ -990,6 +990,11 @@ var WalletIframeRouter = class {
990
990
  this.surfaceRenderer.render(surface);
991
991
  return;
992
992
  }
993
+ const anchor = surface.kind === "modal_auth_menu" ? this.hostedAuthMenuAnchors.get(surface.authMenuSessionId) : void 0;
994
+ if (surface.kind === "modal_auth_menu" && anchor?.isConnected === false) {
995
+ queueMicrotask(this.cancelHostedAuthMenuWithReason.bind(this, surface.authMenuSessionId, "component_unmounted"));
996
+ return;
997
+ }
993
998
  let measurement = this.activeSurfaceMeasurement ? {
994
999
  kind: "measured",
995
1000
  widthCssPx: this.activeSurfaceMeasurement.widthCssPx,
@@ -1016,7 +1021,6 @@ var WalletIframeRouter = class {
1016
1021
  measurement,
1017
1022
  maxModalWidthCssPx: surface.kind === "modal_recovery_codes" ? 688 : void 0
1018
1023
  });
1019
- const anchor = surface.kind === "modal_auth_menu" ? this.hostedAuthMenuAnchors.get(surface.authMenuSessionId) : void 0;
1020
1024
  let anchorMetrics = hostedAuthMenuAnchorMetrics(anchor);
1021
1025
  let geometry = resolvedGeometry;
1022
1026
  let authMenuVisualScale = 1;
@@ -1059,6 +1063,8 @@ var WalletIframeRouter = class {
1059
1063
  if (surface.kind === "modal_auth_menu" && geometry.kind !== "provisional_centered_modal") this.hostedAuthMenuAnchors.get(surface.authMenuSessionId)?.style.setProperty("--seams-auth-menu-placeholder-opacity", "0");
1060
1064
  }
1061
1065
  startHostedAuthMenuAnchorTracking(authMenuSessionId) {
1066
+ const anchor = this.hostedAuthMenuAnchors.get(authMenuSessionId);
1067
+ if (anchor) this.surfaceLayoutObserver?.observe(anchor);
1062
1068
  if (this.hostedAuthMenuAnchorTrackingFrame !== null) cancelAnimationFrame(this.hostedAuthMenuAnchorTrackingFrame);
1063
1069
  this.hostedAuthMenuAnchorTrackingSession = authMenuSessionId;
1064
1070
  this.hostedAuthMenuAnchorTrackingDeadlineMs = performance.now() + 750;
@@ -2513,7 +2519,6 @@ var WalletIframeRouter = class {
2513
2519
  await this.post({ type: "PM_PREPARE_WALLET_RUNTIME" });
2514
2520
  }
2515
2521
  async openHostedAuthMenu(request, anchorElement) {
2516
- await this.ensureConfigured();
2517
2522
  const normalized = parseHostedAuthMenuOpenRequest(request);
2518
2523
  if (!normalized) throw new Error("Hosted auth-menu open request is invalid");
2519
2524
  if (this.hostedAuthMenuRequestIds.has(normalized.authMenuSessionId)) throw new Error("Hosted auth-menu session is already active");
@@ -2521,6 +2526,7 @@ var WalletIframeRouter = class {
2521
2526
  this.hostedAuthMenuRequestIds.set(normalized.authMenuSessionId, requestId);
2522
2527
  if (anchorElement) this.hostedAuthMenuAnchors.set(normalized.authMenuSessionId, anchorElement);
2523
2528
  try {
2529
+ await this.ensureConfigured();
2524
2530
  const outcome = parseHostedAuthMenuOutcome((await this.post({
2525
2531
  type: "PM_OPEN_AUTH_MENU",
2526
2532
  payload: normalized
@@ -1,5 +1,6 @@
1
1
  import { toWalletId } from "../../core/signingEngine/interfaces/ecdsaChainTarget.js";
2
2
  import { buildAnonymousWalletSession } from "../publicApi/session.js";
3
+ import { hostedAuthMenuSessionIdFromBoundary, parseHostedAuthMenuOpenRequest } from "./shared/messages.js";
3
4
  import { createWalletIframeRouter } from "../assembly/createWalletIframeRouter.js";
4
5
  //#region src/SeamsWeb/walletIframe/coordinator.ts
5
6
  function assertNeverConnection(state) {
@@ -34,6 +35,7 @@ var WalletIframeCoordinator = class {
34
35
  walletIframeAuthMenuUnsubscribe = null;
35
36
  sdkLifecycleEventListeners = /* @__PURE__ */ new Set();
36
37
  hostedAuthMenuExternalAuthRequestListeners = /* @__PURE__ */ new Set();
38
+ hostedAuthMenuOpensBeforeRouter = /* @__PURE__ */ new Map();
37
39
  forwardSdkLifecycleEventListener;
38
40
  forwardHostedAuthMenuExternalAuthRequestListener;
39
41
  constructor(deps) {
@@ -228,9 +230,29 @@ var WalletIframeCoordinator = class {
228
230
  this.requireRouter().then(prepareRouterWalletHostRuntime).catch(ignorePreparationFailure);
229
231
  }
230
232
  async openHostedAuthMenu(request, anchorElement) {
231
- return await (await this.requireRouter()).openHostedAuthMenu(request, anchorElement);
233
+ const normalized = parseHostedAuthMenuOpenRequest(request);
234
+ if (!normalized) throw new Error("Hosted auth-menu open request is invalid");
235
+ const authMenuSessionId = normalized.authMenuSessionId;
236
+ if (this.hostedAuthMenuOpensBeforeRouter.has(authMenuSessionId)) throw new Error("Hosted auth-menu session is already active");
237
+ this.hostedAuthMenuOpensBeforeRouter.set(authMenuSessionId, "awaiting_router");
238
+ let router;
239
+ try {
240
+ router = await this.requireRouter();
241
+ } catch (error) {
242
+ this.hostedAuthMenuOpensBeforeRouter.delete(authMenuSessionId);
243
+ throw error;
244
+ }
245
+ const state = this.hostedAuthMenuOpensBeforeRouter.get(authMenuSessionId);
246
+ this.hostedAuthMenuOpensBeforeRouter.delete(authMenuSessionId);
247
+ if (state === "cancelled") throw new Error("Hosted auth-menu cancelled: component_unmounted");
248
+ return await router.openHostedAuthMenu(normalized, anchorElement);
232
249
  }
233
250
  async cancelHostedAuthMenu(args) {
251
+ const authMenuSessionId = hostedAuthMenuSessionIdFromBoundary(args.authMenuSessionId);
252
+ if (authMenuSessionId && this.hostedAuthMenuOpensBeforeRouter.has(authMenuSessionId)) {
253
+ this.hostedAuthMenuOpensBeforeRouter.set(authMenuSessionId, "cancelled");
254
+ return;
255
+ }
234
256
  await (await this.requireRouter()).cancelHostedAuthMenu(args);
235
257
  }
236
258
  onHostedAuthMenuExternalAuthRequest(listener) {
@@ -7,7 +7,7 @@ import { AUTH_MENU_WAITING_PROMPTS, isAuthMenuActionReady, isAuthMenuGoogleActio
7
7
  import { AUTH_MENU_ACCOUNT_LIST_ID, AUTH_MENU_TITLE_ID, accountGroups, accountSecondaryText, authViewKey, menuNotice, modeLabel, modeSwitchCopy, otpCodeDigits, passkeyButtonLabel, recoveryAnnouncement, recoveryBackLabel, recoveryCaretAtPoint, recoveryNavigationLocked, renderDemoEmailCode, renderOtpCodeDigit, savedAccountsTriggerLabel, selectedAccountPrimaryText, selectedLoginAccount } from "./presentation.js";
8
8
  import { PadlockIcon } from "../../../../../core/signingEngine/uiConfirm/ui/preact/PadlockIcon.js";
9
9
  import { blinkMenuItem } from "../../../../../utils/menuItemBlink.js";
10
- import { accountDropdownIcon, backIcon, chevronIcon, fingerprintIcon, googleIcon, linkDeviceIcon, linkFailedIcon, mailIcon, passkeyRingIcon, recoveryIcon, rerollIcon } from "./icons.js";
10
+ import { accountDropdownIcon, backIcon, chevronIcon, fingerprintIcon, googleIcon, linkDeviceIcon, linkFailedIcon, mailIcon, passkeyRingIcon, passkeySuccessIcon, recoveryIcon, rerollIcon } from "./icons.js";
11
11
  import { AuthMenuFooter } from "./AuthMenuFooter.js";
12
12
  import { linkDeviceDotRing, linkDeviceEmailOtpPresentation } from "./linkDeviceBadge.js";
13
13
  import { Component, Fragment } from "preact";
@@ -467,6 +467,7 @@ var AuthMenuSurface = class extends Component {
467
467
  const viewModel = this.viewModel;
468
468
  if (!viewModel) return /* @__PURE__ */ jsx(Fragment$1, {});
469
469
  const loading = isAuthMenuLoadingStatus(viewModel.status);
470
+ const success = viewModel.status.kind === "succeeded" ? viewModel.status.phase : null;
470
471
  const linkDevice = viewModel.kind === "link_device";
471
472
  const otpPrompt = viewModel.kind === "google_otp_login";
472
473
  const registrationPrompt = viewModel.kind === "google_registration";
@@ -474,7 +475,8 @@ var AuthMenuSurface = class extends Component {
474
475
  return /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsxs("div", {
475
476
  class: "seams-signup-menu-root auth-menu-root",
476
477
  "data-mode": viewModel.mode,
477
- "data-waiting": loading ? "true" : "false",
478
+ "data-waiting": loading || success ? "true" : "false",
479
+ "data-success": success ?? void 0,
478
480
  "data-scan-device": linkDevice ? "true" : "false",
479
481
  "data-otp-prompt": otpPrompt ? "true" : "false",
480
482
  "data-registration-prompt": registrationPrompt ? "true" : "false",
@@ -496,11 +498,11 @@ var AuthMenuSurface = class extends Component {
496
498
  class: "seams-content-switcher",
497
499
  children: [
498
500
  /* @__PURE__ */ jsx("button", {
499
- class: `seams-back-button ${loading || linkDevice || otpPrompt || registrationPrompt || recovery ? "is-visible" : ""}`,
501
+ class: `seams-back-button ${!success && (loading || linkDevice || otpPrompt || registrationPrompt || recovery) ? "is-visible" : ""}`,
500
502
  type: "button",
501
503
  "aria-label": walletDisplayText(this.context, recoveryBackLabel(viewModel)),
502
504
  "data-auth-menu-close": true,
503
- disabled: recoveryNavigationLocked(viewModel),
505
+ disabled: success !== null || recoveryNavigationLocked(viewModel),
504
506
  onClick: this.onBackClick,
505
507
  children: backIcon()
506
508
  }),
@@ -515,7 +517,7 @@ var AuthMenuSurface = class extends Component {
515
517
  class: "seams-content-area",
516
518
  children: /* @__PURE__ */ jsx("div", {
517
519
  class: "seams-content-sizer",
518
- children: loading ? this.renderWaiting(viewModel) : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx("div", {
520
+ children: loading || success ? this.renderWaiting(viewModel) : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx("div", {
519
521
  class: "seams-signin-menu",
520
522
  children: /* @__PURE__ */ jsx(Fragment, { children: this.renderActiveView(viewModel) }, authViewKey(viewModel))
521
523
  }) })
@@ -980,6 +982,7 @@ var AuthMenuSurface = class extends Component {
980
982
  }
981
983
  renderWaiting(viewModel) {
982
984
  const status = viewModel.status;
985
+ if (status.kind === "succeeded") return this.renderSuccess(status);
983
986
  if (status.kind !== "busy") return /* @__PURE__ */ jsx(Fragment$1, {});
984
987
  const waitingText = status.headline;
985
988
  const prompt = status.illustration ? AUTH_MENU_WAITING_PROMPTS[status.illustration] : null;
@@ -1018,6 +1021,26 @@ var AuthMenuSurface = class extends Component {
1018
1021
  ]
1019
1022
  }) });
1020
1023
  }
1024
+ renderSuccess(status) {
1025
+ return /* @__PURE__ */ jsxs("div", {
1026
+ class: "seams-waiting seams-success",
1027
+ role: "status",
1028
+ "aria-live": "polite",
1029
+ children: [/* @__PURE__ */ jsx("span", {
1030
+ class: "seams-passkey-prompt seams-success-prompt",
1031
+ children: passkeySuccessIcon()
1032
+ }, "success-prompt"), /* @__PURE__ */ jsxs("div", {
1033
+ class: "seams-waiting-message seams-success-message",
1034
+ children: [/* @__PURE__ */ jsx("span", {
1035
+ class: "seams-waiting-text",
1036
+ children: /* @__PURE__ */ jsx(WalletText, { copy: status.headline })
1037
+ }), /* @__PURE__ */ jsx("span", {
1038
+ class: "seams-passkey-instruction",
1039
+ children: /* @__PURE__ */ jsx(WalletText, { copy: status.message })
1040
+ })]
1041
+ }, "success-message")]
1042
+ });
1043
+ }
1021
1044
  renderLinkDevice(viewModel) {
1022
1045
  const linkDevice = viewModel.linkDevice;
1023
1046
  if (linkDevice.kind === "select_factor") return this.renderLinkDeviceFactorSelection(linkDevice);
@@ -1279,7 +1302,11 @@ var AuthMenuSurface = class extends Component {
1279
1302
  return this.renderLinkDeviceFailurePanel({
1280
1303
  dismiss: "error",
1281
1304
  title: activationFailed ? "Device linked" : "Couldn't link device",
1282
- detail: activationFailed ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(WalletText, { message: "Unable to open the wallet. Go back and try again." }), /* @__PURE__ */ jsx(WalletText, { copy: linkDevice.message })] }) : linkDevice.message,
1305
+ detail: activationFailed ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1306
+ /* @__PURE__ */ jsx(WalletText, { message: "Unable to open the wallet. Go back and try again." }),
1307
+ " ",
1308
+ /* @__PURE__ */ jsx(WalletText, { copy: linkDevice.message })
1309
+ ] }) : linkDevice.message,
1283
1310
  action: "Return to unlock wallet"
1284
1311
  });
1285
1312
  }
@@ -39,6 +39,42 @@ function passkeyRingIcon() {
39
39
  })]
40
40
  });
41
41
  }
42
+ /** The passkey ring as it closes and fills behind a check. */
43
+ function passkeySuccessIcon() {
44
+ return /* @__PURE__ */ jsxs("svg", {
45
+ class: "seams-success-ring",
46
+ viewBox: "0 0 56 56",
47
+ fill: "none",
48
+ "aria-hidden": "true",
49
+ focusable: "false",
50
+ children: [
51
+ /* @__PURE__ */ jsx("circle", {
52
+ class: "seams-passkey-ring-track",
53
+ cx: "28",
54
+ cy: "28",
55
+ r: "26.75"
56
+ }),
57
+ /* @__PURE__ */ jsx("circle", {
58
+ class: "seams-success-ring-arc",
59
+ cx: "28",
60
+ cy: "28",
61
+ r: "26.75",
62
+ pathLength: "100"
63
+ }),
64
+ /* @__PURE__ */ jsx("circle", {
65
+ class: "seams-success-ring-seal",
66
+ cx: "28",
67
+ cy: "28",
68
+ r: "28"
69
+ }),
70
+ /* @__PURE__ */ jsx("path", {
71
+ class: "seams-success-ring-check",
72
+ d: "M36.7 21.5 24.75 33.4l-5.4-5.4",
73
+ pathLength: "1"
74
+ })
75
+ ]
76
+ });
77
+ }
42
78
  function accountDropdownIcon() {
43
79
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("svg", {
44
80
  class: "seams-account-dropdown-arrow",
@@ -153,6 +189,6 @@ function alertIcon() {
153
189
  }));
154
190
  }
155
191
  //#endregion
156
- export { accountDropdownIcon, alertIcon, backIcon, chevronIcon, fingerprintIcon, googleIcon, linkDeviceIcon, linkFailedIcon, mailIcon, passkeyRingIcon, recoveryIcon, rerollIcon, shieldIcon };
192
+ export { accountDropdownIcon, alertIcon, backIcon, chevronIcon, fingerprintIcon, googleIcon, linkDeviceIcon, linkFailedIcon, mailIcon, passkeyRingIcon, passkeySuccessIcon, recoveryIcon, rerollIcon, shieldIcon };
157
193
 
158
194
  //# sourceMappingURL=icons.js.map
@@ -48,6 +48,7 @@ function authViewKey(viewModel) {
48
48
  return `${viewModel.kind}:${viewModel.mode}:${viewModel.status.kind}${stage}`;
49
49
  }
50
50
  function recoveryAnnouncement(viewModel) {
51
+ if (viewModel.status.kind === "succeeded") return "";
51
52
  if (viewModel.status.kind === "busy") return viewModel.status.headline;
52
53
  if (viewModel.status.kind === "recoverable") return viewModel.status.message;
53
54
  if (viewModel.stage === "passkey_ready") return "Recovery code accepted.";
@@ -0,0 +1,6 @@
1
+ //#region src/core/browser/walletIframe/events.ts
2
+ const WalletIframeDomEvents = { TX_CONFIRMER_CANCEL: "seams:tx-confirmer-cancel" };
3
+ //#endregion
4
+ export { WalletIframeDomEvents };
5
+
6
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1,27 @@
1
+ //#region src/core/signingEngine/uiConfirm/ui/appearance.ts
2
+ const DEFAULT_UI_APPEARANCE = {
3
+ theme: {
4
+ id: "default",
5
+ mode: "dark",
6
+ colors: {}
7
+ },
8
+ palette: "default"
9
+ };
10
+ function isThemeMode(value) {
11
+ return value === "light" || value === "dark";
12
+ }
13
+ function resolveUiAppearance(args) {
14
+ const appearance = args.requestedAppearance ?? args.getAppearance?.() ?? DEFAULT_UI_APPEARANCE;
15
+ if (!isThemeMode(args.requestedMode) || args.requestedMode === appearance.theme.mode) return appearance;
16
+ return {
17
+ ...appearance,
18
+ theme: {
19
+ ...appearance.theme,
20
+ mode: args.requestedMode
21
+ }
22
+ };
23
+ }
24
+ //#endregion
25
+ export { resolveUiAppearance };
26
+
27
+ //# sourceMappingURL=appearance.js.map
@@ -0,0 +1,155 @@
1
+ //#region src/core/signingEngine/uiConfirm/ui/export-private-key-reveal.ts
2
+ const HEX_REEL_ALPHABET = "0123456789abcdef";
3
+ const BASE58_REEL_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
4
+ const REEL_GLYPH_MIN_HOLD_MS = 90;
5
+ const REEL_GLYPH_MAX_HOLD_MS = 150;
6
+ const REEL_SETTLE_HOLD_EXTENSION_MS = 90;
7
+ const REEL_SETTLE_STAGGER_MS = 700;
8
+ const REEL_SETTLE_SPIN_MS = 300;
9
+ function assertNever(value) {
10
+ throw new Error(`Unexpected private key reveal state: ${String(value)}`);
11
+ }
12
+ function reelDefinition(scheme) {
13
+ switch (scheme) {
14
+ case "secp256k1": return {
15
+ prefix: "0x",
16
+ alphabet: HEX_REEL_ALPHABET,
17
+ slotCount: 64
18
+ };
19
+ case "ed25519": return {
20
+ prefix: "ed25519:",
21
+ alphabet: BASE58_REEL_ALPHABET,
22
+ slotCount: 88
23
+ };
24
+ default: return assertNever(scheme);
25
+ }
26
+ }
27
+ function randomReelGlyph(alphabet) {
28
+ return alphabet[Math.floor(Math.random() * alphabet.length)] ?? alphabet[0] ?? "x";
29
+ }
30
+ function randomGlyphHoldMs(minimumMs, maximumMs) {
31
+ return minimumMs + Math.random() * (maximumMs - minimumMs);
32
+ }
33
+ function createReelSlots(definition, reducedMotion, now) {
34
+ const slots = [];
35
+ for (let index = 0; index < definition.slotCount; index += 1) slots.push({
36
+ glyph: reducedMotion ? "x" : randomReelGlyph(definition.alphabet),
37
+ nextChangeAtMs: reducedMotion ? Number.POSITIVE_INFINITY : now + index * 37 % 90
38
+ });
39
+ return slots;
40
+ }
41
+ function createSpinningState(entryKey, scheme, reducedMotion, now) {
42
+ const definition = reelDefinition(scheme);
43
+ return {
44
+ kind: "spinning",
45
+ entryKey,
46
+ prefix: definition.prefix,
47
+ alphabet: definition.alphabet,
48
+ slots: createReelSlots(definition, reducedMotion, now)
49
+ };
50
+ }
51
+ function maskedPrivateKey(privateKey) {
52
+ if (!privateKey) return "";
53
+ const visibleStartLength = (privateKey.startsWith("ed25519:") ? 8 : 0) + 6;
54
+ const hiddenEnd = Math.max(visibleStartLength, privateKey.length - 6);
55
+ return `${privateKey.slice(0, visibleStartLength)}${"x".repeat(hiddenEnd - visibleStartLength)}${privateKey.slice(hiddenEnd)}`;
56
+ }
57
+ function settlingState(state, maskedTarget, startedAtMs) {
58
+ const prefix = maskedTarget.startsWith(state.prefix) ? state.prefix : "";
59
+ const targetSlots = Array.from(maskedTarget.slice(prefix.length));
60
+ const slots = targetSlots.length === state.slots.length ? state.slots : targetSlots.map((_, index) => ({
61
+ glyph: randomReelGlyph(state.alphabet),
62
+ nextChangeAtMs: startedAtMs + index * 37 % 90
63
+ }));
64
+ return {
65
+ kind: "settling",
66
+ entryKey: state.entryKey,
67
+ prefix,
68
+ alphabet: state.alphabet,
69
+ slots,
70
+ targetSlots,
71
+ lockedSlots: 0,
72
+ startedAtMs
73
+ };
74
+ }
75
+ function lockedSlotCount(state, now) {
76
+ const lastIndex = Math.max(1, state.targetSlots.length - 1);
77
+ let count = 0;
78
+ for (let index = 0; index < state.targetSlots.length; index += 1) {
79
+ const stagger = index / lastIndex * REEL_SETTLE_STAGGER_MS;
80
+ if (now >= state.startedAtMs + stagger + REEL_SETTLE_SPIN_MS) count += 1;
81
+ }
82
+ return count;
83
+ }
84
+ function settlingProgress(state, index, now) {
85
+ const stagger = index / Math.max(1, state.targetSlots.length - 1) * REEL_SETTLE_STAGGER_MS;
86
+ const slotStartedAtMs = state.startedAtMs + stagger;
87
+ return Math.max(0, Math.min(1, (now - slotStartedAtMs) / REEL_SETTLE_SPIN_MS));
88
+ }
89
+ function cycleSpinningSlots(slots, alphabet, now) {
90
+ let nextSlots = null;
91
+ for (let index = 0; index < slots.length; index += 1) {
92
+ const slot = slots[index];
93
+ if (!slot || now < slot.nextChangeAtMs) continue;
94
+ if (nextSlots === null) nextSlots = [...slots];
95
+ nextSlots[index] = {
96
+ glyph: randomReelGlyph(alphabet),
97
+ nextChangeAtMs: now + randomGlyphHoldMs(REEL_GLYPH_MIN_HOLD_MS, REEL_GLYPH_MAX_HOLD_MS)
98
+ };
99
+ }
100
+ return nextSlots ?? slots;
101
+ }
102
+ function cycleSettlingSlots(state, lockedSlots, now) {
103
+ let nextSlots = null;
104
+ for (let index = 0; index < state.slots.length; index += 1) {
105
+ const slot = state.slots[index];
106
+ if (!slot) continue;
107
+ if (index < lockedSlots) {
108
+ const targetGlyph = state.targetSlots[index] ?? slot.glyph;
109
+ if (slot.glyph === targetGlyph && slot.nextChangeAtMs === Number.POSITIVE_INFINITY) continue;
110
+ if (nextSlots === null) nextSlots = [...state.slots];
111
+ nextSlots[index] = {
112
+ glyph: targetGlyph,
113
+ nextChangeAtMs: Number.POSITIVE_INFINITY
114
+ };
115
+ continue;
116
+ }
117
+ if (now < slot.nextChangeAtMs) continue;
118
+ const holdExtensionMs = settlingProgress(state, index, now) * REEL_SETTLE_HOLD_EXTENSION_MS;
119
+ if (nextSlots === null) nextSlots = [...state.slots];
120
+ nextSlots[index] = {
121
+ glyph: randomReelGlyph(state.alphabet),
122
+ nextChangeAtMs: now + randomGlyphHoldMs(REEL_GLYPH_MIN_HOLD_MS + holdExtensionMs, REEL_GLYPH_MAX_HOLD_MS + holdExtensionMs)
123
+ };
124
+ }
125
+ return nextSlots ?? state.slots;
126
+ }
127
+ function advanceRevealState(state, now) {
128
+ if (state.kind === "spinning") {
129
+ const slots = cycleSpinningSlots(state.slots, state.alphabet, now);
130
+ if (slots === state.slots) return state;
131
+ return {
132
+ ...state,
133
+ slots
134
+ };
135
+ }
136
+ if (state.kind === "settling") {
137
+ const nextLockedSlots = lockedSlotCount(state, now);
138
+ if (nextLockedSlots >= state.targetSlots.length) return {
139
+ kind: "settled",
140
+ entryKey: state.entryKey
141
+ };
142
+ const slots = cycleSettlingSlots(state, nextLockedSlots, now);
143
+ if (slots === state.slots && nextLockedSlots === state.lockedSlots) return state;
144
+ return {
145
+ ...state,
146
+ slots,
147
+ lockedSlots: nextLockedSlots
148
+ };
149
+ }
150
+ return assertNever(state);
151
+ }
152
+ //#endregion
153
+ export { advanceRevealState, createSpinningState, maskedPrivateKey, settlingState };
154
+
155
+ //# sourceMappingURL=export-private-key-reveal.js.map