@seams/wallet-server 0.27.0 → 0.29.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 (182) hide show
  1. package/README.md +19 -4
  2. package/artifact-manifest.json +28 -13
  3. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  4. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  5. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  6. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  7. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  8. package/dist/esm/application-auth.js +2 -0
  9. package/dist/esm/auth/applicationAuth.js +85 -0
  10. package/dist/esm/auth/externalAuthService.js +149 -0
  11. package/dist/esm/auth/externalAuthStore.js +353 -0
  12. package/dist/esm/auth/externalOwnerOperations.js +82 -0
  13. package/dist/esm/authorization/domain.js +2 -2
  14. package/dist/esm/authorization/factorEvidence.js +1 -1
  15. package/dist/esm/authorization/service.js +2 -2
  16. package/dist/esm/authorization/vaultProxyUse.js +1 -1
  17. package/dist/esm/cloud-host.js +12 -11
  18. package/dist/esm/core/ThresholdService/validation.js +1 -1
  19. package/dist/esm/core/WebAuthnCredentialBindingStore.js +1 -1
  20. package/dist/esm/core/authService/webauthn.js +1 -1
  21. package/dist/esm/core/d1EcdsaSignerRead.js +1 -1
  22. package/dist/esm/core/d1WalletAuthMethodStore.js +2 -2
  23. package/dist/esm/core/d1WalletStore.js +1 -1
  24. package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -1
  25. package/dist/esm/core/deviceLinking/linkedDeviceManagement.js +1 -1
  26. package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -2
  27. package/dist/esm/core/nearRelayerAccountProvisioning.js +2 -2
  28. package/dist/esm/hosted-wallet-gateway.js +3 -3
  29. package/dist/esm/index.js +1 -1
  30. package/dist/esm/router/auth/webAuthnCredentialCodecs.js +1 -1
  31. package/dist/esm/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.js +2 -0
  32. package/dist/esm/router/cloudflare/d1/auth/d1RecordedOwnerOperation.js +43 -0
  33. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +27 -3
  34. package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +2 -2
  35. package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +2 -2
  36. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +3 -3
  37. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEd25519ExportRootStore.js +1 -1
  38. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +2 -2
  39. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.js +1 -1
  40. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSourceContributionPreparationPlanner.js +1 -1
  41. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetAuthenticatorStore.js +1 -1
  42. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
  43. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetPlanner.js +1 -1
  44. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkBuilder.js +2 -2
  45. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkSourceReader.js +1 -1
  46. package/dist/esm/router/cloudflare/d1/ed25519Yao/d1Ed25519YaoCapabilityPersistence.js +1 -1
  47. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +1 -1
  48. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +1 -1
  49. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.js +1 -1
  50. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +2 -2
  51. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +3 -3
  52. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +1 -1
  53. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.js +1 -1
  54. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +3 -3
  55. package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +7 -1
  56. package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +1 -1
  57. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +4 -4
  58. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +4 -4
  59. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +1 -1
  60. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +3 -3
  61. package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +1 -1
  62. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +11 -2
  63. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +1 -1
  64. package/dist/esm/router/cloudflare/d1/registration/d1WalletExecutionAuthority.js +9 -16
  65. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +1 -1
  66. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +46 -4
  67. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetup.js +12 -0
  68. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +1 -0
  69. package/dist/esm/router/cloudflare/d1/registration/registrationCompletionWrite.js +1 -0
  70. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationEstablishedSessionIssuer.js +1 -1
  71. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +36 -1
  72. package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +1 -1
  73. package/dist/esm/router/cloudflare/d1/wallet/authorizationSnapshotLayout.js +1 -0
  74. package/dist/esm/router/cloudflare/d1/wallet/d1VoiceIdWalletSessionChallenges.js +2 -2
  75. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodBoundary.js +1 -1
  76. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodRevocationReplayStore.js +1 -1
  77. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +6 -5
  78. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorityStore.js +2 -2
  79. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationCleanup.js +2 -1
  80. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationIntake.js +1 -1
  81. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationSnapshot.js +1 -1
  82. package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationChallenges.js +1 -1
  83. package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationOwnerRequest.js +2 -2
  84. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +2 -2
  85. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +2 -2
  86. package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +9 -0
  87. package/dist/esm/router/cloudflare/runtime/walletConsoleOpsClient.js +6 -0
  88. package/dist/esm/router/cloudflare-adaptor.js +1 -1
  89. package/dist/esm/router/cloudflare.js +6139 -5567
  90. package/dist/esm/router/domains/ecdsa/routerAbEcdsaStrictRegistration.js +1 -1
  91. package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +5 -5
  92. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecovery.js +2 -2
  93. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +1 -1
  94. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoHttpRegistrationBackend.js +1 -1
  95. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistration.js +1 -1
  96. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +1 -1
  97. package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +2 -2
  98. package/dist/esm/router/domains/passkeyCustody/walletCustodyRegistrationCommit.js +1 -1
  99. package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +2 -2
  100. package/dist/esm/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.js +37 -3
  101. package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -1
  102. package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +1 -1
  103. package/dist/esm/router/domains/walletRegistration/walletRegistrationReservation.js +18 -3
  104. package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +12 -4
  105. package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +3 -3
  106. package/dist/esm/router/framework/http.js +1 -1
  107. package/dist/esm/router/framework/routeDefinitions.js +2 -1
  108. package/dist/esm/router/transport/fetch/createFetchRouter.js +5 -3
  109. package/dist/esm/router/transport/fetch/routes/auth.js +1 -1
  110. package/dist/esm/router/transport/fetch/routes/deviceLinking.js +3 -3
  111. package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
  112. package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +3 -3
  113. package/dist/esm/router/transport/fetch/routes/externalAuth.js +351 -0
  114. package/dist/esm/router/transport/fetch/routes/normalSigningRouterProxy.js +1 -1
  115. package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +46 -306
  116. package/dist/esm/router/transport/fetch/routes/sessions.js +4 -4
  117. package/dist/esm/router/transport/fetch/routes/syncAccount.js +2 -2
  118. package/dist/esm/router/transport/fetch/routes/syncAccountBootstrap.js +1 -1
  119. package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +4 -4
  120. package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +6 -6
  121. package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +2 -2
  122. package/dist/esm/router/transport/fetch/routes/walletRegistration.js +4 -4
  123. package/dist/esm/router/transport/fetch/walletOwnerOperationAuthorization.js +306 -0
  124. package/dist/esm/shared-ts/src/auth/externalAuth.js +118 -0
  125. package/dist/esm/shared-ts/src/authorization/index.js +1 -1
  126. package/dist/esm/shared-ts/src/authorization/voiceIdDeviceAssertion.js +1 -1
  127. package/dist/esm/shared-ts/src/authorization/walletAuthority.js +2 -2
  128. package/dist/esm/shared-ts/src/authorization/{walletCustodyOperation.js → walletOwnerOperation.js} +4 -4
  129. package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -1
  130. package/dist/esm/shared-ts/src/device-linking/digests.js +1 -1
  131. package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +1 -1
  132. package/dist/esm/shared-ts/src/device-linking/parsers.js +2 -2
  133. package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +1 -1
  134. package/dist/esm/shared-ts/src/device-linking/walletSessionCredentialDelivery.js +1 -1
  135. package/dist/esm/shared-ts/src/device-linking/wireFields.js +2 -2
  136. package/dist/esm/shared-ts/src/passkey-custody/custodyEnvelope.js +1 -1
  137. package/dist/esm/shared-ts/src/passkey-custody/custodySecretBinding.js +1 -1
  138. package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +1 -1
  139. package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
  140. package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +1 -1
  141. package/dist/esm/shared-ts/src/wallet-recovery/index.js +3 -3
  142. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -1
  143. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEnvelopeSet.js +1 -1
  144. package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +1 -1
  145. package/dist/esm/threshold/session/signingSessionSeal/service.js +1 -1
  146. package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +1 -1
  147. package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +1 -1
  148. package/dist/types/shared-ts/src/auth/externalAuth.d.ts +127 -0
  149. package/dist/types/shared-ts/src/authorization/index.d.ts +1 -1
  150. package/dist/types/shared-ts/src/authorization/walletOwnerOperation.d.ts +10 -0
  151. package/dist/types/shared-ts/src/utils/registrationEstablishedSession.d.ts +4 -0
  152. package/dist/types/shared-ts/src/utils/registrationIntent.d.ts +2 -0
  153. package/dist/types/shared-ts/src/utils/walletManagementProtocol.d.ts +1 -1
  154. package/dist/types/wallet-server/src/application-auth.d.ts +3 -0
  155. package/dist/types/wallet-server/src/auth/applicationAuth.d.ts +29 -0
  156. package/dist/types/wallet-server/src/auth/externalAuthService.d.ts +55 -0
  157. package/dist/types/wallet-server/src/auth/externalAuthStore.d.ts +115 -0
  158. package/dist/types/wallet-server/src/auth/externalOwnerOperations.d.ts +18 -0
  159. package/dist/types/wallet-server/src/cloud-host.d.ts +2 -1
  160. package/dist/types/wallet-server/src/core/threeRouteRegistrationContracts.d.ts +12 -0
  161. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.d.ts +5 -1
  162. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RecordedOwnerOperation.d.ts +16 -0
  163. package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/d1OidcBoundary.d.ts +5 -0
  164. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.d.ts +1 -0
  165. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationSetup.d.ts +2 -0
  166. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.d.ts +7 -1
  167. package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/authorizationSnapshotLayout.d.ts +1 -1
  168. package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAuthMethodService.d.ts +1 -0
  169. package/dist/types/wallet-server/src/router/cloudflare/runtime/staticWalletConsoleBinding.d.ts +2 -0
  170. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.d.ts +2 -2
  171. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbOperationStepUp.d.ts +1 -1
  172. package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +1 -0
  173. package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationReservation.d.ts +11 -6
  174. package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +1 -0
  175. package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +12 -0
  176. package/dist/types/wallet-server/src/router/transport/fetch/routes/externalAuth.d.ts +5 -0
  177. package/dist/types/wallet-server/src/router/transport/fetch/walletOwnerOperationAuthorization.d.ts +23 -0
  178. package/migrations/d1-signer/0085_external_wallet_auth.sql +158 -0
  179. package/migrations/d1-signer/0086_application_auth.sql +67 -0
  180. package/migrations/d1-signer/0087_registration_without_session.sql +43 -0
  181. package/package.json +7 -2
  182. package/dist/types/shared-ts/src/authorization/walletCustodyOperation.d.ts +0 -10
