@seams/wallet 0.6.0 → 0.6.2

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 (150) hide show
  1. package/dist/.build-inputs.sha256 +1 -1
  2. package/dist/esm/SeamsWeb/SeamsWeb.js +1 -0
  3. package/dist/esm/SeamsWeb/operations/registration/registration.js +162 -33
  4. package/dist/esm/SeamsWeb/operations/registration/registrationTiming.js +33 -2
  5. package/dist/esm/SeamsWeb/signingSurface/BrowserSigningSurface.js +3 -0
  6. package/dist/esm/SeamsWeb/walletIframe/client/overlay/overlay-controller.js +63 -10
  7. package/dist/esm/core/rpcClients/relayer/walletRegistration.js +45 -3
  8. package/dist/esm/core/signingEngine/flows/signNear/shared/ed25519YaoNormalSigning.js +19 -0
  9. package/dist/esm/core/signingEngine/flows/signNear/signTransactions.js +25 -6
  10. package/dist/esm/core/signingEngine/nonce/nearNonceLane.js +0 -29
  11. package/dist/esm/core/signingEngine/session/operationState/trace.js +10 -1
  12. package/dist/esm/core/signingEngine/session/passkey/prfCache.js +24 -4
  13. package/dist/esm/core/signingEngine/uiConfirm/PasskeyMpcSessionDurableState.js +5 -3
  14. package/dist/esm/core/signingEngine/uiConfirm/PasskeyMpcSessionManager.js +40 -3
  15. package/dist/esm/core/signingEngine/uiConfirm/ui/preact/TransactionReceipt.js +31 -35
  16. package/dist/esm/core/signingEngine/uiConfirm/ui/preact/mountConfirmationSurface.js +64 -10
  17. package/dist/esm/core/signingEngine/walletCustody/ceremonyDriver.js +1 -1
  18. package/dist/esm/react/SeamsWeb/SeamsWeb.js +1 -0
  19. package/dist/esm/react/SeamsWeb/operations/registration/registration.js +162 -33
  20. package/dist/esm/react/SeamsWeb/operations/registration/registrationTiming.js +33 -2
  21. package/dist/esm/react/SeamsWeb/signingSurface/BrowserSigningSurface.js +3 -0
  22. package/dist/esm/react/SeamsWeb/walletIframe/client/overlay/overlay-controller.js +63 -10
  23. package/dist/esm/react/core/rpcClients/relayer/walletRegistration.js +45 -3
  24. package/dist/esm/react/core/signingEngine/flows/signNear/shared/ed25519YaoNormalSigning.js +19 -0
  25. package/dist/esm/react/core/signingEngine/flows/signNear/signTransactions.js +25 -6
  26. package/dist/esm/react/core/signingEngine/nonce/nearNonceLane.js +0 -29
  27. package/dist/esm/react/core/signingEngine/session/operationState/trace.js +10 -1
  28. package/dist/esm/react/core/signingEngine/session/passkey/prfCache.js +24 -4
  29. package/dist/esm/react/core/signingEngine/uiConfirm/PasskeyMpcSessionDurableState.js +5 -3
  30. package/dist/esm/react/core/signingEngine/uiConfirm/PasskeyMpcSessionManager.js +40 -3
  31. package/dist/esm/react/core/signingEngine/uiConfirm/ui/preact/TransactionReceipt.js +31 -35
  32. package/dist/esm/react/core/signingEngine/uiConfirm/ui/preact/mountConfirmationSurface.js +64 -10
  33. package/dist/esm/react/core/signingEngine/walletCustody/ceremonyDriver.js +1 -1
  34. package/dist/esm/react/shared-ts/src/utils/routerAbEd25519Yao.js +13 -1
  35. package/dist/esm/sdk/{NonceCoordinator-C7QltTDC.js → NonceCoordinator-C7mqpJiU.js} +0 -29
  36. package/dist/esm/sdk/{adapters-Dgy69gf0.js → adapters-m94YFj70.js} +96 -46
  37. package/dist/{public/sdk/defaultConfigs-DJCLCrg9.js → esm/sdk/defaultConfigs-CyNOW4Sy.js} +1 -1
  38. package/dist/{public/sdk/display-Cw90-qmF.js → esm/sdk/display-DHdC2yXU.js} +1 -1
  39. package/dist/{public/sdk/ecdsaCapabilityManifest-DA_fklIs.js → esm/sdk/ecdsaCapabilityManifest-C8itxV9S.js} +1 -1
  40. package/dist/esm/sdk/{ecdsaPresignLifecycle-D_KCktCj.js → ecdsaPresignLifecycle-CnSnzoRJ.js} +13 -1
  41. package/dist/{public/sdk/ed25519SeedMaterial-0VmS6K9P.js → esm/sdk/ed25519SeedMaterial-Cghz8-XB.js} +2 -2
  42. package/dist/esm/sdk/{exactSessionState-C2aAv_ED.js → exactSessionState-Bt0HforB.js} +64 -11
  43. package/dist/esm/sdk/{export-viewer-host-NhjFdpm-.js → export-viewer-host-CbqG8ZQV.js} +1 -1
  44. package/dist/esm/sdk/{host-DACTruOj.js → host-BPC1zSVg.js} +2 -2
  45. package/dist/esm/sdk/{localOnly-DTNq69fJ.js → localOnly-CbLYTVbo.js} +2 -2
  46. package/dist/{public/sdk/nearEd25519YaoMaterialActivation-4AuGG2DG.js → esm/sdk/nearEd25519YaoMaterialActivation-Cz5UJQ_7.js} +46 -4
  47. package/dist/esm/sdk/{nearEd25519YaoSigningPreparation-jiGcQylO.js → nearEd25519YaoSigningPreparation-DX6xG-IW.js} +1 -1
  48. package/dist/esm/sdk/{prfCache-Dwwauj4v.js → prfCache-CgAr-VEU.js} +24 -4
  49. package/dist/{public/sdk/recovery-entrypoint-CFTX6PFZ.js → esm/sdk/recovery-entrypoint-D39R1avB.js} +3 -3
  50. package/dist/{public/sdk/registration-CuP1WmQu.js → esm/sdk/registration-DtDICj-o.js} +1 -1
  51. package/dist/esm/sdk/{registration-D8nYJKec.js → registration-PIBMSsQR.js} +247 -40
  52. package/dist/esm/sdk/{registrationPreparationPreload-DDe0sbZi.js → registrationPreparationPreload-BZfAC_ba.js} +2 -2
  53. package/dist/{public/sdk/router-DeX_cJ2f.js → esm/sdk/router-CeFS9SgT.js} +3 -3
  54. package/dist/{public/sdk/routerAbNormalSigning-BGpRKRAj.js → esm/sdk/routerAbNormalSigning-DktZKnf1.js} +1 -1
  55. package/dist/{public/sdk/runtime-auth-Ch00YcH5.js → esm/sdk/runtime-auth-D_lUQQlc.js} +8 -8
  56. package/dist/esm/sdk/{runtime-device-link-CEhVZYAw.js → runtime-device-link-CEph1iM0.js} +4 -4
  57. package/dist/{public/sdk/runtime-ecdsa-tempo-B-qMRrmx.js → esm/sdk/runtime-ecdsa-tempo-tUWnafRo.js} +5 -5
  58. package/dist/esm/sdk/{runtime-email-otp-giyMPib8.js → runtime-email-otp-1wIPTDim.js} +4 -4
  59. package/dist/esm/sdk/{runtime-export-CV-6G1Oy.js → runtime-export-Du2d4_Vu.js} +4 -4
  60. package/dist/{public/sdk/runtime-near-DoDcS88O.js → esm/sdk/runtime-near-CGoWxu7u.js} +4 -4
  61. package/dist/{public/sdk/runtime-preferences-Canyenle.js → esm/sdk/runtime-preferences-JwJK_xP3.js} +4 -4
  62. package/dist/esm/sdk/{runtime-recovery-lWyILD1g.js → runtime-recovery-BEqBdpyo.js} +4 -4
  63. package/dist/esm/sdk/{runtimeContext-BdTaYxJD.js → runtimeContext-CTt9ON27.js} +83 -40
  64. package/dist/{public/sdk/runtimeLoader-Dxn8UA8B.js → esm/sdk/runtimeLoader-ZXsvx9zX.js} +9 -9
  65. package/dist/{public/sdk/secp256k1-CQFsI3qQ.js → esm/sdk/secp256k1-CWDid9WH.js} +4 -4
  66. package/dist/{public/sdk/signEvmFamily-CZLET02E.js → esm/sdk/signEvmFamily-pbMepepQ.js} +10 -10
  67. package/dist/esm/sdk/{signEvmFamilyWithUiConfirmForTempo-DHTBHHgE.js → signEvmFamilyWithUiConfirmForTempo-CxvfCI_o.js} +2 -2
  68. package/dist/{public/sdk/signEvmWithUiConfirm-CSxTBQUW.js → esm/sdk/signEvmWithUiConfirm-nk-r3Rff.js} +1 -1
  69. package/dist/esm/sdk/{signNear-BeUWiWm_.js → signNear-DVD9-IO5.js} +50 -13
  70. package/dist/{public/sdk/signatureUses-C1o1pDql.js → esm/sdk/signatureUses-BY1IY7uz.js} +1 -1
  71. package/dist/{public/sdk/signerLoader-C_w8vuhm.js → esm/sdk/signerLoader-D_w-SfR9.js} +3 -3
  72. package/dist/{public/sdk/trace-DWnDLSuV.js → esm/sdk/trace-08ayoiNp.js} +10 -1
  73. package/dist/{public/sdk/transactionState-Dd13hMoY.js → esm/sdk/transactionState-Bpm4GamO.js} +2 -2
  74. package/dist/esm/sdk/tx-confirm-ui.js +134 -93
  75. package/dist/esm/sdk/wallet-iframe-host-ecdsa.js +1 -1
  76. package/dist/esm/sdk/wallet-iframe-host-full.js +1 -1
  77. package/dist/esm/sdk/wallet-iframe-host-near.js +1 -1
  78. package/dist/esm/sdk/wallet-iframe-host-runtime.js +1 -1
  79. package/dist/esm/sdk/wallet-ui.css +92 -32
  80. package/dist/esm/sdk/{walletRecoveryCommit-DNvzgeIX.js → walletRecoveryCommit-G6w6N5RV.js} +3 -3
  81. package/dist/esm/sdk/{warmSessionHydration-CCKeEIIy.js → warmSessionHydration-DDNYdTCz.js} +1 -1
  82. package/dist/esm/shared-ts/src/utils/routerAbEd25519Yao.js +13 -1
  83. package/dist/public/headers.manifest.json +1 -1
  84. package/dist/public/sdk/{NonceCoordinator-C7QltTDC.js → NonceCoordinator-C7mqpJiU.js} +0 -29
  85. package/dist/public/sdk/{adapters-Dgy69gf0.js → adapters-m94YFj70.js} +96 -46
  86. package/dist/{esm/sdk/defaultConfigs-DJCLCrg9.js → public/sdk/defaultConfigs-CyNOW4Sy.js} +1 -1
  87. package/dist/{esm/sdk/display-Cw90-qmF.js → public/sdk/display-DHdC2yXU.js} +1 -1
  88. package/dist/{esm/sdk/ecdsaCapabilityManifest-DA_fklIs.js → public/sdk/ecdsaCapabilityManifest-C8itxV9S.js} +1 -1
  89. package/dist/public/sdk/{ecdsaPresignLifecycle-D_KCktCj.js → ecdsaPresignLifecycle-CnSnzoRJ.js} +13 -1
  90. package/dist/{esm/sdk/ed25519SeedMaterial-0VmS6K9P.js → public/sdk/ed25519SeedMaterial-Cghz8-XB.js} +2 -2
  91. package/dist/public/sdk/{exactSessionState-C2aAv_ED.js → exactSessionState-Bt0HforB.js} +64 -11
  92. package/dist/public/sdk/{export-viewer-host-NhjFdpm-.js → export-viewer-host-CbqG8ZQV.js} +1 -1
  93. package/dist/public/sdk/{host-DACTruOj.js → host-BPC1zSVg.js} +2 -2
  94. package/dist/public/sdk/{localOnly-DTNq69fJ.js → localOnly-CbLYTVbo.js} +2 -2
  95. package/dist/{esm/sdk/nearEd25519YaoMaterialActivation-4AuGG2DG.js → public/sdk/nearEd25519YaoMaterialActivation-Cz5UJQ_7.js} +46 -4
  96. package/dist/public/sdk/{nearEd25519YaoSigningPreparation-jiGcQylO.js → nearEd25519YaoSigningPreparation-DX6xG-IW.js} +1 -1
  97. package/dist/public/sdk/{prfCache-Dwwauj4v.js → prfCache-CgAr-VEU.js} +24 -4
  98. package/dist/{esm/sdk/recovery-entrypoint-CFTX6PFZ.js → public/sdk/recovery-entrypoint-D39R1avB.js} +3 -3
  99. package/dist/{esm/sdk/registration-CuP1WmQu.js → public/sdk/registration-DtDICj-o.js} +1 -1
  100. package/dist/public/sdk/{registration-D8nYJKec.js → registration-PIBMSsQR.js} +247 -40
  101. package/dist/public/sdk/{registrationPreparationPreload-DDe0sbZi.js → registrationPreparationPreload-BZfAC_ba.js} +2 -2
  102. package/dist/{esm/sdk/router-DeX_cJ2f.js → public/sdk/router-CeFS9SgT.js} +3 -3
  103. package/dist/{esm/sdk/routerAbNormalSigning-BGpRKRAj.js → public/sdk/routerAbNormalSigning-DktZKnf1.js} +1 -1
  104. package/dist/{esm/sdk/runtime-auth-Ch00YcH5.js → public/sdk/runtime-auth-D_lUQQlc.js} +8 -8
  105. package/dist/public/sdk/{runtime-device-link-CEhVZYAw.js → runtime-device-link-CEph1iM0.js} +4 -4
  106. package/dist/{esm/sdk/runtime-ecdsa-tempo-B-qMRrmx.js → public/sdk/runtime-ecdsa-tempo-tUWnafRo.js} +5 -5
  107. package/dist/public/sdk/{runtime-email-otp-giyMPib8.js → runtime-email-otp-1wIPTDim.js} +4 -4
  108. package/dist/public/sdk/{runtime-export-CV-6G1Oy.js → runtime-export-Du2d4_Vu.js} +4 -4
  109. package/dist/{esm/sdk/runtime-near-DoDcS88O.js → public/sdk/runtime-near-CGoWxu7u.js} +4 -4
  110. package/dist/{esm/sdk/runtime-preferences-Canyenle.js → public/sdk/runtime-preferences-JwJK_xP3.js} +4 -4
  111. package/dist/public/sdk/{runtime-recovery-lWyILD1g.js → runtime-recovery-BEqBdpyo.js} +4 -4
  112. package/dist/public/sdk/{runtimeContext-BdTaYxJD.js → runtimeContext-CTt9ON27.js} +83 -40
  113. package/dist/{esm/sdk/runtimeLoader-Dxn8UA8B.js → public/sdk/runtimeLoader-ZXsvx9zX.js} +9 -9
  114. package/dist/{esm/sdk/secp256k1-CQFsI3qQ.js → public/sdk/secp256k1-CWDid9WH.js} +4 -4
  115. package/dist/{esm/sdk/signEvmFamily-CZLET02E.js → public/sdk/signEvmFamily-pbMepepQ.js} +10 -10
  116. package/dist/public/sdk/{signEvmFamilyWithUiConfirmForTempo-DHTBHHgE.js → signEvmFamilyWithUiConfirmForTempo-CxvfCI_o.js} +2 -2
  117. package/dist/{esm/sdk/signEvmWithUiConfirm-CSxTBQUW.js → public/sdk/signEvmWithUiConfirm-nk-r3Rff.js} +1 -1
  118. package/dist/public/sdk/{signNear-BeUWiWm_.js → signNear-DVD9-IO5.js} +50 -13
  119. package/dist/{esm/sdk/signatureUses-C1o1pDql.js → public/sdk/signatureUses-BY1IY7uz.js} +1 -1
  120. package/dist/{esm/sdk/signerLoader-C_w8vuhm.js → public/sdk/signerLoader-D_w-SfR9.js} +3 -3
  121. package/dist/{esm/sdk/trace-DWnDLSuV.js → public/sdk/trace-08ayoiNp.js} +10 -1
  122. package/dist/{esm/sdk/transactionState-Dd13hMoY.js → public/sdk/transactionState-Bpm4GamO.js} +2 -2
  123. package/dist/public/sdk/tx-confirm-ui.js +134 -93
  124. package/dist/public/sdk/wallet-iframe-host-ecdsa.js +1 -1
  125. package/dist/public/sdk/wallet-iframe-host-full.js +1 -1
  126. package/dist/public/sdk/wallet-iframe-host-near.js +1 -1
  127. package/dist/public/sdk/wallet-iframe-host-runtime.js +1 -1
  128. package/dist/public/sdk/wallet-ui.css +92 -32
  129. package/dist/public/sdk/{walletRecoveryCommit-DNvzgeIX.js → walletRecoveryCommit-G6w6N5RV.js} +3 -3
  130. package/dist/public/sdk/{warmSessionHydration-CCKeEIIy.js → warmSessionHydration-DDNYdTCz.js} +1 -1
  131. package/dist/public/sdk/workers/passkey-mpc-session.worker.js +92 -8
  132. package/dist/public/wallet-assets.manifest.json +86 -86
  133. package/dist/public/wallet-service/index.html +4 -4
  134. package/dist/types/wallet/src/SeamsWeb/operations/registration/registration.d.ts +15 -1
  135. package/dist/types/wallet/src/SeamsWeb/operations/registration/registrationTiming.d.ts +11 -1
  136. package/dist/types/wallet/src/SeamsWeb/signingSurface/BrowserSigningSurface.d.ts +6 -0
  137. package/dist/types/wallet/src/SeamsWeb/signingSurface/ports.d.ts +8 -2
  138. package/dist/types/wallet/src/core/rpcClients/relayer/walletRegistration.d.ts +49 -10
  139. package/dist/types/wallet/src/core/signingEngine/nonce/nearNonceLane.d.ts +2 -1
  140. package/dist/types/wallet/src/core/signingEngine/session/operationState/trace.d.ts +2 -0
  141. package/dist/types/wallet/src/core/signingEngine/session/passkey/prfCache.d.ts +7 -9
  142. package/dist/types/wallet/src/core/signingEngine/session/passkey/warmSessionHydration.d.ts +7 -8
  143. package/dist/types/wallet/src/core/signingEngine/session/passkey/warmSessionMaterialWriter.d.ts +9 -9
  144. package/dist/types/wallet/src/core/signingEngine/session/warmCapabilities/public.d.ts +7 -8
  145. package/dist/types/wallet/src/core/signingEngine/uiConfirm/PasskeyMpcSessionDurableState.d.ts +3 -0
  146. package/dist/types/wallet/src/core/signingEngine/uiConfirm/uiConfirm.types.d.ts +6 -0
  147. package/dist/types/wallet/src/core/signingEngine/workerManager/workers/shamir3pass/clientSealPreparation.d.ts +2 -0
  148. package/dist/types/wallet/src/core/types/secure-confirm-worker.d.ts +15 -1
  149. package/dist/workers/passkey-mpc-session.worker.js +92 -8
  150. package/package.json +1 -1
