@le-space/ui 0.3.17 → 0.3.19
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 +70 -498
- package/shared/index.d.ts +1 -1
- package/shared/index.js +70 -498
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.19";
|
|
42
42
|
|
|
43
43
|
// src/shared/format.ts
|
|
44
44
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -1218,14 +1218,14 @@ async function inspectDeploymentResult2(itemHash, options) {
|
|
|
1218
1218
|
async function waitForDeploymentResult2(itemHash, options) {
|
|
1219
1219
|
const attempts = Math.max(1, Number(options.attempts ?? 15));
|
|
1220
1220
|
const delayMs = Math.max(0, Number(options.delayMs ?? 2e3));
|
|
1221
|
-
const
|
|
1221
|
+
const sleep2 = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1222
1222
|
let lastResult = await inspectDeploymentResult2(itemHash, options);
|
|
1223
1223
|
options.onAttempt?.(lastResult, 1, attempts);
|
|
1224
1224
|
for (let attempt = 1; attempt < attempts; attempt += 1) {
|
|
1225
1225
|
if (lastResult.status === "processed" || lastResult.status === "rejected") {
|
|
1226
1226
|
return lastResult;
|
|
1227
1227
|
}
|
|
1228
|
-
await
|
|
1228
|
+
await sleep2(delayMs);
|
|
1229
1229
|
lastResult = await inspectDeploymentResult2(itemHash, options);
|
|
1230
1230
|
options.onAttempt?.(lastResult, attempt + 1, attempts);
|
|
1231
1231
|
}
|
|
@@ -1883,14 +1883,14 @@ async function fetchVmRuntime(args) {
|
|
|
1883
1883
|
async function waitForVmRuntime(args) {
|
|
1884
1884
|
const attempts = Math.max(1, Number(args.attempts ?? 20));
|
|
1885
1885
|
const delayMs = Math.max(0, Number(args.delayMs ?? 4e3));
|
|
1886
|
-
const
|
|
1886
|
+
const sleep2 = args.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1887
1887
|
let lastRuntime = await fetchVmRuntime(args);
|
|
1888
1888
|
args.onAttempt?.(lastRuntime, 1, attempts);
|
|
1889
1889
|
for (let attempt = 0; attempt < attempts - 1; attempt += 1) {
|
|
1890
1890
|
if (lastRuntime.hostIpv4 && Object.keys(lastRuntime.mappedPorts ?? {}).length > 0) {
|
|
1891
1891
|
return lastRuntime;
|
|
1892
1892
|
}
|
|
1893
|
-
await
|
|
1893
|
+
await sleep2(delayMs);
|
|
1894
1894
|
lastRuntime = await fetchVmRuntime(args);
|
|
1895
1895
|
args.onAttempt?.(lastRuntime, attempt + 2, attempts);
|
|
1896
1896
|
}
|
|
@@ -1969,7 +1969,7 @@ function isRetryableAllocationNotifyReason(reason) {
|
|
|
1969
1969
|
async function notifyCrnAllocationWithRetry(args) {
|
|
1970
1970
|
const attempts = Math.max(1, Number(args.attempts ?? 6));
|
|
1971
1971
|
const delayMs = Math.max(0, Number(args.delayMs ?? 2e3));
|
|
1972
|
-
const
|
|
1972
|
+
const sleep2 = args.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1973
1973
|
let lastResult = null;
|
|
1974
1974
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
1975
1975
|
args.onProgress?.({
|
|
@@ -1995,7 +1995,7 @@ async function notifyCrnAllocationWithRetry(args) {
|
|
|
1995
1995
|
return result;
|
|
1996
1996
|
}
|
|
1997
1997
|
if (attempt < attempts - 1) {
|
|
1998
|
-
await
|
|
1998
|
+
await sleep2(delayMs);
|
|
1999
1999
|
}
|
|
2000
2000
|
}
|
|
2001
2001
|
return lastResult ?? {
|
|
@@ -2006,7 +2006,7 @@ async function notifyCrnAllocationWithRetry(args) {
|
|
|
2006
2006
|
async function waitForSetupEndpoint(args) {
|
|
2007
2007
|
const attempts = Math.max(1, Number(args.attempts ?? 15));
|
|
2008
2008
|
const delayMs = Math.max(0, Number(args.delayMs ?? 4e3));
|
|
2009
|
-
const
|
|
2009
|
+
const sleep2 = args.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
2010
2010
|
const url = `http://${args.hostIpv4}:${args.setupPort}/health`;
|
|
2011
2011
|
let result = await defaultHttpProbe(
|
|
2012
2012
|
args.fetch,
|
|
@@ -2016,7 +2016,7 @@ async function waitForSetupEndpoint(args) {
|
|
|
2016
2016
|
args.onAttempt?.(result, 1, attempts);
|
|
2017
2017
|
for (let attempt = 1; attempt < attempts; attempt += 1) {
|
|
2018
2018
|
if (result.ok) return result;
|
|
2019
|
-
await
|
|
2019
|
+
await sleep2(delayMs);
|
|
2020
2020
|
result = await defaultHttpProbe(
|
|
2021
2021
|
args.fetch,
|
|
2022
2022
|
url,
|
|
@@ -2075,7 +2075,7 @@ async function configureOrbitdbRelaySetup2(args) {
|
|
|
2075
2075
|
async function fetchUcGoPeerMetadata(args) {
|
|
2076
2076
|
const attempts = Math.max(1, Number(args.attempts ?? 60));
|
|
2077
2077
|
const delayMs = Math.max(0, Number(args.delayMs ?? 3e3));
|
|
2078
|
-
const
|
|
2078
|
+
const sleep2 = args.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
2079
2079
|
let lastPayload = null;
|
|
2080
2080
|
let lastError = null;
|
|
2081
2081
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
@@ -2135,7 +2135,7 @@ async function fetchUcGoPeerMetadata(args) {
|
|
|
2135
2135
|
clearTimeout(timeout);
|
|
2136
2136
|
}
|
|
2137
2137
|
if (attempt < attempts - 1) {
|
|
2138
|
-
await
|
|
2138
|
+
await sleep2(delayMs);
|
|
2139
2139
|
}
|
|
2140
2140
|
}
|
|
2141
2141
|
throw new Error(
|
|
@@ -2151,31 +2151,6 @@ var DEFAULT_ALEPH_BOOTSTRAP_REF = "simple-todo-bootstrap";
|
|
|
2151
2151
|
var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap";
|
|
2152
2152
|
var DEFAULT_BOOTSTRAP_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2153
2153
|
var DEFAULT_BOOTSTRAP_PAGINATION = 50;
|
|
2154
|
-
var RELAY_BOOTSTRAP_SIGNATURE_SCHEME = "personal_sign";
|
|
2155
|
-
function serializeOwnerAuthorizationPayload(payload) {
|
|
2156
|
-
return JSON.stringify({
|
|
2157
|
-
ownerAddress: payload.ownerAddress,
|
|
2158
|
-
publisherAddress: payload.publisherAddress,
|
|
2159
|
-
peerId: payload.peerId,
|
|
2160
|
-
registrationId: payload.registrationId,
|
|
2161
|
-
profile: payload.profile,
|
|
2162
|
-
version: payload.version,
|
|
2163
|
-
instanceItemHash: payload.instanceItemHash,
|
|
2164
|
-
issuedAt: payload.issuedAt,
|
|
2165
|
-
expiresAt: payload.expiresAt
|
|
2166
|
-
});
|
|
2167
|
-
}
|
|
2168
|
-
function serializeRelayProofPayload(payload) {
|
|
2169
|
-
return JSON.stringify({
|
|
2170
|
-
peerId: payload.peerId,
|
|
2171
|
-
multiaddrs: dedupeMultiaddrs(payload.multiaddrs),
|
|
2172
|
-
browserMultiaddrs: payload.browserMultiaddrs ? dedupeMultiaddrs(payload.browserMultiaddrs) : void 0,
|
|
2173
|
-
registrationId: payload.registrationId,
|
|
2174
|
-
profile: payload.profile,
|
|
2175
|
-
version: payload.version,
|
|
2176
|
-
updatedAt: payload.updatedAt
|
|
2177
|
-
});
|
|
2178
|
-
}
|
|
2179
2154
|
function asTrimmedString(value) {
|
|
2180
2155
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
2181
2156
|
}
|
|
@@ -2187,48 +2162,9 @@ function asNumber4(value) {
|
|
|
2187
2162
|
}
|
|
2188
2163
|
return null;
|
|
2189
2164
|
}
|
|
2190
|
-
function normalizeHost(host) {
|
|
2191
|
-
return host.trim().toLowerCase();
|
|
2192
|
-
}
|
|
2193
2165
|
function normalizeAddress(address) {
|
|
2194
2166
|
return address.trim().toLowerCase();
|
|
2195
2167
|
}
|
|
2196
|
-
function normalizeSignature(signature) {
|
|
2197
|
-
const trimmed = signature.trim();
|
|
2198
|
-
return trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
2199
|
-
}
|
|
2200
|
-
function splitMultiaddr(addr) {
|
|
2201
|
-
return addr.split("/").filter(Boolean);
|
|
2202
|
-
}
|
|
2203
|
-
function isPrivateIpv4(ip) {
|
|
2204
|
-
const parts = ip.split(".").map((part) => Number(part));
|
|
2205
|
-
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {
|
|
2206
|
-
return false;
|
|
2207
|
-
}
|
|
2208
|
-
if (parts[0] === 10) return true;
|
|
2209
|
-
if (parts[0] === 127) return true;
|
|
2210
|
-
if (parts[0] === 0) return true;
|
|
2211
|
-
if (parts[0] === 169 && parts[1] === 254) return true;
|
|
2212
|
-
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true;
|
|
2213
|
-
if (parts[0] === 192 && parts[1] === 168) return true;
|
|
2214
|
-
if (parts[0] === 100 && parts[1] >= 64 && parts[1] <= 127) return true;
|
|
2215
|
-
return false;
|
|
2216
|
-
}
|
|
2217
|
-
function isPrivateIpv6(ip) {
|
|
2218
|
-
const normalized = ip.trim().toLowerCase();
|
|
2219
|
-
return normalized === "::1" || normalized.startsWith("fc") || normalized.startsWith("fd") || normalized.startsWith("fe8") || normalized.startsWith("fe9") || normalized.startsWith("fea") || normalized.startsWith("feb");
|
|
2220
|
-
}
|
|
2221
|
-
function isLocalHostname(host) {
|
|
2222
|
-
const normalized = normalizeHost(host);
|
|
2223
|
-
return normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local");
|
|
2224
|
-
}
|
|
2225
|
-
function hasPeerId(addr) {
|
|
2226
|
-
return splitMultiaddr(addr).includes("p2p");
|
|
2227
|
-
}
|
|
2228
|
-
function isBrowserDialableMultiaddr(addr) {
|
|
2229
|
-
const normalized = addr.toLowerCase();
|
|
2230
|
-
return normalized.includes("/ws") || normalized.includes("/wss") || normalized.includes("/webtransport") || normalized.includes("/webrtc-direct");
|
|
2231
|
-
}
|
|
2232
2168
|
function dedupeMultiaddrs(addrs) {
|
|
2233
2169
|
const seen = /* @__PURE__ */ new Set();
|
|
2234
2170
|
const result = [];
|
|
@@ -2240,33 +2176,6 @@ function dedupeMultiaddrs(addrs) {
|
|
|
2240
2176
|
}
|
|
2241
2177
|
return result;
|
|
2242
2178
|
}
|
|
2243
|
-
function isPublicMultiaddr(addr) {
|
|
2244
|
-
const parts = splitMultiaddr(addr);
|
|
2245
|
-
for (let index = 0; index < parts.length; index += 1) {
|
|
2246
|
-
const protocol = parts[index];
|
|
2247
|
-
const value = parts[index + 1];
|
|
2248
|
-
if (protocol === "ip4" && value) {
|
|
2249
|
-
return !isPrivateIpv4(value);
|
|
2250
|
-
}
|
|
2251
|
-
if (protocol === "ip6" && value) {
|
|
2252
|
-
return !isPrivateIpv6(value);
|
|
2253
|
-
}
|
|
2254
|
-
if ((protocol === "dns4" || protocol === "dns6" || protocol === "dnsaddr") && value) {
|
|
2255
|
-
return !isLocalHostname(value);
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
return false;
|
|
2259
|
-
}
|
|
2260
|
-
function filterPublicMultiaddrs(addrs, options = {}) {
|
|
2261
|
-
return dedupeMultiaddrs(addrs).filter((addr) => {
|
|
2262
|
-
if (!isPublicMultiaddr(addr)) return false;
|
|
2263
|
-
if (options.requirePeerId !== false && !hasPeerId(addr)) return false;
|
|
2264
|
-
if (options.browserDialableOnly && !isBrowserDialableMultiaddr(addr)) {
|
|
2265
|
-
return false;
|
|
2266
|
-
}
|
|
2267
|
-
return true;
|
|
2268
|
-
});
|
|
2269
|
-
}
|
|
2270
2179
|
function normalizeRelayBootstrapContent(value) {
|
|
2271
2180
|
if (!value || typeof value !== "object") return null;
|
|
2272
2181
|
const content = value;
|
|
@@ -2361,104 +2270,6 @@ function normalizeRelayBootstrapPostRecord(value) {
|
|
|
2361
2270
|
content: normalizeRelayBootstrapContent(entry.content)
|
|
2362
2271
|
};
|
|
2363
2272
|
}
|
|
2364
|
-
function buildRelayBootstrapPostContent(args) {
|
|
2365
|
-
const now = args.now ?? Date.now() / 1e3;
|
|
2366
|
-
const updatedAt = args.now ?? Date.now();
|
|
2367
|
-
return {
|
|
2368
|
-
type: args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE,
|
|
2369
|
-
address: args.sender,
|
|
2370
|
-
...args.ref ? { ref: args.ref } : {},
|
|
2371
|
-
content: {
|
|
2372
|
-
peerId: args.peerId,
|
|
2373
|
-
multiaddrs: filterPublicMultiaddrs(args.multiaddrs),
|
|
2374
|
-
browserMultiaddrs: args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
|
|
2375
|
-
browserDialableOnly: true
|
|
2376
|
-
}) : void 0,
|
|
2377
|
-
registrationId: args.registrationId,
|
|
2378
|
-
profile: args.profile,
|
|
2379
|
-
version: args.version,
|
|
2380
|
-
ownerAddress: args.ownerAddress,
|
|
2381
|
-
publisherAddress: args.publisherAddress,
|
|
2382
|
-
authorization: args.authorization,
|
|
2383
|
-
relayProof: args.relayProof,
|
|
2384
|
-
updatedAt: Math.round(updatedAt)
|
|
2385
|
-
},
|
|
2386
|
-
time: now
|
|
2387
|
-
};
|
|
2388
|
-
}
|
|
2389
|
-
async function createRelayBootstrapPost(args) {
|
|
2390
|
-
const nowMillis = args.now ?? Date.now();
|
|
2391
|
-
const nowSeconds = nowMillis / 1e3;
|
|
2392
|
-
const itemContent = buildRelayBootstrapPostContent({
|
|
2393
|
-
sender: args.sender,
|
|
2394
|
-
peerId: args.peerId,
|
|
2395
|
-
multiaddrs: args.multiaddrs,
|
|
2396
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2397
|
-
registrationId: args.registrationId,
|
|
2398
|
-
ref: args.ref ?? DEFAULT_ALEPH_BOOTSTRAP_REF,
|
|
2399
|
-
postType: args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE,
|
|
2400
|
-
profile: args.profile,
|
|
2401
|
-
version: args.version,
|
|
2402
|
-
ownerAddress: args.ownerAddress,
|
|
2403
|
-
publisherAddress: args.publisherAddress,
|
|
2404
|
-
authorization: args.authorization,
|
|
2405
|
-
relayProof: args.relayProof,
|
|
2406
|
-
now: nowMillis
|
|
2407
|
-
});
|
|
2408
|
-
itemContent.time = nowSeconds;
|
|
2409
|
-
const serialized = JSON.stringify(itemContent);
|
|
2410
|
-
const itemHash = await args.hasher(serialized);
|
|
2411
|
-
return {
|
|
2412
|
-
channel: args.channel ?? DEFAULT_ALEPH_BOOTSTRAP_CHANNEL,
|
|
2413
|
-
sender: args.sender,
|
|
2414
|
-
chain: "ETH",
|
|
2415
|
-
type: "POST",
|
|
2416
|
-
time: nowSeconds,
|
|
2417
|
-
item_type: "inline",
|
|
2418
|
-
item_content: serialized,
|
|
2419
|
-
item_hash: itemHash
|
|
2420
|
-
};
|
|
2421
|
-
}
|
|
2422
|
-
async function signRelayBootstrapAuthorization(args) {
|
|
2423
|
-
const payload = {
|
|
2424
|
-
ownerAddress: args.ownerAddress,
|
|
2425
|
-
publisherAddress: args.publisherAddress,
|
|
2426
|
-
peerId: args.peerId,
|
|
2427
|
-
registrationId: args.registrationId,
|
|
2428
|
-
profile: args.profile,
|
|
2429
|
-
version: args.version,
|
|
2430
|
-
instanceItemHash: args.instanceItemHash,
|
|
2431
|
-
issuedAt: args.issuedAt ?? Date.now(),
|
|
2432
|
-
expiresAt: args.expiresAt
|
|
2433
|
-
};
|
|
2434
|
-
const serialized = serializeOwnerAuthorizationPayload(payload);
|
|
2435
|
-
const signature = await args.signer(args.ownerAddress, serialized);
|
|
2436
|
-
return {
|
|
2437
|
-
scheme: RELAY_BOOTSTRAP_SIGNATURE_SCHEME,
|
|
2438
|
-
payload,
|
|
2439
|
-
signature: normalizeSignature(signature)
|
|
2440
|
-
};
|
|
2441
|
-
}
|
|
2442
|
-
async function signRelayBootstrapProof(args) {
|
|
2443
|
-
const payload = {
|
|
2444
|
-
peerId: args.peerId,
|
|
2445
|
-
multiaddrs: filterPublicMultiaddrs(args.multiaddrs),
|
|
2446
|
-
browserMultiaddrs: args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
|
|
2447
|
-
browserDialableOnly: true
|
|
2448
|
-
}) : void 0,
|
|
2449
|
-
registrationId: args.registrationId,
|
|
2450
|
-
profile: args.profile,
|
|
2451
|
-
version: args.version,
|
|
2452
|
-
updatedAt: args.updatedAt ?? Date.now()
|
|
2453
|
-
};
|
|
2454
|
-
const serialized = serializeRelayProofPayload(payload);
|
|
2455
|
-
const signature = await args.signer(args.publisherAddress, serialized);
|
|
2456
|
-
return {
|
|
2457
|
-
scheme: RELAY_BOOTSTRAP_SIGNATURE_SCHEME,
|
|
2458
|
-
payload,
|
|
2459
|
-
signature: normalizeSignature(signature)
|
|
2460
|
-
};
|
|
2461
|
-
}
|
|
2462
2273
|
async function fetchAlephBootstrapPosts(options = {}) {
|
|
2463
2274
|
const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
|
|
2464
2275
|
if (typeof fetchImpl !== "function") {
|
|
@@ -2530,108 +2341,52 @@ function selectCurrentRelayBootstrapPosts(posts, options = {}) {
|
|
|
2530
2341
|
}
|
|
2531
2342
|
|
|
2532
2343
|
// ../core/src/bootstrap-registration.ts
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
profile: args.profile,
|
|
2545
|
-
version: args.version,
|
|
2546
|
-
instanceItemHash: args.instanceItemHash,
|
|
2547
|
-
issuedAt: args.authorizationIssuedAt ?? args.now ?? Date.now(),
|
|
2548
|
-
expiresAt: args.authorizationExpiresAt,
|
|
2549
|
-
signer: args.ownerSigner
|
|
2550
|
-
});
|
|
2551
|
-
}
|
|
2552
|
-
if (!relayProof && args.publisherSigner) {
|
|
2553
|
-
relayProof = await signRelayBootstrapProof({
|
|
2554
|
-
publisherAddress,
|
|
2555
|
-
peerId: args.peerId,
|
|
2556
|
-
multiaddrs: args.multiaddrs,
|
|
2557
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2558
|
-
registrationId: args.registrationId,
|
|
2559
|
-
profile: args.profile,
|
|
2560
|
-
version: args.version,
|
|
2561
|
-
updatedAt: args.now ?? Date.now(),
|
|
2562
|
-
signer: args.publisherSigner
|
|
2563
|
-
});
|
|
2564
|
-
}
|
|
2565
|
-
const unsigned = await createRelayBootstrapPost({
|
|
2566
|
-
sender: args.sender,
|
|
2567
|
-
peerId: args.peerId,
|
|
2568
|
-
multiaddrs: args.multiaddrs,
|
|
2569
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2570
|
-
registrationId: args.registrationId,
|
|
2571
|
-
channel: args.channel,
|
|
2572
|
-
ref: args.ref,
|
|
2573
|
-
postType: args.postType,
|
|
2574
|
-
profile: args.profile,
|
|
2575
|
-
version: args.version,
|
|
2576
|
-
ownerAddress,
|
|
2577
|
-
publisherAddress,
|
|
2578
|
-
authorization: ownerAuthorization,
|
|
2579
|
-
relayProof,
|
|
2580
|
-
now: args.now,
|
|
2581
|
-
hasher: args.hasher
|
|
2582
|
-
});
|
|
2583
|
-
const content = JSON.parse(unsigned.item_content);
|
|
2584
|
-
if ((content.content?.multiaddrs?.length ?? 0) === 0) {
|
|
2585
|
-
return {
|
|
2586
|
-
status: "skipped",
|
|
2587
|
-
reason: "No public relay multiaddrs remained after filtering.",
|
|
2588
|
-
publishedMultiaddrs: [],
|
|
2589
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? []
|
|
2590
|
-
};
|
|
2591
|
-
}
|
|
2592
|
-
const message = await signAlephMessage(unsigned, args.signer);
|
|
2593
|
-
const { response, httpStatus } = await broadcastAlephMessage2(message, {
|
|
2594
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2595
|
-
sync: args.sync ?? true,
|
|
2596
|
-
fetch: args.fetch
|
|
2597
|
-
});
|
|
2598
|
-
let forgottenHashes = [];
|
|
2599
|
-
let forgetResult;
|
|
2600
|
-
if (args.forgetPrevious && args.registrationId) {
|
|
2601
|
-
const previousPosts = await fetchAlephBootstrapPosts({
|
|
2344
|
+
function sleep(ms) {
|
|
2345
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2346
|
+
}
|
|
2347
|
+
async function waitForRelayBootstrapRegistration(args) {
|
|
2348
|
+
const attempts = Math.max(1, Number(args.attempts ?? 10));
|
|
2349
|
+
const delayMs = Math.max(0, Number(args.delayMs ?? 2e3));
|
|
2350
|
+
const expectedSender = args.sender?.trim().toLowerCase() || null;
|
|
2351
|
+
const expectedRegistrationId = args.registrationId?.trim() || null;
|
|
2352
|
+
const expectedPeerId = args.peerId?.trim() || null;
|
|
2353
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
2354
|
+
const posts = await fetchAlephBootstrapPosts({
|
|
2602
2355
|
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2603
2356
|
channel: args.channel,
|
|
2604
2357
|
ref: args.ref,
|
|
2605
2358
|
postType: args.postType,
|
|
2606
2359
|
fetch: args.fetch
|
|
2607
2360
|
});
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2361
|
+
const currentPosts = selectCurrentRelayBootstrapPosts(posts);
|
|
2362
|
+
const match = currentPosts.find((post) => {
|
|
2363
|
+
if (expectedSender && post.address?.toLowerCase() !== expectedSender) {
|
|
2364
|
+
return false;
|
|
2365
|
+
}
|
|
2366
|
+
if (expectedRegistrationId && post.content?.registrationId === expectedRegistrationId) {
|
|
2367
|
+
return true;
|
|
2368
|
+
}
|
|
2369
|
+
if (expectedPeerId && post.content?.peerId === expectedPeerId) {
|
|
2370
|
+
return true;
|
|
2371
|
+
}
|
|
2372
|
+
return false;
|
|
2373
|
+
});
|
|
2374
|
+
if (match?.content) {
|
|
2375
|
+
return {
|
|
2376
|
+
itemHash: match.itemHash ?? null,
|
|
2377
|
+
hash: match.hash ?? null,
|
|
2378
|
+
sender: typeof match.address === "string" ? match.address : null,
|
|
2379
|
+
registrationId: match.content.registrationId,
|
|
2380
|
+
peerId: match.content.peerId,
|
|
2381
|
+
multiaddrs: Array.isArray(match.content.multiaddrs) ? match.content.multiaddrs : [],
|
|
2382
|
+
browserMultiaddrs: Array.isArray(match.content.browserMultiaddrs) ? match.content.browserMultiaddrs : []
|
|
2383
|
+
};
|
|
2384
|
+
}
|
|
2385
|
+
if (attempt < attempts - 1) {
|
|
2386
|
+
await sleep(delayMs);
|
|
2622
2387
|
}
|
|
2623
2388
|
}
|
|
2624
|
-
return
|
|
2625
|
-
status: "published",
|
|
2626
|
-
itemHash: unsigned.item_hash,
|
|
2627
|
-
message,
|
|
2628
|
-
response,
|
|
2629
|
-
httpStatus,
|
|
2630
|
-
publishedMultiaddrs: content.content?.multiaddrs ?? [],
|
|
2631
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? [],
|
|
2632
|
-
forgottenHashes,
|
|
2633
|
-
forgetResult
|
|
2634
|
-
};
|
|
2389
|
+
return null;
|
|
2635
2390
|
}
|
|
2636
2391
|
|
|
2637
2392
|
// ../core/src/bootstrap-config.ts
|
|
@@ -2786,24 +2541,6 @@ function extractRelayMetadata(payload) {
|
|
|
2786
2541
|
browserBootstrapMultiaddrs
|
|
2787
2542
|
};
|
|
2788
2543
|
}
|
|
2789
|
-
async function fetchOwnerInstances(address, options) {
|
|
2790
|
-
const url = new URL("/api/v0/messages.json", options.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2791
|
-
url.searchParams.set("msgTypes", "INSTANCE");
|
|
2792
|
-
url.searchParams.set("addresses", address);
|
|
2793
|
-
url.searchParams.set("message_statuses", "processed,pending,rejected,removing");
|
|
2794
|
-
url.searchParams.set("pagination", "100");
|
|
2795
|
-
url.searchParams.set("page", "1");
|
|
2796
|
-
url.searchParams.set("sortOrder", "-1");
|
|
2797
|
-
const response = await options.fetch(url.toString(), { cache: "no-cache" });
|
|
2798
|
-
if (!response.ok) {
|
|
2799
|
-
throw new Error(`Instance list request failed: ${response.status}`);
|
|
2800
|
-
}
|
|
2801
|
-
const payload = await response.json();
|
|
2802
|
-
return (payload.messages ?? []).map((message) => ({
|
|
2803
|
-
...message,
|
|
2804
|
-
status: typeof message.status === "string" && message.status.trim() ? message.status : message.confirmed ? "processed" : "pending"
|
|
2805
|
-
}));
|
|
2806
|
-
}
|
|
2807
2544
|
async function fetchRelayMetadataForRuntime(args) {
|
|
2808
2545
|
const setupPort = args.runtime.mappedPorts?.["80"]?.host ?? 80;
|
|
2809
2546
|
const metadataUrl = args.preferSecureMetadata ? secureBootstrapMetadataUrl(args.runtime.proxyUrl) : null;
|
|
@@ -2830,123 +2567,6 @@ async function fetchRelayMetadataForRuntime(args) {
|
|
|
2830
2567
|
}).catch(() => null);
|
|
2831
2568
|
return extractRelayMetadata(payload);
|
|
2832
2569
|
}
|
|
2833
|
-
async function reconcileOwnerRelayBootstrapRegistrations(args) {
|
|
2834
|
-
const result = {
|
|
2835
|
-
refreshedRegistrations: [],
|
|
2836
|
-
forgottenHashes: [],
|
|
2837
|
-
skippedInstanceHashes: [],
|
|
2838
|
-
errors: []
|
|
2839
|
-
};
|
|
2840
|
-
const liveRegistrationIds = /* @__PURE__ */ new Set();
|
|
2841
|
-
if (args.current?.registrationId) {
|
|
2842
|
-
liveRegistrationIds.add(args.current.registrationId);
|
|
2843
|
-
result.refreshedRegistrations.push(args.current.registrationId);
|
|
2844
|
-
}
|
|
2845
|
-
const instances = await fetchOwnerInstances(args.instanceOwnerAddress, {
|
|
2846
|
-
apiHost: args.apiHost,
|
|
2847
|
-
fetch: args.fetch
|
|
2848
|
-
});
|
|
2849
|
-
const processedInstances = instances.filter((instance) => {
|
|
2850
|
-
const status = String(instance.status ?? "").trim().toLowerCase();
|
|
2851
|
-
return status === "processed";
|
|
2852
|
-
});
|
|
2853
|
-
for (const instance of processedInstances) {
|
|
2854
|
-
if (instance.item_hash === args.current?.itemHash) continue;
|
|
2855
|
-
const registrationId = createRelayBootstrapRegistrationId(
|
|
2856
|
-
args.profile,
|
|
2857
|
-
instance.content?.metadata?.name,
|
|
2858
|
-
instance.item_hash
|
|
2859
|
-
);
|
|
2860
|
-
try {
|
|
2861
|
-
const runtime = await fetchVmRuntime({
|
|
2862
|
-
itemHash: instance.item_hash,
|
|
2863
|
-
fetch: args.fetch,
|
|
2864
|
-
crns: args.crns,
|
|
2865
|
-
crnListUrl: args.crnListUrl
|
|
2866
|
-
});
|
|
2867
|
-
if (!runtime.hostIpv4 || Object.keys(runtime.mappedPorts ?? {}).length === 0) {
|
|
2868
|
-
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2869
|
-
continue;
|
|
2870
|
-
}
|
|
2871
|
-
const relayMetadata = await fetchRelayMetadataForRuntime({
|
|
2872
|
-
runtime,
|
|
2873
|
-
fetch: args.fetch,
|
|
2874
|
-
preferSecureMetadata: args.preferSecureMetadata,
|
|
2875
|
-
attempts: 3,
|
|
2876
|
-
delayMs: 1e3,
|
|
2877
|
-
timeoutMs: 1e4
|
|
2878
|
-
});
|
|
2879
|
-
if (!relayMetadata) {
|
|
2880
|
-
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2881
|
-
continue;
|
|
2882
|
-
}
|
|
2883
|
-
liveRegistrationIds.add(registrationId);
|
|
2884
|
-
await publishRelayBootstrapRegistration({
|
|
2885
|
-
sender: args.sender,
|
|
2886
|
-
signer: args.signer,
|
|
2887
|
-
hasher: args.hasher,
|
|
2888
|
-
fetch: args.fetch,
|
|
2889
|
-
apiHost: args.apiHost,
|
|
2890
|
-
channel: args.channel,
|
|
2891
|
-
ref: args.ref,
|
|
2892
|
-
postType: args.postType,
|
|
2893
|
-
peerId: relayMetadata.peerId,
|
|
2894
|
-
multiaddrs: relayMetadata.probeMultiaddrs,
|
|
2895
|
-
browserMultiaddrs: relayMetadata.browserBootstrapMultiaddrs,
|
|
2896
|
-
registrationId,
|
|
2897
|
-
ownerAddress: args.ownerAddress,
|
|
2898
|
-
publisherAddress: args.publisherAddress,
|
|
2899
|
-
ownerSigner: args.ownerSigner,
|
|
2900
|
-
publisherSigner: args.publisherSigner,
|
|
2901
|
-
forgetPrevious: true,
|
|
2902
|
-
profile: args.profile,
|
|
2903
|
-
version: args.version,
|
|
2904
|
-
instanceItemHash: instance.item_hash,
|
|
2905
|
-
sync: true
|
|
2906
|
-
});
|
|
2907
|
-
result.refreshedRegistrations.push(registrationId);
|
|
2908
|
-
} catch (error) {
|
|
2909
|
-
result.errors.push({
|
|
2910
|
-
phase: "publish",
|
|
2911
|
-
itemHash: instance.item_hash,
|
|
2912
|
-
registrationId,
|
|
2913
|
-
message: error instanceof Error ? error.message : String(error)
|
|
2914
|
-
});
|
|
2915
|
-
}
|
|
2916
|
-
}
|
|
2917
|
-
try {
|
|
2918
|
-
const bootstrapPosts = await fetchAlephBootstrapPosts({
|
|
2919
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2920
|
-
channel: args.channel,
|
|
2921
|
-
ref: args.ref,
|
|
2922
|
-
postType: args.postType,
|
|
2923
|
-
fetch: args.fetch
|
|
2924
|
-
});
|
|
2925
|
-
const currentPosts = selectCurrentRelayBootstrapPosts(bootstrapPosts);
|
|
2926
|
-
const staleHashes = currentPosts.filter(
|
|
2927
|
-
(post) => post.address?.toLowerCase() === args.sender.toLowerCase() && post.content?.profile === args.profile && post.content?.registrationId && !liveRegistrationIds.has(post.content.registrationId)
|
|
2928
|
-
).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean);
|
|
2929
|
-
if (staleHashes.length > 0) {
|
|
2930
|
-
await forgetAlephMessages({
|
|
2931
|
-
sender: args.sender,
|
|
2932
|
-
hashes: staleHashes,
|
|
2933
|
-
reason: `Forget stale ${args.profile} relay bootstrap registrations after owner reconcile`,
|
|
2934
|
-
signer: args.signer,
|
|
2935
|
-
hasher: args.hasher,
|
|
2936
|
-
fetch: args.fetch,
|
|
2937
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2938
|
-
sync: true
|
|
2939
|
-
});
|
|
2940
|
-
result.forgottenHashes.push(...staleHashes);
|
|
2941
|
-
}
|
|
2942
|
-
} catch (error) {
|
|
2943
|
-
result.errors.push({
|
|
2944
|
-
phase: "forget",
|
|
2945
|
-
message: error instanceof Error ? error.message : String(error)
|
|
2946
|
-
});
|
|
2947
|
-
}
|
|
2948
|
-
return result;
|
|
2949
|
-
}
|
|
2950
2570
|
|
|
2951
2571
|
// src/shared/events.ts
|
|
2952
2572
|
function createDeploymentProgressEmitter() {
|
|
@@ -3566,7 +3186,7 @@ var SponsorRelayController = class {
|
|
|
3566
3186
|
if (!relayMetadata) {
|
|
3567
3187
|
throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
|
|
3568
3188
|
}
|
|
3569
|
-
const { peerId
|
|
3189
|
+
const { peerId } = relayMetadata;
|
|
3570
3190
|
const registrationId = createRelayBootstrapRegistrationId(
|
|
3571
3191
|
profile,
|
|
3572
3192
|
this.state.instanceName.trim(),
|
|
@@ -3574,57 +3194,30 @@ var SponsorRelayController = class {
|
|
|
3574
3194
|
);
|
|
3575
3195
|
this.emitProgress({
|
|
3576
3196
|
stage: "publishing-bootstrap",
|
|
3577
|
-
label: "
|
|
3197
|
+
label: "Waiting for guest bootstrap registration",
|
|
3578
3198
|
progress: 96,
|
|
3579
3199
|
status: "info",
|
|
3580
3200
|
itemHash: args.itemHash,
|
|
3581
|
-
detail: "
|
|
3201
|
+
detail: "Waiting for the relay VM to publish its own bootstrap registration to Aleph."
|
|
3582
3202
|
});
|
|
3583
|
-
const
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
hasher: sha256Hex,
|
|
3203
|
+
const visibleRegistration = await waitForRelayBootstrapRegistration({
|
|
3204
|
+
registrationId,
|
|
3205
|
+
peerId,
|
|
3587
3206
|
fetch: asJsonFetch,
|
|
3588
3207
|
apiHost: this.client.apiHost,
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
browserMultiaddrs: browserBootstrapMultiaddrs,
|
|
3592
|
-
registrationId,
|
|
3593
|
-
profile,
|
|
3594
|
-
version: this.state.manifest?.version,
|
|
3595
|
-
forgetPrevious: true,
|
|
3596
|
-
sync: true
|
|
3208
|
+
attempts: 24,
|
|
3209
|
+
delayMs: 2500
|
|
3597
3210
|
});
|
|
3598
|
-
this.trace("deploy:bootstrap-registration", {
|
|
3211
|
+
this.trace("deploy:bootstrap-registration-visible", {
|
|
3599
3212
|
itemHash: args.itemHash,
|
|
3213
|
+
registrationId,
|
|
3600
3214
|
peerId,
|
|
3601
|
-
|
|
3602
|
-
publication
|
|
3215
|
+
visibleRegistration
|
|
3603
3216
|
});
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
hasher: sha256Hex,
|
|
3609
|
-
fetch: asJsonFetch,
|
|
3610
|
-
profile,
|
|
3611
|
-
apiHost: this.client.apiHost,
|
|
3612
|
-
crns: this.state.crns,
|
|
3613
|
-
crnListUrl: this.props.crnListUrl,
|
|
3614
|
-
preferSecureMetadata: profile === "uc-go-peer",
|
|
3615
|
-
current: {
|
|
3616
|
-
itemHash: args.itemHash,
|
|
3617
|
-
registrationId,
|
|
3618
|
-
peerId,
|
|
3619
|
-
probeMultiaddrs,
|
|
3620
|
-
browserBootstrapMultiaddrs
|
|
3621
|
-
}
|
|
3622
|
-
});
|
|
3623
|
-
if (reconcileResult.errors.length > 0) {
|
|
3624
|
-
this.trace("deploy:owner-bootstrap-reconcile-errors", {
|
|
3625
|
-
itemHash: args.itemHash,
|
|
3626
|
-
errors: reconcileResult.errors
|
|
3627
|
-
});
|
|
3217
|
+
if (!visibleRegistration) {
|
|
3218
|
+
throw new Error(
|
|
3219
|
+
"Relay bootstrap registration did not become visible on Aleph."
|
|
3220
|
+
);
|
|
3628
3221
|
}
|
|
3629
3222
|
if (profile === "uc-go-peer" && args.deploymentToken) {
|
|
3630
3223
|
await deleteVmBootstrapConfig({
|
|
@@ -4115,12 +3708,14 @@ var SponsorRelayController = class {
|
|
|
4115
3708
|
for (const [candidateIndex, candidateCrn] of orderedCrns.entries()) {
|
|
4116
3709
|
let attemptItemHash = null;
|
|
4117
3710
|
let attemptDeploymentToken = null;
|
|
3711
|
+
const crnAttemptLabel = `CRN ${candidateIndex + 1}/${orderedCrns.length}`;
|
|
3712
|
+
const crnDisplayName = candidateCrn.name ?? candidateCrn.hash;
|
|
4118
3713
|
this.emitProgress({
|
|
4119
3714
|
stage: "selecting-crn",
|
|
4120
|
-
label:
|
|
3715
|
+
label: `Selecting ${crnAttemptLabel}`,
|
|
4121
3716
|
progress: 18,
|
|
4122
3717
|
status: "info",
|
|
4123
|
-
detail: `Trying ${
|
|
3718
|
+
detail: `Trying ${crnDisplayName}`
|
|
4124
3719
|
});
|
|
4125
3720
|
try {
|
|
4126
3721
|
const profile = relayProfileForManifest(this.state.manifest);
|
|
@@ -4330,7 +3925,7 @@ var SponsorRelayController = class {
|
|
|
4330
3925
|
return;
|
|
4331
3926
|
} catch (error) {
|
|
4332
3927
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
4333
|
-
const attemptLabel =
|
|
3928
|
+
const attemptLabel = crnDisplayName;
|
|
4334
3929
|
attemptErrors.push(`${attemptLabel}: ${lastError.message}`);
|
|
4335
3930
|
this.trace("deploy:crn-attempt-error", {
|
|
4336
3931
|
crnHash: candidateCrn.hash,
|
|
@@ -4399,7 +3994,7 @@ var SponsorRelayController = class {
|
|
|
4399
3994
|
if (candidateIndex < orderedCrns.length - 1) {
|
|
4400
3995
|
this.emitProgress({
|
|
4401
3996
|
stage: "selecting-crn",
|
|
4402
|
-
label:
|
|
3997
|
+
label: `Retrying after ${crnAttemptLabel}`,
|
|
4403
3998
|
progress: 20,
|
|
4404
3999
|
status: "warning",
|
|
4405
4000
|
itemHash: attemptItemHash,
|
|
@@ -4461,29 +4056,6 @@ var SponsorRelayController = class {
|
|
|
4461
4056
|
this.emitProgress(event);
|
|
4462
4057
|
}
|
|
4463
4058
|
});
|
|
4464
|
-
const profile = relayProfileForManifest(this.state.manifest);
|
|
4465
|
-
if (profile) {
|
|
4466
|
-
await reconcileOwnerRelayBootstrapRegistrations({
|
|
4467
|
-
instanceOwnerAddress: this.state.wallet.address,
|
|
4468
|
-
sender: this.state.wallet.address,
|
|
4469
|
-
signer: personalSign,
|
|
4470
|
-
hasher: sha256Hex,
|
|
4471
|
-
fetch: asJsonFetch,
|
|
4472
|
-
profile,
|
|
4473
|
-
apiHost: this.client.apiHost,
|
|
4474
|
-
crns: this.state.crns,
|
|
4475
|
-
crnListUrl: this.props.crnListUrl,
|
|
4476
|
-
preferSecureMetadata: profile === "uc-go-peer"
|
|
4477
|
-
}).catch(
|
|
4478
|
-
(error) => {
|
|
4479
|
-
this.trace("delete:owner-bootstrap-reconcile-error", {
|
|
4480
|
-
instanceHash,
|
|
4481
|
-
profile,
|
|
4482
|
-
error: error instanceof Error ? error.message : String(error)
|
|
4483
|
-
});
|
|
4484
|
-
}
|
|
4485
|
-
);
|
|
4486
|
-
}
|
|
4487
4059
|
this.patch({
|
|
4488
4060
|
busy: { deletingInstanceHash: null },
|
|
4489
4061
|
statusText: `Deletion submitted for ${instanceHash}`
|