@le-space/ui 0.6.36 → 0.6.38

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@le-space/ui",
3
- "version": "0.6.36",
3
+ "version": "0.6.38",
4
4
  "description": "Floating Aleph Relay Button UI components for Svelte and React.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,8 +44,8 @@
44
44
  "url": "https://github.com/NiKrause/relay-button/issues"
45
45
  },
46
46
  "dependencies": {
47
- "@le-space/browser": "0.6.36",
48
- "@le-space/core": "0.6.36",
47
+ "@le-space/browser": "0.6.38",
48
+ "@le-space/core": "0.6.38",
49
49
  "viem": "^2.53.1"
50
50
  },
51
51
  "peerDependencies": {
package/react/index.d.ts CHANGED
@@ -147,6 +147,15 @@ interface RootfsManifest {
147
147
  version: string;
148
148
  rootfsInstallStrategy?: 'thin' | 'prebaked' | string;
149
149
  requiresBootstrapNetwork?: boolean;
150
+ /**
151
+ * When true, the guest fetches its own bootstrap configuration from the
152
+ * Aleph aggregate (using the deployment token embedded in its SSH key)
153
+ * instead of the browser pushing it to the guest's plain-HTTP setup
154
+ * endpoint. Required to deploy from an HTTPS origin at all: a HTTPS page
155
+ * cannot call `http://<vm-ip>:<port>/configure` (mixed content).
156
+ * Images that predate the guest-side fetch must leave this unset.
157
+ */
158
+ supportsBootstrapConfigAggregate?: boolean;
150
159
  bootstrapSummary?: string;
151
160
  requiredPortForwards?: RootfsRequiredPortForward[];
152
161
  rootfsItemHash: string;
package/react/index.js CHANGED
@@ -43,7 +43,7 @@ var RECENT_INSTANCE_RUNTIME_GRACE_MS = 10 * 60 * 1e3;
43
43
  var DEPLOYMENT_PENDING_WARNING_MS = 3 * 60 * 1e3;
44
44
 
45
45
  // src/shared/package-version.ts
46
- var UI_PACKAGE_VERSION = "0.6.36";
46
+ var UI_PACKAGE_VERSION = "0.6.38";
47
47
 
48
48
  // src/shared/format.ts
49
49
  function shortHash(value, head = 8, tail = 6) {
@@ -2343,7 +2343,6 @@ async function configureOrbitdbRelaySetup2(args) {
2343
2343
  quic_port: args.quicPort ?? void 0,
2344
2344
  bootstrap_publisher_private_key: args.bootstrapPublisherPrivateKey ?? void 0,
2345
2345
  bootstrap_publisher_libp2p_identity_hex: args.bootstrapPublisherLibp2pIdentityHex ?? void 0,
2346
- bootstrap_owner_private_key: args.bootstrapOwnerPrivateKey ?? void 0,
2347
2346
  bootstrap_owner_authorization_b64: args.bootstrapOwnerAuthorizationBase64 ?? void 0,
2348
2347
  bootstrap_registration_id: args.bootstrapRegistrationId ?? void 0,
2349
2348
  no_start: args.noStart === true ? true : void 0
@@ -3924,6 +3923,10 @@ function deploymentProfileForManifest(manifest) {
3924
3923
  if (manifest?.profile === "ucan-store") return "ucan-store";
3925
3924
  return null;
3926
3925
  }
3926
+ function usesBootstrapConfigAggregate(manifest) {
3927
+ if (deploymentProfileForManifest(manifest) === "uc-go-peer") return true;
3928
+ return manifest?.supportsBootstrapConfigAggregate === true;
3929
+ }
3927
3930
  function bootstrapRelayProfileForManifest(manifest) {
3928
3931
  const profile = deploymentProfileForManifest(manifest);
3929
3932
  if (profile === "uc-go-peer" || profile === "orbitdb-relay") {
@@ -4348,7 +4351,12 @@ var SponsorRelayController = class {
4348
4351
  );
4349
4352
  }
4350
4353
  let bootstrapSignalRelayMetadata = null;
4351
- if (profile === "orbitdb-relay") {
4354
+ if (profile === "orbitdb-relay" && !usesBootstrapConfigAggregate(this.state.manifest)) {
4355
+ if (globalThis.location?.protocol === "https:") {
4356
+ throw new Error(
4357
+ `This rootfs image requires the browser to configure the guest over plain HTTP (http://${runtimeHostIpv4}:${setupPort}/configure), which a page served over HTTPS cannot do (mixed content). Deploy from an HTTP origin, or use a rootfs image that supports the Aleph bootstrap config handoff (manifest: supportsBootstrapConfigAggregate).`
4358
+ );
4359
+ }
4352
4360
  this.emitProgress({
4353
4361
  stage: "deployment-confirmed",
4354
4362
  label: "Configuring relay",
@@ -4537,7 +4545,13 @@ var SponsorRelayController = class {
4537
4545
  instanceItemHash: args.itemHash,
4538
4546
  fetch: asJsonFetch,
4539
4547
  apiHost: this.client.apiHost,
4540
- attempts: 40,
4548
+ // The guest publishes this signal only after its describe step has a
4549
+ // browser-dialable address, which waits on AutoTLS for up to ~240 s.
4550
+ // Wait comfortably longer than that (100 × 3 s = 300 s) so the complete
4551
+ // signal arrives instead of timing out — a timeout here drops into the
4552
+ // recovery path, which used to poll the guest over plain HTTP (mixed
4553
+ // content on an HTTPS origin).
4554
+ attempts: 100,
4541
4555
  delayMs: 3e3
4542
4556
  });
4543
4557
  this.trace("deploy:bootstrap-config-signal-visible", {
@@ -4589,6 +4603,12 @@ var SponsorRelayController = class {
4589
4603
  browserBootstrapMultiaddrCount: relayMetadata.browserBootstrapMultiaddrs.length
4590
4604
  });
4591
4605
  } else {
4606
+ const canReadMetadataSecurely = profile === "uc-go-peer" && Boolean(runtime.proxyUrl);
4607
+ if (usesBootstrapConfigAggregate(this.state.manifest) && !canReadMetadataSecurely) {
4608
+ throw new Error(
4609
+ "The relay applied its bootstrap config but the acknowledgement did not carry its final multiaddrs, and this image exposes no HTTPS metadata endpoint. Reading them over plain HTTP would be blocked as mixed content on an HTTPS origin, so the deployment cannot be completed."
4610
+ );
4611
+ }
4592
4612
  this.emitProgress({
4593
4613
  stage: "publishing-bootstrap",
4594
4614
  label: "Waiting for secure relay metadata",
@@ -4600,7 +4620,7 @@ var SponsorRelayController = class {
4600
4620
  relayMetadata = await fetchRelayMetadataForRuntime({
4601
4621
  runtime,
4602
4622
  fetch: (url, init) => fetch(url, init),
4603
- preferSecureMetadata: profile === "uc-go-peer" && Boolean(runtime.proxyUrl),
4623
+ preferSecureMetadata: canReadMetadataSecurely,
4604
4624
  attempts: 80,
4605
4625
  delayMs: 3e3,
4606
4626
  timeoutMs: 24e4,
@@ -5449,7 +5469,7 @@ var SponsorRelayController = class {
5449
5469
  try {
5450
5470
  const profile = deploymentProfileForManifest(this.state.manifest);
5451
5471
  attemptProfile = profile;
5452
- const sshPublicKey = profile === "uc-go-peer" ? appendDeploymentTokenToSshPublicKey(
5472
+ const sshPublicKey = usesBootstrapConfigAggregate(this.state.manifest) ? appendDeploymentTokenToSshPublicKey(
5453
5473
  this.state.sshPublicKey.trim(),
5454
5474
  this.state.wallet.address,
5455
5475
  attemptDeploymentToken = createDeploymentToken()
@@ -5702,11 +5722,13 @@ var SponsorRelayController = class {
5702
5722
  crnListUrl: this.props.crnListUrl,
5703
5723
  requirePublicGuestIpv6ForProxy: true
5704
5724
  });
5705
- if (latestRuntime.diagnostics?.state === "ready") {
5725
+ const canReconcileMetadataSecurely = attemptProfile === "uc-go-peer" && Boolean(latestRuntime.proxyUrl);
5726
+ const mayReadMetadata = canReconcileMetadataSecurely || !usesBootstrapConfigAggregate(this.state.manifest);
5727
+ if (latestRuntime.diagnostics?.state === "ready" && mayReadMetadata) {
5706
5728
  const reconciledRelayMetadata = await fetchRelayMetadataForRuntime({
5707
5729
  runtime: latestRuntime,
5708
5730
  fetch: (url, init) => fetch(url, init),
5709
- preferSecureMetadata: attemptProfile === "uc-go-peer" && Boolean(latestRuntime.proxyUrl),
5731
+ preferSecureMetadata: canReconcileMetadataSecurely,
5710
5732
  attempts: 3,
5711
5733
  delayMs: 1e3,
5712
5734
  timeoutMs: 15e3
package/shared/index.d.ts CHANGED
@@ -145,6 +145,15 @@ interface RootfsManifest {
145
145
  version: string;
146
146
  rootfsInstallStrategy?: 'thin' | 'prebaked' | string;
147
147
  requiresBootstrapNetwork?: boolean;
148
+ /**
149
+ * When true, the guest fetches its own bootstrap configuration from the
150
+ * Aleph aggregate (using the deployment token embedded in its SSH key)
151
+ * instead of the browser pushing it to the guest's plain-HTTP setup
152
+ * endpoint. Required to deploy from an HTTPS origin at all: a HTTPS page
153
+ * cannot call `http://<vm-ip>:<port>/configure` (mixed content).
154
+ * Images that predate the guest-side fetch must leave this unset.
155
+ */
156
+ supportsBootstrapConfigAggregate?: boolean;
148
157
  bootstrapSummary?: string;
149
158
  requiredPortForwards?: RootfsRequiredPortForward$1[];
150
159
  rootfsItemHash: string;
@@ -332,7 +341,7 @@ declare const STALE_INSTANCE_ALLOCATION_COOLDOWN_MS: number;
332
341
  declare const RECENT_INSTANCE_RUNTIME_GRACE_MS: number;
333
342
  declare const DEPLOYMENT_PENDING_WARNING_MS: number;
334
343
 
335
- declare const UI_PACKAGE_VERSION = "0.6.36";
344
+ declare const UI_PACKAGE_VERSION = "0.6.38";
336
345
 
337
346
  interface RootfsRequiredPortForward {
338
347
  port: number;
package/shared/index.js CHANGED
@@ -42,7 +42,7 @@ var RECENT_INSTANCE_RUNTIME_GRACE_MS = 10 * 60 * 1e3;
42
42
  var DEPLOYMENT_PENDING_WARNING_MS = 3 * 60 * 1e3;
43
43
 
44
44
  // src/shared/package-version.ts
45
- var UI_PACKAGE_VERSION = "0.6.36";
45
+ var UI_PACKAGE_VERSION = "0.6.38";
46
46
 
47
47
  // src/shared/format.ts
48
48
  function shortHash(value, head = 8, tail = 6) {
@@ -2342,7 +2342,6 @@ async function configureOrbitdbRelaySetup2(args) {
2342
2342
  quic_port: args.quicPort ?? void 0,
2343
2343
  bootstrap_publisher_private_key: args.bootstrapPublisherPrivateKey ?? void 0,
2344
2344
  bootstrap_publisher_libp2p_identity_hex: args.bootstrapPublisherLibp2pIdentityHex ?? void 0,
2345
- bootstrap_owner_private_key: args.bootstrapOwnerPrivateKey ?? void 0,
2346
2345
  bootstrap_owner_authorization_b64: args.bootstrapOwnerAuthorizationBase64 ?? void 0,
2347
2346
  bootstrap_registration_id: args.bootstrapRegistrationId ?? void 0,
2348
2347
  no_start: args.noStart === true ? true : void 0
@@ -3923,6 +3922,10 @@ function deploymentProfileForManifest(manifest) {
3923
3922
  if (manifest?.profile === "ucan-store") return "ucan-store";
3924
3923
  return null;
3925
3924
  }
3925
+ function usesBootstrapConfigAggregate(manifest) {
3926
+ if (deploymentProfileForManifest(manifest) === "uc-go-peer") return true;
3927
+ return manifest?.supportsBootstrapConfigAggregate === true;
3928
+ }
3926
3929
  function bootstrapRelayProfileForManifest(manifest) {
3927
3930
  const profile = deploymentProfileForManifest(manifest);
3928
3931
  if (profile === "uc-go-peer" || profile === "orbitdb-relay") {
@@ -4347,7 +4350,12 @@ var SponsorRelayController = class {
4347
4350
  );
4348
4351
  }
4349
4352
  let bootstrapSignalRelayMetadata = null;
4350
- if (profile === "orbitdb-relay") {
4353
+ if (profile === "orbitdb-relay" && !usesBootstrapConfigAggregate(this.state.manifest)) {
4354
+ if (globalThis.location?.protocol === "https:") {
4355
+ throw new Error(
4356
+ `This rootfs image requires the browser to configure the guest over plain HTTP (http://${runtimeHostIpv4}:${setupPort}/configure), which a page served over HTTPS cannot do (mixed content). Deploy from an HTTP origin, or use a rootfs image that supports the Aleph bootstrap config handoff (manifest: supportsBootstrapConfigAggregate).`
4357
+ );
4358
+ }
4351
4359
  this.emitProgress({
4352
4360
  stage: "deployment-confirmed",
4353
4361
  label: "Configuring relay",
@@ -4536,7 +4544,13 @@ var SponsorRelayController = class {
4536
4544
  instanceItemHash: args.itemHash,
4537
4545
  fetch: asJsonFetch,
4538
4546
  apiHost: this.client.apiHost,
4539
- attempts: 40,
4547
+ // The guest publishes this signal only after its describe step has a
4548
+ // browser-dialable address, which waits on AutoTLS for up to ~240 s.
4549
+ // Wait comfortably longer than that (100 × 3 s = 300 s) so the complete
4550
+ // signal arrives instead of timing out — a timeout here drops into the
4551
+ // recovery path, which used to poll the guest over plain HTTP (mixed
4552
+ // content on an HTTPS origin).
4553
+ attempts: 100,
4540
4554
  delayMs: 3e3
4541
4555
  });
4542
4556
  this.trace("deploy:bootstrap-config-signal-visible", {
@@ -4588,6 +4602,12 @@ var SponsorRelayController = class {
4588
4602
  browserBootstrapMultiaddrCount: relayMetadata.browserBootstrapMultiaddrs.length
4589
4603
  });
4590
4604
  } else {
4605
+ const canReadMetadataSecurely = profile === "uc-go-peer" && Boolean(runtime.proxyUrl);
4606
+ if (usesBootstrapConfigAggregate(this.state.manifest) && !canReadMetadataSecurely) {
4607
+ throw new Error(
4608
+ "The relay applied its bootstrap config but the acknowledgement did not carry its final multiaddrs, and this image exposes no HTTPS metadata endpoint. Reading them over plain HTTP would be blocked as mixed content on an HTTPS origin, so the deployment cannot be completed."
4609
+ );
4610
+ }
4591
4611
  this.emitProgress({
4592
4612
  stage: "publishing-bootstrap",
4593
4613
  label: "Waiting for secure relay metadata",
@@ -4599,7 +4619,7 @@ var SponsorRelayController = class {
4599
4619
  relayMetadata = await fetchRelayMetadataForRuntime({
4600
4620
  runtime,
4601
4621
  fetch: (url, init) => fetch(url, init),
4602
- preferSecureMetadata: profile === "uc-go-peer" && Boolean(runtime.proxyUrl),
4622
+ preferSecureMetadata: canReadMetadataSecurely,
4603
4623
  attempts: 80,
4604
4624
  delayMs: 3e3,
4605
4625
  timeoutMs: 24e4,
@@ -5448,7 +5468,7 @@ var SponsorRelayController = class {
5448
5468
  try {
5449
5469
  const profile = deploymentProfileForManifest(this.state.manifest);
5450
5470
  attemptProfile = profile;
5451
- const sshPublicKey = profile === "uc-go-peer" ? appendDeploymentTokenToSshPublicKey(
5471
+ const sshPublicKey = usesBootstrapConfigAggregate(this.state.manifest) ? appendDeploymentTokenToSshPublicKey(
5452
5472
  this.state.sshPublicKey.trim(),
5453
5473
  this.state.wallet.address,
5454
5474
  attemptDeploymentToken = createDeploymentToken()
@@ -5701,11 +5721,13 @@ var SponsorRelayController = class {
5701
5721
  crnListUrl: this.props.crnListUrl,
5702
5722
  requirePublicGuestIpv6ForProxy: true
5703
5723
  });
5704
- if (latestRuntime.diagnostics?.state === "ready") {
5724
+ const canReconcileMetadataSecurely = attemptProfile === "uc-go-peer" && Boolean(latestRuntime.proxyUrl);
5725
+ const mayReadMetadata = canReconcileMetadataSecurely || !usesBootstrapConfigAggregate(this.state.manifest);
5726
+ if (latestRuntime.diagnostics?.state === "ready" && mayReadMetadata) {
5705
5727
  const reconciledRelayMetadata = await fetchRelayMetadataForRuntime({
5706
5728
  runtime: latestRuntime,
5707
5729
  fetch: (url, init) => fetch(url, init),
5708
- preferSecureMetadata: attemptProfile === "uc-go-peer" && Boolean(latestRuntime.proxyUrl),
5730
+ preferSecureMetadata: canReconcileMetadataSecurely,
5709
5731
  attempts: 3,
5710
5732
  delayMs: 1e3,
5711
5733
  timeoutMs: 15e3