@le-space/ui 0.6.4 → 0.6.5
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 +4 -4
- package/react/index.js +118 -32
- package/shared/index.d.ts +1 -1
- package/shared/index.js +118 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@le-space/ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Floating Aleph sponsor relay UI components for Svelte and React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"url": "https://github.com/NiKrause/relay-button/issues"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@le-space/browser": "0.6.
|
|
48
|
-
"@le-space/core": "0.6.
|
|
49
|
-
"viem": "^2.
|
|
47
|
+
"@le-space/browser": "0.6.5",
|
|
48
|
+
"@le-space/core": "0.6.5",
|
|
49
|
+
"viem": "^2.53.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"react": ">=18",
|
package/react/index.js
CHANGED
|
@@ -43,7 +43,7 @@ var RECENT_INSTANCE_RUNTIME_GRACE_MS = 10 * 60 * 1e3;
|
|
|
43
43
|
var DEPLOYMENT_PENDING_WARNING_MS = 3 * 60 * 1e3;
|
|
44
44
|
|
|
45
45
|
// src/shared/package-version.ts
|
|
46
|
-
var UI_PACKAGE_VERSION = "0.6.
|
|
46
|
+
var UI_PACKAGE_VERSION = "0.6.5";
|
|
47
47
|
|
|
48
48
|
// src/shared/format.ts
|
|
49
49
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -2333,9 +2333,11 @@ async function configureUcanStore(args) {
|
|
|
2333
2333
|
proxy_url: args.proxyUrl ?? void 0,
|
|
2334
2334
|
service_did: args.serviceDid ?? void 0,
|
|
2335
2335
|
service_origin: args.serviceOrigin ?? void 0,
|
|
2336
|
+
public_storage_origin: args.publicStorageOrigin ?? void 0,
|
|
2336
2337
|
webauthn_origin: args.webauthnOrigin ?? void 0,
|
|
2337
2338
|
webauthn_origin_fallbacks: args.webauthnOriginFallbacks ?? void 0,
|
|
2338
2339
|
admin_did: args.adminDid ?? void 0,
|
|
2340
|
+
admin_api_token: args.adminApiToken ?? void 0,
|
|
2339
2341
|
bootstrap_package: args.bootstrapPackage ?? void 0,
|
|
2340
2342
|
no_start: args.noStart === true ? true : void 0
|
|
2341
2343
|
};
|
|
@@ -2434,13 +2436,15 @@ async function fetchUcGoPeerMetadata(args) {
|
|
|
2434
2436
|
}
|
|
2435
2437
|
|
|
2436
2438
|
// ../aleph-bootstrap/src/index.ts
|
|
2437
|
-
import { recoverMessageAddress } from "viem";
|
|
2439
|
+
import { keccak256, recoverMessageAddress, stringToHex } from "viem";
|
|
2438
2440
|
var DEFAULT_ALEPH_API_HOST3 = "https://api.aleph.im";
|
|
2439
2441
|
var DEFAULT_ALEPH_BOOTSTRAP_CHANNEL = "simple-todo";
|
|
2440
2442
|
var DEFAULT_ALEPH_BOOTSTRAP_REF = "simple-todo-bootstrap";
|
|
2441
2443
|
var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap";
|
|
2444
|
+
var DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE = "relay-bootstrap-v2";
|
|
2442
2445
|
var DEFAULT_BOOTSTRAP_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2443
2446
|
var DEFAULT_BOOTSTRAP_PAGINATION = 50;
|
|
2447
|
+
var DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT = 3;
|
|
2444
2448
|
var RELAY_BOOTSTRAP_SIGNATURE_SCHEME = "personal_sign";
|
|
2445
2449
|
function serializeOwnerAuthorizationPayload(payload) {
|
|
2446
2450
|
return JSON.stringify({
|
|
@@ -2458,14 +2462,41 @@ function serializeOwnerAuthorizationPayload(payload) {
|
|
|
2458
2462
|
function serializeRelayProofPayload(payload) {
|
|
2459
2463
|
return JSON.stringify({
|
|
2460
2464
|
peerId: payload.peerId,
|
|
2461
|
-
multiaddrs: dedupeMultiaddrs(payload.multiaddrs),
|
|
2465
|
+
multiaddrs: payload.multiaddrs ? dedupeMultiaddrs(payload.multiaddrs) : void 0,
|
|
2462
2466
|
browserMultiaddrs: payload.browserMultiaddrs ? dedupeMultiaddrs(payload.browserMultiaddrs) : void 0,
|
|
2467
|
+
multiaddrsHash: payload.multiaddrsHash,
|
|
2468
|
+
browserMultiaddrsHash: payload.browserMultiaddrsHash,
|
|
2463
2469
|
registrationId: payload.registrationId,
|
|
2464
2470
|
profile: payload.profile,
|
|
2465
2471
|
version: payload.version,
|
|
2466
2472
|
updatedAt: payload.updatedAt
|
|
2467
2473
|
});
|
|
2468
2474
|
}
|
|
2475
|
+
function relayBootstrapMultiaddrsHash(addrs) {
|
|
2476
|
+
return keccak256(stringToHex(JSON.stringify(dedupeMultiaddrs(addrs))));
|
|
2477
|
+
}
|
|
2478
|
+
function compactPostType(postType) {
|
|
2479
|
+
return (postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE) === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2480
|
+
}
|
|
2481
|
+
function browserMultiaddrPreference(addr) {
|
|
2482
|
+
const normalized = addr.toLowerCase();
|
|
2483
|
+
if (normalized.includes("/tcp/443/tls/ws/")) return 0;
|
|
2484
|
+
if (normalized.includes("/tls/ws/")) return 1;
|
|
2485
|
+
if (normalized.includes("/webtransport/")) return 2;
|
|
2486
|
+
if (normalized.includes("/webrtc-direct/")) return 3;
|
|
2487
|
+
if (normalized.includes("/ws")) return 4;
|
|
2488
|
+
return 5;
|
|
2489
|
+
}
|
|
2490
|
+
function selectCompactRelayBootstrapMultiaddrs(addrs, limit = DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT) {
|
|
2491
|
+
const entries = filterPublicMultiaddrs(addrs, {
|
|
2492
|
+
browserDialableOnly: true
|
|
2493
|
+
}).map((addr, index) => ({ addr, index }));
|
|
2494
|
+
entries.sort((left, right) => {
|
|
2495
|
+
const preference = browserMultiaddrPreference(left.addr) - browserMultiaddrPreference(right.addr);
|
|
2496
|
+
return preference !== 0 ? preference : left.index - right.index;
|
|
2497
|
+
});
|
|
2498
|
+
return entries.map((entry) => entry.addr).slice(0, Math.max(1, Math.floor(limit)));
|
|
2499
|
+
}
|
|
2469
2500
|
function asTrimmedString(value) {
|
|
2470
2501
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
2471
2502
|
}
|
|
@@ -2621,8 +2652,10 @@ function normalizeRelayBootstrapProofPayload(value) {
|
|
|
2621
2652
|
const browserMultiaddrs = Array.isArray(payload.browserMultiaddrs) ? payload.browserMultiaddrs.filter((entry) => typeof entry === "string") : void 0;
|
|
2622
2653
|
return {
|
|
2623
2654
|
peerId,
|
|
2624
|
-
multiaddrs: dedupeMultiaddrs(multiaddrs),
|
|
2655
|
+
multiaddrs: multiaddrs.length > 0 ? dedupeMultiaddrs(multiaddrs) : void 0,
|
|
2625
2656
|
browserMultiaddrs: browserMultiaddrs ? dedupeMultiaddrs(browserMultiaddrs) : void 0,
|
|
2657
|
+
multiaddrsHash: asTrimmedString(payload.multiaddrsHash) ?? void 0,
|
|
2658
|
+
browserMultiaddrsHash: asTrimmedString(payload.browserMultiaddrsHash) ?? void 0,
|
|
2626
2659
|
registrationId: asTrimmedString(payload.registrationId) ?? void 0,
|
|
2627
2660
|
profile: asTrimmedString(payload.profile) ?? void 0,
|
|
2628
2661
|
version: asTrimmedString(payload.version) ?? void 0,
|
|
@@ -2654,16 +2687,24 @@ function normalizeRelayBootstrapPostRecord(value) {
|
|
|
2654
2687
|
function buildRelayBootstrapPostContent(args) {
|
|
2655
2688
|
const now = args.now ?? Date.now() / 1e3;
|
|
2656
2689
|
const updatedAt = args.now ?? Date.now();
|
|
2690
|
+
const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE;
|
|
2691
|
+
const compact = args.compact ?? compactPostType(postType);
|
|
2692
|
+
const fullMultiaddrs = filterPublicMultiaddrs(args.multiaddrs);
|
|
2693
|
+
const fullBrowserMultiaddrs = args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
|
|
2694
|
+
browserDialableOnly: true
|
|
2695
|
+
}) : void 0;
|
|
2696
|
+
const compactMultiaddrs = selectCompactRelayBootstrapMultiaddrs(
|
|
2697
|
+
fullBrowserMultiaddrs && fullBrowserMultiaddrs.length > 0 ? fullBrowserMultiaddrs : fullMultiaddrs,
|
|
2698
|
+
args.compactMultiaddrLimit
|
|
2699
|
+
);
|
|
2657
2700
|
return {
|
|
2658
|
-
type:
|
|
2701
|
+
type: postType,
|
|
2659
2702
|
address: args.sender,
|
|
2660
2703
|
...args.ref ? { ref: args.ref } : {},
|
|
2661
2704
|
content: {
|
|
2662
2705
|
peerId: args.peerId,
|
|
2663
|
-
multiaddrs:
|
|
2664
|
-
browserMultiaddrs:
|
|
2665
|
-
browserDialableOnly: true
|
|
2666
|
-
}) : void 0,
|
|
2706
|
+
multiaddrs: compact ? compactMultiaddrs : fullMultiaddrs,
|
|
2707
|
+
browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
|
|
2667
2708
|
registrationId: args.registrationId,
|
|
2668
2709
|
profile: args.profile,
|
|
2669
2710
|
version: args.version,
|
|
@@ -2693,6 +2734,8 @@ async function createRelayBootstrapPost(args) {
|
|
|
2693
2734
|
publisherAddress: args.publisherAddress,
|
|
2694
2735
|
authorization: args.authorization,
|
|
2695
2736
|
relayProof: args.relayProof,
|
|
2737
|
+
compact: args.compact,
|
|
2738
|
+
compactMultiaddrLimit: args.compactMultiaddrLimit,
|
|
2696
2739
|
now: nowMillis
|
|
2697
2740
|
});
|
|
2698
2741
|
itemContent.time = nowSeconds;
|
|
@@ -2730,12 +2773,20 @@ async function signRelayBootstrapAuthorization(args) {
|
|
|
2730
2773
|
};
|
|
2731
2774
|
}
|
|
2732
2775
|
async function signRelayBootstrapProof(args) {
|
|
2776
|
+
const fullMultiaddrs = filterPublicMultiaddrs(args.multiaddrs);
|
|
2777
|
+
const fullBrowserMultiaddrs = args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
|
|
2778
|
+
browserDialableOnly: true
|
|
2779
|
+
}) : void 0;
|
|
2780
|
+
const compactMultiaddrs = selectCompactRelayBootstrapMultiaddrs(
|
|
2781
|
+
fullBrowserMultiaddrs && fullBrowserMultiaddrs.length > 0 ? fullBrowserMultiaddrs : fullMultiaddrs,
|
|
2782
|
+
args.compactMultiaddrLimit
|
|
2783
|
+
);
|
|
2784
|
+
const compact = args.compact ?? false;
|
|
2733
2785
|
const payload = {
|
|
2734
2786
|
peerId: args.peerId,
|
|
2735
|
-
multiaddrs:
|
|
2736
|
-
browserMultiaddrs:
|
|
2737
|
-
|
|
2738
|
-
}) : void 0,
|
|
2787
|
+
multiaddrs: compact ? void 0 : fullMultiaddrs,
|
|
2788
|
+
browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
|
|
2789
|
+
multiaddrsHash: compact ? relayBootstrapMultiaddrsHash(compactMultiaddrs) : void 0,
|
|
2739
2790
|
registrationId: args.registrationId,
|
|
2740
2791
|
profile: args.profile,
|
|
2741
2792
|
version: args.version,
|
|
@@ -2782,7 +2833,7 @@ async function fetchAlephBootstrapPosts(options = {}) {
|
|
|
2782
2833
|
throw new Error(`Aleph bootstrap post lookup failed: ${response.status}`);
|
|
2783
2834
|
}
|
|
2784
2835
|
const payload = await response.json();
|
|
2785
|
-
return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null);
|
|
2836
|
+
return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null).sort((left, right) => compareRelayBootstrapPostRecency(right, left));
|
|
2786
2837
|
}
|
|
2787
2838
|
function compareRelayBootstrapPostRecency(left, right) {
|
|
2788
2839
|
const leftUpdatedAt = left.content?.updatedAt ?? 0;
|
|
@@ -2829,12 +2880,14 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2829
2880
|
const expectedSender = args.sender?.trim().toLowerCase() || null;
|
|
2830
2881
|
const expectedRegistrationId = args.registrationId?.trim() || null;
|
|
2831
2882
|
const expectedPeerId = args.peerId?.trim() || null;
|
|
2883
|
+
const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2884
|
+
const sleepImpl = args.sleep ?? sleep;
|
|
2832
2885
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
2833
2886
|
const posts = await fetchAlephBootstrapPosts({
|
|
2834
2887
|
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2835
2888
|
channel: args.channel,
|
|
2836
2889
|
ref: args.ref,
|
|
2837
|
-
postType
|
|
2890
|
+
postType,
|
|
2838
2891
|
fetch: args.fetch
|
|
2839
2892
|
});
|
|
2840
2893
|
const currentPosts = selectCurrentRelayBootstrapPosts(posts);
|
|
@@ -2865,7 +2918,7 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2865
2918
|
}
|
|
2866
2919
|
args.onAttempt?.(null, attempt + 1, attempts);
|
|
2867
2920
|
if (attempt < attempts - 1) {
|
|
2868
|
-
await
|
|
2921
|
+
await sleepImpl(delayMs);
|
|
2869
2922
|
}
|
|
2870
2923
|
}
|
|
2871
2924
|
return null;
|
|
@@ -2873,6 +2926,8 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2873
2926
|
async function publishRelayBootstrapRegistration(args) {
|
|
2874
2927
|
const publisherAddress = args.publisherAddress ?? args.sender;
|
|
2875
2928
|
const ownerAddress = args.ownerAddress;
|
|
2929
|
+
const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2930
|
+
const compact = postType === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2876
2931
|
let ownerAuthorization = args.ownerAuthorization;
|
|
2877
2932
|
let relayProof = args.relayProof;
|
|
2878
2933
|
if (!ownerAuthorization && ownerAddress && args.ownerSigner) {
|
|
@@ -2899,6 +2954,8 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2899
2954
|
profile: args.profile,
|
|
2900
2955
|
version: args.version,
|
|
2901
2956
|
updatedAt: args.now ?? Date.now(),
|
|
2957
|
+
compact,
|
|
2958
|
+
compactMultiaddrLimit: args.compactMultiaddrLimit,
|
|
2902
2959
|
signer: args.publisherSigner
|
|
2903
2960
|
});
|
|
2904
2961
|
}
|
|
@@ -2910,13 +2967,15 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2910
2967
|
registrationId: args.registrationId,
|
|
2911
2968
|
channel: args.channel,
|
|
2912
2969
|
ref: args.ref,
|
|
2913
|
-
postType
|
|
2970
|
+
postType,
|
|
2914
2971
|
profile: args.profile,
|
|
2915
2972
|
version: args.version,
|
|
2916
2973
|
ownerAddress,
|
|
2917
2974
|
publisherAddress,
|
|
2918
2975
|
authorization: ownerAuthorization,
|
|
2919
2976
|
relayProof,
|
|
2977
|
+
compact,
|
|
2978
|
+
compactMultiaddrLimit: args.compactMultiaddrLimit,
|
|
2920
2979
|
now: args.now,
|
|
2921
2980
|
hasher: args.hasher
|
|
2922
2981
|
});
|
|
@@ -2938,16 +2997,33 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2938
2997
|
let forgottenHashes = [];
|
|
2939
2998
|
let forgetResult;
|
|
2940
2999
|
if (args.forgetPrevious && args.registrationId) {
|
|
2941
|
-
const
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
3000
|
+
const previousPostTypes = compact ? [postType, DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE] : [postType];
|
|
3001
|
+
const previousPosts = (await Promise.all(
|
|
3002
|
+
previousPostTypes.map(
|
|
3003
|
+
(previousPostType) => fetchAlephBootstrapPosts({
|
|
3004
|
+
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
3005
|
+
channel: args.channel,
|
|
3006
|
+
ref: args.ref,
|
|
3007
|
+
postType: previousPostType,
|
|
3008
|
+
fetch: args.fetch
|
|
3009
|
+
})
|
|
3010
|
+
)
|
|
3011
|
+
)).flat();
|
|
3012
|
+
const forgottenHashSet = new Set(
|
|
3013
|
+
previousPosts.filter((post) => {
|
|
3014
|
+
const hash = post.itemHash ?? post.hash;
|
|
3015
|
+
if (!hash || hash === unsigned.item_hash) return false;
|
|
3016
|
+
if (post.address?.toLowerCase() !== args.sender.toLowerCase()) {
|
|
3017
|
+
return false;
|
|
3018
|
+
}
|
|
3019
|
+
const content2 = post.content;
|
|
3020
|
+
if (!content2) return false;
|
|
3021
|
+
if (content2.registrationId === args.registrationId) return true;
|
|
3022
|
+
if (content2.peerId !== args.peerId) return false;
|
|
3023
|
+
return !args.profile || content2.profile === args.profile;
|
|
3024
|
+
}).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean)
|
|
3025
|
+
);
|
|
3026
|
+
forgottenHashes = [...forgottenHashSet];
|
|
2951
3027
|
if (forgottenHashes.length > 0) {
|
|
2952
3028
|
forgetResult = await forgetAlephMessages({
|
|
2953
3029
|
sender: args.sender,
|
|
@@ -2968,7 +3044,7 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2968
3044
|
response,
|
|
2969
3045
|
httpStatus,
|
|
2970
3046
|
publishedMultiaddrs: content.content?.multiaddrs ?? [],
|
|
2971
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? [],
|
|
3047
|
+
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? content.content?.multiaddrs ?? [],
|
|
2972
3048
|
forgottenHashes,
|
|
2973
3049
|
forgetResult
|
|
2974
3050
|
};
|
|
@@ -4118,6 +4194,8 @@ var SponsorRelayController = class {
|
|
|
4118
4194
|
setupPort,
|
|
4119
4195
|
proxyUrl: serviceProxyUrl,
|
|
4120
4196
|
webauthnOrigin: serviceProxyUrl,
|
|
4197
|
+
serviceDid: bootstrapValidation.bootstrapPackage.serviceDid,
|
|
4198
|
+
serviceOrigin: bootstrapValidation.bootstrapPackage.serviceOrigin,
|
|
4121
4199
|
adminDid: bootstrapValidation.bootstrapPackage.adminDid,
|
|
4122
4200
|
bootstrapPackage: bootstrapValidation.bootstrapPackage,
|
|
4123
4201
|
fetch: (url, init) => fetch(url, init),
|
|
@@ -5020,10 +5098,18 @@ var SponsorRelayController = class {
|
|
|
5020
5098
|
const [nextBalance, rawInstances, rawBootstrapPosts] = await Promise.all([
|
|
5021
5099
|
this.client.fetchBalance(this.state.wallet.address),
|
|
5022
5100
|
this.state.showInstances ? this.client.fetchInstances(this.state.wallet.address) : Promise.resolve([]),
|
|
5023
|
-
bootstrapEnabled ?
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5101
|
+
bootstrapEnabled ? Promise.all(
|
|
5102
|
+
[
|
|
5103
|
+
DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE,
|
|
5104
|
+
DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE
|
|
5105
|
+
].map(
|
|
5106
|
+
(postType) => fetchAlephBootstrapPosts({
|
|
5107
|
+
apiHost: this.client.apiHost,
|
|
5108
|
+
postType,
|
|
5109
|
+
fetch
|
|
5110
|
+
}).catch(() => [])
|
|
5111
|
+
)
|
|
5112
|
+
).then((pages) => pages.flat()) : Promise.resolve([])
|
|
5027
5113
|
]);
|
|
5028
5114
|
balance = nextBalance;
|
|
5029
5115
|
instances = await Promise.all(
|
package/shared/index.d.ts
CHANGED
|
@@ -330,7 +330,7 @@ declare const STALE_INSTANCE_ALLOCATION_COOLDOWN_MS: number;
|
|
|
330
330
|
declare const RECENT_INSTANCE_RUNTIME_GRACE_MS: number;
|
|
331
331
|
declare const DEPLOYMENT_PENDING_WARNING_MS: number;
|
|
332
332
|
|
|
333
|
-
declare const UI_PACKAGE_VERSION = "0.6.
|
|
333
|
+
declare const UI_PACKAGE_VERSION = "0.6.5";
|
|
334
334
|
|
|
335
335
|
interface RootfsRequiredPortForward {
|
|
336
336
|
port: number;
|
package/shared/index.js
CHANGED
|
@@ -42,7 +42,7 @@ var RECENT_INSTANCE_RUNTIME_GRACE_MS = 10 * 60 * 1e3;
|
|
|
42
42
|
var DEPLOYMENT_PENDING_WARNING_MS = 3 * 60 * 1e3;
|
|
43
43
|
|
|
44
44
|
// src/shared/package-version.ts
|
|
45
|
-
var UI_PACKAGE_VERSION = "0.6.
|
|
45
|
+
var UI_PACKAGE_VERSION = "0.6.5";
|
|
46
46
|
|
|
47
47
|
// src/shared/format.ts
|
|
48
48
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -2332,9 +2332,11 @@ async function configureUcanStore(args) {
|
|
|
2332
2332
|
proxy_url: args.proxyUrl ?? void 0,
|
|
2333
2333
|
service_did: args.serviceDid ?? void 0,
|
|
2334
2334
|
service_origin: args.serviceOrigin ?? void 0,
|
|
2335
|
+
public_storage_origin: args.publicStorageOrigin ?? void 0,
|
|
2335
2336
|
webauthn_origin: args.webauthnOrigin ?? void 0,
|
|
2336
2337
|
webauthn_origin_fallbacks: args.webauthnOriginFallbacks ?? void 0,
|
|
2337
2338
|
admin_did: args.adminDid ?? void 0,
|
|
2339
|
+
admin_api_token: args.adminApiToken ?? void 0,
|
|
2338
2340
|
bootstrap_package: args.bootstrapPackage ?? void 0,
|
|
2339
2341
|
no_start: args.noStart === true ? true : void 0
|
|
2340
2342
|
};
|
|
@@ -2433,13 +2435,15 @@ async function fetchUcGoPeerMetadata(args) {
|
|
|
2433
2435
|
}
|
|
2434
2436
|
|
|
2435
2437
|
// ../aleph-bootstrap/src/index.ts
|
|
2436
|
-
import { recoverMessageAddress } from "viem";
|
|
2438
|
+
import { keccak256, recoverMessageAddress, stringToHex } from "viem";
|
|
2437
2439
|
var DEFAULT_ALEPH_API_HOST3 = "https://api.aleph.im";
|
|
2438
2440
|
var DEFAULT_ALEPH_BOOTSTRAP_CHANNEL = "simple-todo";
|
|
2439
2441
|
var DEFAULT_ALEPH_BOOTSTRAP_REF = "simple-todo-bootstrap";
|
|
2440
2442
|
var DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE = "relay-bootstrap";
|
|
2443
|
+
var DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE = "relay-bootstrap-v2";
|
|
2441
2444
|
var DEFAULT_BOOTSTRAP_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2442
2445
|
var DEFAULT_BOOTSTRAP_PAGINATION = 50;
|
|
2446
|
+
var DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT = 3;
|
|
2443
2447
|
var RELAY_BOOTSTRAP_SIGNATURE_SCHEME = "personal_sign";
|
|
2444
2448
|
function serializeOwnerAuthorizationPayload(payload) {
|
|
2445
2449
|
return JSON.stringify({
|
|
@@ -2457,14 +2461,41 @@ function serializeOwnerAuthorizationPayload(payload) {
|
|
|
2457
2461
|
function serializeRelayProofPayload(payload) {
|
|
2458
2462
|
return JSON.stringify({
|
|
2459
2463
|
peerId: payload.peerId,
|
|
2460
|
-
multiaddrs: dedupeMultiaddrs(payload.multiaddrs),
|
|
2464
|
+
multiaddrs: payload.multiaddrs ? dedupeMultiaddrs(payload.multiaddrs) : void 0,
|
|
2461
2465
|
browserMultiaddrs: payload.browserMultiaddrs ? dedupeMultiaddrs(payload.browserMultiaddrs) : void 0,
|
|
2466
|
+
multiaddrsHash: payload.multiaddrsHash,
|
|
2467
|
+
browserMultiaddrsHash: payload.browserMultiaddrsHash,
|
|
2462
2468
|
registrationId: payload.registrationId,
|
|
2463
2469
|
profile: payload.profile,
|
|
2464
2470
|
version: payload.version,
|
|
2465
2471
|
updatedAt: payload.updatedAt
|
|
2466
2472
|
});
|
|
2467
2473
|
}
|
|
2474
|
+
function relayBootstrapMultiaddrsHash(addrs) {
|
|
2475
|
+
return keccak256(stringToHex(JSON.stringify(dedupeMultiaddrs(addrs))));
|
|
2476
|
+
}
|
|
2477
|
+
function compactPostType(postType) {
|
|
2478
|
+
return (postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE) === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2479
|
+
}
|
|
2480
|
+
function browserMultiaddrPreference(addr) {
|
|
2481
|
+
const normalized = addr.toLowerCase();
|
|
2482
|
+
if (normalized.includes("/tcp/443/tls/ws/")) return 0;
|
|
2483
|
+
if (normalized.includes("/tls/ws/")) return 1;
|
|
2484
|
+
if (normalized.includes("/webtransport/")) return 2;
|
|
2485
|
+
if (normalized.includes("/webrtc-direct/")) return 3;
|
|
2486
|
+
if (normalized.includes("/ws")) return 4;
|
|
2487
|
+
return 5;
|
|
2488
|
+
}
|
|
2489
|
+
function selectCompactRelayBootstrapMultiaddrs(addrs, limit = DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT) {
|
|
2490
|
+
const entries = filterPublicMultiaddrs(addrs, {
|
|
2491
|
+
browserDialableOnly: true
|
|
2492
|
+
}).map((addr, index) => ({ addr, index }));
|
|
2493
|
+
entries.sort((left, right) => {
|
|
2494
|
+
const preference = browserMultiaddrPreference(left.addr) - browserMultiaddrPreference(right.addr);
|
|
2495
|
+
return preference !== 0 ? preference : left.index - right.index;
|
|
2496
|
+
});
|
|
2497
|
+
return entries.map((entry) => entry.addr).slice(0, Math.max(1, Math.floor(limit)));
|
|
2498
|
+
}
|
|
2468
2499
|
function asTrimmedString(value) {
|
|
2469
2500
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
2470
2501
|
}
|
|
@@ -2620,8 +2651,10 @@ function normalizeRelayBootstrapProofPayload(value) {
|
|
|
2620
2651
|
const browserMultiaddrs = Array.isArray(payload.browserMultiaddrs) ? payload.browserMultiaddrs.filter((entry) => typeof entry === "string") : void 0;
|
|
2621
2652
|
return {
|
|
2622
2653
|
peerId,
|
|
2623
|
-
multiaddrs: dedupeMultiaddrs(multiaddrs),
|
|
2654
|
+
multiaddrs: multiaddrs.length > 0 ? dedupeMultiaddrs(multiaddrs) : void 0,
|
|
2624
2655
|
browserMultiaddrs: browserMultiaddrs ? dedupeMultiaddrs(browserMultiaddrs) : void 0,
|
|
2656
|
+
multiaddrsHash: asTrimmedString(payload.multiaddrsHash) ?? void 0,
|
|
2657
|
+
browserMultiaddrsHash: asTrimmedString(payload.browserMultiaddrsHash) ?? void 0,
|
|
2625
2658
|
registrationId: asTrimmedString(payload.registrationId) ?? void 0,
|
|
2626
2659
|
profile: asTrimmedString(payload.profile) ?? void 0,
|
|
2627
2660
|
version: asTrimmedString(payload.version) ?? void 0,
|
|
@@ -2653,16 +2686,24 @@ function normalizeRelayBootstrapPostRecord(value) {
|
|
|
2653
2686
|
function buildRelayBootstrapPostContent(args) {
|
|
2654
2687
|
const now = args.now ?? Date.now() / 1e3;
|
|
2655
2688
|
const updatedAt = args.now ?? Date.now();
|
|
2689
|
+
const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE;
|
|
2690
|
+
const compact = args.compact ?? compactPostType(postType);
|
|
2691
|
+
const fullMultiaddrs = filterPublicMultiaddrs(args.multiaddrs);
|
|
2692
|
+
const fullBrowserMultiaddrs = args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
|
|
2693
|
+
browserDialableOnly: true
|
|
2694
|
+
}) : void 0;
|
|
2695
|
+
const compactMultiaddrs = selectCompactRelayBootstrapMultiaddrs(
|
|
2696
|
+
fullBrowserMultiaddrs && fullBrowserMultiaddrs.length > 0 ? fullBrowserMultiaddrs : fullMultiaddrs,
|
|
2697
|
+
args.compactMultiaddrLimit
|
|
2698
|
+
);
|
|
2656
2699
|
return {
|
|
2657
|
-
type:
|
|
2700
|
+
type: postType,
|
|
2658
2701
|
address: args.sender,
|
|
2659
2702
|
...args.ref ? { ref: args.ref } : {},
|
|
2660
2703
|
content: {
|
|
2661
2704
|
peerId: args.peerId,
|
|
2662
|
-
multiaddrs:
|
|
2663
|
-
browserMultiaddrs:
|
|
2664
|
-
browserDialableOnly: true
|
|
2665
|
-
}) : void 0,
|
|
2705
|
+
multiaddrs: compact ? compactMultiaddrs : fullMultiaddrs,
|
|
2706
|
+
browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
|
|
2666
2707
|
registrationId: args.registrationId,
|
|
2667
2708
|
profile: args.profile,
|
|
2668
2709
|
version: args.version,
|
|
@@ -2692,6 +2733,8 @@ async function createRelayBootstrapPost(args) {
|
|
|
2692
2733
|
publisherAddress: args.publisherAddress,
|
|
2693
2734
|
authorization: args.authorization,
|
|
2694
2735
|
relayProof: args.relayProof,
|
|
2736
|
+
compact: args.compact,
|
|
2737
|
+
compactMultiaddrLimit: args.compactMultiaddrLimit,
|
|
2695
2738
|
now: nowMillis
|
|
2696
2739
|
});
|
|
2697
2740
|
itemContent.time = nowSeconds;
|
|
@@ -2729,12 +2772,20 @@ async function signRelayBootstrapAuthorization(args) {
|
|
|
2729
2772
|
};
|
|
2730
2773
|
}
|
|
2731
2774
|
async function signRelayBootstrapProof(args) {
|
|
2775
|
+
const fullMultiaddrs = filterPublicMultiaddrs(args.multiaddrs);
|
|
2776
|
+
const fullBrowserMultiaddrs = args.browserMultiaddrs ? filterPublicMultiaddrs(args.browserMultiaddrs, {
|
|
2777
|
+
browserDialableOnly: true
|
|
2778
|
+
}) : void 0;
|
|
2779
|
+
const compactMultiaddrs = selectCompactRelayBootstrapMultiaddrs(
|
|
2780
|
+
fullBrowserMultiaddrs && fullBrowserMultiaddrs.length > 0 ? fullBrowserMultiaddrs : fullMultiaddrs,
|
|
2781
|
+
args.compactMultiaddrLimit
|
|
2782
|
+
);
|
|
2783
|
+
const compact = args.compact ?? false;
|
|
2732
2784
|
const payload = {
|
|
2733
2785
|
peerId: args.peerId,
|
|
2734
|
-
multiaddrs:
|
|
2735
|
-
browserMultiaddrs:
|
|
2736
|
-
|
|
2737
|
-
}) : void 0,
|
|
2786
|
+
multiaddrs: compact ? void 0 : fullMultiaddrs,
|
|
2787
|
+
browserMultiaddrs: compact ? void 0 : fullBrowserMultiaddrs,
|
|
2788
|
+
multiaddrsHash: compact ? relayBootstrapMultiaddrsHash(compactMultiaddrs) : void 0,
|
|
2738
2789
|
registrationId: args.registrationId,
|
|
2739
2790
|
profile: args.profile,
|
|
2740
2791
|
version: args.version,
|
|
@@ -2781,7 +2832,7 @@ async function fetchAlephBootstrapPosts(options = {}) {
|
|
|
2781
2832
|
throw new Error(`Aleph bootstrap post lookup failed: ${response.status}`);
|
|
2782
2833
|
}
|
|
2783
2834
|
const payload = await response.json();
|
|
2784
|
-
return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null);
|
|
2835
|
+
return (payload.posts ?? []).map((entry) => normalizeRelayBootstrapPostRecord(entry)).filter((entry) => entry != null).sort((left, right) => compareRelayBootstrapPostRecency(right, left));
|
|
2785
2836
|
}
|
|
2786
2837
|
function compareRelayBootstrapPostRecency(left, right) {
|
|
2787
2838
|
const leftUpdatedAt = left.content?.updatedAt ?? 0;
|
|
@@ -2828,12 +2879,14 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2828
2879
|
const expectedSender = args.sender?.trim().toLowerCase() || null;
|
|
2829
2880
|
const expectedRegistrationId = args.registrationId?.trim() || null;
|
|
2830
2881
|
const expectedPeerId = args.peerId?.trim() || null;
|
|
2882
|
+
const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2883
|
+
const sleepImpl = args.sleep ?? sleep;
|
|
2831
2884
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
2832
2885
|
const posts = await fetchAlephBootstrapPosts({
|
|
2833
2886
|
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
2834
2887
|
channel: args.channel,
|
|
2835
2888
|
ref: args.ref,
|
|
2836
|
-
postType
|
|
2889
|
+
postType,
|
|
2837
2890
|
fetch: args.fetch
|
|
2838
2891
|
});
|
|
2839
2892
|
const currentPosts = selectCurrentRelayBootstrapPosts(posts);
|
|
@@ -2864,7 +2917,7 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2864
2917
|
}
|
|
2865
2918
|
args.onAttempt?.(null, attempt + 1, attempts);
|
|
2866
2919
|
if (attempt < attempts - 1) {
|
|
2867
|
-
await
|
|
2920
|
+
await sleepImpl(delayMs);
|
|
2868
2921
|
}
|
|
2869
2922
|
}
|
|
2870
2923
|
return null;
|
|
@@ -2872,6 +2925,8 @@ async function waitForRelayBootstrapRegistration(args) {
|
|
|
2872
2925
|
async function publishRelayBootstrapRegistration(args) {
|
|
2873
2926
|
const publisherAddress = args.publisherAddress ?? args.sender;
|
|
2874
2927
|
const ownerAddress = args.ownerAddress;
|
|
2928
|
+
const postType = args.postType ?? DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2929
|
+
const compact = postType === DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE;
|
|
2875
2930
|
let ownerAuthorization = args.ownerAuthorization;
|
|
2876
2931
|
let relayProof = args.relayProof;
|
|
2877
2932
|
if (!ownerAuthorization && ownerAddress && args.ownerSigner) {
|
|
@@ -2898,6 +2953,8 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2898
2953
|
profile: args.profile,
|
|
2899
2954
|
version: args.version,
|
|
2900
2955
|
updatedAt: args.now ?? Date.now(),
|
|
2956
|
+
compact,
|
|
2957
|
+
compactMultiaddrLimit: args.compactMultiaddrLimit,
|
|
2901
2958
|
signer: args.publisherSigner
|
|
2902
2959
|
});
|
|
2903
2960
|
}
|
|
@@ -2909,13 +2966,15 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2909
2966
|
registrationId: args.registrationId,
|
|
2910
2967
|
channel: args.channel,
|
|
2911
2968
|
ref: args.ref,
|
|
2912
|
-
postType
|
|
2969
|
+
postType,
|
|
2913
2970
|
profile: args.profile,
|
|
2914
2971
|
version: args.version,
|
|
2915
2972
|
ownerAddress,
|
|
2916
2973
|
publisherAddress,
|
|
2917
2974
|
authorization: ownerAuthorization,
|
|
2918
2975
|
relayProof,
|
|
2976
|
+
compact,
|
|
2977
|
+
compactMultiaddrLimit: args.compactMultiaddrLimit,
|
|
2919
2978
|
now: args.now,
|
|
2920
2979
|
hasher: args.hasher
|
|
2921
2980
|
});
|
|
@@ -2937,16 +2996,33 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2937
2996
|
let forgottenHashes = [];
|
|
2938
2997
|
let forgetResult;
|
|
2939
2998
|
if (args.forgetPrevious && args.registrationId) {
|
|
2940
|
-
const
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2999
|
+
const previousPostTypes = compact ? [postType, DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE] : [postType];
|
|
3000
|
+
const previousPosts = (await Promise.all(
|
|
3001
|
+
previousPostTypes.map(
|
|
3002
|
+
(previousPostType) => fetchAlephBootstrapPosts({
|
|
3003
|
+
apiHost: args.apiHost ?? DEFAULT_ALEPH_API_HOST3,
|
|
3004
|
+
channel: args.channel,
|
|
3005
|
+
ref: args.ref,
|
|
3006
|
+
postType: previousPostType,
|
|
3007
|
+
fetch: args.fetch
|
|
3008
|
+
})
|
|
3009
|
+
)
|
|
3010
|
+
)).flat();
|
|
3011
|
+
const forgottenHashSet = new Set(
|
|
3012
|
+
previousPosts.filter((post) => {
|
|
3013
|
+
const hash = post.itemHash ?? post.hash;
|
|
3014
|
+
if (!hash || hash === unsigned.item_hash) return false;
|
|
3015
|
+
if (post.address?.toLowerCase() !== args.sender.toLowerCase()) {
|
|
3016
|
+
return false;
|
|
3017
|
+
}
|
|
3018
|
+
const content2 = post.content;
|
|
3019
|
+
if (!content2) return false;
|
|
3020
|
+
if (content2.registrationId === args.registrationId) return true;
|
|
3021
|
+
if (content2.peerId !== args.peerId) return false;
|
|
3022
|
+
return !args.profile || content2.profile === args.profile;
|
|
3023
|
+
}).map((post) => post.itemHash ?? post.hash ?? "").filter(Boolean)
|
|
3024
|
+
);
|
|
3025
|
+
forgottenHashes = [...forgottenHashSet];
|
|
2950
3026
|
if (forgottenHashes.length > 0) {
|
|
2951
3027
|
forgetResult = await forgetAlephMessages({
|
|
2952
3028
|
sender: args.sender,
|
|
@@ -2967,7 +3043,7 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2967
3043
|
response,
|
|
2968
3044
|
httpStatus,
|
|
2969
3045
|
publishedMultiaddrs: content.content?.multiaddrs ?? [],
|
|
2970
|
-
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? [],
|
|
3046
|
+
publishedBrowserMultiaddrs: content.content?.browserMultiaddrs ?? content.content?.multiaddrs ?? [],
|
|
2971
3047
|
forgottenHashes,
|
|
2972
3048
|
forgetResult
|
|
2973
3049
|
};
|
|
@@ -4117,6 +4193,8 @@ var SponsorRelayController = class {
|
|
|
4117
4193
|
setupPort,
|
|
4118
4194
|
proxyUrl: serviceProxyUrl,
|
|
4119
4195
|
webauthnOrigin: serviceProxyUrl,
|
|
4196
|
+
serviceDid: bootstrapValidation.bootstrapPackage.serviceDid,
|
|
4197
|
+
serviceOrigin: bootstrapValidation.bootstrapPackage.serviceOrigin,
|
|
4120
4198
|
adminDid: bootstrapValidation.bootstrapPackage.adminDid,
|
|
4121
4199
|
bootstrapPackage: bootstrapValidation.bootstrapPackage,
|
|
4122
4200
|
fetch: (url, init) => fetch(url, init),
|
|
@@ -5019,10 +5097,18 @@ var SponsorRelayController = class {
|
|
|
5019
5097
|
const [nextBalance, rawInstances, rawBootstrapPosts] = await Promise.all([
|
|
5020
5098
|
this.client.fetchBalance(this.state.wallet.address),
|
|
5021
5099
|
this.state.showInstances ? this.client.fetchInstances(this.state.wallet.address) : Promise.resolve([]),
|
|
5022
|
-
bootstrapEnabled ?
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5100
|
+
bootstrapEnabled ? Promise.all(
|
|
5101
|
+
[
|
|
5102
|
+
DEFAULT_ALEPH_BOOTSTRAP_COMPACT_POST_TYPE,
|
|
5103
|
+
DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE
|
|
5104
|
+
].map(
|
|
5105
|
+
(postType) => fetchAlephBootstrapPosts({
|
|
5106
|
+
apiHost: this.client.apiHost,
|
|
5107
|
+
postType,
|
|
5108
|
+
fetch
|
|
5109
|
+
}).catch(() => [])
|
|
5110
|
+
)
|
|
5111
|
+
).then((pages) => pages.flat()) : Promise.resolve([])
|
|
5026
5112
|
]);
|
|
5027
5113
|
balance = nextBalance;
|
|
5028
5114
|
instances = await Promise.all(
|