@seams/wallet-server 0.26.0 → 0.28.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 (142) hide show
  1. package/artifact-manifest.json +18 -13
  2. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  3. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  4. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  5. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  6. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  7. package/dist/esm/auth/externalAuthService.js +98 -0
  8. package/dist/esm/auth/externalAuthStore.js +217 -0
  9. package/dist/esm/authorization/domain.js +2 -2
  10. package/dist/esm/authorization/factorEvidence.js +1 -1
  11. package/dist/esm/authorization/service.js +2 -2
  12. package/dist/esm/authorization/vaultProxyUse.js +1 -1
  13. package/dist/esm/cloud-host.js +10 -9
  14. package/dist/esm/core/ThresholdService/validation.js +1 -1
  15. package/dist/esm/core/WebAuthnCredentialBindingStore.js +1 -1
  16. package/dist/esm/core/authService/webauthn.js +1 -1
  17. package/dist/esm/core/d1EcdsaSignerRead.js +1 -1
  18. package/dist/esm/core/d1WalletAuthMethodStore.js +2 -2
  19. package/dist/esm/core/d1WalletStore.js +1 -1
  20. package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -1
  21. package/dist/esm/core/deviceLinking/linkedDeviceManagement.js +1 -1
  22. package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -2
  23. package/dist/esm/core/nearRelayerAccountProvisioning.js +1 -1
  24. package/dist/esm/hosted-wallet-gateway.js +3 -3
  25. package/dist/esm/index.js +1 -1
  26. package/dist/esm/router/auth/webAuthnCredentialCodecs.js +1 -1
  27. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +5 -2
  28. package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +2 -2
  29. package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +2 -2
  30. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +3 -3
  31. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEd25519ExportRootStore.js +1 -1
  32. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +2 -2
  33. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.js +1 -1
  34. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSourceContributionPreparationPlanner.js +1 -1
  35. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetAuthenticatorStore.js +1 -1
  36. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
  37. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetPlanner.js +1 -1
  38. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkBuilder.js +2 -2
  39. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkSourceReader.js +1 -1
  40. package/dist/esm/router/cloudflare/d1/ed25519Yao/d1Ed25519YaoCapabilityPersistence.js +1 -1
  41. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +1 -1
  42. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +1 -1
  43. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.js +1 -1
  44. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +2 -2
  45. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +2 -2
  46. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.js +1 -1
  47. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +2 -2
  48. package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +7 -1
  49. package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +1 -1
  50. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +2 -2
  51. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +2 -2
  52. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +1 -1
  53. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +1 -1
  54. package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +1 -1
  55. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +2 -2
  56. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +1 -1
  57. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +1 -1
  58. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +3 -3
  59. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationEstablishedSessionIssuer.js +1 -1
  60. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +1 -1
  61. package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +1 -1
  62. package/dist/esm/router/cloudflare/d1/wallet/authorizationSnapshotLayout.js +1 -0
  63. package/dist/esm/router/cloudflare/d1/wallet/d1VoiceIdWalletSessionChallenges.js +2 -2
  64. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodRevocationReplayStore.js +1 -1
  65. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +2 -2
  66. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorityStore.js +2 -2
  67. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationCleanup.js +2 -1
  68. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationIntake.js +1 -1
  69. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationSnapshot.js +1 -1
  70. package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationChallenges.js +1 -1
  71. package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationOwnerRequest.js +2 -2
  72. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +2 -2
  73. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +2 -2
  74. package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +9 -0
  75. package/dist/esm/router/cloudflare/runtime/walletConsoleOpsClient.js +6 -0
  76. package/dist/esm/router/cloudflare-adaptor.js +1 -1
  77. package/dist/esm/router/cloudflare.js +4635 -4359
  78. package/dist/esm/router/domains/ecdsa/routerAbEcdsaStrictRegistration.js +1 -1
  79. package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +3 -3
  80. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecovery.js +2 -2
  81. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +1 -1
  82. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoHttpRegistrationBackend.js +1 -1
  83. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistration.js +1 -1
  84. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +1 -1
  85. package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +1 -1
  86. package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +2 -2
  87. package/dist/esm/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.js +2 -2
  88. package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -1
  89. package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +1 -1
  90. package/dist/esm/router/domains/walletRegistration/walletRegistrationReservation.js +1 -1
  91. package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +3 -3
  92. package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +2 -2
  93. package/dist/esm/router/framework/http.js +1 -1
  94. package/dist/esm/router/framework/routeDefinitions.js +2 -1
  95. package/dist/esm/router/transport/fetch/createFetchRouter.js +5 -3
  96. package/dist/esm/router/transport/fetch/routes/auth.js +1 -1
  97. package/dist/esm/router/transport/fetch/routes/deviceLinking.js +3 -3
  98. package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
  99. package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +1 -1
  100. package/dist/esm/router/transport/fetch/routes/externalAuth.js +244 -0
  101. package/dist/esm/router/transport/fetch/routes/normalSigningRouterProxy.js +1 -1
  102. package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +4 -4
  103. package/dist/esm/router/transport/fetch/routes/sessions.js +2 -2
  104. package/dist/esm/router/transport/fetch/routes/syncAccount.js +2 -2
  105. package/dist/esm/router/transport/fetch/routes/syncAccountBootstrap.js +1 -1
  106. package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +4 -4
  107. package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +4 -4
  108. package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +2 -2
  109. package/dist/esm/router/transport/fetch/routes/walletRegistration.js +3 -3
  110. package/dist/esm/shared-ts/src/auth/externalAuth.js +45 -0
  111. package/dist/esm/shared-ts/src/authorization/voiceIdDeviceAssertion.js +1 -1
  112. package/dist/esm/shared-ts/src/authorization/walletAuthority.js +2 -2
  113. package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -1
  114. package/dist/esm/shared-ts/src/device-linking/digests.js +1 -1
  115. package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +1 -1
  116. package/dist/esm/shared-ts/src/device-linking/parsers.js +2 -2
  117. package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +1 -1
  118. package/dist/esm/shared-ts/src/device-linking/walletSessionCredentialDelivery.js +1 -1
  119. package/dist/esm/shared-ts/src/device-linking/wireFields.js +2 -2
  120. package/dist/esm/shared-ts/src/passkey-custody/custodyEnvelope.js +1 -1
  121. package/dist/esm/shared-ts/src/passkey-custody/custodySecretBinding.js +1 -1
  122. package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +1 -1
  123. package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
  124. package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +1 -1
  125. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -1
  126. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEnvelopeSet.js +1 -1
  127. package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +1 -1
  128. package/dist/esm/threshold/session/signingSessionSeal/service.js +1 -1
  129. package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +1 -1
  130. package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +1 -1
  131. package/dist/types/shared-ts/src/auth/externalAuth.d.ts +84 -0
  132. package/dist/types/wallet-server/src/auth/externalAuthService.d.ts +36 -0
  133. package/dist/types/wallet-server/src/auth/externalAuthStore.d.ts +61 -0
  134. package/dist/types/wallet-server/src/cloud-host.d.ts +2 -1
  135. package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/d1OidcBoundary.d.ts +5 -0
  136. package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/authorizationSnapshotLayout.d.ts +1 -1
  137. package/dist/types/wallet-server/src/router/cloudflare/runtime/staticWalletConsoleBinding.d.ts +2 -0
  138. package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +1 -0
  139. package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +1 -0
  140. package/dist/types/wallet-server/src/router/transport/fetch/routes/externalAuth.d.ts +5 -0
  141. package/migrations/d1-signer/0085_external_wallet_auth.sql +158 -0
  142. package/package.json +1 -1