@@ -8,6 +8,7 @@ import { resolveNearNetwork } from "../../../../config/chains.js";
8
8
  import { SigningSessionIds } from "../../../session/operationState/types.js";
9
9
  import { ActionType, fromActionArgsWasm } from "../../../../../shared-ts/src/near/actions.js";
10
10
  import { PASSKEY_MANAGER_DEFAULT_CONFIGS } from "../../../../config/defaultConfigs.js";
11
+ import { emitEd25519SigningTiming } from "../../../session/operationState/trace.js";
11
12
  import { parseThresholdEd25519NearTransaction, thresholdEd25519NearTransactionOperationFingerprint } from "../../../../../shared-ts/src/threshold/ed25519OperationFingerprint.js";
12
13
  import { WorkerResponseType } from "../../../../types/signer-worker.js";
13
14
  import { buildThresholdEd25519DelegateSigningPayloadWasm, buildThresholdEd25519NearTxUnsignedBorshWasm, decodeThresholdEd25519SignedNearTxBorshWasm, finalizeThresholdEd25519DelegateFromSignatureWasm, finalizeThresholdEd25519NearTxFromSignatureWasm } from "../../../chains/near/nearSignerWasm.js";
@@ -260,6 +261,18 @@ function requireActiveClientMatchesNormalSigningOperation(args) {
260
261
  if (!sameBytes(metadata.signingWorkerVerifyingShare, args.signingWorkerVerifyingShare)) throw new Error("Router A/B Ed25519 active Client SigningWorker verifying share mismatch");
261
262
  }
