@le-space/ui 0.3.18 → 0.3.20
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 +10 -513
- package/shared/index.d.ts +1 -1
- package/shared/index.js +10 -513
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@le-space/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.20",
|
|
4
4
|
"description": "Floating Aleph sponsor relay UI components for Svelte and React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@le-space/browser": "0.3.
|
|
40
|
-
"@le-space/core": "0.3.
|
|
39
|
+
"@le-space/browser": "0.3.20",
|
|
40
|
+
"@le-space/core": "0.3.20",
|
|
41
41
|
"viem": "^2.38.5"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
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.20";
|
|
43
43
|
|
|
44
44
|
// src/shared/format.ts
|
|
45
45
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -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") {
|
|
@@ -2537,7 +2348,7 @@ function sleep(ms) {
|
|
|
2537
2348
|
async function waitForRelayBootstrapRegistration(args) {
|
|
2538
2349
|
const attempts = Math.max(1, Number(args.attempts ?? 10));
|
|
2539
2350
|
const delayMs = Math.max(0, Number(args.delayMs ?? 2e3));
|
|
2540
|
-
const expectedSender = args.sender
|
|
2351
|
+
const expectedSender = args.sender?.trim().toLowerCase() || null;
|
|
2541
2352
|
const expectedRegistrationId = args.registrationId?.trim() || null;
|
|
2542
2353
|
const expectedPeerId = args.peerId?.trim() || null;
|
|
2543
2354
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
@@ -2550,8 +2361,9 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2550
2361
|
});
|
|
2551
2362
|
const currentPosts = selectCurrentRelayBootstrapPosts(posts);
|
|
2552
2363
|
const match = currentPosts.find((post) => {
|
|
2553
|
-
|
|
2554
|
-
|
|
2364
|
+
if (expectedSender && post.address?.toLowerCase() !== expectedSender) {
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2555
2367
|
if (expectedRegistrationId && post.content?.registrationId === expectedRegistrationId) {
|
|
2556
2368
|
return true;
|
|
2557
2369
|
}
|
|
@@ -2564,6 +2376,7 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2564
2376
|
return {
|
|
2565
2377
|
itemHash: match.itemHash ?? null,
|
|
2566
2378
|
hash: match.hash ?? null,
|
|
2379
|
+
sender: typeof match.address === "string" ? match.address : null,
|
|
2567
2380
|
registrationId: match.content.registrationId,
|
|
2568
2381
|
peerId: match.content.peerId,
|
|
2569
2382
|
multiaddrs: Array.isArray(match.content.multiaddrs) ? match.content.multiaddrs : [],
|
|
@@ -2576,109 +2389,6 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2576
2389
|
}
|
|
2577
2390
|
return null;
|
|
2578
2391
|
}
|
|
2579
|
-
async function publishRelayBootstrapRegistration(args) {
|
|
2580
|
-
const publisherAddress = args.publisherAddress ?? args.sender;
|
|
2581
|
-
const ownerAddress = args.ownerAddress;
|
|
2582
|
-
let ownerAuthorization = args.ownerAuthorization;
|
|
2583
|
-
let relayProof = args.relayProof;
|
|
2584
|
-
if (!ownerAuthorization && ownerAddress && args.ownerSigner) {
|
|
2585
|
-
ownerAuthorization = await signRelayBootstrapAuthorization({
|
|
2586
|
-
ownerAddress,
|
|
2587
|
-
publisherAddress,
|
|
2588
|
-
peerId: args.peerId,
|
|
2589
|
-
registrationId: args.registrationId,
|
|
2590
|
-
profile: args.profile,
|
|
2591
|
-
version: args.version,
|
|
2592
|
-
instanceItemHash: args.instanceItemHash,
|
|
2593
|
-
issuedAt: args.authorizationIssuedAt ?? args.now ?? Date.now(),
|
|
2594
|
-
expiresAt: args.authorizationExpiresAt,
|
|
2595
|
-
signer: args.ownerSigner
|
|
2596
|
-
});
|
|
2597
|
-
}
|
|
2598
|
-
if (!relayProof && args.publisherSigner) {
|
|
2599
|
-
relayProof = await signRelayBootstrapProof({
|
|
2600
|
-
publisherAddress,
|
|
2601
|
-
peerId: args.peerId,
|
|
2602
|
-
multiaddrs: args.multiaddrs,
|
|
2603
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2604
|
-
registrationId: args.registrationId,
|
|
2605
|
-
profile: args.profile,
|
|
2606
|
-
version: args.version,
|
|
2607
|
-
updatedAt: args.now ?? Date.now(),
|
|
2608
|
-
signer: args.publisherSigner
|
|
2609
|
-
});
|
|
2610
|
-
}
|
|
2611
|
-
const unsigned = await createRelayBootstrapPost({
|
|
2612
|
-
sender: args.sender,
|
|
2613
|
-
peerId: args.peerId,
|
|
2614
|
-
multiaddrs: args.multiaddrs,
|
|
2615
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2616
|
-
registrationId: args.registrationId,
|
|
2617
|
-
channel: args.channel,
|
|
2618
|
-
ref: args.ref,
|
|
2619
|
-
postType: args.postType,
|
|
2620
|
-
profile: args.profile,
|
|
2621
|
-
version: args.version,
|
|
2622
|
-
ownerAddress,
|
|
2623
|
-
publisherAddress,
|
|
2624
|
-
authorization: ownerAuthorization,
|
|
2625
|
-
relayProof,
|
|
2626
|
-
now: args.now,
|
|
2627
|
-
hasher: args.hasher
|
|
2628
|
-
});
|
|
2629
|
-
const content = JSON.parse(unsigned.item_content);
|
|
2630
|
-
if ((content.content?.multiaddrs?.length ?? 0) === 0) {
|
|
2631
|
-
return {
|
|
2632
|
-
status: "skipped",
|
|
2633
|
-
reason: "No public relay multiaddrs remained after filtering.",
|
|
2634
|
-
publishedMultiaddrs: [],
|
|
2635
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? []
|
|
2636
|
-
};
|
|
2637
|
-
}
|
|
2638
|
-
const message = await signAlephMessage(unsigned, args.signer);
|
|
2639
|
-
const { response, httpStatus } = await broadcastAlephMessage2(message, {
|
|
2640
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2641
|
-
sync: args.sync ?? true,
|
|
2642
|
-
fetch: args.fetch
|
|
2643
|
-
});
|
|
2644
|
-
let forgottenHashes = [];
|
|
2645
|
-
let forgetResult;
|
|
2646
|
-
if (args.forgetPrevious && args.registrationId) {
|
|
2647
|
-
const previousPosts = await fetchAlephBootstrapPosts({
|
|
2648
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2649
|
-
channel: args.channel,
|
|
2650
|
-
ref: args.ref,
|
|
2651
|
-
postType: args.postType,
|
|
2652
|
-
fetch: args.fetch
|
|
2653
|
-
});
|
|
2654
|
-
forgottenHashes = previousPosts.filter(
|
|
2655
|
-
(post) => post.address?.toLowerCase() === args.sender.toLowerCase() && post.content?.registrationId === args.registrationId && (post.itemHash ?? post.hash) != null && (post.itemHash ?? post.hash) !== unsigned.item_hash
|
|
2656
|
-
).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean);
|
|
2657
|
-
if (forgottenHashes.length > 0) {
|
|
2658
|
-
forgetResult = await forgetAlephMessages({
|
|
2659
|
-
sender: args.sender,
|
|
2660
|
-
hashes: forgottenHashes,
|
|
2661
|
-
reason: args.forgetPreviousReason ?? `Replace older relay bootstrap records for ${args.registrationId}`,
|
|
2662
|
-
signer: args.signer,
|
|
2663
|
-
hasher: args.hasher,
|
|
2664
|
-
fetch: args.fetch,
|
|
2665
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2666
|
-
sync: args.sync ?? true
|
|
2667
|
-
});
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
return {
|
|
2671
|
-
status: "published",
|
|
2672
|
-
itemHash: unsigned.item_hash,
|
|
2673
|
-
message,
|
|
2674
|
-
response,
|
|
2675
|
-
httpStatus,
|
|
2676
|
-
publishedMultiaddrs: content.content?.multiaddrs ?? [],
|
|
2677
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? [],
|
|
2678
|
-
forgottenHashes,
|
|
2679
|
-
forgetResult
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
2392
|
|
|
2683
2393
|
// ../core/src/bootstrap-config.ts
|
|
2684
2394
|
var VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY = "vm-bootstrap-config";
|
|
@@ -2832,24 +2542,6 @@ function extractRelayMetadata(payload) {
|
|
|
2832
2542
|
browserBootstrapMultiaddrs
|
|
2833
2543
|
};
|
|
2834
2544
|
}
|
|
2835
|
-
async function fetchOwnerInstances(address, options) {
|
|
2836
|
-
const url = new URL("/api/v0/messages.json", options.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2837
|
-
url.searchParams.set("msgTypes", "INSTANCE");
|
|
2838
|
-
url.searchParams.set("addresses", address);
|
|
2839
|
-
url.searchParams.set("message_statuses", "processed,pending,rejected,removing");
|
|
2840
|
-
url.searchParams.set("pagination", "100");
|
|
2841
|
-
url.searchParams.set("page", "1");
|
|
2842
|
-
url.searchParams.set("sortOrder", "-1");
|
|
2843
|
-
const response = await options.fetch(url.toString(), { cache: "no-cache" });
|
|
2844
|
-
if (!response.ok) {
|
|
2845
|
-
throw new Error(`Instance list request failed: ${response.status}`);
|
|
2846
|
-
}
|
|
2847
|
-
const payload = await response.json();
|
|
2848
|
-
return (payload.messages ?? []).map((message) => ({
|
|
2849
|
-
...message,
|
|
2850
|
-
status: typeof message.status === "string" && message.status.trim() ? message.status : message.confirmed ? "processed" : "pending"
|
|
2851
|
-
}));
|
|
2852
|
-
}
|
|
2853
2545
|
async function fetchRelayMetadataForRuntime(args) {
|
|
2854
2546
|
const setupPort = args.runtime.mappedPorts?.["80"]?.host ?? 80;
|
|
2855
2547
|
const metadataUrl = args.preferSecureMetadata ? secureBootstrapMetadataUrl(args.runtime.proxyUrl) : null;
|
|
@@ -2876,123 +2568,6 @@ async function fetchRelayMetadataForRuntime(args) {
|
|
|
2876
2568
|
}).catch(() => null);
|
|
2877
2569
|
return extractRelayMetadata(payload);
|
|
2878
2570
|
}
|
|
2879
|
-
async function reconcileOwnerRelayBootstrapRegistrations(args) {
|
|
2880
|
-
const result = {
|
|
2881
|
-
refreshedRegistrations: [],
|
|
2882
|
-
forgottenHashes: [],
|
|
2883
|
-
skippedInstanceHashes: [],
|
|
2884
|
-
errors: []
|
|
2885
|
-
};
|
|
2886
|
-
const liveRegistrationIds = /* @__PURE__ */ new Set();
|
|
2887
|
-
if (args.current?.registrationId) {
|
|
2888
|
-
liveRegistrationIds.add(args.current.registrationId);
|
|
2889
|
-
result.refreshedRegistrations.push(args.current.registrationId);
|
|
2890
|
-
}
|
|
2891
|
-
const instances = await fetchOwnerInstances(args.instanceOwnerAddress, {
|
|
2892
|
-
apiHost: args.apiHost,
|
|
2893
|
-
fetch: args.fetch
|
|
2894
|
-
});
|
|
2895
|
-
const processedInstances = instances.filter((instance) => {
|
|
2896
|
-
const status = String(instance.status ?? "").trim().toLowerCase();
|
|
2897
|
-
return status === "processed";
|
|
2898
|
-
});
|
|
2899
|
-
for (const instance of processedInstances) {
|
|
2900
|
-
if (instance.item_hash === args.current?.itemHash) continue;
|
|
2901
|
-
const registrationId = createRelayBootstrapRegistrationId(
|
|
2902
|
-
args.profile,
|
|
2903
|
-
instance.content?.metadata?.name,
|
|
2904
|
-
instance.item_hash
|
|
2905
|
-
);
|
|
2906
|
-
try {
|
|
2907
|
-
const runtime = await fetchVmRuntime({
|
|
2908
|
-
itemHash: instance.item_hash,
|
|
2909
|
-
fetch: args.fetch,
|
|
2910
|
-
crns: args.crns,
|
|
2911
|
-
crnListUrl: args.crnListUrl
|
|
2912
|
-
});
|
|
2913
|
-
if (!runtime.hostIpv4 || Object.keys(runtime.mappedPorts ?? {}).length === 0) {
|
|
2914
|
-
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2915
|
-
continue;
|
|
2916
|
-
}
|
|
2917
|
-
const relayMetadata = await fetchRelayMetadataForRuntime({
|
|
2918
|
-
runtime,
|
|
2919
|
-
fetch: args.fetch,
|
|
2920
|
-
preferSecureMetadata: args.preferSecureMetadata,
|
|
2921
|
-
attempts: 3,
|
|
2922
|
-
delayMs: 1e3,
|
|
2923
|
-
timeoutMs: 1e4
|
|
2924
|
-
});
|
|
2925
|
-
if (!relayMetadata) {
|
|
2926
|
-
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2927
|
-
continue;
|
|
2928
|
-
}
|
|
2929
|
-
liveRegistrationIds.add(registrationId);
|
|
2930
|
-
await publishRelayBootstrapRegistration({
|
|
2931
|
-
sender: args.sender,
|
|
2932
|
-
signer: args.signer,
|
|
2933
|
-
hasher: args.hasher,
|
|
2934
|
-
fetch: args.fetch,
|
|
2935
|
-
apiHost: args.apiHost,
|
|
2936
|
-
channel: args.channel,
|
|
2937
|
-
ref: args.ref,
|
|
2938
|
-
postType: args.postType,
|
|
2939
|
-
peerId: relayMetadata.peerId,
|
|
2940
|
-
multiaddrs: relayMetadata.probeMultiaddrs,
|
|
2941
|
-
browserMultiaddrs: relayMetadata.browserBootstrapMultiaddrs,
|
|
2942
|
-
registrationId,
|
|
2943
|
-
ownerAddress: args.ownerAddress,
|
|
2944
|
-
publisherAddress: args.publisherAddress,
|
|
2945
|
-
ownerSigner: args.ownerSigner,
|
|
2946
|
-
publisherSigner: args.publisherSigner,
|
|
2947
|
-
forgetPrevious: true,
|
|
2948
|
-
profile: args.profile,
|
|
2949
|
-
version: args.version,
|
|
2950
|
-
instanceItemHash: instance.item_hash,
|
|
2951
|
-
sync: true
|
|
2952
|
-
});
|
|
2953
|
-
result.refreshedRegistrations.push(registrationId);
|
|
2954
|
-
} catch (error) {
|
|
2955
|
-
result.errors.push({
|
|
2956
|
-
phase: "publish",
|
|
2957
|
-
itemHash: instance.item_hash,
|
|
2958
|
-
registrationId,
|
|
2959
|
-
message: error instanceof Error ? error.message : String(error)
|
|
2960
|
-
});
|
|
2961
|
-
}
|
|
2962
|
-
}
|
|
2963
|
-
try {
|
|
2964
|
-
const bootstrapPosts = await fetchAlephBootstrapPosts({
|
|
2965
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2966
|
-
channel: args.channel,
|
|
2967
|
-
ref: args.ref,
|
|
2968
|
-
postType: args.postType,
|
|
2969
|
-
fetch: args.fetch
|
|
2970
|
-
});
|
|
2971
|
-
const currentPosts = selectCurrentRelayBootstrapPosts(bootstrapPosts);
|
|
2972
|
-
const staleHashes = currentPosts.filter(
|
|
2973
|
-
(post) => post.address?.toLowerCase() === args.sender.toLowerCase() && post.content?.profile === args.profile && post.content?.registrationId && !liveRegistrationIds.has(post.content.registrationId)
|
|
2974
|
-
).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean);
|
|
2975
|
-
if (staleHashes.length > 0) {
|
|
2976
|
-
await forgetAlephMessages({
|
|
2977
|
-
sender: args.sender,
|
|
2978
|
-
hashes: staleHashes,
|
|
2979
|
-
reason: `Forget stale ${args.profile} relay bootstrap registrations after owner reconcile`,
|
|
2980
|
-
signer: args.signer,
|
|
2981
|
-
hasher: args.hasher,
|
|
2982
|
-
fetch: args.fetch,
|
|
2983
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2984
|
-
sync: true
|
|
2985
|
-
});
|
|
2986
|
-
result.forgottenHashes.push(...staleHashes);
|
|
2987
|
-
}
|
|
2988
|
-
} catch (error) {
|
|
2989
|
-
result.errors.push({
|
|
2990
|
-
phase: "forget",
|
|
2991
|
-
message: error instanceof Error ? error.message : String(error)
|
|
2992
|
-
});
|
|
2993
|
-
}
|
|
2994
|
-
return result;
|
|
2995
|
-
}
|
|
2996
2571
|
|
|
2997
2572
|
// src/shared/events.ts
|
|
2998
2573
|
function createDeploymentProgressEmitter() {
|
|
@@ -3612,7 +3187,7 @@ var SponsorRelayController = class {
|
|
|
3612
3187
|
if (!relayMetadata) {
|
|
3613
3188
|
throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
|
|
3614
3189
|
}
|
|
3615
|
-
const { peerId
|
|
3190
|
+
const { peerId } = relayMetadata;
|
|
3616
3191
|
const registrationId = createRelayBootstrapRegistrationId(
|
|
3617
3192
|
profile,
|
|
3618
3193
|
this.state.instanceName.trim(),
|
|
@@ -3620,48 +3195,18 @@ var SponsorRelayController = class {
|
|
|
3620
3195
|
);
|
|
3621
3196
|
this.emitProgress({
|
|
3622
3197
|
stage: "publishing-bootstrap",
|
|
3623
|
-
label: "
|
|
3198
|
+
label: "Waiting for guest bootstrap registration",
|
|
3624
3199
|
progress: 96,
|
|
3625
3200
|
status: "info",
|
|
3626
3201
|
itemHash: args.itemHash,
|
|
3627
|
-
detail: "
|
|
3628
|
-
});
|
|
3629
|
-
const publication = await publishRelayBootstrapRegistration({
|
|
3630
|
-
sender: this.state.wallet.address,
|
|
3631
|
-
signer: personalSign,
|
|
3632
|
-
hasher: sha256Hex,
|
|
3633
|
-
fetch: asJsonFetch,
|
|
3634
|
-
apiHost: this.client.apiHost,
|
|
3635
|
-
peerId,
|
|
3636
|
-
multiaddrs: probeMultiaddrs,
|
|
3637
|
-
browserMultiaddrs: browserBootstrapMultiaddrs,
|
|
3638
|
-
registrationId,
|
|
3639
|
-
profile,
|
|
3640
|
-
version: this.state.manifest?.version,
|
|
3641
|
-
forgetPrevious: true,
|
|
3642
|
-
sync: true
|
|
3643
|
-
});
|
|
3644
|
-
this.trace("deploy:bootstrap-registration", {
|
|
3645
|
-
itemHash: args.itemHash,
|
|
3646
|
-
peerId,
|
|
3647
|
-
metadata: relayMetadata,
|
|
3648
|
-
publication
|
|
3649
|
-
});
|
|
3650
|
-
this.emitProgress({
|
|
3651
|
-
stage: "publishing-bootstrap",
|
|
3652
|
-
label: "Verifying bootstrap registration",
|
|
3653
|
-
progress: 97,
|
|
3654
|
-
status: "info",
|
|
3655
|
-
itemHash: args.itemHash,
|
|
3656
|
-
detail: "Waiting for the relay bootstrap registration to appear on Aleph."
|
|
3202
|
+
detail: "Waiting for the relay VM to publish its own bootstrap registration to Aleph."
|
|
3657
3203
|
});
|
|
3658
3204
|
const visibleRegistration = await waitForRelayBootstrapRegistration({
|
|
3659
|
-
sender: this.state.wallet.address,
|
|
3660
3205
|
registrationId,
|
|
3661
3206
|
peerId,
|
|
3662
3207
|
fetch: asJsonFetch,
|
|
3663
3208
|
apiHost: this.client.apiHost,
|
|
3664
|
-
attempts:
|
|
3209
|
+
attempts: 24,
|
|
3665
3210
|
delayMs: 2500
|
|
3666
3211
|
});
|
|
3667
3212
|
this.trace("deploy:bootstrap-registration-visible", {
|
|
@@ -3675,31 +3220,6 @@ var SponsorRelayController = class {
|
|
|
3675
3220
|
"Relay bootstrap registration did not become visible on Aleph."
|
|
3676
3221
|
);
|
|
3677
3222
|
}
|
|
3678
|
-
const reconcileResult = await reconcileOwnerRelayBootstrapRegistrations({
|
|
3679
|
-
instanceOwnerAddress: this.state.wallet.address,
|
|
3680
|
-
sender: this.state.wallet.address,
|
|
3681
|
-
signer: personalSign,
|
|
3682
|
-
hasher: sha256Hex,
|
|
3683
|
-
fetch: asJsonFetch,
|
|
3684
|
-
profile,
|
|
3685
|
-
apiHost: this.client.apiHost,
|
|
3686
|
-
crns: this.state.crns,
|
|
3687
|
-
crnListUrl: this.props.crnListUrl,
|
|
3688
|
-
preferSecureMetadata: profile === "uc-go-peer",
|
|
3689
|
-
current: {
|
|
3690
|
-
itemHash: args.itemHash,
|
|
3691
|
-
registrationId,
|
|
3692
|
-
peerId,
|
|
3693
|
-
probeMultiaddrs,
|
|
3694
|
-
browserBootstrapMultiaddrs
|
|
3695
|
-
}
|
|
3696
|
-
});
|
|
3697
|
-
if (reconcileResult.errors.length > 0) {
|
|
3698
|
-
this.trace("deploy:owner-bootstrap-reconcile-errors", {
|
|
3699
|
-
itemHash: args.itemHash,
|
|
3700
|
-
errors: reconcileResult.errors
|
|
3701
|
-
});
|
|
3702
|
-
}
|
|
3703
3223
|
if (profile === "uc-go-peer" && args.deploymentToken) {
|
|
3704
3224
|
await deleteVmBootstrapConfig({
|
|
3705
3225
|
sender: this.state.wallet.address,
|
|
@@ -4537,29 +4057,6 @@ var SponsorRelayController = class {
|
|
|
4537
4057
|
this.emitProgress(event);
|
|
4538
4058
|
}
|
|
4539
4059
|
});
|
|
4540
|
-
const profile = relayProfileForManifest(this.state.manifest);
|
|
4541
|
-
if (profile) {
|
|
4542
|
-
await reconcileOwnerRelayBootstrapRegistrations({
|
|
4543
|
-
instanceOwnerAddress: this.state.wallet.address,
|
|
4544
|
-
sender: this.state.wallet.address,
|
|
4545
|
-
signer: personalSign,
|
|
4546
|
-
hasher: sha256Hex,
|
|
4547
|
-
fetch: asJsonFetch,
|
|
4548
|
-
profile,
|
|
4549
|
-
apiHost: this.client.apiHost,
|
|
4550
|
-
crns: this.state.crns,
|
|
4551
|
-
crnListUrl: this.props.crnListUrl,
|
|
4552
|
-
preferSecureMetadata: profile === "uc-go-peer"
|
|
4553
|
-
}).catch(
|
|
4554
|
-
(error) => {
|
|
4555
|
-
this.trace("delete:owner-bootstrap-reconcile-error", {
|
|
4556
|
-
instanceHash,
|
|
4557
|
-
profile,
|
|
4558
|
-
error: error instanceof Error ? error.message : String(error)
|
|
4559
|
-
});
|
|
4560
|
-
}
|
|
4561
|
-
);
|
|
4562
|
-
}
|
|
4563
4060
|
this.patch({
|
|
4564
4061
|
busy: { deletingInstanceHash: null },
|
|
4565
4062
|
statusText: `Deletion submitted for ${instanceHash}`
|
package/shared/index.d.ts
CHANGED
|
@@ -304,7 +304,7 @@ declare const STALE_INSTANCE_ALLOCATION_COOLDOWN_MS: number;
|
|
|
304
304
|
declare const RECENT_INSTANCE_RUNTIME_GRACE_MS: number;
|
|
305
305
|
declare const DEPLOYMENT_PENDING_WARNING_MS: number;
|
|
306
306
|
|
|
307
|
-
declare const UI_PACKAGE_VERSION = "0.3.
|
|
307
|
+
declare const UI_PACKAGE_VERSION = "0.3.20";
|
|
308
308
|
|
|
309
309
|
interface RootfsRequiredPortForward {
|
|
310
310
|
port: number;
|
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.20";
|
|
42
42
|
|
|
43
43
|
// src/shared/format.ts
|
|
44
44
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -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") {
|
|
@@ -2536,7 +2347,7 @@ function sleep(ms) {
|
|
|
2536
2347
|
async function waitForRelayBootstrapRegistration(args) {
|
|
2537
2348
|
const attempts = Math.max(1, Number(args.attempts ?? 10));
|
|
2538
2349
|
const delayMs = Math.max(0, Number(args.delayMs ?? 2e3));
|
|
2539
|
-
const expectedSender = args.sender
|
|
2350
|
+
const expectedSender = args.sender?.trim().toLowerCase() || null;
|
|
2540
2351
|
const expectedRegistrationId = args.registrationId?.trim() || null;
|
|
2541
2352
|
const expectedPeerId = args.peerId?.trim() || null;
|
|
2542
2353
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
@@ -2549,8 +2360,9 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2549
2360
|
});
|
|
2550
2361
|
const currentPosts = selectCurrentRelayBootstrapPosts(posts);
|
|
2551
2362
|
const match = currentPosts.find((post) => {
|
|
2552
|
-
|
|
2553
|
-
|
|
2363
|
+
if (expectedSender && post.address?.toLowerCase() !== expectedSender) {
|
|
2364
|
+
return false;
|
|
2365
|
+
}
|
|
2554
2366
|
if (expectedRegistrationId && post.content?.registrationId === expectedRegistrationId) {
|
|
2555
2367
|
return true;
|
|
2556
2368
|
}
|
|
@@ -2563,6 +2375,7 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2563
2375
|
return {
|
|
2564
2376
|
itemHash: match.itemHash ?? null,
|
|
2565
2377
|
hash: match.hash ?? null,
|
|
2378
|
+
sender: typeof match.address === "string" ? match.address : null,
|
|
2566
2379
|
registrationId: match.content.registrationId,
|
|
2567
2380
|
peerId: match.content.peerId,
|
|
2568
2381
|
multiaddrs: Array.isArray(match.content.multiaddrs) ? match.content.multiaddrs : [],
|
|
@@ -2575,109 +2388,6 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2575
2388
|
}
|
|
2576
2389
|
return null;
|
|
2577
2390
|
}
|
|
2578
|
-
async function publishRelayBootstrapRegistration(args) {
|
|
2579
|
-
const publisherAddress = args.publisherAddress ?? args.sender;
|
|
2580
|
-
const ownerAddress = args.ownerAddress;
|
|
2581
|
-
let ownerAuthorization = args.ownerAuthorization;
|
|
2582
|
-
let relayProof = args.relayProof;
|
|
2583
|
-
if (!ownerAuthorization && ownerAddress && args.ownerSigner) {
|
|
2584
|
-
ownerAuthorization = await signRelayBootstrapAuthorization({
|
|
2585
|
-
ownerAddress,
|
|
2586
|
-
publisherAddress,
|
|
2587
|
-
peerId: args.peerId,
|
|
2588
|
-
registrationId: args.registrationId,
|
|
2589
|
-
profile: args.profile,
|
|
2590
|
-
version: args.version,
|
|
2591
|
-
instanceItemHash: args.instanceItemHash,
|
|
2592
|
-
issuedAt: args.authorizationIssuedAt ?? args.now ?? Date.now(),
|
|
2593
|
-
expiresAt: args.authorizationExpiresAt,
|
|
2594
|
-
signer: args.ownerSigner
|
|
2595
|
-
});
|
|
2596
|
-
}
|
|
2597
|
-
if (!relayProof && args.publisherSigner) {
|
|
2598
|
-
relayProof = await signRelayBootstrapProof({
|
|
2599
|
-
publisherAddress,
|
|
2600
|
-
peerId: args.peerId,
|
|
2601
|
-
multiaddrs: args.multiaddrs,
|
|
2602
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2603
|
-
registrationId: args.registrationId,
|
|
2604
|
-
profile: args.profile,
|
|
2605
|
-
version: args.version,
|
|
2606
|
-
updatedAt: args.now ?? Date.now(),
|
|
2607
|
-
signer: args.publisherSigner
|
|
2608
|
-
});
|
|
2609
|
-
}
|
|
2610
|
-
const unsigned = await createRelayBootstrapPost({
|
|
2611
|
-
sender: args.sender,
|
|
2612
|
-
peerId: args.peerId,
|
|
2613
|
-
multiaddrs: args.multiaddrs,
|
|
2614
|
-
browserMultiaddrs: args.browserMultiaddrs,
|
|
2615
|
-
registrationId: args.registrationId,
|
|
2616
|
-
channel: args.channel,
|
|
2617
|
-
ref: args.ref,
|
|
2618
|
-
postType: args.postType,
|
|
2619
|
-
profile: args.profile,
|
|
2620
|
-
version: args.version,
|
|
2621
|
-
ownerAddress,
|
|
2622
|
-
publisherAddress,
|
|
2623
|
-
authorization: ownerAuthorization,
|
|
2624
|
-
relayProof,
|
|
2625
|
-
now: args.now,
|
|
2626
|
-
hasher: args.hasher
|
|
2627
|
-
});
|
|
2628
|
-
const content = JSON.parse(unsigned.item_content);
|
|
2629
|
-
if ((content.content?.multiaddrs?.length ?? 0) === 0) {
|
|
2630
|
-
return {
|
|
2631
|
-
status: "skipped",
|
|
2632
|
-
reason: "No public relay multiaddrs remained after filtering.",
|
|
2633
|
-
publishedMultiaddrs: [],
|
|
2634
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? []
|
|
2635
|
-
};
|
|
2636
|
-
}
|
|
2637
|
-
const message = await signAlephMessage(unsigned, args.signer);
|
|
2638
|
-
const { response, httpStatus } = await broadcastAlephMessage2(message, {
|
|
2639
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2640
|
-
sync: args.sync ?? true,
|
|
2641
|
-
fetch: args.fetch
|
|
2642
|
-
});
|
|
2643
|
-
let forgottenHashes = [];
|
|
2644
|
-
let forgetResult;
|
|
2645
|
-
if (args.forgetPrevious && args.registrationId) {
|
|
2646
|
-
const previousPosts = await fetchAlephBootstrapPosts({
|
|
2647
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2648
|
-
channel: args.channel,
|
|
2649
|
-
ref: args.ref,
|
|
2650
|
-
postType: args.postType,
|
|
2651
|
-
fetch: args.fetch
|
|
2652
|
-
});
|
|
2653
|
-
forgottenHashes = previousPosts.filter(
|
|
2654
|
-
(post) => post.address?.toLowerCase() === args.sender.toLowerCase() && post.content?.registrationId === args.registrationId && (post.itemHash ?? post.hash) != null && (post.itemHash ?? post.hash) !== unsigned.item_hash
|
|
2655
|
-
).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean);
|
|
2656
|
-
if (forgottenHashes.length > 0) {
|
|
2657
|
-
forgetResult = await forgetAlephMessages({
|
|
2658
|
-
sender: args.sender,
|
|
2659
|
-
hashes: forgottenHashes,
|
|
2660
|
-
reason: args.forgetPreviousReason ?? `Replace older relay bootstrap records for ${args.registrationId}`,
|
|
2661
|
-
signer: args.signer,
|
|
2662
|
-
hasher: args.hasher,
|
|
2663
|
-
fetch: args.fetch,
|
|
2664
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2665
|
-
sync: args.sync ?? true
|
|
2666
|
-
});
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
return {
|
|
2670
|
-
status: "published",
|
|
2671
|
-
itemHash: unsigned.item_hash,
|
|
2672
|
-
message,
|
|
2673
|
-
response,
|
|
2674
|
-
httpStatus,
|
|
2675
|
-
publishedMultiaddrs: content.content?.multiaddrs ?? [],
|
|
2676
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? [],
|
|
2677
|
-
forgottenHashes,
|
|
2678
|
-
forgetResult
|
|
2679
|
-
};
|
|
2680
|
-
}
|
|
2681
2391
|
|
|
2682
2392
|
// ../core/src/bootstrap-config.ts
|
|
2683
2393
|
var VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY = "vm-bootstrap-config";
|
|
@@ -2831,24 +2541,6 @@ function extractRelayMetadata(payload) {
|
|
|
2831
2541
|
browserBootstrapMultiaddrs
|
|
2832
2542
|
};
|
|
2833
2543
|
}
|
|
2834
|
-
async function fetchOwnerInstances(address, options) {
|
|
2835
|
-
const url = new URL("/api/v0/messages.json", options.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2836
|
-
url.searchParams.set("msgTypes", "INSTANCE");
|
|
2837
|
-
url.searchParams.set("addresses", address);
|
|
2838
|
-
url.searchParams.set("message_statuses", "processed,pending,rejected,removing");
|
|
2839
|
-
url.searchParams.set("pagination", "100");
|
|
2840
|
-
url.searchParams.set("page", "1");
|
|
2841
|
-
url.searchParams.set("sortOrder", "-1");
|
|
2842
|
-
const response = await options.fetch(url.toString(), { cache: "no-cache" });
|
|
2843
|
-
if (!response.ok) {
|
|
2844
|
-
throw new Error(`Instance list request failed: ${response.status}`);
|
|
2845
|
-
}
|
|
2846
|
-
const payload = await response.json();
|
|
2847
|
-
return (payload.messages ?? []).map((message) => ({
|
|
2848
|
-
...message,
|
|
2849
|
-
status: typeof message.status === "string" && message.status.trim() ? message.status : message.confirmed ? "processed" : "pending"
|
|
2850
|
-
}));
|
|
2851
|
-
}
|
|
2852
2544
|
async function fetchRelayMetadataForRuntime(args) {
|
|
2853
2545
|
const setupPort = args.runtime.mappedPorts?.["80"]?.host ?? 80;
|
|
2854
2546
|
const metadataUrl = args.preferSecureMetadata ? secureBootstrapMetadataUrl(args.runtime.proxyUrl) : null;
|
|
@@ -2875,123 +2567,6 @@ async function fetchRelayMetadataForRuntime(args) {
|
|
|
2875
2567
|
}).catch(() => null);
|
|
2876
2568
|
return extractRelayMetadata(payload);
|
|
2877
2569
|
}
|
|
2878
|
-
async function reconcileOwnerRelayBootstrapRegistrations(args) {
|
|
2879
|
-
const result = {
|
|
2880
|
-
refreshedRegistrations: [],
|
|
2881
|
-
forgottenHashes: [],
|
|
2882
|
-
skippedInstanceHashes: [],
|
|
2883
|
-
errors: []
|
|
2884
|
-
};
|
|
2885
|
-
const liveRegistrationIds = /* @__PURE__ */ new Set();
|
|
2886
|
-
if (args.current?.registrationId) {
|
|
2887
|
-
liveRegistrationIds.add(args.current.registrationId);
|
|
2888
|
-
result.refreshedRegistrations.push(args.current.registrationId);
|
|
2889
|
-
}
|
|
2890
|
-
const instances = await fetchOwnerInstances(args.instanceOwnerAddress, {
|
|
2891
|
-
apiHost: args.apiHost,
|
|
2892
|
-
fetch: args.fetch
|
|
2893
|
-
});
|
|
2894
|
-
const processedInstances = instances.filter((instance) => {
|
|
2895
|
-
const status = String(instance.status ?? "").trim().toLowerCase();
|
|
2896
|
-
return status === "processed";
|
|
2897
|
-
});
|
|
2898
|
-
for (const instance of processedInstances) {
|
|
2899
|
-
if (instance.item_hash === args.current?.itemHash) continue;
|
|
2900
|
-
const registrationId = createRelayBootstrapRegistrationId(
|
|
2901
|
-
args.profile,
|
|
2902
|
-
instance.content?.metadata?.name,
|
|
2903
|
-
instance.item_hash
|
|
2904
|
-
);
|
|
2905
|
-
try {
|
|
2906
|
-
const runtime = await fetchVmRuntime({
|
|
2907
|
-
itemHash: instance.item_hash,
|
|
2908
|
-
fetch: args.fetch,
|
|
2909
|
-
crns: args.crns,
|
|
2910
|
-
crnListUrl: args.crnListUrl
|
|
2911
|
-
});
|
|
2912
|
-
if (!runtime.hostIpv4 || Object.keys(runtime.mappedPorts ?? {}).length === 0) {
|
|
2913
|
-
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2914
|
-
continue;
|
|
2915
|
-
}
|
|
2916
|
-
const relayMetadata = await fetchRelayMetadataForRuntime({
|
|
2917
|
-
runtime,
|
|
2918
|
-
fetch: args.fetch,
|
|
2919
|
-
preferSecureMetadata: args.preferSecureMetadata,
|
|
2920
|
-
attempts: 3,
|
|
2921
|
-
delayMs: 1e3,
|
|
2922
|
-
timeoutMs: 1e4
|
|
2923
|
-
});
|
|
2924
|
-
if (!relayMetadata) {
|
|
2925
|
-
result.skippedInstanceHashes.push(instance.item_hash);
|
|
2926
|
-
continue;
|
|
2927
|
-
}
|
|
2928
|
-
liveRegistrationIds.add(registrationId);
|
|
2929
|
-
await publishRelayBootstrapRegistration({
|
|
2930
|
-
sender: args.sender,
|
|
2931
|
-
signer: args.signer,
|
|
2932
|
-
hasher: args.hasher,
|
|
2933
|
-
fetch: args.fetch,
|
|
2934
|
-
apiHost: args.apiHost,
|
|
2935
|
-
channel: args.channel,
|
|
2936
|
-
ref: args.ref,
|
|
2937
|
-
postType: args.postType,
|
|
2938
|
-
peerId: relayMetadata.peerId,
|
|
2939
|
-
multiaddrs: relayMetadata.probeMultiaddrs,
|
|
2940
|
-
browserMultiaddrs: relayMetadata.browserBootstrapMultiaddrs,
|
|
2941
|
-
registrationId,
|
|
2942
|
-
ownerAddress: args.ownerAddress,
|
|
2943
|
-
publisherAddress: args.publisherAddress,
|
|
2944
|
-
ownerSigner: args.ownerSigner,
|
|
2945
|
-
publisherSigner: args.publisherSigner,
|
|
2946
|
-
forgetPrevious: true,
|
|
2947
|
-
profile: args.profile,
|
|
2948
|
-
version: args.version,
|
|
2949
|
-
instanceItemHash: instance.item_hash,
|
|
2950
|
-
sync: true
|
|
2951
|
-
});
|
|
2952
|
-
result.refreshedRegistrations.push(registrationId);
|
|
2953
|
-
} catch (error) {
|
|
2954
|
-
result.errors.push({
|
|
2955
|
-
phase: "publish",
|
|
2956
|
-
itemHash: instance.item_hash,
|
|
2957
|
-
registrationId,
|
|
2958
|
-
message: error instanceof Error ? error.message : String(error)
|
|
2959
|
-
});
|
|
2960
|
-
}
|
|
2961
|
-
}
|
|
2962
|
-
try {
|
|
2963
|
-
const bootstrapPosts = await fetchAlephBootstrapPosts({
|
|
2964
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2965
|
-
channel: args.channel,
|
|
2966
|
-
ref: args.ref,
|
|
2967
|
-
postType: args.postType,
|
|
2968
|
-
fetch: args.fetch
|
|
2969
|
-
});
|
|
2970
|
-
const currentPosts = selectCurrentRelayBootstrapPosts(bootstrapPosts);
|
|
2971
|
-
const staleHashes = currentPosts.filter(
|
|
2972
|
-
(post) => post.address?.toLowerCase() === args.sender.toLowerCase() && post.content?.profile === args.profile && post.content?.registrationId && !liveRegistrationIds.has(post.content.registrationId)
|
|
2973
|
-
).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean);
|
|
2974
|
-
if (staleHashes.length > 0) {
|
|
2975
|
-
await forgetAlephMessages({
|
|
2976
|
-
sender: args.sender,
|
|
2977
|
-
hashes: staleHashes,
|
|
2978
|
-
reason: `Forget stale ${args.profile} relay bootstrap registrations after owner reconcile`,
|
|
2979
|
-
signer: args.signer,
|
|
2980
|
-
hasher: args.hasher,
|
|
2981
|
-
fetch: args.fetch,
|
|
2982
|
-
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST2,
|
|
2983
|
-
sync: true
|
|
2984
|
-
});
|
|
2985
|
-
result.forgottenHashes.push(...staleHashes);
|
|
2986
|
-
}
|
|
2987
|
-
} catch (error) {
|
|
2988
|
-
result.errors.push({
|
|
2989
|
-
phase: "forget",
|
|
2990
|
-
message: error instanceof Error ? error.message : String(error)
|
|
2991
|
-
});
|
|
2992
|
-
}
|
|
2993
|
-
return result;
|
|
2994
|
-
}
|
|
2995
2570
|
|
|
2996
2571
|
// src/shared/events.ts
|
|
2997
2572
|
function createDeploymentProgressEmitter() {
|
|
@@ -3611,7 +3186,7 @@ var SponsorRelayController = class {
|
|
|
3611
3186
|
if (!relayMetadata) {
|
|
3612
3187
|
throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
|
|
3613
3188
|
}
|
|
3614
|
-
const { peerId
|
|
3189
|
+
const { peerId } = relayMetadata;
|
|
3615
3190
|
const registrationId = createRelayBootstrapRegistrationId(
|
|
3616
3191
|
profile,
|
|
3617
3192
|
this.state.instanceName.trim(),
|
|
@@ -3619,48 +3194,18 @@ var SponsorRelayController = class {
|
|
|
3619
3194
|
);
|
|
3620
3195
|
this.emitProgress({
|
|
3621
3196
|
stage: "publishing-bootstrap",
|
|
3622
|
-
label: "
|
|
3197
|
+
label: "Waiting for guest bootstrap registration",
|
|
3623
3198
|
progress: 96,
|
|
3624
3199
|
status: "info",
|
|
3625
3200
|
itemHash: args.itemHash,
|
|
3626
|
-
detail: "
|
|
3627
|
-
});
|
|
3628
|
-
const publication = await publishRelayBootstrapRegistration({
|
|
3629
|
-
sender: this.state.wallet.address,
|
|
3630
|
-
signer: personalSign,
|
|
3631
|
-
hasher: sha256Hex,
|
|
3632
|
-
fetch: asJsonFetch,
|
|
3633
|
-
apiHost: this.client.apiHost,
|
|
3634
|
-
peerId,
|
|
3635
|
-
multiaddrs: probeMultiaddrs,
|
|
3636
|
-
browserMultiaddrs: browserBootstrapMultiaddrs,
|
|
3637
|
-
registrationId,
|
|
3638
|
-
profile,
|
|
3639
|
-
version: this.state.manifest?.version,
|
|
3640
|
-
forgetPrevious: true,
|
|
3641
|
-
sync: true
|
|
3642
|
-
});
|
|
3643
|
-
this.trace("deploy:bootstrap-registration", {
|
|
3644
|
-
itemHash: args.itemHash,
|
|
3645
|
-
peerId,
|
|
3646
|
-
metadata: relayMetadata,
|
|
3647
|
-
publication
|
|
3648
|
-
});
|
|
3649
|
-
this.emitProgress({
|
|
3650
|
-
stage: "publishing-bootstrap",
|
|
3651
|
-
label: "Verifying bootstrap registration",
|
|
3652
|
-
progress: 97,
|
|
3653
|
-
status: "info",
|
|
3654
|
-
itemHash: args.itemHash,
|
|
3655
|
-
detail: "Waiting for the relay bootstrap registration to appear on Aleph."
|
|
3201
|
+
detail: "Waiting for the relay VM to publish its own bootstrap registration to Aleph."
|
|
3656
3202
|
});
|
|
3657
3203
|
const visibleRegistration = await waitForRelayBootstrapRegistration({
|
|
3658
|
-
sender: this.state.wallet.address,
|
|
3659
3204
|
registrationId,
|
|
3660
3205
|
peerId,
|
|
3661
3206
|
fetch: asJsonFetch,
|
|
3662
3207
|
apiHost: this.client.apiHost,
|
|
3663
|
-
attempts:
|
|
3208
|
+
attempts: 24,
|
|
3664
3209
|
delayMs: 2500
|
|
3665
3210
|
});
|
|
3666
3211
|
this.trace("deploy:bootstrap-registration-visible", {
|
|
@@ -3674,31 +3219,6 @@ var SponsorRelayController = class {
|
|
|
3674
3219
|
"Relay bootstrap registration did not become visible on Aleph."
|
|
3675
3220
|
);
|
|
3676
3221
|
}
|
|
3677
|
-
const reconcileResult = await reconcileOwnerRelayBootstrapRegistrations({
|
|
3678
|
-
instanceOwnerAddress: this.state.wallet.address,
|
|
3679
|
-
sender: this.state.wallet.address,
|
|
3680
|
-
signer: personalSign,
|
|
3681
|
-
hasher: sha256Hex,
|
|
3682
|
-
fetch: asJsonFetch,
|
|
3683
|
-
profile,
|
|
3684
|
-
apiHost: this.client.apiHost,
|
|
3685
|
-
crns: this.state.crns,
|
|
3686
|
-
crnListUrl: this.props.crnListUrl,
|
|
3687
|
-
preferSecureMetadata: profile === "uc-go-peer",
|
|
3688
|
-
current: {
|
|
3689
|
-
itemHash: args.itemHash,
|
|
3690
|
-
registrationId,
|
|
3691
|
-
peerId,
|
|
3692
|
-
probeMultiaddrs,
|
|
3693
|
-
browserBootstrapMultiaddrs
|
|
3694
|
-
}
|
|
3695
|
-
});
|
|
3696
|
-
if (reconcileResult.errors.length > 0) {
|
|
3697
|
-
this.trace("deploy:owner-bootstrap-reconcile-errors", {
|
|
3698
|
-
itemHash: args.itemHash,
|
|
3699
|
-
errors: reconcileResult.errors
|
|
3700
|
-
});
|
|
3701
|
-
}
|
|
3702
3222
|
if (profile === "uc-go-peer" && args.deploymentToken) {
|
|
3703
3223
|
await deleteVmBootstrapConfig({
|
|
3704
3224
|
sender: this.state.wallet.address,
|
|
@@ -4536,29 +4056,6 @@ var SponsorRelayController = class {
|
|
|
4536
4056
|
this.emitProgress(event);
|
|
4537
4057
|
}
|
|
4538
4058
|
});
|
|
4539
|
-
const profile = relayProfileForManifest(this.state.manifest);
|
|
4540
|
-
if (profile) {
|
|
4541
|
-
await reconcileOwnerRelayBootstrapRegistrations({
|
|
4542
|
-
instanceOwnerAddress: this.state.wallet.address,
|
|
4543
|
-
sender: this.state.wallet.address,
|
|
4544
|
-
signer: personalSign,
|
|
4545
|
-
hasher: sha256Hex,
|
|
4546
|
-
fetch: asJsonFetch,
|
|
4547
|
-
profile,
|
|
4548
|
-
apiHost: this.client.apiHost,
|
|
4549
|
-
crns: this.state.crns,
|
|
4550
|
-
crnListUrl: this.props.crnListUrl,
|
|
4551
|
-
preferSecureMetadata: profile === "uc-go-peer"
|
|
4552
|
-
}).catch(
|
|
4553
|
-
(error) => {
|
|
4554
|
-
this.trace("delete:owner-bootstrap-reconcile-error", {
|
|
4555
|
-
instanceHash,
|
|
4556
|
-
profile,
|
|
4557
|
-
error: error instanceof Error ? error.message : String(error)
|
|
4558
|
-
});
|
|
4559
|
-
}
|
|
4560
|
-
);
|
|
4561
|
-
}
|
|
4562
4059
|
this.patch({
|
|
4563
4060
|
busy: { deletingInstanceHash: null },
|
|
4564
4061
|
statusText: `Deletion submitted for ${instanceHash}`
|