@@ -0,0 +1,61 @@
1
+ import type { ExternalWalletAuthentication, ExternalAuthConfiguration } from '../../../shared-ts/src/auth/externalAuth';
2
+ import type { Variant } from '../../../shared-ts/src/utils/variant';
3
+ import type { WalletId, WalletAuthorityId } from '../../../shared-ts/src/utils/domainIds';
4
+ import { type D1TenantScope } from '../core/d1TenantStore';
5
+ import type { D1DatabaseLike } from '../storage/tenantRoute';
6
+ export type ExternalAuthTrust = Variant<ExternalAuthConfiguration, 'kind', 'google'>;
7
+ type ExternalAuthPreparedAttempt = Readonly<{
8
+ attemptId: string;
9
+ walletId: WalletId;
10
+ originBinding: string;
11
+ bindingHash: string;
12
+ sessionTokenHash: string;
13
+ expiresAtMs: number;
14
+ }>;
15
+ export declare class ExternalAuthStore {
16
+ private readonly database;
17
+ readonly scope: D1TenantScope;
18
+ constructor(database: D1DatabaseLike, scope: D1TenantScope);
19
+ private prepare;
20
+ consumeAuthenticationAllowance(rateKey: string, nowMs: number): Promise<boolean>;
21
+ associate(input: {
22
+ walletId: WalletId;
23
+ subject: string;
24
+ authorityId: WalletAuthorityId;
25
+ authorityEpoch: number;
26
+ }): Promise<boolean>;
27
+ revokeAssociation(walletId: WalletId, associationId: string): Promise<void>;
28
+ prepareAttempt(input: ExternalAuthPreparedAttempt): Promise<void>;
29
+ verifyAttempt(input: {
30
+ attemptId: string;
31
+ walletId: WalletId;
32
+ subject: string;
33
+ trust: ExternalAuthTrust;
34
+ codeHash: string;
35
+ nowMs: number;
36
+ sessionExpiresAtMs: number;
37
+ }): Promise<boolean>;
38
+ redeem(input: {
39
+ attemptId: string;
40
+ walletId: WalletId;
41
+ originBinding: string;
42
+ bindingHash: string;
43
+ sessionTokenHash: string;
44
+ codeHash: string;
45
+ nowMs: number;
46
+ trustRevision: number;
47
+ }): Promise<ExternalWalletAuthentication | null>;
48
+ readSession(input: {
49
+ tokenHash: string;
50
+ originBinding: string;
51
+ nowMs: number;
52
+ trustRevision: number;
53
+ }): Promise<ExternalWalletAuthentication | null>;
54
+ revokeSession(tokenHash: string, originBinding: string): Promise<void>;
55
+ devices(walletId: WalletId): Promise<readonly {
56
+ id: string;
57
+ }[]>;
58
+ private authentication;
59
+ }
60
+ export {};
61
+ //# sourceMappingURL=externalAuthStore.d.ts.map
@@ -1,3 +1,4 @@
1
+ export { parseExternalAuthConfiguration, type ExternalAuthConfiguration, } from '../../shared-ts/src/auth/externalAuth';
1
2
  export * from './core/SessionService';