262
263
  async function tryFinalizeRouterAbEd25519NormalSigningSignature(args) {
264
+ const operationId = args.prepare.request.intent.operation_id;
265
+ const signatureStartedAt = performance.now();
266
+ let outcome = "failed";
267
+ try {
268
+ const finalized = await finalizeRouterAbEd25519NormalSigningSignature(args, operationId);
269
+ outcome = "succeeded";
270
+ return finalized;
271
+ } finally {
272
+ emitEd25519SigningTiming(operationId, "signature_total", signatureStartedAt, outcome);
273
+ }
274
+ }
275
+ async function finalizeRouterAbEd25519NormalSigningSignature(args, operationId) {
263
276
  const signingPayload = base64UrlDecode(args.signingDigestB64u);
264
277
  if (signingPayload.length !== 32) throw new Error(`Router A/B normal-signing ${args.signingPayloadLabel} must be 32 bytes`);
265
278
  const admittedDigest = requireWireBytes32(args.prepare.admissionMaterial.admittedSigningDigest.bytes, "admitted digest");
@@ -279,11 +292,13 @@ async function tryFinalizeRouterAbEd25519NormalSigningSignature(args) {
279
292
  runtimePolicyScope: args.walletSessionState.runtimePolicyScope,
280
293
  relayerUrl: args.walletSessionState.relayerUrl
281
294
  } : args.materialFacts;
295
+ const prepareStartedAt = performance.now();
282
296
  const prepareResponse = await prepareRouterAbNormalSigningV2({
283
297
  relayServerUrl: materialFacts.relayerUrl,
284
298
  credential: args.credential,
285
299
  request: args.prepare.request
286
300
  });
301
+ emitEd25519SigningTiming(operationId, "prepare", prepareStartedAt);
287
302
  requireRouterAbNormalSigningPrepareMatchesRequest({
288
303
  request: args.prepare.request,
289
304
  signingPayloadDigest: args.prepare.admissionMaterial.signingPayloadDigest,
@@ -304,12 +319,15 @@ async function tryFinalizeRouterAbEd25519NormalSigningSignature(args) {
304
319
  signingWorkerId: prepareResponse.signing_worker.server_id,
305
320
  signingWorkerVerifyingShare
306
321
  });
322
+ const clientShareStartedAt = performance.now();
307
323
  const clientShare = await args.activeClient.createSigningShare({
308
324
  admittedDigest,
309
325
  signingWorkerCommitments: prepareResponse.server_commitments,
310
326
  signingWorkerVerifyingShare
311
327
  });
328
+ emitEd25519SigningTiming(operationId, "client_share", clientShareStartedAt);
312
329
  if (clientShare.clientVerifyingShare.length !== 32) throw new Error("Router A/B normal-signing Client verifying share must be 32 bytes");
330
+ const finalizeStartedAt = performance.now();
313
331
  const signingResponse = await finalizeRouterAbNormalSigningV2({
314
332
  relayServerUrl: materialFacts.relayerUrl,
315
333
  credential: args.credential,
@@ -323,6 +341,7 @@ async function tryFinalizeRouterAbEd25519NormalSigningSignature(args) {
323
341
  clientSignatureShareB64u: clientShare.clientSignatureShareB64u
324
342
  })
325
343
  });
344
+ emitEd25519SigningTiming(operationId, "finalize", finalizeStartedAt);
326
345
  requireRouterAbNormalSigningResponseMatchesRequest({
327
346
  request: args.prepare.request,
328
347
  signingPayloadDigest: args.prepare.admissionMaterial.signingPayloadDigest,
@@ -9,7 +9,7 @@ import { SignedTransaction } from "../../../rpcClients/near/NearClient.js";
9
9
  import { PASSKEY_MANAGER_DEFAULT_CONFIGS } from "../../../config/defaultConfigs.js";
10
10
  import { resolveNearSigningMaterials } from "./shared/signingMaterials.js";
11
11
  import { buildNearTransactionSigningPayload } from "../../chains/near/payloads.js";
12
- import { createSigningBoundaryTraceEvent, emitSigningBoundaryTrace } from "../../session/operationState/trace.js";
12
+ import { createSigningBoundaryTraceEvent, emitEd25519SigningTiming, emitSigningBoundaryTrace } from "../../session/operationState/trace.js";
13
13
  import { parseThresholdEd25519NearTransaction, thresholdEd25519NearTransactionPlanningOperationFingerprint } from "../../../../shared-ts/src/threshold/ed25519OperationFingerprint.js";
14
14
  import { SigningOperationCommandKind, isSigningOperationReviewApprovedState, runSigningOperationCommand } from "../shared/signingStateMachine.js";
15
15
  import { requireNearStepUpAuth, signingAuthPlanForNearMaterialRequirement } from "./requireNearStepUpAuth.js";
@@ -45,6 +45,16 @@ function disposeOwnedNearOperationStepUpMaterialAndRethrow(args, error) {
45
45
  disposeOwnedNearOperationStepUpMaterial(args);
46
46
  throw error;
47
47
  }
48
+ async function resolveWarmNearSigningMaterial(args) {
49
+ return {
50
+ material: await resolvePreparedNearEd25519YaoMaterial(args.preparation, args.executor),
51
+ walletSessionState: await args.executor.resolveWalletSessionState()
52
+ };
53
+ }
54
+ function requireWarmNearSigningMaterialTask(task) {
55
+ if (!task) throw new Error("[SigningEngine][near] warm signing material was not prepared");
56
+ return task;
57
+ }
48
58
  async function resolveNearTransactionOperationStepUpMaterial(args) {
49
59
  if (args.authorization.kind === "passkey") {
50
60
  if (args.material.kind !== "passkey_live" && args.material.kind !== "passkey_sealed") throw new Error("[SigningEngine][near] passkey transaction material changed factor");
@@ -385,6 +395,8 @@ async function runAuthorizedNearTransactionWithActionsSigning({ ctx, commandSubj
385
395
  const nearAccountId = toAccountId(nearAccount.accountId);
386
396
  const relayerUrl = ctx.relayerUrl;
387
397
  const warnings = [];
398
+ const durableLeaseRecovery = ctx.nonceCoordinator.recoverDurableLeases({ walletId: String(commandSubject.walletSession.walletId) });
399
+ durableLeaseRecovery.catch(() => {});
388
400
  emitNearSigningEvent(onEvent, nearAccountId, {
389
401
  phase: SigningEventPhase.STEP_02_REQUEST_PREPARED,
390
402
  status: "running",
@@ -484,6 +496,11 @@ async function runAuthorizedNearTransactionWithActionsSigning({ ctx, commandSubj
484
496
  ...passkeyEd25519OperationStepUp ? { passkeyEd25519OperationStepUp } : {},
485
497
  ...emailOtpEd25519StepUp ? { emailOtpEd25519StepUp } : {}
486
498
  });
499
+ const warmSigningMaterialTask = preparedStepUp.kind === "warm_session" ? resolveWarmNearSigningMaterial({
500
+ preparation: yaoSigningPreparation,
501
+ executor: yaoMaterialExecutor
502
+ }) : null;
503
+ warmSigningMaterialTask?.catch(() => {});
487
504
  const confirmationAuthPayload = preparedStepUp.confirmationAuthPayload;
488
505
  if (isWarmSessionSigningAuthPlan(confirmationAuthPayload.signingAuthPlan)) emitNearSigningEvent(onEvent, nearAccountId, {
489
506
  phase: SigningEventPhase.STEP_06_AUTH_WARM_SESSION_CLAIMED,
@@ -578,6 +595,7 @@ async function runAuthorizedNearTransactionWithActionsSigning({ ctx, commandSubj
578
595
  readiness: operationStepUpReadiness
579
596
  });
580
597
  }
598
+ const confirmationCompletedAt = performance.now();
581
599
  const operationStepUpMaterial = operationStepUpReadiness ? await operationStepUpReadiness : null;
582
600
  if (transactionReviewRequired) emitNearSigningEvent(onEvent, nearAccountId, {
583
601
  phase: SigningEventPhase.STEP_05_CONFIRMATION_APPROVED,
@@ -610,7 +628,7 @@ async function runAuthorizedNearTransactionWithActionsSigning({ ctx, commandSubj
610
628
  });
611
629
  const ownsResolvedOperationStepUpMaterial = operationStepUpMaterial?.kind === "passkey_sealed" || operationStepUpMaterial?.kind === "email_otp_sealed";
612
630
  try {
613
- await ctx.nonceCoordinator.recoverDurableLeases({ walletId: String(signingLane.identity.signer.account.wallet.walletId) });
631
+ await durableLeaseRecovery;
614
632
  } catch (error) {
615
633
  disposeOwnedNearOperationStepUpMaterial({
616
634
  resolved: resolvedOperationStepUpMaterial,
@@ -633,14 +651,14 @@ async function runAuthorizedNearTransactionWithActionsSigning({ ctx, commandSubj
633
651
  });
634
652
  const resolvedMaterial = stepUpAuthorization.kind === "warm_session" ? {
635
653
  kind: "warm_session",
636
- material: await resolvePreparedNearEd25519YaoMaterial(yaoSigningPreparation, yaoMaterialExecutor)
654
+ resolved: await requireWarmNearSigningMaterialTask(warmSigningMaterialTask)
637
655
  } : {
638
656
  kind: "operation_step_up",
639
657
  resolved: resolvedOperationStepUpMaterial
640
658
  };
641
- const canonicalThresholdSessionId = resolvedMaterial.kind === "warm_session" ? resolvedMaterial.material.facts.thresholdSessionId : resolvedMaterial.resolved.material.facts.thresholdSessionId;
642
- const activeYaoClient = resolvedMaterial.kind === "warm_session" ? resolvedMaterial.material.activeClient : resolvedMaterial.resolved.material.activeClient;
643
- const activeWalletSessionState = resolvedMaterial.kind === "warm_session" ? await yaoMaterialExecutor.resolveWalletSessionState() : null;
659
+ const canonicalThresholdSessionId = resolvedMaterial.kind === "warm_session" ? resolvedMaterial.resolved.material.facts.thresholdSessionId : resolvedMaterial.resolved.material.facts.thresholdSessionId;
660
+ const activeYaoClient = resolvedMaterial.kind === "warm_session" ? resolvedMaterial.resolved.material.activeClient : resolvedMaterial.resolved.material.activeClient;
661
+ const activeWalletSessionState = resolvedMaterial.kind === "warm_session" ? resolvedMaterial.resolved.walletSessionState : null;
644
662
  const confirmedNearContext = resolvedMaterial.kind === "warm_session" ? await resolveConfirmedNearTransactionContext({
645
663
  confirmation,
646
664
  ctx,
@@ -771,6 +789,7 @@ async function runAuthorizedNearTransactionWithActionsSigning({ ctx, commandSubj
771
789
  warnings,
772
790
  nonceLeases: nonceLeaseRefs
773
791
  });
792
+ emitEd25519SigningTiming(String(signingOperation.operationId), "confirmed_to_signed", confirmationCompletedAt);
774
793
  emitNearSigningEvent(onEvent, nearAccountId, {
775
794
  phase: SigningEventPhase.STEP_11_TRANSACTION_SIGNED,
776
795
  status: "succeeded",
@@ -393,22 +393,6 @@ var NearImplicitAccountFundingRequiredError = class extends Error {
393
393
  });
394
394
  }
395
395
  };
396
- async function readImplicitNearAccountFundingState(input) {
397
- try {
398
- await input.nearClient.viewAccount(input.subject.nearAccountId);
399
- return { kind: "funded" };
400
- } catch (error) {
401
- if (!isMissingNearAccessKeyError(errorMessage(error))) throw error;
402
- }
403
- return {
404
- kind: "needs_funding",
405
- error: new NearImplicitAccountFundingRequiredError({
406
- walletId: input.subject.walletId,
407
- nearAccountId: input.subject.nearAccountId,
408
- nearPublicKeyStr: input.subject.publicKey
409
- })
410
- };
411
- }
412
396
  var NearAccountLookupFailedError = class extends Error {
413
397
  constructor(args) {
414
398
  super(args.message || `NEAR account ${args.nearAccountId} access key lookup failed.`);
@@ -442,16 +426,11 @@ async function fetchNearFreshDataForState(input) {
442
426
  let txBlockHash = previousTransactionContext?.txBlockHash;
443
427
  const fetchAccessKey = isNonceStale || !accessKeyInfo;
444
428
  const fetchBlock = isBlockStale || !txBlockHeight || !txBlockHash;
445
- const fetchImplicitAccountFunding = isImplicitNearAccountId(capturedSubject.nearAccountId) && (input.force || fetchAccessKey || !readyContext);
446
429
  let maybeAccessKey = accessKeyInfo ?? null;
447
430
  let maybeBlock = null;
448
431
  let accessKeyError = null;
449
432
  let blockError = null;
450
433
  const tasks = [];
451
- const implicitFundingPromise = fetchImplicitAccountFunding ? readImplicitNearAccountFundingState({
452
- nearClient: input.nearClient,
453
- subject: capturedSubject
454
- }) : null;
455
434
  if (fetchAccessKey) tasks.push((async () => {
456
435
  try {
457
436
  maybeAccessKey = await input.nearClient.viewAccessKey(capturedSubject.nearAccountId, capturedSubject.publicKey);
@@ -485,14 +464,6 @@ async function fetchNearFreshDataForState(input) {
485
464
  }
486
465
  })());
487
466
  if (tasks.length > 0) await Promise.all(tasks);
488
- const implicitFunding = implicitFundingPromise ? await implicitFundingPromise : null;
489
- if (implicitFunding?.kind === "needs_funding") {
490
- setNearImplicitUnfunded({
491
- state,
492
- subject: capturedSubject
493
- });
494
- throw implicitFunding.error;
495
- }
496
467
  if (accessKeyError) {
497
468
  if (accessKeyError instanceof NearImplicitAccountFundingRequiredError) setNearImplicitUnfunded({
498
469
  state,
@@ -30,6 +30,15 @@ function emitEcdsaSigningTiming(operationId, stage, startedAt, outcome = "succee
30
30
  outcome
31
31
  });
32
32
  }
33
+ function emitEd25519SigningTiming(operationId, stage, startedAt, outcome = "succeeded") {
34
+ emitSigningSessionFlowTrace("near", {
35
+ event: "ed25519_signing_timing",
36
+ operationId,
37
+ stage,
38
+ durationMs: Math.max(0, performance.now() - startedAt),
39
+ outcome
40
+ });
41
+ }
33
42
  function emitSigningLaneResolutionTrace(scope, lane, args = {}) {
34
43
  if (!lane || !isSigningSessionTraceEnabled()) return;
35
44
  try {
@@ -80,6 +89,6 @@ function isSigningSessionTraceEnabled() {
80
89
  }
81
90
  }
82
91
  //#endregion
83
- export { createSigningBoundaryTraceEvent, emitEcdsaPresignServerTiming, emitEcdsaServerTiming, emitEcdsaSigningTiming, emitSigningBoundaryTrace, emitSigningLaneResolutionTrace, emitSigningPlannerDecisionTrace, emitSigningSessionFlowFailure, emitSigningSessionFlowTrace };
92
+ export { createSigningBoundaryTraceEvent, emitEcdsaPresignServerTiming, emitEcdsaServerTiming, emitEcdsaSigningTiming, emitEd25519SigningTiming, emitSigningBoundaryTrace, emitSigningLaneResolutionTrace, emitSigningPlannerDecisionTrace, emitSigningSessionFlowFailure, emitSigningSessionFlowTrace };
84
93
 
85
94
  //# sourceMappingURL=trace.js.map
@@ -15,23 +15,43 @@ function normalizeSigningSessionCacheEntry(args) {
15
15
  if (!thresholdSessionId || !prfFirstB64u) throw new Error("Missing thresholdSessionId or prfFirstB64u for signing session hydration");
16
16
  if (!Number.isFinite(expiresAtMsRaw) || expiresAtMsRaw <= 0) throw new Error("Invalid expiresAtMs for signing session hydration");
17
17
  if (remainingUses == null) throw new Error("Invalid remainingUses for signing session hydration");
18
- return {
18
+ const normalized = {
19
19
  thresholdSessionId,
20
20
  prfFirstB64u,
21
21
  expiresAtMs: Math.floor(expiresAtMsRaw),
22
22
  remainingUses,
23
+ ...args.diagnostics ? { diagnostics: args.diagnostics } : {}
24
+ };
25
+ if (args.preparedServerSeal) return {
26
+ ...normalized,
27
+ transport: args.transport,
28
+ preparedServerSeal: args.preparedServerSeal
29
+ };
30
+ return {
31
+ ...normalized,
23
32
  ...args.transport ? { transport: args.transport } : {}
24
33
  };
25
34
  }
26
35
  async function cacheCredentialBoundarySetupExportPrfFirst(writer, args) {
27
36
  const normalized = normalizeSigningSessionCacheEntry(args);
28
- await writer.putWarmSessionMaterial({
37
+ const material = {
29
38
  thresholdSessionId: normalized.thresholdSessionId,
30
39
  prfFirstB64u: normalized.prfFirstB64u,
31
40
  expiresAtMs: normalized.expiresAtMs,
32
41
  remainingUses: normalized.remainingUses,
33
- ...args.transport ? { transport: args.transport } : {},
34
- ...args.diagnostics ? { diagnostics: args.diagnostics } : {}
42
+ ...normalized.diagnostics ? { diagnostics: normalized.diagnostics } : {}
43
+ };
44
+ if (normalized.preparedServerSeal) {
45
+ await writer.putWarmSessionMaterial({
46
+ ...material,
47
+ transport: normalized.transport,
48
+ preparedServerSeal: normalized.preparedServerSeal
49
+ });
50
+ return;
51
+ }
52
+ await writer.putWarmSessionMaterial({
53
+ ...material,
54
+ ...normalized.transport ? { transport: normalized.transport } : {}
35
55
  });
36
56
  }
37
57
  //#endregion
@@ -230,7 +230,8 @@ var PasskeyMpcSessionDurableState = class {
230
230
  metadata,
231
231
  purpose,
232
232
  relayerUrl,
233
- diagnostics: args.diagnostics
233
+ diagnostics: args.diagnostics,
234
+ completedSeal: args.completedSeal
234
235
  });
235
236
  else persistTask = this.persistExactRecord({
236
237
  thresholdSessionId,
@@ -238,7 +239,8 @@ var PasskeyMpcSessionDurableState = class {
238
239
  metadata,
239
240
  purpose,
240
241
  relayerUrl,
241
- diagnostics: args.diagnostics
242
+ diagnostics: args.diagnostics,
243
+ completedSeal: args.completedSeal
242
244
  });
243
245
  const task = persistTask.finally(() => {
244
246
  signingSessionSealPersistSingleFlight.delete(singleFlightKey);
@@ -379,7 +381,7 @@ var PasskeyMpcSessionDurableState = class {
379
381
  };
380
382
  const groupId = SIGNING_SESSION_SEAL_GROUP_ID;
381
383
  const sealStartedAt = performance.now();
382
- const sealed = await this.deps.sealAndPersistWarmSessionMaterial({
384
+ const sealed = args.completedSeal ?? await this.deps.sealAndPersistWarmSessionMaterial({
383
385
  thresholdSessionId: args.thresholdSessionId,
384
386
  transport: normalizedPasskeyTransport(args.transport, groupId)
385
387
  });
@@ -237,7 +237,8 @@ var PasskeyMpcSessionManagerImpl = class {
237
237
  this.boundHandleWorkerMessage = this.handleWorkerMessage.bind(this);
238
238
  this.boundHandleWorkerError = this.handleWorkerError.bind(this);
239
239
  this.putWarmSessionMaterial = async (args) => {
240
- const { diagnostics, ...workerPayload } = args;
240
+ const { diagnostics, preparedServerSeal, ...workerPayload } = args;
241
+ if (preparedServerSeal && !args.transport) throw new Error("Prepared server seal requires exact persistence transport");
241
242
  const workerReadyStartedAt = performance.now();
242
243
  await this.ensureWorkerReady();
243
244
  recordDiagnosticDuration({
@@ -260,11 +261,38 @@ var PasskeyMpcSessionManagerImpl = class {
260
261
  bucket: "worker_put",
261
262
  startedAt: workerPutStartedAt
262
263
  });
264
+ let completedSeal;
265
+ if (preparedServerSeal && args.transport) {
266
+ const completed = await this.sendMessage({
267
+ type: "COMPLETE_SESSION_CLIENT_SEAL",
268
+ id: this.generateMessageId(),
269
+ payload: {
270
+ preparationId: preparedServerSeal.preparationId,
271
+ thresholdSessionId: args.thresholdSessionId,
272
+ transport: requirePasskeySealTransport(args.transport),
273
+ serverSeal: {
274
+ ok: true,
275
+ ciphertext: preparedServerSeal.ciphertext,
276
+ keyVersion: preparedServerSeal.keyVersion,
277
+ expiresAtMs: preparedServerSeal.expiresAtMs,
278
+ remainingUses: preparedServerSeal.remainingUses
279
+ }
280
+ }
281
+ });
282
+ const parsed = completed.success ? parseWarmSessionSealAndPersistResult(completed.data) : null;
283
+ if (!parsed) {
284
+ const message = completed.success ? "Prepared signing-session seal returned an invalid response" : completed.error || "Prepared signing-session seal failed";
285
+ throw new Error(message);
286
+ }
287
+ if (!parsed.ok) throw new Error(`Prepared signing-session seal failed (${parsed.code}): ${parsed.message}`);
288
+ completedSeal = parsed;
289
+ }
263
290
  const persistStartedAt = performance.now();
264
- const persisted = args.transport ? await this.persistSigningSessionSealForThresholdSession({
291
+ const persisted = args.transport ? await this.durableState.persistSigningSessionSealForThresholdSession({
265
292
  thresholdSessionId: args.thresholdSessionId,
266
293
  transport: requirePasskeySealTransport(args.transport),
267
- ...diagnostics ? { diagnostics } : {}
294
+ ...diagnostics ? { diagnostics } : {},
295
+ ...completedSeal ? { completedSeal } : {}
268
296
  }) : null;
269
297
  recordDiagnosticDuration({
270
298
  diagnostics,
@@ -488,6 +516,15 @@ var PasskeyMpcSessionManagerImpl = class {
488
516
  });
489
517
  if (!response.success) throw new Error(response.error || "Client seal cleanup failed");
490
518
  }
519
+ async readPreparedSigningSessionHydration(input) {
520
+ const response = await this.sendMessage({
521
+ type: "READ_SESSION_CLIENT_SEAL",
522
+ id: this.generateMessageId(),
523
+ payload: input
524
+ });
525
+ if (!response.success || !isObjectRecord(response.data) || response.data.ok !== true || typeof response.data.ciphertext !== "string" || !response.data.ciphertext.trim()) throw new Error(response.success ? "Prepared client seal is invalid" : response.error || "Client seal read failed");
526
+ return { ciphertext: response.data.ciphertext };
527
+ }
491
528
  async restorePasskeyEcdsaRecord(args) {
492
529
  const thresholdSessionId = args.purpose.thresholdSessionId;
493
530
  const chainTarget = args.purpose.chainTarget;
@@ -30,12 +30,16 @@ var TransactionReceipt = class extends Component {
30
30
  if (receipt.view === "toast") return /* @__PURE__ */ jsxs("div", {
31
31
  class: "seams-transaction-toast",
32
32
  "data-completed-stages": completedStages,
33
+ "data-stage": receipt.state.kind,
33
34
  "data-pending": pending,
34
35
  children: [
35
36
  /* @__PURE__ */ jsx("div", {
36
37
  class: "seams-toast-progress",
37
38
  "aria-hidden": "true",
38
- children: /* @__PURE__ */ jsx("span", {})
39
+ children: /* @__PURE__ */ jsx("span", {
40
+ class: "seams-toast-progress-fill",
41
+ children: pending && /* @__PURE__ */ jsx("span", { class: "seams-toast-progress-active" })
42
+ })
39
43
  }),
40
44
  /* @__PURE__ */ jsx("span", {
41
45
  class: "seams-receipt-symbol",
@@ -62,17 +66,12 @@ var TransactionReceipt = class extends Component {
62
66
  children: [
63
67
  /* @__PURE__ */ jsxs("div", {
64
68
  class: "seams-review-toolbar",
65
- children: [/* @__PURE__ */ jsx("span", { children: "Transaction receipt" }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("button", {
69
+ children: [/* @__PURE__ */ jsx("span", { children: "Transaction receipt" }), /* @__PURE__ */ jsx("button", {
66
70
  type: "button",
67
71
  "aria-label": "Minimize transaction",
68
72
  onClick: this.minimize,
69
73
  children: /* @__PURE__ */ jsx(ReviewIcon, { kind: "minimize" })
70
- }), /* @__PURE__ */ jsx("button", {
71
- type: "button",
72
- "aria-label": receiptIsPending(receipt.state) ? "Minimize transaction" : "Close receipt",
73
- onClick: this.close,
74
- children: /* @__PURE__ */ jsx(ReviewIcon, { kind: "close" })
75
- })] })]
74
+ })]
76
75
  }),
77
76
  /* @__PURE__ */ jsxs("div", {
78
77
  class: "seams-receipt-heading",
@@ -132,33 +131,30 @@ var TransactionReceipt = class extends Component {
132
131
  })
133
132
  ]
134
133
  }),
135
- /* @__PURE__ */ jsx("div", {
136
- class: "seams-receipt-box",
137
- children: /* @__PURE__ */ jsx(ReviewDisclosure, {
138
- label: "Receipt details",
139
- children: /* @__PURE__ */ jsxs("dl", {
140
- class: "seams-review-fields",
141
- children: [
142
- data.model?.signerAccount && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "From" }), /* @__PURE__ */ jsx("dd", {
143
- class: "seams-review-recipient",
144
- children: /* @__PURE__ */ jsx(CopyReviewValue, {
145
- value: data.model.signerAccount,
146
- address: true,
147
- label: `Copy signer address ${data.model.signerAccount}`
148
- })
149
- })] }),
150
- recipient && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "To" }), /* @__PURE__ */ jsx("dd", {
151
- class: "seams-review-recipient",
152
- children: /* @__PURE__ */ jsx(CopyReviewValue, {
153
- value: recipient,
154
- address: true,
155
- label: `Copy recipient address ${recipient}`
156
- })
157
- })] }),
158
- receipt.state.hash && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Transaction" }), /* @__PURE__ */ jsxs("dd", { children: [/* @__PURE__ */ jsx(ReviewAddress, { value: receipt.state.hash }), /* @__PURE__ */ jsx(CopyReviewValue, { value: receipt.state.hash })] })] }),
159
- /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Status" }), /* @__PURE__ */ jsx("dd", { children: heading })] })
160
- ]
161
- })
134
+ /* @__PURE__ */ jsx(ReviewDisclosure, {
135
+ label: "Receipt details",
136
+ children: /* @__PURE__ */ jsxs("dl", {
137
+ class: "seams-review-fields",
138
+ children: [
139
+ data.model?.signerAccount && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "From" }), /* @__PURE__ */ jsx("dd", {
140
+ class: "seams-review-recipient",
141
+ children: /* @__PURE__ */ jsx(CopyReviewValue, {
142
+ value: data.model.signerAccount,
143
+ address: true,
144
+ label: `Copy signer address ${data.model.signerAccount}`
145
+ })
146
+ })] }),
147
+ recipient && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "To" }), /* @__PURE__ */ jsx("dd", {
148
+ class: "seams-review-recipient",
149
+ children: /* @__PURE__ */ jsx(CopyReviewValue, {
150
+ value: recipient,
151
+ address: true,
152
+ label: `Copy recipient address ${recipient}`
153
+ })
154
+ })] }),
155
+ receipt.state.hash && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Transaction" }), /* @__PURE__ */ jsxs("dd", { children: [/* @__PURE__ */ jsx(ReviewAddress, { value: receipt.state.hash }), /* @__PURE__ */ jsx(CopyReviewValue, { value: receipt.state.hash })] })] }),
156
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", { children: "Status" }), /* @__PURE__ */ jsx("dd", { children: heading })] })
157
+ ]
162
158
  })
163
159
  }),
164
160
  /* @__PURE__ */ jsx("button", {
@@ -11,6 +11,27 @@ import { render } from "preact";
11
11
  import { Fragment as Fragment$1, jsx, jsxs } from "preact/jsx-runtime";
12
12
  //#region src/core/signingEngine/uiConfirm/ui/preact/mountConfirmationSurface.tsx
13
13
  /** @jsxImportSource preact */
14
+ const RECEIPT_MORPH_DURATION_MS = 360;
15
+ const RECEIPT_MORPH_EASING = "cubic-bezier(0.22, 1, 0.36, 1)";
16
+ const RECEIPT_ANCHORS = [
17
+ ".seams-receipt-symbol",
18
+ "[role=\"status\"]",
19
+ ".seams-review-amount"
20
+ ];
21
+ function captureReceiptAnchors(surface) {
22
+ const anchors = [];
23
+ for (const selector of RECEIPT_ANCHORS) {
24
+ const element = surface.querySelector(selector);
25
+ if (!element) continue;
26
+ anchors.push({
27
+ selector,
28
+ text: element.textContent,
29
+ bounds: element.getBoundingClientRect(),
30
+ fontSize: getComputedStyle(element).fontSize
31
+ });
32
+ }
33
+ return anchors;
34
+ }
14
35
  let nextSurfaceId = 0;
15
36
  var MountedConfirmationSurface = class {
16
37
  constructor(input) {
@@ -22,6 +43,7 @@ var MountedConfirmationSurface = class {
22
43
  this.receiptMotion = [];
23
44
  this.receiptShell?.remove();
24
45
  this.receiptShell = null;
46
+ this.element.removeAttribute("data-receipt-morphing");
25
47
  };
26
48
  this.dispose = () => {
27
49
  if (this.state.kind === "disposed") return;
@@ -100,6 +122,7 @@ var MountedConfirmationSurface = class {
100
122
  const viewChanged = this.receipt?.view !== model.view;
101
123
  const previousShell = this.receiptShell ?? this.element.querySelector(".modal-container-root");
102
124
  const previousBounds = previousShell?.getBoundingClientRect();
125
+ const anchors = viewChanged ? captureReceiptAnchors(this.element) : [];
103
126
  const previousRadius = previousShell ? getComputedStyle(previousShell).borderRadius : "26px";
104
127
  if (viewChanged) this.clearReceiptMotion();
105
128
  this.receipt = model;
@@ -115,6 +138,7 @@ var MountedConfirmationSurface = class {
115
138
  shell.setAttribute("aria-hidden", "true");
116
139
  this.element.appendChild(shell);
117
140
  this.receiptShell = shell;
141
+ this.element.setAttribute("data-receipt-morphing", "");
118
142
  const morph = shell.animate([{
119
143
  left: `${previousBounds.left}px`,
120
144
  top: `${previousBounds.top}px`,
@@ -128,18 +152,48 @@ var MountedConfirmationSurface = class {
128
152
  height: `${bounds.height}px`,
129
153
  borderRadius: getComputedStyle(target).borderRadius
130
154
  }], {
131
- duration: 360,
132
- easing: "cubic-bezier(0.22, 1, 0.36, 1)",
155
+ duration: RECEIPT_MORPH_DURATION_MS,
156
+ easing: RECEIPT_MORPH_EASING,
133
157
  fill: "both"
134
158
  });
135
- const reveal = target.animate([{ opacity: 0 }, { opacity: 1 }], {
136
- duration: 140,
137
- delay: 220,
138
- fill: "backwards",
139
- easing: "ease-out"
140
- });
141
- this.receiptMotion = [morph, reveal];
142
- reveal.onfinish = this.clearReceiptMotion;
159
+ this.receiptMotion = [morph];
160
+ const shared = /* @__PURE__ */ new Set();
161
+ for (const anchor of anchors) {
162
+ const element = target.querySelector(anchor.selector);
163
+ if (!element || element.textContent !== anchor.text) continue;
164
+ const destination = element.getBoundingClientRect();
165
+ shared.add(element);
166
+ const scale = parseFloat(anchor.fontSize) / parseFloat(getComputedStyle(element).fontSize);
167
+ this.receiptMotion.push(element.animate([{
168
+ transform: `translate(${anchor.bounds.left - destination.left}px, ${anchor.bounds.top - destination.top}px) scale(${scale})`,
169
+ transformOrigin: "top left"
170
+ }, {
171
+ transform: "translate(0, 0) scale(1)",
172
+ transformOrigin: "top left"
173
+ }], {
174
+ duration: RECEIPT_MORPH_DURATION_MS,
175
+ easing: RECEIPT_MORPH_EASING
176
+ }));
177
+ }
178
+ const details = target.querySelectorAll(".seams-transaction-receipt > :not(.seams-receipt-heading), .seams-receipt-heading > .seams-receipt-symbol, .seams-receipt-heading h2, .seams-receipt-heading p, .seams-transaction-toast > :not(.seams-transaction-toast-text, .seams-toast-progress), .seams-transaction-toast-text > *");
179
+ let order = 0;
180
+ for (const detail of details) {
181
+ if (shared.has(detail)) continue;
182
+ this.receiptMotion.push(detail.animate([{
183
+ opacity: 0,
184
+ transform: "translateY(8px)"
185
+ }, {
186
+ opacity: 1,
187
+ transform: "translateY(0)"
188
+ }], {
189
+ duration: 120,
190
+ delay: model.view === "toast" ? 240 : 180 + Math.min(order, 4) * 15,
191
+ fill: "backwards",
192
+ easing: "ease-out"
193
+ }));
194
+ order += 1;
195
+ }
196
+ morph.onfinish = this.clearReceiptMotion;
143
197
  }
144
198
  }
145
199
  remove() {
@@ -71,7 +71,7 @@ function isRegistrationBenchmarkDiagnosticsEnabled() {
71
71
  function recordWalletCustodyTiming(ceremonyId, stage, startedAt) {
72
72
  if (!isRegistrationBenchmarkDiagnosticsEnabled()) return;
73
73
  try {
74
- console.debug("[WalletCustody] timing " + JSON.stringify({
74
+ console.info("[WalletCustody] timing " + JSON.stringify({
75
75
  event: "wallet_custody_timing",
76
76
  ceremonyId,
77
77
  stage: `custody.${stage}`,
@@ -763,6 +763,7 @@ var SeamsWeb = class {
763
763
  account: nearAccountBinding
764
764
  } : { kind: "none" };
765
765
  tasks.push(this.signingEngine.warmCriticalResources(accountContext));
766
+ tasks.push(this.signingEngine.prewarmEcdsaRegistrationCrypto());
766
767
  }
767
768
  if (tasks.length === 0) return;
768
769
  let status = "succeeded";