@@ -1,22 +1,22 @@
1
1
  import { parseEmailOtpChallengeId, parseOrgId, parseProviderSubject, parseWalletId, parseWebAuthnCredentialIdB64u } from "../../../../shared-ts/src/utils/domainIds.js";
2
- import { buildAuthorizationGrantRef, parseAuthFactorId, parseAuthorizationAuditEventId, parseAuthorizationEvidenceId, parseAuthorizationEvidenceSetId, parseAuthorizedOperationId, parseCapabilityId, parseCapabilityOperationId, parsePrincipalId } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
3
2
  import { isPlainObject } from "../../../../shared-ts/src/utils/validation.js";
4
3
  import { base64UrlEncode } from "../../../../shared-ts/src/utils/base64.js";
5
4
  import { alphabetizeStringify, sha256BytesUtf8 } from "../../../../shared-ts/src/utils/digests.js";
6
5
  import { parseDigestB64u } from "../../../../shared-ts/src/utils/canonicalPrimitives.js";
7
- import { buildCapabilityOperationEnvelope, computeCapabilityOperationFingerprintDigest, parseCapabilityOperationFingerprintDigest, parseSigningOperationFingerprintDigest } from "../../../../shared-ts/src/authorization/operationFingerprint.js";
8
6
  import "../../../../shared-ts/src/utils/encoders.js";
7
+ import { buildAuthorizationGrantRef, parseAuthFactorId, parseAuthorizationAuditEventId, parseAuthorizationEvidenceId, parseAuthorizationEvidenceSetId, parseAuthorizedOperationId, parseCapabilityId, parseCapabilityOperationId, parsePrincipalId } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
8
+ import { buildCapabilityOperationEnvelope, computeCapabilityOperationFingerprintDigest, parseCapabilityOperationFingerprintDigest, parseSigningOperationFingerprintDigest } from "../../../../shared-ts/src/authorization/operationFingerprint.js";
9
9
  import { sameRouterAbMpcMaterialActivationRef } from "../../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
10
10
  import { isPasskeyWalletAuthAuthority, walletAuthAuthorityRef } from "../../../../shared-ts/src/utils/walletAuthAuthority.js";
11
11
  import { authorizedOperationReplayBodyInit, parseSessionOrigin, parseVerifiedOwnerProofId } from "../../../../authorization/domain.js";
12
12
  import { buildVerifiedWalletOperationEmailOtpFactorResult, buildVerifiedWalletOperationPasskeyFactorResult, buildVerifiedWalletSessionPasskeyFactorResult } from "../../../../authorization/factorEvidence.js";
13
- import { ROUTER_AB_ED25519_NORMAL_SIGNING_PATH, ROUTER_AB_ED25519_NORMAL_SIGNING_PREPARE_PATH, ROUTER_AB_ED25519_WALLET_SESSION_PATH } from "../../../../shared-ts/src/utils/signingSessionSeal.js";
13
+ import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_TRANSACTION_SIGN_OPERATION } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
14
+ import { emailOtpStatusCode, hashEmailOtpOperationBinding } from "../../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
14
15
  import { normalizeCorsOrigin } from "../../../../core/SessionService.js";