2
3
  export * from './core/ThresholdService/evmCryptoWasm';
3
4
  export * from './core/d1WalletStore';
@@ -121,5 +122,5 @@ export type { LinkedDeviceSessionRecordV1 } from './core/deviceLinking/linkedDev
121
122
  export { computeLinkedDeviceSessionClaimDigestV1 } from '../../shared-ts/src/device-linking/digests';
122
123
  export { admitD1EstablishedWalletHome, resumeRegistrationDirectoryPublicationsV1, type RegistrationDirectoryPublicationDelivery, } from './router/cloudflare/d1/registration/d1WalletExecutionAuthority';
123
124
  export { D1WalletObjectAddresses } from './router/cloudflare/d1/walletObjectAddresses';
124
- export { walletObjectIdentity, WalletObjectAddressSnapshot, type WalletObjectIdentity } from './router/cloudflare/runtime/walletObjectAddresses';
125
+ export { walletObjectIdentity, WalletObjectAddressSnapshot, type WalletObjectIdentity, } from './router/cloudflare/runtime/walletObjectAddresses';
125
126
  //# sourceMappingURL=cloud-host.d.ts.map
@@ -22,6 +22,11 @@ export type ParsedRs256JwtResult = {
22
22
  export type GoogleIdTokenClaims = {
23
23
  readonly ok: true;
24
24
  readonly sub: string;
25
+ readonly issuer: 'https://accounts.google.com';
26
+ readonly audience: string;
27
+ readonly expiresAtMs: number;
28
+ readonly authorizedParty: string | null;
29
+ readonly audienceCount: number;
25
30
  readonly email?: string;
26
31
  readonly name?: string;
27
32
  readonly givenName?: string;
@@ -1,5 +1,5 @@
1
1
  import type { D1DatabaseLike } from '../../../../storage/tenantRoute';
2
- declare const TABLES: readonly ['wallet_email_otp_rate_limits', 'email_otp_wallet_enrollments', 'email_otp_auth_states', 'wallets', 'wallet_signers', 'wallet_recovery_code_locators', 'wallet_authorities', 'wallet_auth_methods', 'wallet_relocation_approvals', 'webauthn_credential_bindings', 'webauthn_authenticators', 'router_ab_yao_versioned_json_records', 'authorization_wallet_session_quotas', 'wallet_session_authorizations_v2', 'wallet_session_hosted_credentials_v2', 'wallet_session_hosted_exchange_codes_v2', 'verified_wallet_operation_evidence_sets', 'authorized_operations', 'authorized_operation_audit_events', 'linked_device_sessions', 'linked_device_authority_allocations', 'linked_device_authority_installations', 'linked_device_target_credentials', 'linked_device_target_commit_reservations', 'linked_device_session_transcripts', 'linked_device_ed25519_export_root_transfers', 'linked_device_email_otp_grants', 'linked_device_request_proof_nonces', 'linked_device_bootstrap_imports', 'linked_device_wallet_session_credential_deliveries_v1'];
2
+ declare const TABLES: readonly ['wallet_email_otp_rate_limits', 'email_otp_wallet_enrollments', 'email_otp_auth_states', 'wallets', 'wallet_signers', 'wallet_recovery_code_locators', 'wallet_authorities', 'wallet_auth_methods', 'external_auth_associations', 'wallet_relocation_approvals', 'webauthn_credential_bindings', 'webauthn_authenticators', 'router_ab_yao_versioned_json_records', 'authorization_wallet_session_quotas', 'wallet_session_authorizations_v2', 'wallet_session_hosted_credentials_v2', 'wallet_session_hosted_exchange_codes_v2', 'verified_wallet_operation_evidence_sets', 'authorized_operations', 'authorized_operation_audit_events', 'linked_device_sessions', 'linked_device_authority_allocations', 'linked_device_authority_installations', 'linked_device_target_credentials', 'linked_device_target_commit_reservations', 'linked_device_session_transcripts', 'linked_device_ed25519_export_root_transfers', 'linked_device_email_otp_grants', 'linked_device_request_proof_nonces', 'linked_device_bootstrap_imports', 'linked_device_wallet_session_credential_deliveries_v1'];
3
3
  type Table = (typeof TABLES)[number];
4
4
  export declare class AuthorizationSnapshotLayout {
5
5
  #private;
@@ -1,4 +1,5 @@
1
1
  import { type RouterApiCredentialScope } from '../../framework/apiCredentialPorts';
2
+ import { type ExternalAuthConfiguration } from '../../../../../shared-ts/src/auth/externalAuth';
2
3
  import type { WalletConsoleServiceBinding } from './walletConsoleOpsClient';
3
4
  export interface StaticWalletConsoleBindingConfigV1 {
4
5
  readonly credential: {
@@ -9,6 +10,7 @@ export interface StaticWalletConsoleBindingConfigV1 {
9
10
  readonly scopes: readonly RouterApiCredentialScope[];
10
11
  };
11
12
  readonly deployment: {
13
+ readonly externalAuth?: ExternalAuthConfiguration;
12
14
  readonly orgId: string;
13
15
  readonly projectId: string;
14
16
  readonly environmentId: string;
@@ -88,6 +88,7 @@ export interface RouterApiUsageMeterAdapter {
88
88
  recordEvent(input: RouterApiUsageMeterEvent): Promise<void>;
89
89
  }
90
90
  export interface RouterApiProjectEnvironment {
91
+ externalAuth?: import('../../../../shared-ts/src/auth/externalAuth').ExternalAuthConfiguration;
91
92
  id: string;
92
93
  projectId: string;
93
94
  key: string;
@@ -1298,6 +1298,7 @@ interface RouterApiRouterAccountService {
1298
1298
  export type { RouterApiPasskeyCustodyService } from '../cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService';
1299
1299
  import type { RouterApiPasskeyCustodyService } from '../cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService';
1300
1300
  export interface RouterApiServiceBag {
1301
+ externalAuth?: import('../../auth/externalAuthService').ExternalAuthService;
1301
1302
  walletRegistration: RouterApiWalletRegistrationService;
1302
1303
  walletAuthMethods: RouterApiWalletAuthMethodService;
1303
1304
  walletUnlock: RouterApiWalletUnlockService;
@@ -0,0 +1,5 @@
1
+ import type { FetchRouterApiContext } from '../fetchRouter.types';
2
+ import type { RouteDefinition } from '../../../framework/routeDefinitions';
3
+ export declare function externalAuthRoutes(): RouteDefinition[];
4
+ export declare function handleExternalAuth(ctx: FetchRouterApiContext): Promise<Response | null>;
5
+ //# sourceMappingURL=externalAuth.d.ts.map
@@ -0,0 +1,158 @@
1
+ -- Reject unfinished transfers. Completed receipts remain immutable.
2
+ CREATE TABLE external_auth_relocation_upgrade_guard (count INTEGER NOT NULL CHECK (count = 0));
3
+ INSERT INTO external_auth_relocation_upgrade_guard
4
+ SELECT (SELECT COUNT(*) FROM wallet_relocation_authorization_snapshots AS snapshot
5
+ WHERE NOT EXISTS (
6
+ SELECT 1 FROM wallet_relocation_authorization_cleanups AS cleanup
7
+ WHERE cleanup.namespace = snapshot.namespace AND cleanup.org_id = snapshot.org_id
8
+ AND cleanup.project_id = snapshot.project_id AND cleanup.env_id = snapshot.env_id
9
+ AND cleanup.wallet_id = snapshot.wallet_id AND cleanup.move_id = snapshot.move_id
10
+ AND cleanup.request_digest_hex = snapshot.request_digest_hex
11
+ AND cleanup.source_generation = snapshot.source_generation
12
+ AND cleanup.state = 'cleaned'))
13
+ + (SELECT COUNT(*) FROM wallet_relocation_authorization_imports WHERE state != 'activated');
14
+ DROP TABLE external_auth_relocation_upgrade_guard;
15
+
16
+
17
+ -- External identity sessions grant settings reads only. Signing tables remain separate.
18
+ CREATE TABLE external_auth_associations (
19
+ namespace TEXT NOT NULL,
20
+ org_id TEXT NOT NULL,
21
+ project_id TEXT NOT NULL,
22
+ env_id TEXT NOT NULL,
23
+ association_id TEXT NOT NULL,
24
+ wallet_id TEXT NOT NULL,
25
+ provider_subject TEXT NOT NULL,
26
+ authority_id TEXT NOT NULL,
27
+ authority_epoch INTEGER NOT NULL,
28
+ status TEXT NOT NULL CHECK (status IN ('active', 'revoked')),
29
+ PRIMARY KEY (namespace, org_id, project_id, env_id, association_id)
30
+ );
31
+ CREATE UNIQUE INDEX external_auth_active_association
32
+ ON external_auth_associations(namespace, org_id, project_id, env_id, wallet_id, provider_subject)
33
+ WHERE status = 'active';
34
+
35
+ CREATE TABLE external_auth_attempts (
36
+ namespace TEXT NOT NULL,
37
+ org_id TEXT NOT NULL,
38
+ project_id TEXT NOT NULL,
39
+ env_id TEXT NOT NULL,
40
+ attempt_id TEXT NOT NULL,
41
+ wallet_id TEXT NOT NULL,
42
+ -- Canonical JSON pair: wallet request origin and embedding application origin.
43
+ origin TEXT NOT NULL,
44
+ binding_hash TEXT NOT NULL,
45
+ session_token_hash TEXT NOT NULL,
46
+ expires_at_ms INTEGER NOT NULL,
47
+ status TEXT NOT NULL CHECK (status IN ('prepared', 'verified', 'consumed', 'revoked')),
48
+ association_id TEXT,
49
+ trust_revision INTEGER,
50
+ code_hash TEXT,
51
+ session_expires_at_ms INTEGER,
52
+ PRIMARY KEY (namespace, org_id, project_id, env_id, attempt_id),
53
+ CHECK (status IN ('prepared', 'revoked') OR
54
+ (association_id IS NOT NULL AND trust_revision IS NOT NULL AND code_hash IS NOT NULL
55
+ AND session_expires_at_ms IS NOT NULL))
56
+ );
57
+ CREATE UNIQUE INDEX external_auth_session_token
58
+ ON external_auth_attempts(namespace, org_id, project_id, env_id, session_token_hash);
59
+ CREATE INDEX external_auth_attempt_expiry ON external_auth_attempts(expires_at_ms);
60
+
61
+ CREATE TABLE external_auth_rate_limits (
62
+ namespace TEXT NOT NULL, org_id TEXT NOT NULL, project_id TEXT NOT NULL, env_id TEXT NOT NULL,
63
+ rate_key TEXT NOT NULL, consumed_count INTEGER NOT NULL, reset_at_ms INTEGER NOT NULL,
64
+ PRIMARY KEY (namespace, org_id, project_id, env_id, rate_key)
65
+ );
66
+ CREATE INDEX external_auth_rate_expiry ON external_auth_rate_limits(reset_at_ms);
67
+
68
+ CREATE TRIGGER external_auth_associations_capacity_insert BEFORE INSERT ON external_auth_associations
69
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_fences AS fence
70
+ JOIN wallet_relocation_write_blocks AS block USING (namespace, org_id, project_id, env_id, wallet_id, move_id, request_digest_hex, source_generation)
71
+ WHERE block.state IN ('draining', 'checked') AND fence.namespace = NEW.namespace AND fence.org_id = NEW.org_id
72
+ AND fence.project_id = NEW.project_id AND fence.env_id = NEW.env_id AND fence.wallet_id = NEW.wallet_id)
73
+ BEGIN SELECT RAISE(ABORT, 'wallet_relocation_write_blocked'); END;
74
+
75
+ CREATE TRIGGER external_auth_associations_capacity_update BEFORE UPDATE ON external_auth_associations
76
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_fences AS fence
77
+ JOIN wallet_relocation_write_blocks AS block USING (namespace, org_id, project_id, env_id, wallet_id, move_id, request_digest_hex, source_generation)
78
+ WHERE block.state IN ('draining', 'checked') AND fence.namespace = OLD.namespace AND fence.org_id = OLD.org_id
79
+ AND fence.project_id = OLD.project_id AND fence.env_id = OLD.env_id AND fence.wallet_id = OLD.wallet_id)
80
+ BEGIN SELECT RAISE(ABORT, 'wallet_relocation_write_blocked'); END;
81
+
82
+ CREATE TRIGGER external_auth_associations_capacity_delete BEFORE DELETE ON external_auth_associations
83
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_fences AS fence
84
+ JOIN wallet_relocation_write_blocks AS block USING (namespace, org_id, project_id, env_id, wallet_id, move_id, request_digest_hex, source_generation)
85
+ WHERE block.state IN ('draining', 'checked') AND fence.namespace = OLD.namespace AND fence.org_id = OLD.org_id
86
+ AND fence.project_id = OLD.project_id AND fence.env_id = OLD.env_id AND fence.wallet_id = OLD.wallet_id)
87
+ BEGIN SELECT RAISE(ABORT, 'wallet_relocation_write_blocked'); END;
88
+
89
+ CREATE TRIGGER external_auth_associations_relocation_frozen_insert
90
+ BEFORE INSERT ON external_auth_associations
91
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_fences AS fence
92
+ WHERE fence.namespace = NEW.namespace AND fence.org_id = NEW.org_id
93
+ AND fence.project_id = NEW.project_id AND fence.env_id = NEW.env_id
94
+ AND fence.wallet_id = NEW.wallet_id)
95
+ BEGIN SELECT RAISE(ABORT, 'wallet_authorization_history_frozen'); END;
96
+
97
+ CREATE TRIGGER external_auth_associations_relocation_frozen_update
98
+ BEFORE UPDATE ON external_auth_associations
99
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_fences AS fence
100
+ WHERE fence.namespace = OLD.namespace AND fence.org_id = OLD.org_id
101
+ AND fence.project_id = OLD.project_id AND fence.env_id = OLD.env_id
102
+ AND fence.wallet_id = OLD.wallet_id)
103
+ BEGIN SELECT RAISE(ABORT, 'wallet_authorization_history_frozen'); END;
104
+
105
+ CREATE TRIGGER external_auth_associations_relocation_frozen_delete
106
+ BEFORE DELETE ON external_auth_associations
107
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_fences AS fence
108
+ WHERE fence.namespace = OLD.namespace AND fence.org_id = OLD.org_id
109
+ AND fence.project_id = OLD.project_id AND fence.env_id = OLD.env_id
110
+ AND fence.wallet_id = OLD.wallet_id
111
+ AND NOT EXISTS (SELECT 1 FROM wallet_relocation_authorization_cleanups AS cleanup
112
+ WHERE cleanup.namespace = fence.namespace AND cleanup.org_id = fence.org_id
113
+ AND cleanup.project_id = fence.project_id AND cleanup.env_id = fence.env_id
114
+ AND cleanup.wallet_id = fence.wallet_id AND cleanup.move_id = fence.move_id
115
+ AND cleanup.request_digest_hex = fence.request_digest_hex
116
+ AND cleanup.source_generation = fence.source_generation AND cleanup.state = 'cleaning'))
117
+ BEGIN SELECT RAISE(ABORT, 'wallet_authorization_history_frozen'); END;
118
+
119
+ CREATE TRIGGER external_auth_associations_relocation_inactive_insert
120
+ BEFORE INSERT ON external_auth_associations
121
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_imports AS destination
122
+ WHERE destination.namespace = NEW.namespace AND destination.org_id = NEW.org_id
123
+ AND destination.project_id = NEW.project_id AND destination.env_id = NEW.env_id
124
+ AND destination.wallet_id = NEW.wallet_id AND destination.state != 'activated')
125
+ AND NOT EXISTS (SELECT 1 FROM wallet_relocation_authorization_import_context AS context
126
+ JOIN wallet_relocation_authorization_imports AS destination
127
+ ON destination.namespace = context.namespace AND destination.org_id = context.org_id
128
+ AND destination.project_id = context.project_id AND destination.env_id = context.env_id
129
+ AND destination.wallet_id = context.wallet_id AND destination.move_id = context.move_id
130
+ AND destination.request_digest_hex = context.request_digest_hex
131
+ AND destination.source_generation = context.source_generation
132
+ WHERE context.namespace = NEW.namespace AND context.org_id = NEW.org_id
133
+ AND context.project_id = NEW.project_id AND context.env_id = NEW.env_id
134
+ AND context.wallet_id = NEW.wallet_id
135
+ AND destination.state = 'importing' AND context.table_name = 'external_auth_associations'
136
+ AND context.record_key = json_array(NEW.association_id, NEW.env_id, NEW.namespace, NEW.org_id, NEW.project_id))
137
+ BEGIN SELECT RAISE(ABORT, 'wallet_authorization_destination_inactive'); END;
138
+
139
+ CREATE TRIGGER external_auth_associations_relocation_inactive_update
140
+ BEFORE UPDATE ON external_auth_associations
141
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_imports AS destination
142
+ WHERE destination.namespace = OLD.namespace AND destination.org_id = OLD.org_id
143
+ AND destination.project_id = OLD.project_id AND destination.env_id = OLD.env_id
144
+ AND destination.wallet_id = OLD.wallet_id AND destination.state != 'activated')
145
+ BEGIN SELECT RAISE(ABORT, 'wallet_authorization_destination_inactive'); END;
146
+
147
+ CREATE TRIGGER external_auth_associations_relocation_inactive_delete
148
+ BEFORE DELETE ON external_auth_associations
149
+ WHEN EXISTS (SELECT 1 FROM wallet_relocation_authorization_imports AS destination
150
+ WHERE destination.namespace = OLD.namespace AND destination.org_id = OLD.org_id
151
+ AND destination.project_id = OLD.project_id AND destination.env_id = OLD.env_id
152
+ AND destination.wallet_id = OLD.wallet_id AND destination.state != 'activated')
153
+ BEGIN SELECT RAISE(ABORT, 'wallet_authorization_destination_inactive'); END;
154
+
155
+ CREATE TRIGGER external_auth_associations_relocation_owner_immutable
156
+ BEFORE UPDATE ON external_auth_associations
157
+ WHEN NEW.namespace IS NOT OLD.namespace OR NEW.org_id IS NOT OLD.org_id OR NEW.project_id IS NOT OLD.project_id OR NEW.env_id IS NOT OLD.env_id OR NEW.wallet_id IS NOT OLD.wallet_id
158
+ BEGIN SELECT RAISE(ABORT, 'wallet_record_owner_changed'); END;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seams/wallet-server",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "type": "module",
5
5
  "description": "Seams server TypeScript SDK for NEAR and EVM-family wallets",
6
6
  "main": "./dist/esm/index.js",