@tinycloud/node-sdk 3.8.0-beta.10 → 3.8.0-beta.13

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.
@@ -1,6 +1,6 @@
1
1
  import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
2
2
  export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
3
- import { T as TinyCloudNode } from './TinyCloudNode-Dy65bxqs.cjs';
3
+ import { T as TinyCloudNode } from './TinyCloudNode-BVDUdEcf.cjs';
4
4
  import '@tinycloud/sdk-core';
5
5
  import '@tinycloud/sdk-services/kv/replication';
6
6
  import '@tinycloud/sdk-services';
@@ -1,6 +1,6 @@
1
1
  import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
2
2
  export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
3
- import { T as TinyCloudNode } from './TinyCloudNode-DnD-SH6t.js';
3
+ import { T as TinyCloudNode } from './TinyCloudNode-jMK_2Uj8.js';
4
4
  import '@tinycloud/sdk-core';
5
5
  import '@tinycloud/sdk-services/kv/replication';
6
6
  import '@tinycloud/sdk-services';
package/dist/index.cjs CHANGED
@@ -17968,6 +17968,7 @@ __export(src_exports, {
17968
17968
  hexDecode: () => import_sdk_core22.hexDecode,
17969
17969
  hexEncode: () => import_sdk_core22.hexEncode,
17970
17970
  installTinyCloudDebugGlobals: () => import_sdk_core16.installTinyCloudDebugGlobals,
17971
+ isAppKeyHostBound: () => isAppKeyHostBound,
17971
17972
  isCapabilitySubset: () => import_sdk_core17.isCapabilitySubset,
17972
17973
  isEvmAddress: () => import_sdk_core16.isEvmAddress,
17973
17974
  isNetworkId: () => import_sdk_core22.isNetworkId,
@@ -18862,6 +18863,18 @@ function appKeyHostBinding(domain, appId) {
18862
18863
  const reversed = labels.reverse().join(".");
18863
18864
  return appId === reversed || appId.startsWith(`${reversed}.`);
18864
18865
  }
18866
+ function isAppKeyHostBound(keysAppId, origin) {
18867
+ if (typeof origin === "string" && !origin.includes("://")) {
18868
+ return appKeyHostBinding(origin, keysAppId);
18869
+ }
18870
+ let url;
18871
+ try {
18872
+ url = typeof origin === "string" ? new URL(origin) : origin;
18873
+ } catch {
18874
+ return false;
18875
+ }
18876
+ return appKeyHostBinding(url.host, keysAppId);
18877
+ }
18865
18878
 
18866
18879
  // src/authorization/NodeUserAuthorization.ts
18867
18880
  init_authority_sign_in();
@@ -19019,6 +19032,7 @@ function cloneAbilitiesMap(actions) {
19019
19032
  var NodeUserAuthorization = class {
19020
19033
  constructor(config) {
19021
19034
  this.activeSessionKeyId = "default";
19035
+ this.preparedSessionCounter = 0;
19022
19036
  /** Incremented by resetSession; a sign-in started earlier publishes nothing. */
19023
19037
  this.sessionGeneration = 0;
19024
19038
  /**
@@ -20152,9 +20166,8 @@ var NodeUserAuthorization = class {
20152
20166
  const address = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
20153
20167
  const chainId = await this.signer.getChainId();
20154
20168
  await this.refreshNamedKeyFeatureForSignIn(address, chainId);
20155
- const keyId = `session-${Date.now()}`;
20156
- this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
20157
- this.activeSessionKeyId = keyId;
20169
+ const keyId = `openkey-session-${Date.now()}-${++this.preparedSessionCounter}`;
20170
+ this.sessionManager.createSessionKey(keyId);
20158
20171
  const jwkString = this.sessionManager.jwk(keyId);
20159
20172
  if (!jwkString) {
20160
20173
  throw new Error("Failed to create session key");
@@ -20235,6 +20248,7 @@ var NodeUserAuthorization = class {
20235
20248
  await this.sessionStorage.save(address, persistedData);
20236
20249
  this._session = clientSession;
20237
20250
  this._tinyCloudSession = tinyCloudSession;
20251
+ this.activeSessionKeyId = keyId;
20238
20252
  this._address = address;
20239
20253
  this._chainId = chainId;
20240
20254
  await this.refreshNodeInfo();
@@ -20281,6 +20295,11 @@ var NodeUserAuthorization = class {
20281
20295
  * @param options Optional overrides for the OpenKey request.
20282
20296
  */
20283
20297
  async signInWithOpenKey(authorizeFn, options) {
20298
+ const pending = await this.prepareOpenKeySignIn(options);
20299
+ return this.completeOpenKeySignIn(pending, authorizeFn(pending.request), options);
20300
+ }
20301
+ /** Finish address, host and SIWE preparation before an approval click. */
20302
+ async prepareOpenKeySignIn(options) {
20284
20303
  refuseCaveated(this.getCapabilityRequest()?.manifests);
20285
20304
  if (options?.host !== void 0) {
20286
20305
  const overrideHost = options.host.trim();
@@ -20292,7 +20311,7 @@ var NodeUserAuthorization = class {
20292
20311
  const signingAddress = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
20293
20312
  const signingChainId = await this.signer.getChainId();
20294
20313
  await this.resolveTinyCloudHostsForSignIn(signingAddress, signingChainId);
20295
- const { prepared, keyId, jwk } = await this.prepareSessionForSigning();
20314
+ const { prepared, keyId, jwk, address, chainId } = await this.prepareSessionForSigning();
20296
20315
  const presentation = this.buildPresentationEnvelope(options?.reason);
20297
20316
  const hostHint = this.primaryTinyCloudHost;
20298
20317
  const originalRequest = {
@@ -20304,12 +20323,32 @@ var NodeUserAuthorization = class {
20304
20323
  keyId: options?.openkeyKeyId,
20305
20324
  presentation
20306
20325
  };
20326
+ return {
20327
+ request: originalRequest,
20328
+ prepared,
20329
+ keyId,
20330
+ jwk,
20331
+ address,
20332
+ chainId,
20333
+ generation: this.sessionGeneration,
20334
+ createdAt: Date.now()
20335
+ };
20336
+ }
20337
+ /** Complete a prepared approval. The caller starts authorization before awaiting this method. */
20338
+ async completeOpenKeySignIn(pending, authorization, options) {
20339
+ if (Date.now() - pending.createdAt > 5 * 6e4) {
20340
+ throw new Error("Prepared OpenKey sign-in expired; prepare again");
20341
+ }
20342
+ if (pending.generation !== this.sessionGeneration) {
20343
+ throw new Error("Prepared OpenKey sign-in expired after sign-out");
20344
+ }
20345
+ const { request: originalRequest, prepared, keyId, jwk } = pending;
20307
20346
  let result;
20308
20347
  let signed2;
20309
20348
  let signature2;
20310
20349
  for (let attempt = 0; ; ) {
20311
20350
  try {
20312
- result ?? (result = await authorizeFn(originalRequest));
20351
+ result ?? (result = await authorization);
20313
20352
  signed2 = await this.verifyOpenKeyResult(result, prepared);
20314
20353
  signature2 = result.signature;
20315
20354
  break;
@@ -21703,6 +21742,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21703
21742
  constructor(config = {}) {
21704
21743
  this.signer = null;
21705
21744
  this.auth = null;
21745
+ this.consumedOpenKeyPendings = /* @__PURE__ */ new WeakSet();
21706
21746
  this.tc = null;
21707
21747
  this._chainId = 1;
21708
21748
  this.replicaPurgeFailedHandlers = /* @__PURE__ */ new Set();
@@ -22643,6 +22683,37 @@ var _TinyCloudNode = class _TinyCloudNode {
22643
22683
  }
22644
22684
  await this.signInWith(() => this.auth.signInWithOpenKey(authorizeFn, options));
22645
22685
  }
22686
+ /** Prepare the OpenKey request before the approval click. */
22687
+ async prepareOpenKeySignIn() {
22688
+ if (!this.signer || !this.tc || !this.auth) {
22689
+ throw new Error("Cannot prepare OpenKey sign-in in session-only mode. Provide a signer in config.");
22690
+ }
22691
+ await this.signOutInFlight;
22692
+ await this.accountRegistryTail;
22693
+ await this.wasmBindings.ensureInitialized?.();
22694
+ return this.auth.prepareOpenKeySignIn();
22695
+ }
22696
+ /** Start OpenKey authorization synchronously, then complete normal session setup. */
22697
+ signInWithPreparedOpenKey(pending, authorizeFn) {
22698
+ if (!this.signer || !this.tc || !this.auth || this.signOutInFlight) {
22699
+ throw new Error("Prepared OpenKey sign-in is unavailable");
22700
+ }
22701
+ if (this.consumedOpenKeyPendings.has(pending)) {
22702
+ throw new Error("Prepared OpenKey sign-in was already used");
22703
+ }
22704
+ if (Date.now() - pending.createdAt > 5 * 6e4) {
22705
+ throw new Error("Prepared OpenKey sign-in expired; prepare again");
22706
+ }
22707
+ this.consumedOpenKeyPendings.add(pending);
22708
+ const authorization = authorizeFn(pending.request);
22709
+ void authorization.catch(() => void 0);
22710
+ return this.signInWith(() => {
22711
+ if (this._address !== pending.address || this._chainId !== pending.chainId) {
22712
+ throw new Error("OpenKey account changed after sign-in preparation");
22713
+ }
22714
+ return this.auth.completeOpenKeySignIn(pending, authorization);
22715
+ });
22716
+ }
22646
22717
  async signInWith(performSignIn) {
22647
22718
  refuseCaveated(this.auth?.capabilityRequest?.manifests);
22648
22719
  const epoch = this.sessionEpoch;
@@ -28141,7 +28212,7 @@ var FileSessionStorage = class {
28141
28212
  };
28142
28213
 
28143
28214
  // src/authorization/openKeyBridge.ts
28144
- function wireOpenKeyAuthorize(openkey) {
28215
+ function wireOpenKeyAuthorize(openkey, opts) {
28145
28216
  return async (input) => {
28146
28217
  const result = await openkey.authorizeTinyCloud({
28147
28218
  protocolVersion: 1,
@@ -28152,7 +28223,7 @@ function wireOpenKeyAuthorize(openkey) {
28152
28223
  // Forward the presentation envelope verbatim — the OpenKey SDK
28153
28224
  // validates and size-bounds it before use.
28154
28225
  presentation: input.presentation
28155
- });
28226
+ }, opts);
28156
28227
  if (result.protocolVersion !== 1) {
28157
28228
  throw new Error(
28158
28229
  `wireOpenKeyAuthorize: OpenKey returned unsupported protocolVersion ${result.protocolVersion}`
@@ -30846,6 +30917,7 @@ function sqliteReplicaStorage(options) {
30846
30917
  hexDecode,
30847
30918
  hexEncode,
30848
30919
  installTinyCloudDebugGlobals,
30920
+ isAppKeyHostBound,
30849
30921
  isCapabilitySubset,
30850
30922
  isEvmAddress,
30851
30923
  isNetworkId,