16
+ import { json, readJson } from "../../../framework/http.js";
17
+ import { ROUTER_AB_ED25519_NORMAL_SIGNING_PATH, ROUTER_AB_ED25519_NORMAL_SIGNING_PREPARE_PATH, ROUTER_AB_ED25519_WALLET_SESSION_PATH } from "../../../../shared-ts/src/utils/signingSessionSeal.js";
15
18
  import { walletIdFromString } from "../../../../shared-ts/src/utils/registrationIds.js";
16
19
  import { resolveThresholdRuntimePolicyScope } from "../../../auth/commonRouterUtils.js";
17
- import { json, readJson } from "../../../framework/http.js";
18
- import { emailOtpStatusCode, hashEmailOtpOperationBinding } from "../../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
19
- import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_TRANSACTION_SIGN_OPERATION } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
20
20
  import { thresholdEd25519StatusCode } from "../../../../threshold/statusCodes.js";
21
21
  import { signingPrepareSessionResponse } from "../../../domains/signingOperations/signingPrepareSession.js";
22
22
  import { authenticateRouterAbWalletOperationStepUpIdentity } from "../../../domains/signingOperations/routerAbOperationStepUp.js";
@@ -1,10 +1,10 @@
1
1
  import { parseMpcMaterialActivationRef } from "../../../../shared-ts/src/utils/domainIds.js";
2
- import { EVM_ECDSA_MPC_OPERATION_KINDS } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
3
2
  import { isPlainObject } from "../../../../shared-ts/src/utils/validation.js";
3
+ import { EVM_ECDSA_MPC_OPERATION_KINDS } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
4
4
  import { routerAbMpcMaterialActivationRefToWire } from "../../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
5
+ import { json, readJson } from "../../../framework/http.js";
5
6
  import { walletSessionFailure, walletSessionFailureStatus } from "../../../auth/walletSessionFailure.js";
6
7
  import { validateRouterAbEcdsaDerivationWalletSessionInputs } from "../../../auth/commonRouterUtils.js";
7
- import { json, readJson } from "../../../framework/http.js";
8
8
  //#region src/router/transport/fetch/routes/walletExecutionLanePreflight.ts
9
9
  const OWNER_WALLET_EXECUTION_LANE_PREFLIGHT_PATH = "/wallet/execution-lane/owner";
