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