@le-space/ui 0.3.10 → 0.3.12
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 +3 -3
- package/react/index.js +542 -121
- package/shared/index.d.ts +1 -1
- package/shared/index.js +542 -121
- package/svelte/SponsorRelayFab.svelte +1 -2
package/shared/index.js
CHANGED
|
@@ -38,7 +38,7 @@ var RECENT_INSTANCE_RUNTIME_GRACE_MS = 10 * 60 * 1e3;
|
|
|
38
38
|
var DEPLOYMENT_PENDING_WARNING_MS = 3 * 60 * 1e3;
|
|
39
39
|
|
|
40
40
|
// src/shared/package-version.ts
|
|
41
|
-
var UI_PACKAGE_VERSION = "0.3.
|
|
41
|
+
var UI_PACKAGE_VERSION = "0.3.12";
|
|
42
42
|
|
|
43
43
|
// src/shared/format.ts
|
|
44
44
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -1470,6 +1470,24 @@ function normalizeSshPublicKey(value) {
|
|
|
1470
1470
|
function isValidSshPublicKey(value) {
|
|
1471
1471
|
return SSH_PUBLIC_KEY_PATTERN.test(normalizeSshPublicKey(value));
|
|
1472
1472
|
}
|
|
1473
|
+
function createDeploymentToken() {
|
|
1474
|
+
const randomUuid = globalThis.crypto?.randomUUID?.();
|
|
1475
|
+
if (typeof randomUuid === "string" && randomUuid.trim()) {
|
|
1476
|
+
return randomUuid;
|
|
1477
|
+
}
|
|
1478
|
+
return `deploy-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
1479
|
+
}
|
|
1480
|
+
function appendDeploymentTokenToSshPublicKey(sshPublicKey, ownerAddress, deploymentToken) {
|
|
1481
|
+
const normalized = normalizeSshPublicKey(sshPublicKey);
|
|
1482
|
+
if (!normalized) return normalized;
|
|
1483
|
+
const [algorithm = "", key = ""] = normalized.split(/\s+/, 3);
|
|
1484
|
+
const owner = ownerAddress.trim().toLowerCase();
|
|
1485
|
+
const token = deploymentToken.trim();
|
|
1486
|
+
if (!algorithm || !key || !owner || !token) {
|
|
1487
|
+
return normalized;
|
|
1488
|
+
}
|
|
1489
|
+
return `${algorithm} ${key} aleph-bootstrap-config:${owner}:${token}`;
|
|
1490
|
+
}
|
|
1473
1491
|
function createReleaseMetadata(name, rootfsVersion, deployer = "shared-aleph-tooling") {
|
|
1474
1492
|
return {
|
|
1475
1493
|
name,
|
|
@@ -2008,51 +2026,6 @@ async function waitForSetupEndpoint(args) {
|
|
|
2008
2026
|
}
|
|
2009
2027
|
return result;
|
|
2010
2028
|
}
|
|
2011
|
-
async function configureUcGoPeer(args) {
|
|
2012
|
-
const controller = new AbortController();
|
|
2013
|
-
const timeout = setTimeout(
|
|
2014
|
-
() => controller.abort(),
|
|
2015
|
-
Number(args.timeoutMs ?? 18e4)
|
|
2016
|
-
);
|
|
2017
|
-
const payload = {
|
|
2018
|
-
public_ipv4: args.hostIpv4,
|
|
2019
|
-
public_ipv6: args.publicIpv6 ?? void 0,
|
|
2020
|
-
proxy_url: args.proxyUrl ?? void 0,
|
|
2021
|
-
tcp_port: args.tcpPort ?? void 0,
|
|
2022
|
-
ws_port: args.wsPort ?? void 0,
|
|
2023
|
-
udp_port: args.udpPort ?? void 0,
|
|
2024
|
-
quic_port: args.quicPort ?? void 0,
|
|
2025
|
-
webrtc_port: args.webrtcPort ?? void 0,
|
|
2026
|
-
bootstrap_publisher_private_key: args.bootstrapPublisherPrivateKey ?? void 0,
|
|
2027
|
-
bootstrap_publisher_libp2p_identity_b64: args.bootstrapPublisherLibp2pIdentityBase64 ?? void 0,
|
|
2028
|
-
bootstrap_owner_private_key: args.bootstrapOwnerPrivateKey ?? void 0,
|
|
2029
|
-
bootstrap_owner_authorization_b64: args.bootstrapOwnerAuthorizationBase64 ?? void 0,
|
|
2030
|
-
bootstrap_registration_id: args.bootstrapRegistrationId ?? void 0,
|
|
2031
|
-
no_start: args.noStart === true ? true : void 0
|
|
2032
|
-
};
|
|
2033
|
-
try {
|
|
2034
|
-
const response = await args.fetch(
|
|
2035
|
-
`http://${args.hostIpv4}:${args.setupPort}/configure`,
|
|
2036
|
-
{
|
|
2037
|
-
method: "POST",
|
|
2038
|
-
headers: {
|
|
2039
|
-
"content-type": "application/json"
|
|
2040
|
-
},
|
|
2041
|
-
body: JSON.stringify(payload),
|
|
2042
|
-
signal: controller.signal
|
|
2043
|
-
}
|
|
2044
|
-
);
|
|
2045
|
-
const responsePayload = await response.json().catch(() => null);
|
|
2046
|
-
if (!response.ok) {
|
|
2047
|
-
throw new Error(
|
|
2048
|
-
`Relay setup request failed: ${response.status} ${typeof responsePayload === "string" ? responsePayload : JSON.stringify(responsePayload ?? {})}`
|
|
2049
|
-
);
|
|
2050
|
-
}
|
|
2051
|
-
return responsePayload;
|
|
2052
|
-
} finally {
|
|
2053
|
-
clearTimeout(timeout);
|
|
2054
|
-
}
|
|
2055
|
-
}
|
|
2056
2029
|
async function configureOrbitdbRelaySetup2(args) {
|
|
2057
2030
|
const controller = new AbortController();
|
|
2058
2031
|
const timeout = setTimeout(
|
|
@@ -2111,8 +2084,9 @@ async function fetchUcGoPeerMetadata(args) {
|
|
|
2111
2084
|
Number(args.timeoutMs ?? 18e4)
|
|
2112
2085
|
);
|
|
2113
2086
|
try {
|
|
2087
|
+
const requestUrl = args.metadataUrl && args.metadataUrl.trim() ? args.metadataUrl : `http://${args.hostIpv4}:${args.setupPort}/metadata`;
|
|
2114
2088
|
const response = await args.fetch(
|
|
2115
|
-
|
|
2089
|
+
requestUrl,
|
|
2116
2090
|
{
|
|
2117
2091
|
signal: controller.signal
|
|
2118
2092
|
}
|
|
@@ -2194,6 +2168,9 @@ function asNumber4(value) {
|
|
|
2194
2168
|
function normalizeHost(host) {
|
|
2195
2169
|
return host.trim().toLowerCase();
|
|
2196
2170
|
}
|
|
2171
|
+
function normalizeAddress(address) {
|
|
2172
|
+
return address.trim().toLowerCase();
|
|
2173
|
+
}
|
|
2197
2174
|
function normalizeSignature(signature) {
|
|
2198
2175
|
const trimmed = signature.trim();
|
|
2199
2176
|
return trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
@@ -2495,6 +2472,40 @@ async function fetchAlephBootstrapPosts(options = {}) {
|
|
|
2495
2472
|
const payload = await response.json();
|
|
2496
2473
|
return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null);
|
|
2497
2474
|
}
|
|
2475
|
+
function compareRelayBootstrapPostRecency(left, right) {
|
|
2476
|
+
const leftUpdatedAt = left.content?.updatedAt ?? 0;
|
|
2477
|
+
const rightUpdatedAt = right.content?.updatedAt ?? 0;
|
|
2478
|
+
if (leftUpdatedAt !== rightUpdatedAt) return leftUpdatedAt - rightUpdatedAt;
|
|
2479
|
+
const leftTime = left.time ?? 0;
|
|
2480
|
+
const rightTime = right.time ?? 0;
|
|
2481
|
+
return leftTime - rightTime;
|
|
2482
|
+
}
|
|
2483
|
+
function relayBootstrapRecordIdentity(post) {
|
|
2484
|
+
const content = post.content;
|
|
2485
|
+
if (!content) return null;
|
|
2486
|
+
if (content.registrationId) return `registration:${content.registrationId}`;
|
|
2487
|
+
if (post.address) return `sender:${normalizeAddress(post.address)}`;
|
|
2488
|
+
return content.peerId ? `peer:${content.peerId}` : null;
|
|
2489
|
+
}
|
|
2490
|
+
function selectCurrentRelayBootstrapPosts(posts, options = {}) {
|
|
2491
|
+
const maxAgeMs = options.maxAgeMs ?? DEFAULT_BOOTSTRAP_MAX_AGE_MS;
|
|
2492
|
+
const now = options.now ?? Date.now();
|
|
2493
|
+
const selected = /* @__PURE__ */ new Map();
|
|
2494
|
+
for (const post of posts) {
|
|
2495
|
+
const content = post.content;
|
|
2496
|
+
if (!content) continue;
|
|
2497
|
+
if (now - content.updatedAt > maxAgeMs) continue;
|
|
2498
|
+
const identity = relayBootstrapRecordIdentity(post);
|
|
2499
|
+
if (!identity) continue;
|
|
2500
|
+
const previous = selected.get(identity);
|
|
2501
|
+
if (!previous || compareRelayBootstrapPostRecency(post, previous) > 0) {
|
|
2502
|
+
selected.set(identity, post);
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
return [...selected.values()].sort(
|
|
2506
|
+
(left, right) => compareRelayBootstrapPostRecency(right, left)
|
|
2507
|
+
);
|
|
2508
|
+
}
|
|
2498
2509
|
|
|
2499
2510
|
// ../core/src/bootstrap-registration.ts
|
|
2500
2511
|
async function publishRelayBootstrapRegistration(args) {
|
|
@@ -2601,6 +2612,311 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2601
2612
|
};
|
|
2602
2613
|
}
|
|
2603
2614
|
|
|
2615
|
+
// ../core/src/bootstrap-config.ts
|
|
2616
|
+
var VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY = "vm-bootstrap-config";
|
|
2617
|
+
async function fetchVmBootstrapConfigAggregate(address, options) {
|
|
2618
|
+
const requestUrl = new URL(`/api/v0/aggregates/${address}.json`, options.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2619
|
+
requestUrl.searchParams.set("keys", VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY);
|
|
2620
|
+
const response = await options.fetch(requestUrl.toString(), { cache: "no-cache" });
|
|
2621
|
+
if (response.status === 404) return {};
|
|
2622
|
+
if (!response.ok) {
|
|
2623
|
+
throw new Error(`VM bootstrap config aggregate request failed: ${response.status}`);
|
|
2624
|
+
}
|
|
2625
|
+
const payload = await response.json();
|
|
2626
|
+
const aggregate = payload.data?.[VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY];
|
|
2627
|
+
if (!aggregate || typeof aggregate !== "object" || Array.isArray(aggregate)) return {};
|
|
2628
|
+
return aggregate;
|
|
2629
|
+
}
|
|
2630
|
+
function normalizeVmBootstrapConfigAggregate(aggregate) {
|
|
2631
|
+
if (!aggregate || typeof aggregate !== "object") return {};
|
|
2632
|
+
return Object.fromEntries(
|
|
2633
|
+
Object.entries(aggregate).filter(
|
|
2634
|
+
(entry) => Boolean(entry[1] && typeof entry[1] === "object" && !Array.isArray(entry[1]))
|
|
2635
|
+
)
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
function createVmBootstrapConfigAggregateContent(args) {
|
|
2639
|
+
const content = normalizeVmBootstrapConfigAggregate(args.existingAggregate);
|
|
2640
|
+
content[args.record.deploymentToken] = args.record;
|
|
2641
|
+
return {
|
|
2642
|
+
address: args.sender,
|
|
2643
|
+
key: VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY,
|
|
2644
|
+
content,
|
|
2645
|
+
time: args.now ?? Date.now() / 1e3
|
|
2646
|
+
};
|
|
2647
|
+
}
|
|
2648
|
+
async function createUnsignedVmBootstrapConfigAggregateMessage(args) {
|
|
2649
|
+
const itemContent = JSON.stringify(args.content);
|
|
2650
|
+
const itemHash = await args.hasher(itemContent);
|
|
2651
|
+
return {
|
|
2652
|
+
sender: args.sender,
|
|
2653
|
+
chain: "ETH",
|
|
2654
|
+
type: "AGGREGATE",
|
|
2655
|
+
item_hash: itemHash,
|
|
2656
|
+
item_type: "inline",
|
|
2657
|
+
item_content: itemContent,
|
|
2658
|
+
time: args.now ?? Date.now() / 1e3,
|
|
2659
|
+
channel: args.channel ?? DEFAULT_ALEPH_CHANNEL
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
async function publishVmBootstrapConfigAggregate(args) {
|
|
2663
|
+
const unsignedMessage = await createUnsignedVmBootstrapConfigAggregateMessage({
|
|
2664
|
+
sender: args.sender,
|
|
2665
|
+
content: args.content,
|
|
2666
|
+
hasher: args.hasher,
|
|
2667
|
+
channel: args.channel
|
|
2668
|
+
});
|
|
2669
|
+
const message = await signAlephMessage(unsignedMessage, args.signer);
|
|
2670
|
+
const { response, httpStatus } = await broadcastAlephMessage2(message, {
|
|
2671
|
+
apiHost: args.apiHost,
|
|
2672
|
+
sync: args.sync,
|
|
2673
|
+
fetch: args.fetch
|
|
2674
|
+
});
|
|
2675
|
+
const aggregateStatus = httpStatus >= 200 && httpStatus < 300 ? response.message_status ?? "processed" : "unknown";
|
|
2676
|
+
if (aggregateStatus === "rejected") {
|
|
2677
|
+
throw new Error(`VM bootstrap config aggregate was rejected by Aleph: ${JSON.stringify(response.details ?? response)}`);
|
|
2678
|
+
}
|
|
2679
|
+
return {
|
|
2680
|
+
aggregateItemHash: message.item_hash,
|
|
2681
|
+
aggregateStatus
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
async function publishVmBootstrapConfig(args) {
|
|
2685
|
+
const aggregate = await fetchVmBootstrapConfigAggregate(args.sender, {
|
|
2686
|
+
apiHost: args.apiHost,
|
|
2687
|
+
fetch: args.fetch
|
|
2688
|
+
});
|
|
2689
|
+
const content = createVmBootstrapConfigAggregateContent({
|
|
2690
|
+
sender: args.sender,
|
|
2691
|
+
record: args.record,
|
|
2692
|
+
existingAggregate: aggregate
|
|
2693
|
+
});
|
|
2694
|
+
const result = await publishVmBootstrapConfigAggregate({
|
|
2695
|
+
sender: args.sender,
|
|
2696
|
+
content,
|
|
2697
|
+
signer: args.signer,
|
|
2698
|
+
hasher: args.hasher,
|
|
2699
|
+
fetch: args.fetch,
|
|
2700
|
+
channel: args.channel,
|
|
2701
|
+
apiHost: args.apiHost,
|
|
2702
|
+
sync: args.sync
|
|
2703
|
+
});
|
|
2704
|
+
return {
|
|
2705
|
+
...result,
|
|
2706
|
+
aggregate: content.content
|
|
2707
|
+
};
|
|
2708
|
+
}
|
|
2709
|
+
async function deleteVmBootstrapConfig(args) {
|
|
2710
|
+
const aggregate = await fetchVmBootstrapConfigAggregate(args.sender, {
|
|
2711
|
+
apiHost: args.apiHost,
|
|
2712
|
+
fetch: args.fetch
|
|
2713
|
+
});
|
|
2714
|
+
const content = normalizeVmBootstrapConfigAggregate(aggregate);
|
|
2715
|
+
delete content[args.deploymentToken];
|
|
2716
|
+
const publishResult = await publishVmBootstrapConfigAggregate({
|
|
2717
|
+
sender: args.sender,
|
|
2718
|
+
content: {
|
|
2719
|
+
address: args.sender,
|
|
2720
|
+
key: VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY,
|
|
2721
|
+
content,
|
|
2722
|
+
time: Date.now() / 1e3
|
|
2723
|
+
},
|
|
2724
|
+
signer: args.signer,
|
|
2725
|
+
hasher: args.hasher,
|
|
2726
|
+
fetch: args.fetch,
|
|
2727
|
+
channel: args.channel,
|
|
2728
|
+
apiHost: args.apiHost,
|
|
2729
|
+
sync: args.sync
|
|
2730
|
+
});
|
|
2731
|
+
return {
|
|
2732
|
+
...publishResult,
|
|
2733
|
+
aggregate: content
|
|
2734
|
+
};
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
// ../core/src/bootstrap-reconcile.ts
|
|
2738
|
+
function createRelayBootstrapRegistrationId(profile, instanceName, itemHash) {
|
|
2739
|
+
const normalizedName = String(instanceName ?? "").trim();
|
|
2740
|
+
const normalizedHash = String(itemHash ?? "").trim();
|
|
2741
|
+
if (!normalizedHash) {
|
|
2742
|
+
return `relay:${profile}:${normalizedName || "instance"}`;
|
|
2743
|
+
}
|
|
2744
|
+
return `relay:${profile}:${normalizedName || normalizedHash}:${normalizedHash}`;
|
|
2745
|
+
}
|
|
2746
|
+
function secureBootstrapMetadataUrl(proxyUrl) {
|
|
2747
|
+
const normalized = String(proxyUrl ?? "").trim();
|
|
2748
|
+
if (!normalized) return null;
|
|
2749
|
+
try {
|
|
2750
|
+
return new URL("/bootstrap/metadata", normalized).toString();
|
|
2751
|
+
} catch {
|
|
2752
|
+
return null;
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
function extractRelayMetadata(payload) {
|
|
2756
|
+
const metadata = payload && typeof payload === "object" && payload.metadata && typeof payload.metadata === "object" ? payload.metadata : null;
|
|
2757
|
+
const peerId = typeof metadata?.peer_id === "string" ? metadata.peer_id : null;
|
|
2758
|
+
const probeMultiaddrs = Array.isArray(metadata?.probe_multiaddrs) ? metadata.probe_multiaddrs.filter((entry) => typeof entry === "string") : [];
|
|
2759
|
+
const browserBootstrapMultiaddrs = Array.isArray(metadata?.browser_bootstrap_multiaddrs) ? metadata.browser_bootstrap_multiaddrs.filter((entry) => typeof entry === "string") : [];
|
|
2760
|
+
if (!peerId || probeMultiaddrs.length === 0) return null;
|
|
2761
|
+
return {
|
|
2762
|
+
peerId,
|
|
2763
|
+
probeMultiaddrs,
|
|
2764
|
+
browserBootstrapMultiaddrs
|
|
2765
|
+
};
|
|
2766
|
+
}
|
|
2767
|
+
async function fetchOwnerInstances(address, options) {
|
|
2768
|
+
const url = new URL("/api/v0/messages.json", options.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2769
|
+
url.searchParams.set("msgTypes", "INSTANCE");
|
|
2770
|
+
url.searchParams.set("addresses", address);
|
|
2771
|
+
url.searchParams.set("message_statuses", "processed,pending,rejected,removing");
|
|
2772
|
+
url.searchParams.set("pagination", "100");
|
|
2773
|
+
url.searchParams.set("page", "1");
|
|
2774
|
+
url.searchParams.set("sortOrder", "-1");
|
|
2775
|
+
const response = await options.fetch(url.toString(), { cache: "no-cache" });
|
|
2776
|
+
if (!response.ok) {
|
|
2777
|
+
throw new Error(`Instance list request failed: ${response.status}`);
|
|
2778
|
+
}
|
|
2779
|
+
const payload = await response.json();
|
|
2780
|
+
return (payload.messages ?? []).map((message) => ({
|
|
2781
|
+
...message,
|
|
2782
|
+
status: typeof message.status === "string" && message.status.trim() ? message.status : message.confirmed ? "processed" : "pending"
|
|
2783
|
+
}));
|
|
2784
|
+
}
|
|
2785
|
+
async function fetchRelayMetadataForRuntime(args) {
|
|
2786
|
+
const setupPort = args.runtime.mappedPorts?.["80"]?.host ?? 80;
|
|
2787
|
+
const metadataUrl = args.preferSecureMetadata ? secureBootstrapMetadataUrl(args.runtime.proxyUrl) : null;
|
|
2788
|
+
if (args.preferSecureMetadata && !metadataUrl) {
|
|
2789
|
+
return null;
|
|
2790
|
+
}
|
|
2791
|
+
const payload = await fetchUcGoPeerMetadata({
|
|
2792
|
+
hostIpv4: args.runtime.hostIpv4 ?? "",
|
|
2793
|
+
setupPort,
|
|
2794
|
+
metadataUrl,
|
|
2795
|
+
fetch: args.fetch,
|
|
2796
|
+
attempts: args.attempts,
|
|
2797
|
+
delayMs: args.delayMs,
|
|
2798
|
+
timeoutMs: args.timeoutMs
|
|
2799
|
+
}).catch(() => null);
|
|
2800
|
+
return extractRelayMetadata(payload);
|
|
2801
|
+
}
|
|
2802
|
+
async function reconcileOwnerRelayBootstrapRegistrations(args) {
|
|
2803
|
+
const result = {
|
|
2804
|
+
refreshedRegistrations: [],
|
|
2805
|
+
forgottenHashes: [],
|
|
2806
|
+
skippedInstanceHashes: [],
|
|
2807
|
+
errors: []
|
|
2808
|
+
};
|
|
2809
|
+
const liveRegistrationIds = /* @__PURE__ */ new Set();
|
|
2810
|
+
if (args.current?.registrationId) {
|
|
2811
|
+
liveRegistrationIds.add(args.current.registrationId);
|
|
2812
|
+
result.refreshedRegistrations.push(args.current.registrationId);
|
|
2813
|
+
}
|
|
2814
|
+
const instances = await fetchOwnerInstances(args.instanceOwnerAddress, {
|
|
2815
|
+
apiHost: args.apiHost,
|
|
2816
|
+
fetch: args.fetch
|
|
2817
|
+
});
|
|
2818
|
+
const processedInstances = instances.filter((instance) => {
|
|
2819
|
+
const status = String(instance.status ?? "").trim().toLowerCase();
|
|
2820
|
+
return status === "processed";
|
|
2821
|
+
});
|
|
2822
|
+
for (const instance of processedInstances) {
|
|
2823
|
+
if (instance.item_hash === args.current?.itemHash) continue;
|
|
2824
|
+
const registrationId = createRelayBootstrapRegistrationId(
|
|
2825
|
+
args.profile,
|
|
2826
|
+
instance.content?.metadata?.name,
|
|
2827
|
+
instance.item_hash
|
|
2828
|
+
);
|
|
2829
|
+
try {
|
|
2830
|
+
const runtime = await fetchVmRuntime({
|
|
2831
|
+
itemHash: instance.item_hash,
|
|
2832
|
+
fetch: args.fetch,
|
|
2833
|
+
crns: args.crns,
|
|
2834
|
+
crnListUrl: args.crnListUrl
|
|
2835
|
+
});
|
|
2836
|
+
if (!runtime.hostIpv4 || Object.keys(runtime.mappedPorts ?? {}).length === 0) {
|
|
2837
|
+
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2838
|
+
continue;
|
|
2839
|
+
}
|
|
2840
|
+
const relayMetadata = await fetchRelayMetadataForRuntime({
|
|
2841
|
+
runtime,
|
|
2842
|
+
fetch: args.fetch,
|
|
2843
|
+
preferSecureMetadata: args.preferSecureMetadata,
|
|
2844
|
+
attempts: 3,
|
|
2845
|
+
delayMs: 1e3,
|
|
2846
|
+
timeoutMs: 1e4
|
|
2847
|
+
});
|
|
2848
|
+
if (!relayMetadata) {
|
|
2849
|
+
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2850
|
+
continue;
|
|
2851
|
+
}
|
|
2852
|
+
liveRegistrationIds.add(registrationId);
|
|
2853
|
+
await publishRelayBootstrapRegistration({
|
|
2854
|
+
sender: args.sender,
|
|
2855
|
+
signer: args.signer,
|
|
2856
|
+
hasher: args.hasher,
|
|
2857
|
+
fetch: args.fetch,
|
|
2858
|
+
apiHost: args.apiHost,
|
|
2859
|
+
channel: args.channel,
|
|
2860
|
+
ref: args.ref,
|
|
2861
|
+
postType: args.postType,
|
|
2862
|
+
peerId: relayMetadata.peerId,
|
|
2863
|
+
multiaddrs: relayMetadata.probeMultiaddrs,
|
|
2864
|
+
browserMultiaddrs: relayMetadata.browserBootstrapMultiaddrs,
|
|
2865
|
+
registrationId,
|
|
2866
|
+
ownerAddress: args.ownerAddress,
|
|
2867
|
+
publisherAddress: args.publisherAddress,
|
|
2868
|
+
ownerSigner: args.ownerSigner,
|
|
2869
|
+
publisherSigner: args.publisherSigner,
|
|
2870
|
+
forgetPrevious: true,
|
|
2871
|
+
profile: args.profile,
|
|
2872
|
+
version: args.version,
|
|
2873
|
+
instanceItemHash: instance.item_hash,
|
|
2874
|
+
sync: true
|
|
2875
|
+
});
|
|
2876
|
+
result.refreshedRegistrations.push(registrationId);
|
|
2877
|
+
} catch (error) {
|
|
2878
|
+
result.errors.push({
|
|
2879
|
+
phase: "publish",
|
|
2880
|
+
itemHash: instance.item_hash,
|
|
2881
|
+
registrationId,
|
|
2882
|
+
message: error instanceof Error ? error.message : String(error)
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
try {
|
|
2887
|
+
const bootstrapPosts = await fetchAlephBootstrapPosts({
|
|
2888
|
+
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2889
|
+
channel: args.channel,
|
|
2890
|
+
ref: args.ref,
|
|
2891
|
+
postType: args.postType,
|
|
2892
|
+
fetch: args.fetch
|
|
2893
|
+
});
|
|
2894
|
+
const currentPosts = selectCurrentRelayBootstrapPosts(bootstrapPosts);
|
|
2895
|
+
const staleHashes = currentPosts.filter(
|
|
2896
|
+
(post) => post.address?.toLowerCase() === args.sender.toLowerCase() && post.content?.profile === args.profile && post.content?.registrationId && !liveRegistrationIds.has(post.content.registrationId)
|
|
2897
|
+
).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean);
|
|
2898
|
+
if (staleHashes.length > 0) {
|
|
2899
|
+
await forgetAlephMessages({
|
|
2900
|
+
sender: args.sender,
|
|
2901
|
+
hashes: staleHashes,
|
|
2902
|
+
reason: `Forget stale ${args.profile} relay bootstrap registrations after owner reconcile`,
|
|
2903
|
+
signer: args.signer,
|
|
2904
|
+
hasher: args.hasher,
|
|
2905
|
+
fetch: args.fetch,
|
|
2906
|
+
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2907
|
+
sync: true
|
|
2908
|
+
});
|
|
2909
|
+
result.forgottenHashes.push(...staleHashes);
|
|
2910
|
+
}
|
|
2911
|
+
} catch (error) {
|
|
2912
|
+
result.errors.push({
|
|
2913
|
+
phase: "forget",
|
|
2914
|
+
message: error instanceof Error ? error.message : String(error)
|
|
2915
|
+
});
|
|
2916
|
+
}
|
|
2917
|
+
return result;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2604
2920
|
// src/shared/events.ts
|
|
2605
2921
|
function createDeploymentProgressEmitter() {
|
|
2606
2922
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -2621,6 +2937,13 @@ function createDeploymentProgressEmitter() {
|
|
|
2621
2937
|
}
|
|
2622
2938
|
|
|
2623
2939
|
// src/shared/controller.ts
|
|
2940
|
+
function asJsonFetch(input, init) {
|
|
2941
|
+
return fetch(input, init).then(async (response) => ({
|
|
2942
|
+
ok: response.ok,
|
|
2943
|
+
status: response.status,
|
|
2944
|
+
json: async () => await response.json()
|
|
2945
|
+
}));
|
|
2946
|
+
}
|
|
2624
2947
|
function isConfirmedRelaySetupResult(value) {
|
|
2625
2948
|
return Boolean(
|
|
2626
2949
|
value && typeof value === "object" && "status" in value && value.status === "configured"
|
|
@@ -3063,36 +3386,36 @@ var SponsorRelayController = class {
|
|
|
3063
3386
|
if (!setupPort) {
|
|
3064
3387
|
throw new Error("Relay runtime did not expose the temporary setup endpoint.");
|
|
3065
3388
|
}
|
|
3066
|
-
this.emitProgress({
|
|
3067
|
-
stage: "deployment-confirmed",
|
|
3068
|
-
label: "Configuring relay",
|
|
3069
|
-
progress: 93,
|
|
3070
|
-
status: "info",
|
|
3071
|
-
itemHash: args.itemHash,
|
|
3072
|
-
detail: "Waiting for the guest setup endpoint before collecting relay metadata."
|
|
3073
|
-
});
|
|
3074
|
-
const setupHealth = await waitForSetupEndpoint({
|
|
3075
|
-
hostIpv4: args.runtime.hostIpv4,
|
|
3076
|
-
setupPort,
|
|
3077
|
-
fetch: (url, init) => fetch(url, init),
|
|
3078
|
-
attempts: 15,
|
|
3079
|
-
delayMs: 4e3,
|
|
3080
|
-
httpTimeoutMs: 1e4
|
|
3081
|
-
});
|
|
3082
|
-
if (!setupHealth.ok) {
|
|
3083
|
-
throw new Error(
|
|
3084
|
-
`Relay setup endpoint did not become reachable at http://${args.runtime.hostIpv4}:${setupPort}/health.`
|
|
3085
|
-
);
|
|
3086
|
-
}
|
|
3087
|
-
this.emitProgress({
|
|
3088
|
-
stage: "deployment-confirmed",
|
|
3089
|
-
label: "Applying relay networking",
|
|
3090
|
-
progress: 94,
|
|
3091
|
-
status: "info",
|
|
3092
|
-
itemHash: args.itemHash,
|
|
3093
|
-
detail: "Publishing the host port mapping into the guest relay configuration."
|
|
3094
|
-
});
|
|
3095
3389
|
if (profile === "orbitdb-relay-pinner") {
|
|
3390
|
+
this.emitProgress({
|
|
3391
|
+
stage: "deployment-confirmed",
|
|
3392
|
+
label: "Configuring relay",
|
|
3393
|
+
progress: 93,
|
|
3394
|
+
status: "info",
|
|
3395
|
+
itemHash: args.itemHash,
|
|
3396
|
+
detail: "Waiting for the guest setup endpoint before collecting relay metadata."
|
|
3397
|
+
});
|
|
3398
|
+
const setupHealth = await waitForSetupEndpoint({
|
|
3399
|
+
hostIpv4: args.runtime.hostIpv4,
|
|
3400
|
+
setupPort,
|
|
3401
|
+
fetch: (url, init) => fetch(url, init),
|
|
3402
|
+
attempts: 15,
|
|
3403
|
+
delayMs: 4e3,
|
|
3404
|
+
httpTimeoutMs: 1e4
|
|
3405
|
+
});
|
|
3406
|
+
if (!setupHealth.ok) {
|
|
3407
|
+
throw new Error(
|
|
3408
|
+
`Relay setup endpoint did not become reachable at http://${args.runtime.hostIpv4}:${setupPort}/health.`
|
|
3409
|
+
);
|
|
3410
|
+
}
|
|
3411
|
+
this.emitProgress({
|
|
3412
|
+
stage: "deployment-confirmed",
|
|
3413
|
+
label: "Applying relay networking",
|
|
3414
|
+
progress: 94,
|
|
3415
|
+
status: "info",
|
|
3416
|
+
itemHash: args.itemHash,
|
|
3417
|
+
detail: "Publishing the host port mapping into the guest relay configuration."
|
|
3418
|
+
});
|
|
3096
3419
|
const tcpPort = mappedPorts2["9091"]?.host ?? 0;
|
|
3097
3420
|
const wsPort = mappedPorts2["9092"]?.host ?? mappedPorts2["443"]?.host ?? 0;
|
|
3098
3421
|
if (!tcpPort || !wsPort) {
|
|
@@ -3118,24 +3441,48 @@ var SponsorRelayController = class {
|
|
|
3118
3441
|
);
|
|
3119
3442
|
}
|
|
3120
3443
|
} else {
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
publicIpv6: args.runtime.ipv6,
|
|
3124
|
-
setupPort,
|
|
3125
|
-
tcpPort: mappedPorts2["9095"]?.host ?? null,
|
|
3126
|
-
wsPort: mappedPorts2["9097"]?.host ?? mappedPorts2["9095"]?.host ?? null,
|
|
3127
|
-
udpPort: mappedPorts2["9095"]?.udp === true ? mappedPorts2["9095"]?.host ?? null : null,
|
|
3128
|
-
quicPort: mappedPorts2["9095"]?.udp === true ? mappedPorts2["9095"]?.host ?? null : null,
|
|
3129
|
-
webrtcPort: mappedPorts2["9095"]?.udp === true ? mappedPorts2["9095"]?.host ?? null : null,
|
|
3130
|
-
proxyUrl: args.runtime.proxyUrl ?? void 0,
|
|
3131
|
-
fetch: (url, init) => fetch(url, init),
|
|
3132
|
-
timeoutMs: 18e4
|
|
3133
|
-
});
|
|
3134
|
-
if (!isConfirmedRelaySetupResult(configureResult)) {
|
|
3135
|
-
throw new Error(
|
|
3136
|
-
`Relay guest configuration could not be confirmed at http://${args.runtime.hostIpv4}:${setupPort}/configure.`
|
|
3137
|
-
);
|
|
3444
|
+
if (!args.deploymentToken) {
|
|
3445
|
+
throw new Error("Missing deployment token for Aleph bootstrap config handoff.");
|
|
3138
3446
|
}
|
|
3447
|
+
this.emitProgress({
|
|
3448
|
+
stage: "deployment-confirmed",
|
|
3449
|
+
label: "Publishing relay config",
|
|
3450
|
+
progress: 94,
|
|
3451
|
+
status: "info",
|
|
3452
|
+
itemHash: args.itemHash,
|
|
3453
|
+
detail: "Publishing runtime networking into the Aleph guest bootstrap config aggregate."
|
|
3454
|
+
});
|
|
3455
|
+
const record = {
|
|
3456
|
+
deploymentToken: args.deploymentToken,
|
|
3457
|
+
profile,
|
|
3458
|
+
ownerAddress: this.state.wallet.address,
|
|
3459
|
+
instanceItemHash: args.itemHash,
|
|
3460
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3461
|
+
expiresAt: new Date(Date.now() + 30 * 6e4).toISOString(),
|
|
3462
|
+
status: "pending",
|
|
3463
|
+
runtime: {
|
|
3464
|
+
publicIpv4: args.runtime.hostIpv4,
|
|
3465
|
+
publicIpv6: args.runtime.ipv6 ?? null,
|
|
3466
|
+
proxyUrl: args.runtime.proxyUrl ?? null,
|
|
3467
|
+
mappedPorts: mappedPorts2
|
|
3468
|
+
},
|
|
3469
|
+
bootstrap: {
|
|
3470
|
+
registrationId: createRelayBootstrapRegistrationId(
|
|
3471
|
+
profile,
|
|
3472
|
+
this.state.instanceName.trim(),
|
|
3473
|
+
args.itemHash
|
|
3474
|
+
)
|
|
3475
|
+
}
|
|
3476
|
+
};
|
|
3477
|
+
await publishVmBootstrapConfig({
|
|
3478
|
+
sender: this.state.wallet.address,
|
|
3479
|
+
record,
|
|
3480
|
+
signer: personalSign,
|
|
3481
|
+
hasher: sha256Hex,
|
|
3482
|
+
fetch: asJsonFetch,
|
|
3483
|
+
apiHost: this.client.apiHost,
|
|
3484
|
+
sync: true
|
|
3485
|
+
});
|
|
3139
3486
|
}
|
|
3140
3487
|
this.emitProgress({
|
|
3141
3488
|
stage: "publishing-bootstrap",
|
|
@@ -3145,27 +3492,23 @@ var SponsorRelayController = class {
|
|
|
3145
3492
|
itemHash: args.itemHash,
|
|
3146
3493
|
detail: "Waiting for the relay to report its final public multiaddrs."
|
|
3147
3494
|
});
|
|
3148
|
-
const
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3495
|
+
const relayMetadata = await fetchRelayMetadataForRuntime({
|
|
3496
|
+
runtime: args.runtime,
|
|
3497
|
+
fetch,
|
|
3498
|
+
preferSecureMetadata: profile === "uc-go-peer",
|
|
3152
3499
|
attempts: 80,
|
|
3153
3500
|
delayMs: 3e3,
|
|
3154
3501
|
timeoutMs: 24e4
|
|
3155
3502
|
});
|
|
3156
|
-
|
|
3157
|
-
const peerId = typeof metadata?.peer_id === "string" ? metadata.peer_id : null;
|
|
3158
|
-
const probeMultiaddrs = Array.isArray(metadata?.probe_multiaddrs) ? metadata.probe_multiaddrs.filter(
|
|
3159
|
-
(entry) => typeof entry === "string"
|
|
3160
|
-
) : [];
|
|
3161
|
-
const browserBootstrapMultiaddrs = Array.isArray(
|
|
3162
|
-
metadata?.browser_bootstrap_multiaddrs
|
|
3163
|
-
) ? metadata.browser_bootstrap_multiaddrs.filter(
|
|
3164
|
-
(entry) => typeof entry === "string"
|
|
3165
|
-
) : [];
|
|
3166
|
-
if (!peerId || probeMultiaddrs.length === 0) {
|
|
3503
|
+
if (!relayMetadata) {
|
|
3167
3504
|
throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
|
|
3168
3505
|
}
|
|
3506
|
+
const { peerId, probeMultiaddrs, browserBootstrapMultiaddrs } = relayMetadata;
|
|
3507
|
+
const registrationId = createRelayBootstrapRegistrationId(
|
|
3508
|
+
profile,
|
|
3509
|
+
this.state.instanceName.trim(),
|
|
3510
|
+
args.itemHash
|
|
3511
|
+
);
|
|
3169
3512
|
this.emitProgress({
|
|
3170
3513
|
stage: "publishing-bootstrap",
|
|
3171
3514
|
label: "Publishing bootstrap registration",
|
|
@@ -3178,25 +3521,65 @@ var SponsorRelayController = class {
|
|
|
3178
3521
|
sender: this.state.wallet.address,
|
|
3179
3522
|
signer: personalSign,
|
|
3180
3523
|
hasher: sha256Hex,
|
|
3181
|
-
fetch:
|
|
3182
|
-
ok: response.ok,
|
|
3183
|
-
status: response.status,
|
|
3184
|
-
json: async () => await response.json()
|
|
3185
|
-
})),
|
|
3524
|
+
fetch: asJsonFetch,
|
|
3186
3525
|
apiHost: this.client.apiHost,
|
|
3187
3526
|
peerId,
|
|
3188
3527
|
multiaddrs: probeMultiaddrs,
|
|
3189
3528
|
browserMultiaddrs: browserBootstrapMultiaddrs,
|
|
3529
|
+
registrationId,
|
|
3190
3530
|
profile,
|
|
3191
3531
|
version: this.state.manifest?.version,
|
|
3532
|
+
forgetPrevious: true,
|
|
3192
3533
|
sync: true
|
|
3193
3534
|
});
|
|
3194
3535
|
this.trace("deploy:bootstrap-registration", {
|
|
3195
3536
|
itemHash: args.itemHash,
|
|
3196
3537
|
peerId,
|
|
3197
|
-
metadata,
|
|
3538
|
+
metadata: relayMetadata,
|
|
3198
3539
|
publication
|
|
3199
3540
|
});
|
|
3541
|
+
const reconcileResult = await reconcileOwnerRelayBootstrapRegistrations({
|
|
3542
|
+
instanceOwnerAddress: this.state.wallet.address,
|
|
3543
|
+
sender: this.state.wallet.address,
|
|
3544
|
+
signer: personalSign,
|
|
3545
|
+
hasher: sha256Hex,
|
|
3546
|
+
fetch: asJsonFetch,
|
|
3547
|
+
profile,
|
|
3548
|
+
apiHost: this.client.apiHost,
|
|
3549
|
+
crns: this.state.crns,
|
|
3550
|
+
crnListUrl: this.props.crnListUrl,
|
|
3551
|
+
preferSecureMetadata: profile === "uc-go-peer",
|
|
3552
|
+
current: {
|
|
3553
|
+
itemHash: args.itemHash,
|
|
3554
|
+
registrationId,
|
|
3555
|
+
peerId,
|
|
3556
|
+
probeMultiaddrs,
|
|
3557
|
+
browserBootstrapMultiaddrs
|
|
3558
|
+
}
|
|
3559
|
+
});
|
|
3560
|
+
if (reconcileResult.errors.length > 0) {
|
|
3561
|
+
this.trace("deploy:owner-bootstrap-reconcile-errors", {
|
|
3562
|
+
itemHash: args.itemHash,
|
|
3563
|
+
errors: reconcileResult.errors
|
|
3564
|
+
});
|
|
3565
|
+
}
|
|
3566
|
+
if (profile === "uc-go-peer" && args.deploymentToken) {
|
|
3567
|
+
await deleteVmBootstrapConfig({
|
|
3568
|
+
sender: this.state.wallet.address,
|
|
3569
|
+
deploymentToken: args.deploymentToken,
|
|
3570
|
+
signer: personalSign,
|
|
3571
|
+
hasher: sha256Hex,
|
|
3572
|
+
fetch: asJsonFetch,
|
|
3573
|
+
apiHost: this.client.apiHost,
|
|
3574
|
+
sync: true
|
|
3575
|
+
}).catch((error) => {
|
|
3576
|
+
this.trace("deploy:bootstrap-config-cleanup-error", {
|
|
3577
|
+
itemHash: args.itemHash,
|
|
3578
|
+
deploymentToken: args.deploymentToken,
|
|
3579
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3580
|
+
});
|
|
3581
|
+
});
|
|
3582
|
+
}
|
|
3200
3583
|
}
|
|
3201
3584
|
syncLatestDeploymentProgress(instances) {
|
|
3202
3585
|
const itemHash = this.state.lastDeploymentHash;
|
|
@@ -3668,6 +4051,7 @@ var SponsorRelayController = class {
|
|
|
3668
4051
|
let lastError = null;
|
|
3669
4052
|
for (const [candidateIndex, candidateCrn] of orderedCrns.entries()) {
|
|
3670
4053
|
let attemptItemHash = null;
|
|
4054
|
+
let attemptDeploymentToken = null;
|
|
3671
4055
|
this.emitProgress({
|
|
3672
4056
|
stage: "selecting-crn",
|
|
3673
4057
|
label: "Selecting CRN",
|
|
@@ -3676,10 +4060,16 @@ var SponsorRelayController = class {
|
|
|
3676
4060
|
detail: `Trying ${candidateCrn.name ?? candidateCrn.hash} (${candidateIndex + 1}/${orderedCrns.length})`
|
|
3677
4061
|
});
|
|
3678
4062
|
try {
|
|
4063
|
+
const profile = relayProfileForManifest(this.state.manifest);
|
|
4064
|
+
const sshPublicKey = profile === "uc-go-peer" ? appendDeploymentTokenToSshPublicKey(
|
|
4065
|
+
this.state.sshPublicKey.trim(),
|
|
4066
|
+
this.state.wallet.address,
|
|
4067
|
+
attemptDeploymentToken = createDeploymentToken()
|
|
4068
|
+
) : this.state.sshPublicKey.trim();
|
|
3679
4069
|
const content = createInstanceContent({
|
|
3680
4070
|
address: this.state.wallet.address,
|
|
3681
4071
|
name: this.state.instanceName.trim(),
|
|
3682
|
-
sshPublicKey
|
|
4072
|
+
sshPublicKey,
|
|
3683
4073
|
rootfsItemHash: this.state.manifest.rootfsItemHash,
|
|
3684
4074
|
rootfsSizeMiB: Math.max(
|
|
3685
4075
|
this.state.manifest.rootfsSizeMiB,
|
|
@@ -3859,7 +4249,8 @@ var SponsorRelayController = class {
|
|
|
3859
4249
|
});
|
|
3860
4250
|
await this.configureRelayBootstrapRegistration({
|
|
3861
4251
|
itemHash: result.itemHash,
|
|
3862
|
-
runtime
|
|
4252
|
+
runtime,
|
|
4253
|
+
deploymentToken: attemptDeploymentToken
|
|
3863
4254
|
});
|
|
3864
4255
|
this.patch({
|
|
3865
4256
|
busy: { deploying: false }
|
|
@@ -3885,6 +4276,17 @@ var SponsorRelayController = class {
|
|
|
3885
4276
|
error: lastError.message
|
|
3886
4277
|
});
|
|
3887
4278
|
if (attemptItemHash) {
|
|
4279
|
+
if (attemptDeploymentToken) {
|
|
4280
|
+
await deleteVmBootstrapConfig({
|
|
4281
|
+
sender: this.state.wallet.address,
|
|
4282
|
+
deploymentToken: attemptDeploymentToken,
|
|
4283
|
+
signer: personalSign,
|
|
4284
|
+
hasher: sha256Hex,
|
|
4285
|
+
fetch: asJsonFetch,
|
|
4286
|
+
apiHost: this.client.apiHost,
|
|
4287
|
+
sync: true
|
|
4288
|
+
}).catch(() => void 0);
|
|
4289
|
+
}
|
|
3888
4290
|
await forgetAlephMessages({
|
|
3889
4291
|
sender: this.state.wallet.address,
|
|
3890
4292
|
hashes: [attemptItemHash],
|
|
@@ -3963,16 +4365,35 @@ var SponsorRelayController = class {
|
|
|
3963
4365
|
reason: "Deleted from Sponsor Relay panel",
|
|
3964
4366
|
signer: personalSign,
|
|
3965
4367
|
hasher: sha256Hex,
|
|
3966
|
-
fetch:
|
|
3967
|
-
ok: response.ok,
|
|
3968
|
-
status: response.status,
|
|
3969
|
-
json: async () => await response.json()
|
|
3970
|
-
})),
|
|
4368
|
+
fetch: asJsonFetch,
|
|
3971
4369
|
apiHost: this.client.apiHost,
|
|
3972
4370
|
onProgress: (event) => {
|
|
3973
4371
|
this.emitProgress(event);
|
|
3974
4372
|
}
|
|
3975
4373
|
});
|
|
4374
|
+
const profile = relayProfileForManifest(this.state.manifest);
|
|
4375
|
+
if (profile) {
|
|
4376
|
+
await reconcileOwnerRelayBootstrapRegistrations({
|
|
4377
|
+
instanceOwnerAddress: this.state.wallet.address,
|
|
4378
|
+
sender: this.state.wallet.address,
|
|
4379
|
+
signer: personalSign,
|
|
4380
|
+
hasher: sha256Hex,
|
|
4381
|
+
fetch: asJsonFetch,
|
|
4382
|
+
profile,
|
|
4383
|
+
apiHost: this.client.apiHost,
|
|
4384
|
+
crns: this.state.crns,
|
|
4385
|
+
crnListUrl: this.props.crnListUrl,
|
|
4386
|
+
preferSecureMetadata: profile === "uc-go-peer"
|
|
4387
|
+
}).catch(
|
|
4388
|
+
(error) => {
|
|
4389
|
+
this.trace("delete:owner-bootstrap-reconcile-error", {
|
|
4390
|
+
instanceHash,
|
|
4391
|
+
profile,
|
|
4392
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4393
|
+
});
|
|
4394
|
+
}
|
|
4395
|
+
);
|
|
4396
|
+
}
|
|
3976
4397
|
this.patch({
|
|
3977
4398
|
busy: { deletingInstanceHash: null },
|
|
3978
4399
|
statusText: `Deletion submitted for ${instanceHash}`
|