10
10
  function parsePreflightRequest(raw) {
@@ -1,9 +1,9 @@
1
- import { findRouteDefinitionById, matchesRouteDefinitionRequest } from "../../../framework/routeDefinitions.js";
2
- import { resolveSourceIpFromFetchHeaders } from "../../../auth/routerApiKeyAuth.js";
3
1
  import { toFetchRouteResponse } from "../../../framework/routeResponses.js";
4
- import { handleRouterApiWalletAddAuthMethodEmailOtpChallenge, handleRouterApiWalletAddAuthMethodFinalize, handleRouterApiWalletAddAuthMethodIntent, handleRouterApiWalletAddAuthMethodStart, handleRouterApiWalletAddSignerEcdsaActivation, handleRouterApiWalletAddSignerEcdsaDerivationRespond, handleRouterApiWalletAddSignerFinalize, handleRouterApiWalletAddSignerIntent, handleRouterApiWalletAddSignerStart, handleRouterApiWalletEcdsaKeyFactsInventory, handleRouterApiWalletNearImplicitAccountFund, handleRouterApiWalletRegistrationActivate, handleRouterApiWalletRegistrationNearAdmission, handleRouterApiWalletRegistrationNearProvisioning, handleRouterApiWalletRegistrationRespond, handleRouterApiWalletRegistrationSetup, handleRouterApiWalletRevokeAuthMethod } from "../../../domains/walletRegistration/walletRegistrationRoutes.js";
2
+ import { resolveSourceIpFromFetchHeaders } from "../../../auth/routerApiKeyAuth.js";
5
3
  import "../../../../shared-ts/src/utils/walletManagementProtocol.js";
6
4
  import { jsonFailure, readJson } from "../../../framework/http.js";
5
+ import { findRouteDefinitionById, matchesRouteDefinitionRequest } from "../../../framework/routeDefinitions.js";
6
+ import { handleRouterApiWalletAddAuthMethodEmailOtpChallenge, handleRouterApiWalletAddAuthMethodFinalize, handleRouterApiWalletAddAuthMethodIntent, handleRouterApiWalletAddAuthMethodStart, handleRouterApiWalletAddSignerEcdsaActivation, handleRouterApiWalletAddSignerEcdsaDerivationRespond, handleRouterApiWalletAddSignerFinalize, handleRouterApiWalletAddSignerIntent, handleRouterApiWalletAddSignerStart, handleRouterApiWalletEcdsaKeyFactsInventory, handleRouterApiWalletNearImplicitAccountFund, handleRouterApiWalletRegistrationActivate, handleRouterApiWalletRegistrationNearAdmission, handleRouterApiWalletRegistrationNearProvisioning, handleRouterApiWalletRegistrationRespond, handleRouterApiWalletRegistrationSetup, handleRouterApiWalletRevokeAuthMethod } from "../../../domains/walletRegistration/walletRegistrationRoutes.js";
7
7
  import { routerApiWalletRegistrationRouteService } from "../../../framework/authServicePort.js";
8
8
  //#region src/router/transport/fetch/routes/walletRegistration.ts
9
9
  const ROUTE_IDS = [
@@ -44,7 +44,7 @@ function resolveWalletRegistrationRoute(ctx) {
44
44
  async function handleWalletRegistration(ctx) {
45
45
  const route = resolveWalletRegistrationRoute(ctx);
46
46
  if (!route) return null;
47
- if (ctx.request.headers.get("X-Seams-Wallet-Protocol") !== "4") return jsonFailure(409, "wallet_protocol_mismatch", "Your wallet application needs an update. Reload this page and try again. If the problem continues, ask the application developer to upgrade the Wallet SDK.");
47
+ if (ctx.request.headers.get("X-Seams-Wallet-Protocol") !== "5") return jsonFailure(409, "wallet_protocol_mismatch", "Your wallet application needs an update. Reload this page and try again. If the problem continues, ask the application developer to upgrade the Wallet SDK.");
48
48
  const common = {
49
49
  body: await readJson(ctx.request),
50
50
  headers: Object.fromEntries(ctx.request.headers.entries()),
@@ -0,0 +1,306 @@
1
+ import { parseEmailOtpChallengeId, parseOrgId, parseProviderSubject, parseWalletId, parseWebAuthnCredentialIdB64u } from "../../../shared-ts/src/utils/domainIds.js";
2
+ import { normalizeOptionalTrimmedString } from "../../../shared-ts/src/utils/normalize.js";
3
+ import { alphabetizeStringify } from "../../../shared-ts/src/utils/digests.js";
4
+ import { sha256Utf8DigestB64u } from "../../../shared-ts/src/utils/canonicalPrimitives.js";
5
+ import { requireParsed } from "../../../shared-ts/src/passkey-custody/primitives.js";
6
+ import { computeWalletOwnerAdminChallengeDigest } from "../../../shared-ts/src/authorization/walletOwnerOperation.js";
7
+ import { buildVaultOperationRef, parseAuthFactorId, parseAuthorizationAuditEventId, parseAuthorizationEvidenceId, parseAuthorizationEvidenceSetId, parseAuthorizedOperationId, parseCapabilityId, parseCapabilityOperationId, parsePrincipalId, parseTenantId } from "../../../shared-ts/src/authorization/capabilityKinds.js";
8
+ import { buildDelegatedWalletAuthorityV1, buildFullOwnerPermissionsV1, sameDelegatedWalletAuthorityV1 } from "../../../shared-ts/src/authorization/delegatedAuthority.js";
9
+ import { buildCapabilityOperationEnvelope, computeCapabilityOperationFingerprintDigest } from "../../../shared-ts/src/authorization/operationFingerprint.js";
10
+ import { buildPasskeyWalletAuthAuthority, walletAuthAuthorityRef } from "../../../shared-ts/src/utils/walletAuthAuthority.js";
11
+ import { parseSessionOrigin, parseVerifiedOwnerProofId } from "../../../authorization/domain.js";
12
+ import { buildVerifiedWalletOperationEmailOtpFactorResult, buildVerifiedWalletOperationPasskeyFactorResult } from "../../../authorization/factorEvidence.js";
13
+ import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_UNLOCK_OPERATION } from "../../../shared-ts/src/utils/emailOtpDomain.js";
14
+ import { parseWebAuthnAuthenticationCredential } from "../../auth/webAuthnCredentialCodecs.js";
15
+ import { emailOtpStatusCode, hashEmailOtpOperationBinding } from "../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
16
+ import { toFetchRouteResponse } from "../../framework/routeResponses.js";
17
+ import { parseCustodyOwnerProof } from "./routes/walletCustodyRequestBoundary.js";
18
+ //#region src/router/transport/fetch/walletOwnerOperationAuthorization.ts
19
+ const CUSTODY_OPERATION_CAPABILITY_ID = "wallet-custody-admin";
20
+ const CUSTODY_PROOF_TTL_MS = 6e4;
21
+ function walletOwnerOperationAuthorizationId(operation, challenge) {
22
+ return requireParsed(parseAuthorizedOperationId(`wallet-custody:authorized:wallet-custody:${operation}:${challenge}`), "owner operation");
23
+ }
24
+ function hasFullOwnerAuthority(authority) {
25
+ return sameDelegatedWalletAuthorityV1(buildDelegatedWalletAuthorityV1({ permissions: authority.permissions }), buildDelegatedWalletAuthorityV1({ permissions: buildFullOwnerPermissionsV1() }));
26
+ }
27
+ async function custodyDigest(domain, value) {
28
+ return sha256Utf8DigestB64u(`${domain}|${alphabetizeStringify(value)}`);
29
+ }
30
+ async function buildWalletCustodyOperation(input) {
31
+ const tenantId = requireParsed(parseTenantId(input.tenantId), "authorization");
32
+ const principalId = requireParsed(parsePrincipalId(input.principalId), "authorization");
33
+ const capabilityId = requireParsed(parseCapabilityId(CUSTODY_OPERATION_CAPABILITY_ID), "authorization");
34
+ const operationRef = buildVaultOperationRef("vault.reveal");
35
+ const laneDigest = await custodyDigest("seams:wallet-custody:lane:v1", {
36
+ capabilityId,
37
+ operation: input.operation,
38
+ operationRef
39
+ });
40
+ const challengeDigest = await computeWalletOwnerAdminChallengeDigest({
41
+ walletId: input.walletId,
42
+ operation: input.operation,
43
+ payload: input.payload,
44
+ requestOrigin: input.requestOrigin
45
+ });
46
+ const intentDigest = challengeDigest;
47
+ const displayDigest = await custodyDigest("seams:wallet-custody:display:v1", {
48
+ walletId: input.walletId,
49
+ operation: input.operation
50
+ });
51
+ return {
52
+ operation: buildCapabilityOperationEnvelope({
53
+ tenantId,
54
+ principalId,
55
+ capabilityId,
56
+ operationId: requireParsed(parseCapabilityOperationId(`wallet-custody:${input.operation}:${intentDigest}`), "authorization"),
57
+ operation: operationRef,
58
+ digests: {
59
+ laneDigest,
60
+ intentDigest,
61
+ displayDigest
62
+ }
63
+ }),
64
+ challengeDigest
65
+ };
66
+ }
67
+ async function authorizeWalletOwnerOperation(input) {
68
+ const requestOrigin = normalizeOptionalTrimmedString(input.ctx.request.headers.get("origin"));
69
+ if (!requestOrigin) return toCustodyAuthorizationFailure(400, "invalid_origin", "request Origin is required");
70
+ let origin;
71
+ let proof;
72
+ let walletId;
73
+ try {
74
+ origin = parseSessionOrigin(requestOrigin);
75
+ walletId = requireParsed(parseWalletId(input.walletId), "authorization");
76
+ proof = parseCustodyOwnerProof(input.factorProof);
77
+ } catch (error) {
78
+ return toCustodyAuthorizationFailure(400, "invalid_owner_proof", error instanceof Error ? error.message : "owner proof is invalid");
79
+ }
80
+ if (proof.kind === "passkey" && proof.walletId !== input.walletId) return toCustodyAuthorizationFailure(403, "scope_mismatch", "owner proof wallet differs");
81
+ let principalId;
82
+ let factor;
83
+ let ownerAuthorityRef;
84
+ let ownerAuthority;
85
+ let operation;
86
+ let challengeDigest;
87
+ try {
88
+ principalId = proof.kind === "passkey" ? input.walletId : proof.provider_subject_id;
89
+ const built = await buildWalletCustodyOperation({
90
+ tenantId: input.ctx.service.authorizedOperations.tenantId,
91
+ principalId,
92
+ walletId: input.walletId,
93
+ operation: input.operation,
94
+ payload: input.payload,
95
+ requestOrigin
96
+ });
97
+ operation = built.operation;
98
+ challengeDigest = built.challengeDigest;
99
+ } catch (error) {
100
+ return toCustodyAuthorizationFailure(400, "invalid_owner_proof", error instanceof Error ? error.message : "owner proof binding is invalid");
101
+ }
102
+ const operationFingerprintDigest = await computeCapabilityOperationFingerprintDigest(operation);
103
+ const nowMs = Date.now();
104
+ if (proof.challenge_digest !== String(challengeDigest)) return toCustodyAuthorizationFailure(403, "scope_mismatch", "factor proof challenge does not match the requested operation");
105
+ if (proof.kind === "passkey") {
106
+ let authority;
107
+ try {
108
+ authority = buildPasskeyWalletAuthAuthority({
109
+ walletId,
110
+ rpId: proof.rpId,
111
+ credentialIdB64u: proof.credentialIdB64u
112
+ });
113
+ } catch (error) {
114
+ return toCustodyAuthorizationFailure(400, "invalid_owner_proof", error instanceof Error ? error.message : "passkey authority is invalid");
115
+ }
116
+ const active = await input.ctx.service.walletAuthMethods.resolveActivePasskeyAuthorityForVerifiedCredential({
117
+ walletId,
118
+ rpId: authority.verifier.rpId,
119
+ credentialIdB64u: authority.factor.credentialIdB64u
120
+ });
121
+ if (!active.ok) return toCustodyAuthorizationFailure(403, active.code, active.message);
122
+ if (!hasFullOwnerAuthority(active.walletAuthority)) return toCustodyAuthorizationFailure(403, "forbidden", "Full owner authority is required");
123
+ ownerAuthority = active.walletAuthority;
124
+ const credential = parseWebAuthnAuthenticationCredential(proof.webauthn_authentication);
125
+ if (!credential) return toCustodyAuthorizationFailure(400, "invalid_owner_proof", "passkey assertion is invalid");
126
+ if (String(credential.rawId || credential.id).trim() !== authority.factor.credentialIdB64u) return toCustodyAuthorizationFailure(401, "unauthorized", "passkey credential changed");
127
+ const verified = await input.ctx.service.webAuthn.verifyWebAuthnAuthenticationLite({
128
+ userId: input.walletId,
129
+ rpId: authority.verifier.rpId,
130
+ expectedChallenge: challengeDigest,
131
+ expected_origin: requestOrigin,
132
+ webauthn_authentication: credential
133
+ });
134
+ if (!verified.success || !verified.verified) return toCustodyAuthorizationFailure(401, verified.code || "not_verified", verified.message || "WebAuthn authentication verification failed");
135
+ ownerAuthorityRef = await walletAuthAuthorityRef({ authority: active.authority });
136
+ factor = buildVerifiedWalletOperationPasskeyFactorResult({
137
+ tenantId: operation.tenantId,
138
+ principalId: operation.principalId,
139
+ walletId,
140
+ authorityRef: ownerAuthorityRef,
141
+ requestOrigin: origin,
142
+ audience: origin,
143
+ factorId: requireParsed(parseAuthFactorId(`passkey:${authority.factor.credentialIdB64u}`), "authorization"),
144
+ credentialIdB64u: requireParsed(parseWebAuthnCredentialIdB64u(authority.factor.credentialIdB64u), "authorization"),
145
+ assertionDigest: await custodyDigest("seams:wallet-custody:assertion:v1", { credential }),
146
+ operation,
147
+ verifiedAtMs: nowMs,
148
+ expiresAtMs: nowMs + CUSTODY_PROOF_TTL_MS
149
+ });
150
+ } else {
151
+ const providerSubject = requireParsed(parseProviderSubject(proof.provider_subject_id), "authorization");
152
+ const orgId = requireParsed(parseOrgId(input.ctx.service.authorizedOperations.tenantId), "authorization");
153
+ const active = await input.ctx.service.walletAuthMethods.resolveActiveEmailOtpAuthorityForVerifiedSubject({
154
+ walletId: input.walletId,
155
+ providerUserId: proof.provider_subject_id
156
+ });
157
+ if (!active.ok) return toCustodyAuthorizationFailure(403, active.code, active.message);
158
+ const activeAuthorityRef = await walletAuthAuthorityRef({ authority: active.authority });
159
+ ownerAuthorityRef = activeAuthorityRef;
160
+ ownerAuthority = active.walletAuthority;
161
+ const ownerProofBindingDigest = await hashEmailOtpOperationBinding({
162
+ walletId: input.walletId,
163
+ providerUserId: proof.provider_subject_id,
164
+ orgId,
165
+ operation: `wallet_custody:${input.operation}`,
166
+ requestOrigin,
167
+ audience: requestOrigin,
168
+ authorityRef: activeAuthorityRef,
169
+ operationFingerprintDigest: challengeDigest
170
+ });
171
+ const verified = await input.ctx.service.emailOtp.verifyEmailOtpChallenge({
172
+ userId: proof.provider_subject_id,
173
+ walletId: input.walletId,
174
+ orgId,
175
+ challengeId: proof.challenge_id,
176
+ otpCode: proof.otp_code,
177
+ otpChannel: EMAIL_OTP_CHANNEL,
178
+ ownerProofBindingDigest,
179
+ operation: WALLET_EMAIL_OTP_UNLOCK_OPERATION
180
+ });
181
+ if (!verified.ok) return toCustodyAuthorizationFailure(verified.code === "invalid_body" ? 400 : 401, verified.code, verified.message);
182
+ const consumed = await input.ctx.service.emailOtp.consumeEmailOtpGrant({
183
+ subject: {
184
+ kind: "provider_identity",
185
+ orgId,
186
+ providerSubject,
187
+ walletId
188
+ },
189
+ loginGrant: verified.loginGrant,
190
+ otpChannel: EMAIL_OTP_CHANNEL
191
+ });
192
+ if (!consumed.ok) return toCustodyAuthorizationFailure(emailOtpStatusCode(consumed.code), consumed.code, consumed.message);
193
+ factor = buildVerifiedWalletOperationEmailOtpFactorResult({
194
+ tenantId: operation.tenantId,
195
+ principalId: operation.principalId,
196
+ walletId,
197
+ authorityRef: activeAuthorityRef,
198
+ requestOrigin: origin,
199
+ audience: origin,
200
+ factorId: requireParsed(parseAuthFactorId(`email_otp:${active.authority.factor.provider}:${proof.provider_subject_id}`), "authorization"),
201
+ operation,
202
+ challengeId: requireParsed(parseEmailOtpChallengeId(consumed.challengeId), "authorization"),
203
+ verificationReceiptDigest: await custodyDigest("seams:wallet-custody:otp-receipt:v1", {
204
+ challengeId: consumed.challengeId,
205
+ operationFingerprintDigest
206
+ }),
207
+ verifiedAtMs: nowMs,
208
+ expiresAtMs: Math.min(nowMs + CUSTODY_PROOF_TTL_MS, verified.grantExpiresAtMs)
209
+ });
210
+ }
211
+ const ownerProof = await input.ctx.service.authorizedOperations.buildVerifiedOwnerProof({
212
+ purpose: "operation",
213
+ proofId: parseVerifiedOwnerProofId(`wallet-custody:${operation.operationId}`),
214
+ factor
215
+ });
216
+ if (ownerProof.purpose !== "operation" || ownerProof.operation.operationFingerprintDigest !== operationFingerprintDigest) return toCustodyAuthorizationFailure(403, "owner_proof_rejected", "owner proof binding is invalid");
217
+ const existing = await input.ctx.service.authorizedOperations.readAuthorizedOperation({
218
+ tenantId: operation.tenantId,
219
+ operationFingerprintDigest
220
+ });
221
+ if (existing) {
222
+ if (existing.authorization.kind !== "verified_step_up" || existing.quota.kind !== "quota_neutral") return toCustodyAuthorizationFailure(403, "owner_proof_rejected", "Owner operation authorization differs");
223
+ return {
224
+ ok: false,
225
+ response: authorizedOperationReplay(existing)
226
+ };
227
+ }
228
+ const evidenceSet = await input.ctx.service.authorizedOperations.recordVerifiedWalletOperationFactorEvidenceSet({
229
+ operation,
230
+ evidenceId: requireParsed(parseAuthorizationEvidenceId(`wallet-custody:evidence:${operation.operationId}`), "authorization"),
231
+ evidenceSetId: requireParsed(parseAuthorizationEvidenceSetId(`wallet-custody:evidence-set:${operation.operationId}`), "authorization"),
232
+ factor
233
+ });
234
+ const admission = await input.ctx.service.authorizedOperations.admitAuthorizedOperation({ operation: {
235
+ tenantId: operation.tenantId,
236
+ authorizedOperationId: walletOwnerOperationAuthorizationId(input.operation, challengeDigest),
237
+ auditEventId: requireParsed(parseAuthorizationAuditEventId(`wallet-custody:audit:${operation.operationId}`), "authorization"),
238
+ operation,
239
+ authorization: {
240
+ kind: "verified_step_up",
241
+ evidenceSetDigest: evidenceSet.evidenceSetDigest
242
+ },
243
+ quota: { kind: "quota_neutral" },
244
+ claimedAtMs: nowMs
245
+ } });
246
+ switch (admission.kind) {
247
+ case "claimed": return {
248
+ ok: true,
249
+ operation: admission.operation,
250
+ ownerAuthority
251
+ };
252
+ case "replayed":
253
+ case "operation_in_progress": return {
254
+ ok: false,
255
+ response: authorizedOperationReplay(admission.operation)
256
+ };
257
+ case "authorization_grant_rejected":
258
+ case "verified_step_up_rejected":
259
+ case "wallet_session_quota_exhausted":
260
+ case "material_mismatch": return toCustodyAuthorizationFailure(403, "owner_proof_rejected", "owner proof was rejected");
261
+ }
262
+ }
263
+ function toCustodyAuthorizationFailure(status, code, message) {
264
+ return {
265
+ ok: false,
266
+ response: routeErrorResponse(status, code, message)
267
+ };
268
+ }
269
+ function routeErrorResponse(status, code, message) {
270
+ return toFetchRouteResponse({
271
+ status,
272
+ body: {
273
+ ok: false,
274
+ code,
275
+ message
276
+ }
277
+ });
278
+ }
279
+ function authorizedOperationReplay(operation) {
280
+ if (operation.lifecycle !== "completed") return routeErrorResponse(409, "recovery_in_progress", "wallet recovery is still in progress");
281
+ return new Response(operation.response.bodyText, {
282
+ status: operation.response.status,
283
+ headers: { "content-type": operation.response.contentType }
284
+ });
285
+ }
286
+ async function completeWalletOwnerOperation(ctx, operation, status, body, result = "succeeded") {
287
+ const bodyText = JSON.stringify(body);
288
+ await ctx.service.authorizedOperations.completeAuthorizedOperation({
289
+ operation,
290
+ result,
291
+ response: {
292
+ status,
293
+ contentType: "application/json",
294
+ bodyText
295
+ },
296
+ completedAtMs: Date.now()
297
+ });
298
+ return toFetchRouteResponse({
299
+ status,
300
+ body
301
+ });
302
+ }
303
+ //#endregion
304
+ export { authorizeWalletOwnerOperation, completeWalletOwnerOperation, walletOwnerOperationAuthorizationId };
305
+
306
+ //# sourceMappingURL=walletOwnerOperationAuthorization.js.map
@@ -0,0 +1,118 @@
1
+ import { parseWalletId } from "../utils/domainIds.js";
2
+ import { requireCanonicalString, requireRecord } from "../utils/validation.js";
3
+ import { parseEd25519PublicKeyB64u, parseUnixMs } from "../passkey-custody/primitives.js";
4
+ //#region ../shared-ts/src/auth/externalAuth.ts
5
+ const EXTERNAL_AUTH_PATH = "/wallet/external-auth";
6
+ function parseExternalAuthProvider(raw) {
7
+ const value = requireRecord(raw, "external authentication provider");
8
+ switch (value.kind) {
9
+ case "disabled": return { kind: "disabled" };
10
+ case "google": return {
11
+ kind: "google",
12
+ clientId: requireCanonicalString(value.clientId, "clientId")
13
+ };
14
+ case "application": {
15
+ const issuer = requireCanonicalString(value.issuer, "issuer");
16
+ const url = new URL(issuer);
17
+ if (url.protocol !== "https:" || url.origin !== issuer) throw new Error("Application issuer must be a canonical HTTPS origin");
18
+ return {
19
+ kind: "application",
20
+ issuer,
21
+ publicKeyB64u: parseEd25519PublicKeyB64u(value.publicKeyB64u, "publicKeyB64u")
22
+ };
23
+ }
24
+ default: throw new Error("Unsupported external authentication provider");
25
+ }
26
+ }
27
+ function externalAuthConfiguration(provider, revision) {
28
+ switch (provider.kind) {
29
+ case "disabled": return {
30
+ kind: "disabled",
31
+ revision
32
+ };
33
+ case "google": return {
34
+ kind: "google",
35
+ revision,
36
+ clientId: provider.clientId
37
+ };
38
+ case "application": return {
39
+ kind: "application",
40
+ revision,
41
+ issuer: provider.issuer,
42
+ publicKeyB64u: provider.publicKeyB64u
43
+ };
44
+ default: return assertNever(provider);
45
+ }
46
+ }
47
+ function parseExternalAuthConfiguration(raw) {
48
+ const value = requireRecord(raw, "external authentication configuration");
49
+ if (typeof value.revision !== "number" || !Number.isSafeInteger(value.revision) || value.revision < 0) throw new Error("Invalid external authentication revision");
50
+ return externalAuthConfiguration(parseExternalAuthProvider(value), value.revision);
51
+ }
52
+ function serializeExternalIdentity(identity) {
53
+ return JSON.stringify([
54
+ identity.provider,
55
+ identity.issuer,
56
+ identity.subject
57
+ ]);
58
+ }
59
+ function parseStoredExternalIdentity(serialized) {
60
+ const raw = JSON.parse(serialized);
61
+ if (!Array.isArray(raw) || raw.length !== 3) throw new Error("Invalid external identity");
62
+ const [provider, issuer, subject] = raw;
63
+ return parseExternalIdentity({
64
+ provider,
65
+ issuer,
66
+ subject
67
+ });
68
+ }
69
+ function parseExternalIdentity(raw) {
70
+ const value = requireRecord(raw, "external identity");
71
+ const provider = value.provider;
72
+ const issuer = requireCanonicalString(value.issuer, "issuer");
73
+ const subject = requireCanonicalString(value.subject, "subject");
74
+ switch (provider) {
75
+ case "google":
76
+ if (issuer !== "https://accounts.google.com") throw new Error("Invalid Google issuer");
77
+ return {
78
+ provider,
79
+ issuer,
80
+ subject
81
+ };
82
+ case "application": return {
83
+ provider,
84
+ issuer,
85
+ subject
86
+ };
87
+ default: throw new Error("Invalid external identity provider");
88
+ }
89
+ }
90
+ function assertNever(value) {
91
+ throw new Error(`Unsupported external authentication provider: ${String(value)}`);
92
+ }
93
+ function parseExternalWalletAuthentication(value) {
94
+ const record = requireRecord(value, "external authentication");
95
+ const walletId = parseWalletId(record.walletId);
96
+ if (!walletId.ok || record.kind !== "external_authenticated" || record.provider !== "google" && record.provider !== "application" || record.permission !== "wallet_settings_read" || "authMethod" in record) throw new Error("External authentication is invalid");
97
+ return {
98
+ kind: "external_authenticated",
99
+ walletId: walletId.value,
100
+ sessionId: requireCanonicalString(record.sessionId, "sessionId"),
101
+ associationId: requireCanonicalString(record.associationId, "associationId"),
102
+ environmentId: requireCanonicalString(record.environmentId, "environmentId"),
103
+ provider: record.provider,
104
+ permission: "wallet_settings_read",
105
+ expiresAtMs: parseUnixMs(record.expiresAtMs, "expiresAtMs")
106
+ };
107
+ }
108
+ function externalAuthFailure(code) {
109
+ return {
110
+ ok: false,
111
+ code,
112
+ message: "Wallet authentication could not be completed."
113
+ };
114
+ }
115
+ //#endregion
116
+ export { EXTERNAL_AUTH_PATH, externalAuthFailure, parseExternalAuthConfiguration, parseExternalAuthProvider, parseExternalWalletAuthentication, parseStoredExternalIdentity, serializeExternalIdentity };
117
+
118
+ //# sourceMappingURL=externalAuth.js.map
@@ -1,6 +1,6 @@
1
+ import "./walletOwnerOperation.js";
1
2
  import "./capabilityKinds.js";
2
3
  import "./delegatedAuthority.js";
3
4
  import "./operationFingerprint.js";
4
5
  import "./walletAuthority.js";
5
- import "./walletCustodyOperation.js";
6
6
  import "./walletSessionIssuance.js";
@@ -1,9 +1,9 @@
1
1
  import { parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId } from "../utils/domainIds.js";
2
- import { parseWalletSessionMintId } from "./capabilityKinds.js";
3
2
  import { isPlainObject } from "../utils/validation.js";
4
3
  import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
5
4
  import { alphabetizeStringify } from "../utils/digests.js";
6
5
  import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
6
+ import { parseWalletSessionMintId } from "./capabilityKinds.js";
7
7
  //#region ../shared-ts/src/authorization/voiceIdDeviceAssertion.ts
8
8
  const CHALLENGE_DOMAIN = "seams:wallet-session:voiceid-device:v1";
9
9
  const MAXIMUM_CHALLENGE_MS = 6e4;
@@ -1,10 +1,10 @@
1
1
  import { parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseMpcMaterialActivationRef, parseWalletAuthorityId, parseWalletId, parseWalletRecoveryOperationId } from "../utils/domainIds.js";
2
- import { parseDeviceId } from "./capabilityKinds.js";
3
2
  import { requireRecord } from "../utils/validation.js";
4
- import { parseDelegatedWalletPermissionSetV1 } from "./delegatedAuthority.js";
5
3
  import { base64UrlEncode } from "../utils/base64.js";
6
4
  import { sha256Bytes } from "../utils/digests.js";
7
5
  import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
6
+ import { parseDeviceId } from "./capabilityKinds.js";
7
+ import { parseDelegatedWalletPermissionSetV1 } from "./delegatedAuthority.js";
8
8
  import { buildExactAdministeredSignerManifestV1, parseExactAdministeredSignerManifestV1 } from "../device-linking/delegatedActivationPlan.js";
9
9
  import { concat, lp32, rawDigest, rawPublicKey, text, u32, u64 } from "../utils/digestEncoding.js";
10
10
  //#region ../shared-ts/src/authorization/walletAuthority.ts
@@ -1,8 +1,8 @@
1
1
  import { alphabetizeStringify } from "../utils/digests.js";
2
2
  import { sha256Utf8DigestB64u } from "../utils/canonicalPrimitives.js";
3
- //#region ../shared-ts/src/authorization/walletCustodyOperation.ts
3
+ //#region ../shared-ts/src/authorization/walletOwnerOperation.ts
4
4
  /** Public challenge digest for a single wallet-administration factor proof. */
5
- async function computeWalletCustodyAdminChallengeDigest(input) {
5
+ async function computeWalletOwnerAdminChallengeDigest(input) {
6
6
  return sha256Utf8DigestB64u(`seams:wallet-custody:challenge:v1|${alphabetizeStringify({
7
7
  walletId: input.walletId,
8
8
  operation: input.operation,
@@ -11,6 +11,6 @@ async function computeWalletCustodyAdminChallengeDigest(input) {
11
11
  })}`);
12
12
  }
13
13
  //#endregion
14
- export { computeWalletCustodyAdminChallengeDigest };
14
+ export { computeWalletOwnerAdminChallengeDigest };
15
15
 
16
- //# sourceMappingURL=walletCustodyOperation.js.map
16
+ //# sourceMappingURL=walletOwnerOperation.js.map
@@ -1,7 +1,7 @@
1
1
  import { parseWalletId, parseWalletKeyId } from "../utils/domainIds.js";
2
2
  import { requireRecord } from "../utils/validation.js";
3
- import { rejectUnknownFields } from "../utils/exactRecord.js";
4
3
  import { parseEd25519PublicKeyB64u, parseSecp256k1CompressedPublicKeyB64u, requireParsed } from "../passkey-custody/primitives.js";
4
+ import { rejectUnknownFields } from "../utils/exactRecord.js";
5
5
  //#region ../shared-ts/src/device-linking/delegatedActivationPlan.ts
6
6
  const MANIFEST_FIELDS = [
7
7
  "kind",
@@ -1,6 +1,6 @@
1
- import { delegatedWalletPermissionNamesV1 } from "../authorization/delegatedAuthority.js";
2
1
  import { alphabetizeStringify } from "../utils/digests.js";
3
2
  import { sha256DigestB64u, sha256Utf8DigestB64u } from "../utils/canonicalPrimitives.js";
3
+ import { delegatedWalletPermissionNamesV1 } from "../authorization/delegatedAuthority.js";
4
4
  import { concat, lp32, rawDigest, rawPublicKey, text, u32, u64 } from "../utils/digestEncoding.js";
5
5
  import "./committedSignerPackages.js";
6
6
  //#region ../shared-ts/src/device-linking/digests.ts
@@ -1,8 +1,8 @@
1
1
  import { parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseLinkedDeviceId, parseWalletId, parseWalletKeyId } from "../utils/domainIds.js";
2
2
  import { requireRecord } from "../utils/validation.js";
3
- import { rejectUnknownFields } from "../utils/exactRecord.js";
4
3
  import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
5
4
  import { parseDigestField, parseEd25519PublicKeyB64u, parseEnvelopeCiphertextB64u, parseEnvelopeNonceB64u, requireParsed } from "../passkey-custody/primitives.js";
5
+ import { rejectUnknownFields } from "../utils/exactRecord.js";
6
6
  //#region ../shared-ts/src/device-linking/ed25519ExportRoot.ts
7
7
  /**
8
8
  * Authenticated relay records for the cross-device Ed25519 Yao Client export
@@ -1,9 +1,9 @@
1
1
  import { requireArray, requireRecord } from "../utils/validation.js";
2
+ import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
3
+ import { parseEd25519PublicKeyB64u } from "../passkey-custody/primitives.js";
2
4
  import { exactRecord } from "../utils/exactRecord.js";
3
5
  import { wireLiteral, wireNullable, wireObject, wireUnion } from "../utils/wireSchema.js";
4
6
  import "../authorization/delegatedAuthority.js";
5
- import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
6
- import { parseEd25519PublicKeyB64u } from "../passkey-custody/primitives.js";
7
7
  import { authorizationDeviceId, credentialId, digest, enrollmentId, linkedDeviceId, parseDelegatedWalletAuthority, parseNonEmptyToken, parseNonNegativeSafeInteger, parseTargetEmail, parseUnixTime, rpId, sessionId, walletAuthMethodId, walletAuthorityId, walletId, walletKeyId, walletSessionAuthorizationId, walletSessionId } from "./wireFields.js";
8
8
  import { parseWalletAddAuthMethodRegistrationOptions } from "../utils/addAuthMethodRegistration.js";
9
9
  import { requireRouterAbX25519PublicKey } from "../utils/routerAbPublicKeyset.js";
@@ -1,9 +1,9 @@
1
1
  import { mpcMaterialActivationRefsEqual, parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseMpcMaterialActivationRef, parseWalletAuthorityId, parseWalletKeyId } from "../utils/domainIds.js";
2
- import { parseDeviceId } from "../authorization/capabilityKinds.js";
3
2
  import { requireRecordCopy } from "../utils/validation.js";
4
3
  import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
5
4
  import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
6
5
  import { parseEd25519PublicKeyB64u, parseEnvelopeCiphertextB64u, parseSecp256k1CompressedPublicKeyB64u } from "../passkey-custody/primitives.js";
6
+ import { parseDeviceId } from "../authorization/capabilityKinds.js";
7
7
  import { routerAbMpcMaterialActivationRefFromWire } from "../utils/routerAbNormalSigningIdentity.js";
8
8
  import { parseRouterAbEd25519YaoActivationBindingV1, parseRouterAbEd25519YaoActivationPublicReceiptV1, parseRouterAbEd25519YaoApplicationBindingFactsV1, parseRouterAbEd25519YaoEncryptedPackageV1, parseRouterAbEd25519YaoParticipantIdsV1, parseRouterAbEd25519YaoRegistrationActivationAdmissionReceiptV1, sameRouterAbEd25519YaoByteSequence } from "../utils/routerAbEd25519Yao.js";
9
9
  import { parseSdkEcdsaDerivationThresholdKeyId } from "../threshold/ecdsaDerivationRoleLocalBootstrap.js";
@@ -1,8 +1,8 @@
1
1
  import { parseLinkDeviceSessionId, parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId } from "../utils/domainIds.js";
2
- import { parseMpcWalletSigningQuotaId, parsePrincipalId, parseTenantId, parseWalletSessionAuthorizationId, parseWalletSessionId } from "../authorization/capabilityKinds.js";
3
2
  import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
4
3
  import { alphabetizeStringify } from "../utils/digests.js";
5
4
  import { parseDigestB64u, sha256Utf8DigestB64u } from "../utils/canonicalPrimitives.js";
5
+ import { parseMpcWalletSigningQuotaId, parsePrincipalId, parseTenantId, parseWalletSessionAuthorizationId, parseWalletSessionId } from "../authorization/capabilityKinds.js";
6
6
  import { parseLinkDevicePublicKeyB64u } from "./parsers.js";
7
7
  //#region ../shared-ts/src/device-linking/walletSessionCredentialDelivery.ts
8
8
  const DELIVERY_AAD_DOMAIN = "seams/linked-device/wallet-session-credential-delivery-aad/v1";
@@ -1,9 +1,9 @@
1
1
  import { parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseLinkedDeviceId, parseMpcMaterialActivationRef, parseVerifiedEmailAddress, parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId, parseWalletKeyId, parseWebAuthnCredentialIdB64u, parseWebAuthnRpId } from "../utils/domainIds.js";
2
+ import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
3
+ import { parseUnixMs } from "../passkey-custody/primitives.js";
2
4
  import { parseDeviceId, parseMpcWalletSigningQuotaId, parseWalletSessionAuthorizationId, parseWalletSessionId } from "../authorization/capabilityKinds.js";
3
5
  import { wireLabeled, wireNullable, wireResult } from "../utils/wireSchema.js";
4
6
  import { parseDelegatedWalletAuthorityV1 } from "../authorization/delegatedAuthority.js";
5
- import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
6
- import { parseUnixMs } from "../passkey-custody/primitives.js";
7
7
  //#region ../shared-ts/src/device-linking/wireFields.ts
8
8
  const sessionId = /* @__PURE__ */ wireResult(parseLinkDeviceSessionId);
9
9
  const walletId = /* @__PURE__ */ wireResult(parseWalletId);
@@ -1,7 +1,7 @@
1
1
  import { parsePasskeyEnvelopeId, parseWalletAuthMethodId, parseWalletId, parseWebAuthnCredentialIdB64u, parseWebAuthnRpId } from "../utils/domainIds.js";
2
2
  import { requireRecord } from "../utils/validation.js";
3
- import { rejectUnknownFields } from "../utils/exactRecord.js";
4
3
  import { parseDigestField, parseEnvelopeCiphertextB64u, parseEnvelopeNonceB64u, parseEnvelopeRevision, parseUnixMs } from "./primitives.js";
4
+ import { rejectUnknownFields } from "../utils/exactRecord.js";
5
5
  import { parsePasskeyCustodySecretBinding } from "./custodySecretBinding.js";
6
6
  //#region ../shared-ts/src/passkey-custody/custodyEnvelope.ts
7
7
  const WALLET_CUSTODY_ENVELOPE_VERSION_V2 = "wallet_custody_envelope_v2";