@le-space/ui 0.6.24 → 0.6.25

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/README.md CHANGED
@@ -4,7 +4,7 @@ Floating Aleph relay deployment UI components for Svelte and React.
4
4
 
5
5
  Primary goals:
6
6
 
7
- - Svelte-first floating `Sponsor Relay` panel
7
+ - Svelte-first floating `Relay Button` panel
8
8
  - lightweight React wrapper
9
9
  - shared controller and browser-safe Aleph helpers
10
10
  - minimal host configuration beyond a rootfs manifest URL
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@le-space/ui",
3
- "version": "0.6.24",
4
- "description": "Floating Aleph sponsor relay UI components for Svelte and React.",
3
+ "version": "0.6.25",
4
+ "description": "Floating Aleph Relay Button UI components for Svelte and React.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "files": [
@@ -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.24",
48
- "@le-space/core": "0.6.24",
47
+ "@le-space/browser": "0.6.25",
48
+ "@le-space/core": "0.6.25",
49
49
  "viem": "^2.53.1"
50
50
  },
51
51
  "peerDependencies": {
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.24";
46
+ var UI_PACKAGE_VERSION = "0.6.25";
47
47
 
48
48
  // src/shared/format.ts
49
49
  function shortHash(value, head = 8, tail = 6) {
@@ -2486,8 +2486,7 @@ import { keccak256, recoverMessageAddress, stringToHex } from "viem";
2486
2486
  var DEFAULT_ALEPH_API_HOST3 = "https://api.aleph.im";
2487
2487
  var DEFAULT_ALEPH_BOOTSTRAP_CHANNEL = "simple-todo";
2488
2488
  var DEFAULT_ALEPH_BOOTSTRAP_REF = "simple-todo-bootstrap";
2489
- var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap";
2490
- var DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE = "relay-bootstrap-v2";
2489
+ var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap-v2";
2491
2490
  var DEFAULT_BOOTSTRAP_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
2492
2491
  var DEFAULT_BOOTSTRAP_PAGINATION = 50;
2493
2492
  var DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT = 3;
@@ -2521,9 +2520,6 @@ function serializeRelayProofPayload(payload) {
2521
2520
  function relayBootstrapMultiaddrsHash(addrs) {
2522
2521
  return keccak256(stringToHex(JSON.stringify(dedupeMultiaddrs(addrs))));
2523
2522
  }
2524
- function compactPostType(postType) {
2525
- return (postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE) === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2526
- }
2527
2523
  function browserMultiaddrPreference(addr) {
2528
2524
  const normalized = addr.toLowerCase();
2529
2525
  if (normalized.includes("/tcp/443/tls/ws/")) return 0;
@@ -2753,8 +2749,6 @@ function normalizeRelayBootstrapPostRecord(value) {
2753
2749
  function buildRelayBootstrapPostContent(args) {
2754
2750
  const now = args.now ?? Date.now() / 1e3;
2755
2751
  const updatedAt = args.now ?? Date.now();
2756
- const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE;
2757
- const compact = args.compact ?? compactPostType(postType);
2758
2752
  const fullMultiaddrs = filterPublicMultiaddrs(args.multiaddrs);
2759
2753
  const fullBrowserMultiaddrs = args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
2760
2754
  browserDialableOnly: true
@@ -2764,13 +2758,13 @@ function buildRelayBootstrapPostContent(args) {
2764
2758
  args.compactMultiaddrLimit
2765
2759
  );
2766
2760
  return {
2767
- type: postType,
2761
+ type: DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE,
2768
2762
  address: args.sender,
2769
2763
  ...args.ref ? { ref: args.ref } : {},
2770
2764
  content: {
2771
2765
  peerId: args.peerId,
2772
- multiaddrs: compact ? compactMultiaddrs : fullMultiaddrs,
2773
- browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
2766
+ multiaddrs: compactMultiaddrs,
2767
+ browserMultiaddrs: void 0,
2774
2768
  registrationId: args.registrationId,
2775
2769
  profile: args.profile,
2776
2770
  version: args.version,
@@ -2793,14 +2787,12 @@ async function createRelayBootstrapPost(args) {
2793
2787
  browserMultiaddrs: args.browserMultiaddrs,
2794
2788
  registrationId: args.registrationId,
2795
2789
  ref: args.ref ?? DEFAULT_ALEPH_BOOTSTRAP_REF,
2796
- postType: args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE,
2797
2790
  profile: args.profile,
2798
2791
  version: args.version,
2799
2792
  ownerAddress: args.ownerAddress,
2800
2793
  publisherAddress: args.publisherAddress,
2801
2794
  authorization: args.authorization,
2802
2795
  relayProof: args.relayProof,
2803
- compact: args.compact,
2804
2796
  compactMultiaddrLimit: args.compactMultiaddrLimit,
2805
2797
  now: nowMillis
2806
2798
  });
@@ -2847,12 +2839,11 @@ async function signRelayBootstrapProof(args) {
2847
2839
  fullBrowserMultiaddrs && fullBrowserMultiaddrs.length > 0 ? fullBrowserMultiaddrs : fullMultiaddrs,
2848
2840
  args.compactMultiaddrLimit
2849
2841
  );
2850
- const compact = args.compact ?? false;
2851
2842
  const payload = {
2852
2843
  peerId: args.peerId,
2853
- multiaddrs: compact ? void 0 : fullMultiaddrs,
2854
- browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
2855
- multiaddrsHash: compact ? relayBootstrapMultiaddrsHash(compactMultiaddrs) : void 0,
2844
+ multiaddrs: void 0,
2845
+ browserMultiaddrs: void 0,
2846
+ multiaddrsHash: relayBootstrapMultiaddrsHash(compactMultiaddrs),
2856
2847
  registrationId: args.registrationId,
2857
2848
  profile: args.profile,
2858
2849
  version: args.version,
@@ -2882,10 +2873,7 @@ async function fetchAlephBootstrapPosts(options = {}) {
2882
2873
  options.channel ?? DEFAULT_ALEPH_BOOTSTRAP_CHANNEL
2883
2874
  );
2884
2875
  url.searchParams.set("refs", options.ref ?? DEFAULT_ALEPH_BOOTSTRAP_REF);
2885
- url.searchParams.set(
2886
- "types",
2887
- options.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE
2888
- );
2876
+ url.searchParams.set("types", DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE);
2889
2877
  url.searchParams.set(
2890
2878
  "pagination",
2891
2879
  String(options.pagination ?? DEFAULT_BOOTSTRAP_PAGINATION)
@@ -2899,7 +2887,21 @@ async function fetchAlephBootstrapPosts(options = {}) {
2899
2887
  throw new Error(`Aleph bootstrap post lookup failed: ${response.status}`);
2900
2888
  }
2901
2889
  const payload = await response.json();
2902
- return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null).sort((left, right) => compareRelayBootstrapPostRecency(right, left));
2890
+ const posts = (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null).sort((left, right) => compareRelayBootstrapPostRecency(right, left));
2891
+ posts.forEach(assertSupportedRelayBootstrapPost);
2892
+ return posts;
2893
+ }
2894
+ function assertSupportedRelayBootstrapPost(post) {
2895
+ if (post.type === "relay-bootstrap") {
2896
+ throw new Error(
2897
+ "Legacy relay-bootstrap record encountered. Only relay-bootstrap-v2 is supported."
2898
+ );
2899
+ }
2900
+ if (post.type && post.type !== DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE) {
2901
+ throw new Error(
2902
+ `Unsupported relay bootstrap post type: ${post.type}. Expected ${DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE}.`
2903
+ );
2904
+ }
2903
2905
  }
2904
2906
  function compareRelayBootstrapPostRecency(left, right) {
2905
2907
  const leftUpdatedAt = left.content?.updatedAt ?? 0;
@@ -2921,6 +2923,7 @@ function selectCurrentRelayBootstrapPosts(posts, options = {}) {
2921
2923
  const now = options.now ?? Date.now();
2922
2924
  const selected = /* @__PURE__ */ new Map();
2923
2925
  for (const post of posts) {
2926
+ assertSupportedRelayBootstrapPost(post);
2924
2927
  const content = post.content;
2925
2928
  if (!content) continue;
2926
2929
  if (now - content.updatedAt > maxAgeMs) continue;
@@ -2946,14 +2949,12 @@ async function waitForRelayBootstrapRegistration(args) {
2946
2949
  const expectedSender = args.sender?.trim().toLowerCase() || null;
2947
2950
  const expectedRegistrationId = args.registrationId?.trim() || null;
2948
2951
  const expectedPeerId = args.peerId?.trim() || null;
2949
- const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2950
2952
  const sleepImpl = args.sleep ?? sleep;
2951
2953
  for (let attempt = 0; attempt < attempts; attempt += 1) {
2952
2954
  const posts = await fetchAlephBootstrapPosts({
2953
2955
  apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
2954
2956
  channel: args.channel,
2955
2957
  ref: args.ref,
2956
- postType,
2957
2958
  fetch: args.fetch
2958
2959
  });
2959
2960
  const currentPosts = selectCurrentRelayBootstrapPosts(posts);
@@ -2992,8 +2993,6 @@ async function waitForRelayBootstrapRegistration(args) {
2992
2993
  async function publishRelayBootstrapRegistration(args) {
2993
2994
  const publisherAddress = args.publisherAddress ?? args.sender;
2994
2995
  const ownerAddress = args.ownerAddress;
2995
- const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2996
- const compact = postType === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2997
2996
  let ownerAuthorization = args.ownerAuthorization;
2998
2997
  let relayProof = args.relayProof;
2999
2998
  if (!ownerAuthorization && ownerAddress && args.ownerSigner) {
@@ -3020,7 +3019,6 @@ async function publishRelayBootstrapRegistration(args) {
3020
3019
  profile: args.profile,
3021
3020
  version: args.version,
3022
3021
  updatedAt: args.now ?? Date.now(),
3023
- compact,
3024
3022
  compactMultiaddrLimit: args.compactMultiaddrLimit,
3025
3023
  signer: args.publisherSigner
3026
3024
  });
@@ -3033,14 +3031,12 @@ async function publishRelayBootstrapRegistration(args) {
3033
3031
  registrationId: args.registrationId,
3034
3032
  channel: args.channel,
3035
3033
  ref: args.ref,
3036
- postType,
3037
3034
  profile: args.profile,
3038
3035
  version: args.version,
3039
3036
  ownerAddress,
3040
3037
  publisherAddress,
3041
3038
  authorization: ownerAuthorization,
3042
3039
  relayProof,
3043
- compact,
3044
3040
  compactMultiaddrLimit: args.compactMultiaddrLimit,
3045
3041
  now: args.now,
3046
3042
  hasher: args.hasher
@@ -3063,18 +3059,12 @@ async function publishRelayBootstrapRegistration(args) {
3063
3059
  let forgottenHashes = [];
3064
3060
  let forgetResult;
3065
3061
  if (args.forgetPrevious && args.registrationId) {
3066
- const previousPostTypes = compact ? [postType, DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE] : [postType];
3067
- const previousPosts = (await Promise.all(
3068
- previousPostTypes.map(
3069
- (previousPostType) => fetchAlephBootstrapPosts({
3070
- apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
3071
- channel: args.channel,
3072
- ref: args.ref,
3073
- postType: previousPostType,
3074
- fetch: args.fetch
3075
- })
3076
- )
3077
- )).flat();
3062
+ const previousPosts = await fetchAlephBootstrapPosts({
3063
+ apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
3064
+ channel: args.channel,
3065
+ ref: args.ref,
3066
+ fetch: args.fetch
3067
+ });
3078
3068
  const forgottenHashSet = new Set(
3079
3069
  previousPosts.filter((post) => {
3080
3070
  const hash = post.itemHash ?? post.hash;
@@ -3676,7 +3666,9 @@ function draftUcanStoreBootstrapErrors(args) {
3676
3666
  const errors = [];
3677
3667
  const { input } = args;
3678
3668
  if (!args.operatorAddress) {
3679
- errors.push("Connect MetaMask before configuring the ucan-store bootstrap package.");
3669
+ errors.push(
3670
+ "Connect MetaMask before configuring the ucan-store bootstrap package."
3671
+ );
3680
3672
  }
3681
3673
  if (!input.adminDid.trim().startsWith("did:")) {
3682
3674
  errors.push("Admin DID must be a non-empty DID string.");
@@ -3727,7 +3719,9 @@ function buildUcanStoreBootstrapPackage(args) {
3727
3719
  serviceDid: args.input.serviceDid.trim() || null,
3728
3720
  spaceDid: args.input.spaceDid.trim(),
3729
3721
  rootDelegationProof: args.input.rootDelegationProof.trim(),
3730
- allowedCapabilities: parseAllowedCapabilities(args.input.allowedCapabilities),
3722
+ allowedCapabilities: parseAllowedCapabilities(
3723
+ args.input.allowedCapabilities
3724
+ ),
3731
3725
  defaultUserDelegationExpiration: parseOptionalExpiration(
3732
3726
  args.input.defaultUserDelegationExpiration
3733
3727
  ),
@@ -3766,7 +3760,9 @@ function defaultState(props = {}) {
3766
3760
  instanceName: props.instanceName ?? DEFAULT_INSTANCE_NAME,
3767
3761
  ucanStoreBootstrap: defaultUcanStoreBootstrapInput(props),
3768
3762
  tierId: DEFAULT_TIER_ID,
3769
- showAdvanced: Boolean(props.manifestJson?.trim() || props.sshPublicKey?.trim()),
3763
+ showAdvanced: Boolean(
3764
+ props.manifestJson?.trim() || props.sshPublicKey?.trim()
3765
+ ),
3770
3766
  showInstances: props.showInstances ?? true,
3771
3767
  showPasteManifest: Boolean(props.manifestJson?.trim()),
3772
3768
  busy: {
@@ -4186,7 +4182,9 @@ var SponsorRelayController = class {
4186
4182
  const profile = bootstrapRelayProfileForManifest(this.state.manifest);
4187
4183
  if (!profile && deploymentProfile !== "ucan-store") return;
4188
4184
  if (profile && !this.state.wallet.address) {
4189
- throw new Error("A connected wallet is required to register relay bootstrap addresses.");
4185
+ throw new Error(
4186
+ "A connected wallet is required to register relay bootstrap addresses."
4187
+ );
4190
4188
  }
4191
4189
  const runtimeHostIpv4 = args.runtime.hostIpv4;
4192
4190
  if (!runtimeHostIpv4) {
@@ -4210,7 +4208,9 @@ var SponsorRelayController = class {
4210
4208
  }
4211
4209
  const walletAddress2 = this.state.wallet.address;
4212
4210
  if (!walletAddress2) {
4213
- throw new Error("A connected wallet is required to configure the ucan-store bootstrap package.");
4211
+ throw new Error(
4212
+ "A connected wallet is required to configure the ucan-store bootstrap package."
4213
+ );
4214
4214
  }
4215
4215
  const bootstrapValidation = buildUcanStoreBootstrapPackage({
4216
4216
  input: this.state.ucanStoreBootstrap,
@@ -4325,7 +4325,9 @@ var SponsorRelayController = class {
4325
4325
  if (!profile) return;
4326
4326
  const walletAddress = this.state.wallet.address;
4327
4327
  if (!walletAddress) {
4328
- throw new Error("A connected wallet is required to register relay bootstrap addresses.");
4328
+ throw new Error(
4329
+ "A connected wallet is required to register relay bootstrap addresses."
4330
+ );
4329
4331
  }
4330
4332
  let bootstrapSignalRelayMetadata = null;
4331
4333
  if (profile === "orbitdb-relay") {
@@ -4371,7 +4373,9 @@ var SponsorRelayController = class {
4371
4373
  const tcpPort = mappedPorts2["9091"]?.host ?? 0;
4372
4374
  const wsPort = mappedPorts2["9092"]?.host ?? mappedPorts2["443"]?.host ?? 0;
4373
4375
  if (!tcpPort || !wsPort) {
4374
- throw new Error("OrbitDB relay runtime is missing required mapped TCP/WS ports.");
4376
+ throw new Error(
4377
+ "OrbitDB relay runtime is missing required mapped TCP/WS ports."
4378
+ );
4375
4379
  }
4376
4380
  const configureResult = await configureOrbitdbRelaySetup2({
4377
4381
  hostIpv4: runtimeHostIpv4,
@@ -4394,7 +4398,9 @@ var SponsorRelayController = class {
4394
4398
  }
4395
4399
  } else {
4396
4400
  if (!args.deploymentToken) {
4397
- throw new Error("Missing deployment token for Aleph bootstrap config handoff.");
4401
+ throw new Error(
4402
+ "Missing deployment token for Aleph bootstrap config handoff."
4403
+ );
4398
4404
  }
4399
4405
  if (runtime.proxyUrl && runtime.webAccess?.active !== true) {
4400
4406
  this.emitProgress({
@@ -4620,7 +4626,19 @@ var SponsorRelayController = class {
4620
4626
  });
4621
4627
  return;
4622
4628
  }
4623
- throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
4629
+ throw new Error(
4630
+ "Relay metadata did not include a peer ID and public multiaddrs."
4631
+ );
4632
+ }
4633
+ if (profile === "uc-go-peer") {
4634
+ const browserDialableMultiaddrs = relayMetadata.browserBootstrapMultiaddrs.filter(
4635
+ (multiaddr) => /\/(?:tls\/ws|wss)\/p2p\//.test(multiaddr) || /\/(?:webtransport|webrtc-direct)\//.test(multiaddr) && /\/certhash\//.test(multiaddr)
4636
+ );
4637
+ if (browserDialableMultiaddrs.length === 0) {
4638
+ throw new Error(
4639
+ "Relay metadata did not include a browser-dialable WSS address or a WebTransport/WebRTC Direct address with certhash."
4640
+ );
4641
+ }
4624
4642
  }
4625
4643
  const { peerId } = relayMetadata;
4626
4644
  const registrationId = createRelayBootstrapRegistrationId(
@@ -5172,18 +5190,10 @@ var SponsorRelayController = class {
5172
5190
  const [nextBalance, rawInstances, rawBootstrapPosts] = await Promise.all([
5173
5191
  this.client.fetchBalance(this.state.wallet.address),
5174
5192
  this.state.showInstances ? this.client.fetchInstances(this.state.wallet.address) : Promise.resolve([]),
5175
- bootstrapEnabled ? Promise.all(
5176
- [
5177
- DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE,
5178
- DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE
5179
- ].map(
5180
- (postType) => fetchAlephBootstrapPosts({
5181
- apiHost: this.client.apiHost,
5182
- postType,
5183
- fetch
5184
- }).catch(() => [])
5185
- )
5186
- ).then((pages) => pages.flat()) : Promise.resolve([])
5193
+ bootstrapEnabled ? fetchAlephBootstrapPosts({
5194
+ apiHost: this.client.apiHost,
5195
+ fetch
5196
+ }) : Promise.resolve([])
5187
5197
  ]);
5188
5198
  balance = nextBalance;
5189
5199
  instances = await Promise.all(
@@ -5247,7 +5257,9 @@ var SponsorRelayController = class {
5247
5257
  const activeInstanceHashes = new Set(
5248
5258
  instances.map((entry) => entry.instance.item_hash)
5249
5259
  );
5250
- bootstrapRegistrations = selectCurrentRelayBootstrapPosts(rawBootstrapPosts).filter(
5260
+ bootstrapRegistrations = selectCurrentRelayBootstrapPosts(
5261
+ rawBootstrapPosts
5262
+ ).filter(
5251
5263
  (entry) => relayBootstrapMatchesCurrentWallet(
5252
5264
  entry,
5253
5265
  normalizedWalletAddress,
@@ -5270,7 +5282,9 @@ var SponsorRelayController = class {
5270
5282
  peerId: entry.content.peerId,
5271
5283
  registrationId: entry.content.registrationId,
5272
5284
  multiaddrs: Array.isArray(entry.content.multiaddrs) ? entry.content.multiaddrs : [],
5273
- browserMultiaddrs: Array.isArray(entry.content.browserMultiaddrs) ? entry.content.browserMultiaddrs : [],
5285
+ browserMultiaddrs: Array.isArray(
5286
+ entry.content.browserMultiaddrs
5287
+ ) ? entry.content.browserMultiaddrs : [],
5274
5288
  ownerAddress: typeof entry.content.ownerAddress === "string" ? entry.content.ownerAddress : void 0,
5275
5289
  publisherAddress: typeof entry.content.publisherAddress === "string" ? entry.content.publisherAddress : void 0,
5276
5290
  updatedAt: entry.content.updatedAt
@@ -5391,7 +5405,9 @@ var SponsorRelayController = class {
5391
5405
  ...compatibleCrns2.filter((crn) => crn.hash !== preferredCrnHash)
5392
5406
  ].slice(0, 5);
5393
5407
  if (orderedCrns.length === 0) {
5394
- throw new Error("No compatible CRN is currently available for this tier.");
5408
+ throw new Error(
5409
+ "No compatible CRN is currently available for this tier."
5410
+ );
5395
5411
  }
5396
5412
  const attemptErrors = [];
5397
5413
  let lastError = null;
@@ -5824,7 +5840,7 @@ var SponsorRelayController = class {
5824
5840
  await forgetAlephMessages({
5825
5841
  sender: this.state.wallet.address,
5826
5842
  hashes: [attemptItemHash],
5827
- reason: `Discard failed Sponsor Relay deployment attempt on ${attemptLabel}`,
5843
+ reason: `Discard failed Relay Button deployment attempt on ${attemptLabel}`,
5828
5844
  signer: personalSign,
5829
5845
  hasher: sha256Hex,
5830
5846
  fetch: (url, init) => fetch(url, init).then(async (response) => ({
@@ -5934,7 +5950,7 @@ var SponsorRelayController = class {
5934
5950
  await forgetAlephMessages({
5935
5951
  sender: this.state.wallet.address,
5936
5952
  hashes: hashesToForget,
5937
- reason: linkedRegistrationCount > 0 ? `Deleted instance and ${linkedRegistrationCount} linked relay bootstrap registration${linkedRegistrationCount === 1 ? "" : "s"} from Sponsor Relay panel` : "Deleted from Sponsor Relay panel",
5953
+ reason: linkedRegistrationCount > 0 ? `Deleted instance and ${linkedRegistrationCount} linked relay bootstrap registration${linkedRegistrationCount === 1 ? "" : "s"} from Relay Button panel` : "Deleted from Relay Button panel",
5938
5954
  signer: personalSign,
5939
5955
  hasher: sha256Hex,
5940
5956
  fetch: asJsonFetch,
@@ -6003,7 +6019,7 @@ var SponsorRelayController = class {
6003
6019
  await forgetAlephMessages({
6004
6020
  sender: this.state.wallet.address,
6005
6021
  hashes: [registrationHash],
6006
- reason: "Deleted orphan relay bootstrap registration from Sponsor Relay panel",
6022
+ reason: "Deleted orphan relay bootstrap registration from Relay Button panel",
6007
6023
  signer: personalSign,
6008
6024
  hasher: sha256Hex,
6009
6025
  fetch: asJsonFetch,
@@ -6208,7 +6224,7 @@ function supportsBootstrapUi(state) {
6208
6224
  return stateDeploymentProfile(state) !== "ucan-store";
6209
6225
  }
6210
6226
  function deploymentPanelTitle(state) {
6211
- return stateDeploymentProfile(state) === "ucan-store" ? "Sponsor Service" : "Sponsor Relay";
6227
+ return stateDeploymentProfile(state) === "ucan-store" ? "Sponsor Service" : "Relay Button";
6212
6228
  }
6213
6229
  function deploymentLauncherLabel(state, compactInlineLabel, launcherMode) {
6214
6230
  if (launcherMode === "inline" && compactInlineLabel) {
package/shared/index.d.ts CHANGED
@@ -332,7 +332,7 @@ declare const STALE_INSTANCE_ALLOCATION_COOLDOWN_MS: number;
332
332
  declare const RECENT_INSTANCE_RUNTIME_GRACE_MS: number;
333
333
  declare const DEPLOYMENT_PENDING_WARNING_MS: number;
334
334
 
335
- declare const UI_PACKAGE_VERSION = "0.6.24";
335
+ declare const UI_PACKAGE_VERSION = "0.6.25";
336
336
 
337
337
  interface RootfsRequiredPortForward {
338
338
  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.24";
45
+ var UI_PACKAGE_VERSION = "0.6.25";
46
46
 
47
47
  // src/shared/format.ts
48
48
  function shortHash(value, head = 8, tail = 6) {
@@ -2485,8 +2485,7 @@ import { keccak256, recoverMessageAddress, stringToHex } from "viem";
2485
2485
  var DEFAULT_ALEPH_API_HOST3 = "https://api.aleph.im";
2486
2486
  var DEFAULT_ALEPH_BOOTSTRAP_CHANNEL = "simple-todo";
2487
2487
  var DEFAULT_ALEPH_BOOTSTRAP_REF = "simple-todo-bootstrap";
2488
- var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap";
2489
- var DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE = "relay-bootstrap-v2";
2488
+ var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap-v2";
2490
2489
  var DEFAULT_BOOTSTRAP_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
2491
2490
  var DEFAULT_BOOTSTRAP_PAGINATION = 50;
2492
2491
  var DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT = 3;
@@ -2520,9 +2519,6 @@ function serializeRelayProofPayload(payload) {
2520
2519
  function relayBootstrapMultiaddrsHash(addrs) {
2521
2520
  return keccak256(stringToHex(JSON.stringify(dedupeMultiaddrs(addrs))));
2522
2521
  }
2523
- function compactPostType(postType) {
2524
- return (postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE) === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2525
- }
2526
2522
  function browserMultiaddrPreference(addr) {
2527
2523
  const normalized = addr.toLowerCase();
2528
2524
  if (normalized.includes("/tcp/443/tls/ws/")) return 0;
@@ -2752,8 +2748,6 @@ function normalizeRelayBootstrapPostRecord(value) {
2752
2748
  function buildRelayBootstrapPostContent(args) {
2753
2749
  const now = args.now ?? Date.now() / 1e3;
2754
2750
  const updatedAt = args.now ?? Date.now();
2755
- const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE;
2756
- const compact = args.compact ?? compactPostType(postType);
2757
2751
  const fullMultiaddrs = filterPublicMultiaddrs(args.multiaddrs);
2758
2752
  const fullBrowserMultiaddrs = args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
2759
2753
  browserDialableOnly: true
@@ -2763,13 +2757,13 @@ function buildRelayBootstrapPostContent(args) {
2763
2757
  args.compactMultiaddrLimit
2764
2758
  );
2765
2759
  return {
2766
- type: postType,
2760
+ type: DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE,
2767
2761
  address: args.sender,
2768
2762
  ...args.ref ? { ref: args.ref } : {},
2769
2763
  content: {
2770
2764
  peerId: args.peerId,
2771
- multiaddrs: compact ? compactMultiaddrs : fullMultiaddrs,
2772
- browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
2765
+ multiaddrs: compactMultiaddrs,
2766
+ browserMultiaddrs: void 0,
2773
2767
  registrationId: args.registrationId,
2774
2768
  profile: args.profile,
2775
2769
  version: args.version,
@@ -2792,14 +2786,12 @@ async function createRelayBootstrapPost(args) {
2792
2786
  browserMultiaddrs: args.browserMultiaddrs,
2793
2787
  registrationId: args.registrationId,
2794
2788
  ref: args.ref ?? DEFAULT_ALEPH_BOOTSTRAP_REF,
2795
- postType: args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE,
2796
2789
  profile: args.profile,
2797
2790
  version: args.version,
2798
2791
  ownerAddress: args.ownerAddress,
2799
2792
  publisherAddress: args.publisherAddress,
2800
2793
  authorization: args.authorization,
2801
2794
  relayProof: args.relayProof,
2802
- compact: args.compact,
2803
2795
  compactMultiaddrLimit: args.compactMultiaddrLimit,
2804
2796
  now: nowMillis
2805
2797
  });
@@ -2846,12 +2838,11 @@ async function signRelayBootstrapProof(args) {
2846
2838
  fullBrowserMultiaddrs && fullBrowserMultiaddrs.length > 0 ? fullBrowserMultiaddrs : fullMultiaddrs,
2847
2839
  args.compactMultiaddrLimit
2848
2840
  );
2849
- const compact = args.compact ?? false;
2850
2841
  const payload = {
2851
2842
  peerId: args.peerId,
2852
- multiaddrs: compact ? void 0 : fullMultiaddrs,
2853
- browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
2854
- multiaddrsHash: compact ? relayBootstrapMultiaddrsHash(compactMultiaddrs) : void 0,
2843
+ multiaddrs: void 0,
2844
+ browserMultiaddrs: void 0,
2845
+ multiaddrsHash: relayBootstrapMultiaddrsHash(compactMultiaddrs),
2855
2846
  registrationId: args.registrationId,
2856
2847
  profile: args.profile,
2857
2848
  version: args.version,
@@ -2881,10 +2872,7 @@ async function fetchAlephBootstrapPosts(options = {}) {
2881
2872
  options.channel ?? DEFAULT_ALEPH_BOOTSTRAP_CHANNEL
2882
2873
  );
2883
2874
  url.searchParams.set("refs", options.ref ?? DEFAULT_ALEPH_BOOTSTRAP_REF);
2884
- url.searchParams.set(
2885
- "types",
2886
- options.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE
2887
- );
2875
+ url.searchParams.set("types", DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE);
2888
2876
  url.searchParams.set(
2889
2877
  "pagination",
2890
2878
  String(options.pagination ?? DEFAULT_BOOTSTRAP_PAGINATION)
@@ -2898,7 +2886,21 @@ async function fetchAlephBootstrapPosts(options = {}) {
2898
2886
  throw new Error(`Aleph bootstrap post lookup failed: ${response.status}`);
2899
2887
  }
2900
2888
  const payload = await response.json();
2901
- return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null).sort((left, right) => compareRelayBootstrapPostRecency(right, left));
2889
+ const posts = (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null).sort((left, right) => compareRelayBootstrapPostRecency(right, left));
2890
+ posts.forEach(assertSupportedRelayBootstrapPost);
2891
+ return posts;
2892
+ }
2893
+ function assertSupportedRelayBootstrapPost(post) {
2894
+ if (post.type === "relay-bootstrap") {
2895
+ throw new Error(
2896
+ "Legacy relay-bootstrap record encountered. Only relay-bootstrap-v2 is supported."
2897
+ );
2898
+ }
2899
+ if (post.type && post.type !== DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE) {
2900
+ throw new Error(
2901
+ `Unsupported relay bootstrap post type: ${post.type}. Expected ${DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE}.`
2902
+ );
2903
+ }
2902
2904
  }
2903
2905
  function compareRelayBootstrapPostRecency(left, right) {
2904
2906
  const leftUpdatedAt = left.content?.updatedAt ?? 0;
@@ -2920,6 +2922,7 @@ function selectCurrentRelayBootstrapPosts(posts, options = {}) {
2920
2922
  const now = options.now ?? Date.now();
2921
2923
  const selected = /* @__PURE__ */ new Map();
2922
2924
  for (const post of posts) {
2925
+ assertSupportedRelayBootstrapPost(post);
2923
2926
  const content = post.content;
2924
2927
  if (!content) continue;
2925
2928
  if (now - content.updatedAt > maxAgeMs) continue;
@@ -2945,14 +2948,12 @@ async function waitForRelayBootstrapRegistration(args) {
2945
2948
  const expectedSender = args.sender?.trim().toLowerCase() || null;
2946
2949
  const expectedRegistrationId = args.registrationId?.trim() || null;
2947
2950
  const expectedPeerId = args.peerId?.trim() || null;
2948
- const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2949
2951
  const sleepImpl = args.sleep ?? sleep;
2950
2952
  for (let attempt = 0; attempt < attempts; attempt += 1) {
2951
2953
  const posts = await fetchAlephBootstrapPosts({
2952
2954
  apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
2953
2955
  channel: args.channel,
2954
2956
  ref: args.ref,
2955
- postType,
2956
2957
  fetch: args.fetch
2957
2958
  });
2958
2959
  const currentPosts = selectCurrentRelayBootstrapPosts(posts);
@@ -2991,8 +2992,6 @@ async function waitForRelayBootstrapRegistration(args) {
2991
2992
  async function publishRelayBootstrapRegistration(args) {
2992
2993
  const publisherAddress = args.publisherAddress ?? args.sender;
2993
2994
  const ownerAddress = args.ownerAddress;
2994
- const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2995
- const compact = postType === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
2996
2995
  let ownerAuthorization = args.ownerAuthorization;
2997
2996
  let relayProof = args.relayProof;
2998
2997
  if (!ownerAuthorization && ownerAddress && args.ownerSigner) {
@@ -3019,7 +3018,6 @@ async function publishRelayBootstrapRegistration(args) {
3019
3018
  profile: args.profile,
3020
3019
  version: args.version,
3021
3020
  updatedAt: args.now ?? Date.now(),
3022
- compact,
3023
3021
  compactMultiaddrLimit: args.compactMultiaddrLimit,
3024
3022
  signer: args.publisherSigner
3025
3023
  });
@@ -3032,14 +3030,12 @@ async function publishRelayBootstrapRegistration(args) {
3032
3030
  registrationId: args.registrationId,
3033
3031
  channel: args.channel,
3034
3032
  ref: args.ref,
3035
- postType,
3036
3033
  profile: args.profile,
3037
3034
  version: args.version,
3038
3035
  ownerAddress,
3039
3036
  publisherAddress,
3040
3037
  authorization: ownerAuthorization,
3041
3038
  relayProof,
3042
- compact,
3043
3039
  compactMultiaddrLimit: args.compactMultiaddrLimit,
3044
3040
  now: args.now,
3045
3041
  hasher: args.hasher
@@ -3062,18 +3058,12 @@ async function publishRelayBootstrapRegistration(args) {
3062
3058
  let forgottenHashes = [];
3063
3059
  let forgetResult;
3064
3060
  if (args.forgetPrevious && args.registrationId) {
3065
- const previousPostTypes = compact ? [postType, DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE] : [postType];
3066
- const previousPosts = (await Promise.all(
3067
- previousPostTypes.map(
3068
- (previousPostType) => fetchAlephBootstrapPosts({
3069
- apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
3070
- channel: args.channel,
3071
- ref: args.ref,
3072
- postType: previousPostType,
3073
- fetch: args.fetch
3074
- })
3075
- )
3076
- )).flat();
3061
+ const previousPosts = await fetchAlephBootstrapPosts({
3062
+ apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
3063
+ channel: args.channel,
3064
+ ref: args.ref,
3065
+ fetch: args.fetch
3066
+ });
3077
3067
  const forgottenHashSet = new Set(
3078
3068
  previousPosts.filter((post) => {
3079
3069
  const hash = post.itemHash ?? post.hash;
@@ -3675,7 +3665,9 @@ function draftUcanStoreBootstrapErrors(args) {
3675
3665
  const errors = [];
3676
3666
  const { input } = args;
3677
3667
  if (!args.operatorAddress) {
3678
- errors.push("Connect MetaMask before configuring the ucan-store bootstrap package.");
3668
+ errors.push(
3669
+ "Connect MetaMask before configuring the ucan-store bootstrap package."
3670
+ );
3679
3671
  }
3680
3672
  if (!input.adminDid.trim().startsWith("did:")) {
3681
3673
  errors.push("Admin DID must be a non-empty DID string.");
@@ -3726,7 +3718,9 @@ function buildUcanStoreBootstrapPackage(args) {
3726
3718
  serviceDid: args.input.serviceDid.trim() || null,
3727
3719
  spaceDid: args.input.spaceDid.trim(),
3728
3720
  rootDelegationProof: args.input.rootDelegationProof.trim(),
3729
- allowedCapabilities: parseAllowedCapabilities(args.input.allowedCapabilities),
3721
+ allowedCapabilities: parseAllowedCapabilities(
3722
+ args.input.allowedCapabilities
3723
+ ),
3730
3724
  defaultUserDelegationExpiration: parseOptionalExpiration(
3731
3725
  args.input.defaultUserDelegationExpiration
3732
3726
  ),
@@ -3765,7 +3759,9 @@ function defaultState(props = {}) {
3765
3759
  instanceName: props.instanceName ?? DEFAULT_INSTANCE_NAME,
3766
3760
  ucanStoreBootstrap: defaultUcanStoreBootstrapInput(props),
3767
3761
  tierId: DEFAULT_TIER_ID,
3768
- showAdvanced: Boolean(props.manifestJson?.trim() || props.sshPublicKey?.trim()),
3762
+ showAdvanced: Boolean(
3763
+ props.manifestJson?.trim() || props.sshPublicKey?.trim()
3764
+ ),
3769
3765
  showInstances: props.showInstances ?? true,
3770
3766
  showPasteManifest: Boolean(props.manifestJson?.trim()),
3771
3767
  busy: {
@@ -4185,7 +4181,9 @@ var SponsorRelayController = class {
4185
4181
  const profile = bootstrapRelayProfileForManifest(this.state.manifest);
4186
4182
  if (!profile && deploymentProfile !== "ucan-store") return;
4187
4183
  if (profile && !this.state.wallet.address) {
4188
- throw new Error("A connected wallet is required to register relay bootstrap addresses.");
4184
+ throw new Error(
4185
+ "A connected wallet is required to register relay bootstrap addresses."
4186
+ );
4189
4187
  }
4190
4188
  const runtimeHostIpv4 = args.runtime.hostIpv4;
4191
4189
  if (!runtimeHostIpv4) {
@@ -4209,7 +4207,9 @@ var SponsorRelayController = class {
4209
4207
  }
4210
4208
  const walletAddress2 = this.state.wallet.address;
4211
4209
  if (!walletAddress2) {
4212
- throw new Error("A connected wallet is required to configure the ucan-store bootstrap package.");
4210
+ throw new Error(
4211
+ "A connected wallet is required to configure the ucan-store bootstrap package."
4212
+ );
4213
4213
  }
4214
4214
  const bootstrapValidation = buildUcanStoreBootstrapPackage({
4215
4215
  input: this.state.ucanStoreBootstrap,
@@ -4324,7 +4324,9 @@ var SponsorRelayController = class {
4324
4324
  if (!profile) return;
4325
4325
  const walletAddress = this.state.wallet.address;
4326
4326
  if (!walletAddress) {
4327
- throw new Error("A connected wallet is required to register relay bootstrap addresses.");
4327
+ throw new Error(
4328
+ "A connected wallet is required to register relay bootstrap addresses."
4329
+ );
4328
4330
  }
4329
4331
  let bootstrapSignalRelayMetadata = null;
4330
4332
  if (profile === "orbitdb-relay") {
@@ -4370,7 +4372,9 @@ var SponsorRelayController = class {
4370
4372
  const tcpPort = mappedPorts2["9091"]?.host ?? 0;
4371
4373
  const wsPort = mappedPorts2["9092"]?.host ?? mappedPorts2["443"]?.host ?? 0;
4372
4374
  if (!tcpPort || !wsPort) {
4373
- throw new Error("OrbitDB relay runtime is missing required mapped TCP/WS ports.");
4375
+ throw new Error(
4376
+ "OrbitDB relay runtime is missing required mapped TCP/WS ports."
4377
+ );
4374
4378
  }
4375
4379
  const configureResult = await configureOrbitdbRelaySetup2({
4376
4380
  hostIpv4: runtimeHostIpv4,
@@ -4393,7 +4397,9 @@ var SponsorRelayController = class {
4393
4397
  }
4394
4398
  } else {
4395
4399
  if (!args.deploymentToken) {
4396
- throw new Error("Missing deployment token for Aleph bootstrap config handoff.");
4400
+ throw new Error(
4401
+ "Missing deployment token for Aleph bootstrap config handoff."
4402
+ );
4397
4403
  }
4398
4404
  if (runtime.proxyUrl && runtime.webAccess?.active !== true) {
4399
4405
  this.emitProgress({
@@ -4619,7 +4625,19 @@ var SponsorRelayController = class {
4619
4625
  });
4620
4626
  return;
4621
4627
  }
4622
- throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
4628
+ throw new Error(
4629
+ "Relay metadata did not include a peer ID and public multiaddrs."
4630
+ );
4631
+ }
4632
+ if (profile === "uc-go-peer") {
4633
+ const browserDialableMultiaddrs = relayMetadata.browserBootstrapMultiaddrs.filter(
4634
+ (multiaddr) => /\/(?:tls\/ws|wss)\/p2p\//.test(multiaddr) || /\/(?:webtransport|webrtc-direct)\//.test(multiaddr) && /\/certhash\//.test(multiaddr)
4635
+ );
4636
+ if (browserDialableMultiaddrs.length === 0) {
4637
+ throw new Error(
4638
+ "Relay metadata did not include a browser-dialable WSS address or a WebTransport/WebRTC Direct address with certhash."
4639
+ );
4640
+ }
4623
4641
  }
4624
4642
  const { peerId } = relayMetadata;
4625
4643
  const registrationId = createRelayBootstrapRegistrationId(
@@ -5171,18 +5189,10 @@ var SponsorRelayController = class {
5171
5189
  const [nextBalance, rawInstances, rawBootstrapPosts] = await Promise.all([
5172
5190
  this.client.fetchBalance(this.state.wallet.address),
5173
5191
  this.state.showInstances ? this.client.fetchInstances(this.state.wallet.address) : Promise.resolve([]),
5174
- bootstrapEnabled ? Promise.all(
5175
- [
5176
- DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE,
5177
- DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE
5178
- ].map(
5179
- (postType) => fetchAlephBootstrapPosts({
5180
- apiHost: this.client.apiHost,
5181
- postType,
5182
- fetch
5183
- }).catch(() => [])
5184
- )
5185
- ).then((pages) => pages.flat()) : Promise.resolve([])
5192
+ bootstrapEnabled ? fetchAlephBootstrapPosts({
5193
+ apiHost: this.client.apiHost,
5194
+ fetch
5195
+ }) : Promise.resolve([])
5186
5196
  ]);
5187
5197
  balance = nextBalance;
5188
5198
  instances = await Promise.all(
@@ -5246,7 +5256,9 @@ var SponsorRelayController = class {
5246
5256
  const activeInstanceHashes = new Set(
5247
5257
  instances.map((entry) => entry.instance.item_hash)
5248
5258
  );
5249
- bootstrapRegistrations = selectCurrentRelayBootstrapPosts(rawBootstrapPosts).filter(
5259
+ bootstrapRegistrations = selectCurrentRelayBootstrapPosts(
5260
+ rawBootstrapPosts
5261
+ ).filter(
5250
5262
  (entry) => relayBootstrapMatchesCurrentWallet(
5251
5263
  entry,
5252
5264
  normalizedWalletAddress,
@@ -5269,7 +5281,9 @@ var SponsorRelayController = class {
5269
5281
  peerId: entry.content.peerId,
5270
5282
  registrationId: entry.content.registrationId,
5271
5283
  multiaddrs: Array.isArray(entry.content.multiaddrs) ? entry.content.multiaddrs : [],
5272
- browserMultiaddrs: Array.isArray(entry.content.browserMultiaddrs) ? entry.content.browserMultiaddrs : [],
5284
+ browserMultiaddrs: Array.isArray(
5285
+ entry.content.browserMultiaddrs
5286
+ ) ? entry.content.browserMultiaddrs : [],
5273
5287
  ownerAddress: typeof entry.content.ownerAddress === "string" ? entry.content.ownerAddress : void 0,
5274
5288
  publisherAddress: typeof entry.content.publisherAddress === "string" ? entry.content.publisherAddress : void 0,
5275
5289
  updatedAt: entry.content.updatedAt
@@ -5390,7 +5404,9 @@ var SponsorRelayController = class {
5390
5404
  ...compatibleCrns2.filter((crn) => crn.hash !== preferredCrnHash)
5391
5405
  ].slice(0, 5);
5392
5406
  if (orderedCrns.length === 0) {
5393
- throw new Error("No compatible CRN is currently available for this tier.");
5407
+ throw new Error(
5408
+ "No compatible CRN is currently available for this tier."
5409
+ );
5394
5410
  }
5395
5411
  const attemptErrors = [];
5396
5412
  let lastError = null;
@@ -5823,7 +5839,7 @@ var SponsorRelayController = class {
5823
5839
  await forgetAlephMessages({
5824
5840
  sender: this.state.wallet.address,
5825
5841
  hashes: [attemptItemHash],
5826
- reason: `Discard failed Sponsor Relay deployment attempt on ${attemptLabel}`,
5842
+ reason: `Discard failed Relay Button deployment attempt on ${attemptLabel}`,
5827
5843
  signer: personalSign,
5828
5844
  hasher: sha256Hex,
5829
5845
  fetch: (url, init) => fetch(url, init).then(async (response) => ({
@@ -5933,7 +5949,7 @@ var SponsorRelayController = class {
5933
5949
  await forgetAlephMessages({
5934
5950
  sender: this.state.wallet.address,
5935
5951
  hashes: hashesToForget,
5936
- reason: linkedRegistrationCount > 0 ? `Deleted instance and ${linkedRegistrationCount} linked relay bootstrap registration${linkedRegistrationCount === 1 ? "" : "s"} from Sponsor Relay panel` : "Deleted from Sponsor Relay panel",
5952
+ reason: linkedRegistrationCount > 0 ? `Deleted instance and ${linkedRegistrationCount} linked relay bootstrap registration${linkedRegistrationCount === 1 ? "" : "s"} from Relay Button panel` : "Deleted from Relay Button panel",
5937
5953
  signer: personalSign,
5938
5954
  hasher: sha256Hex,
5939
5955
  fetch: asJsonFetch,
@@ -6002,7 +6018,7 @@ var SponsorRelayController = class {
6002
6018
  await forgetAlephMessages({
6003
6019
  sender: this.state.wallet.address,
6004
6020
  hashes: [registrationHash],
6005
- reason: "Deleted orphan relay bootstrap registration from Sponsor Relay panel",
6021
+ reason: "Deleted orphan relay bootstrap registration from Relay Button panel",
6006
6022
  signer: personalSign,
6007
6023
  hasher: sha256Hex,
6008
6024
  fetch: asJsonFetch,
@@ -51,7 +51,7 @@ export let apiHosts = undefined
51
51
  }
52
52
 
53
53
  function deploymentTitle() {
54
- return deploymentProfile() === 'ucan-store' ? 'Sponsor Service' : 'Sponsor Relay'
54
+ return deploymentProfile() === 'ucan-store' ? 'Service Button' : 'Relay Button'
55
55
  }
56
56
 
57
57
  function deploymentInstanceFallbackLabel() {
@@ -5,7 +5,7 @@
5
5
  </script>
6
6
 
7
7
  <button class={`launcher ${mode} ${open ? 'open' : ''}`} type="button" on:click={onToggle}>
8
- <span>Sponsor Relay</span>
8
+ <span>Relay Button</span>
9
9
  </button>
10
10
 
11
11
  <style>