mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-12 13:40:43 +08:00
Migrate to host/id based seed node records
Instead of having one record per service, we configure the host and expect services to run on certain ports.
This commit is contained in:
+4
-1
@@ -23,7 +23,10 @@
|
||||
// Maximum is 15 characters.
|
||||
// For simplification of the regex pattern we use a combined version of both requirements.
|
||||
handle: /^[a-zA-Z0-9-_]{1,39}$/,
|
||||
address: /^0x[a-zA-Z0-9]{40}$/
|
||||
address: /^0x[a-zA-Z0-9]{40}$/,
|
||||
id: /^[a-z0-9]+$/,
|
||||
// Just make sure there is a TLD at the end.
|
||||
domain: /\.[a-z]{2,}$/,
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
+5
-4
@@ -5,8 +5,8 @@ export async function get(
|
||||
params: Record<string, any>,
|
||||
config: Config
|
||||
): Promise<any> {
|
||||
if (! config.seed.api) {
|
||||
throw new Error("Seed HTTP API unavailable");
|
||||
if (! config.seed.host) {
|
||||
throw new Error("Seed host unavailable");
|
||||
}
|
||||
|
||||
const query: Record<string, string> = {};
|
||||
@@ -14,9 +14,10 @@ export async function get(
|
||||
query[key] = val.toString();
|
||||
}
|
||||
|
||||
const base = config.seed.api.replace(/\/$/, "");
|
||||
const base = config.seed.host;
|
||||
const port = config.seed.port;
|
||||
const search = new URLSearchParams(query).toString();
|
||||
const baseUrl = `${base}/v1/${path}`;
|
||||
const baseUrl = `https://${base}:${port}/v1/${path}`;
|
||||
const url = search ? `${baseUrl}?${search}` : baseUrl;
|
||||
|
||||
let response = null;
|
||||
|
||||
@@ -188,9 +188,9 @@
|
||||
<div class="stat">
|
||||
<strong>{tree.stats.contributors}</strong> contributor(s)
|
||||
</div>
|
||||
{#if config.seed.api}
|
||||
{#if config.seed.host}
|
||||
<div class="stat" title="Project data is fetched from this seed">
|
||||
<span>{utils.formatSeedApi(config.seed.api)}</span>
|
||||
<span>{config.seed.host}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="anchor">
|
||||
|
||||
@@ -75,12 +75,14 @@
|
||||
{ name: "github", validate: "handle", label: "GitHub", placeholder: "GitHub username, eg. 'acme'",
|
||||
description: "The GitHub username associated with this name.",
|
||||
value: r.profile.github, editable: true },
|
||||
{ name: "seed.id", label: "Seed ID", placeholder: "hynkyn...3nrzc@seed.acme.org:8887",
|
||||
description: "The ID of a Radicle Link node that hosts entities associated with this name.",
|
||||
{ name: "seed.host", label: "Seed Host", validate: "domain", placeholder: "seed.acme.org",
|
||||
description: "The seed host address. " +
|
||||
"Only domain names with TLS are supported. " +
|
||||
`HTTP(S) API requests use port ${config.seed.port}.`,
|
||||
value: r.profile.seedHost, editable: true },
|
||||
{ name: "seed.id", label: "Seed ID", validate: "id", placeholder: "hynkyndc6w3p8urucakobzncqny7xxtw88...",
|
||||
description: "The Device ID of a Radicle Link node that hosts entities associated with this name.",
|
||||
value: r.profile.seedId, editable: true },
|
||||
{ name: "seed.api", label: "Seed API", validate: "url", placeholder: "https://seed.acme.org:8888",
|
||||
description: "The HTTP address of a node that serves Radicle entities over HTTP.",
|
||||
value: r.profile.seedApi, editable: true },
|
||||
];
|
||||
state = { status: Status.Found, registration: r };
|
||||
} else {
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface EnsProfile {
|
||||
owner?: string;
|
||||
address: string | null;
|
||||
seedId: string | null;
|
||||
seedApi: string | null;
|
||||
seedHost: string | null;
|
||||
url: string | null;
|
||||
avatar: string | null;
|
||||
twitter: string | null;
|
||||
@@ -72,12 +72,12 @@ export async function getRegistration(name: string, config: Config): Promise<Reg
|
||||
resolver.getText('avatar'),
|
||||
resolver.getText('url'),
|
||||
resolver.getText('eth.radicle.seed.id'),
|
||||
resolver.getText('eth.radicle.seed.api'),
|
||||
resolver.getText('eth.radicle.seed.host'),
|
||||
resolver.getText('com.twitter'),
|
||||
resolver.getText('com.github'),
|
||||
]);
|
||||
|
||||
const [address, avatar, url, seedId, seedApi, twitter, github] =
|
||||
const [address, avatar, url, seedId, seedHost, twitter, github] =
|
||||
meta.map(r => r.status == "fulfilled" ? r.value : null);
|
||||
|
||||
return {
|
||||
@@ -88,7 +88,7 @@ export async function getRegistration(name: string, config: Config): Promise<Reg
|
||||
url,
|
||||
avatar,
|
||||
seedId,
|
||||
seedApi,
|
||||
seedHost,
|
||||
address,
|
||||
twitter,
|
||||
github,
|
||||
@@ -113,7 +113,7 @@ export async function getSeed(name: string, config: Config): Promise<string | nu
|
||||
if (! resolver) {
|
||||
return null;
|
||||
}
|
||||
return resolver.getText('eth.radicle.seed.api');
|
||||
return resolver.getText('eth.radicle.seed.host');
|
||||
}
|
||||
|
||||
export function registrar(config: Config): ethers.Contract {
|
||||
|
||||
@@ -35,7 +35,7 @@ export async function setRecords(name: string, records: EnsRecord[], resolver: E
|
||||
);
|
||||
break;
|
||||
case "seed.id":
|
||||
case "seed.api":
|
||||
case "seed.host":
|
||||
calls.push(
|
||||
iface.encodeFunctionData("setText", [node, "eth.radicle." + r.name, r.value])
|
||||
);
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@
|
||||
},
|
||||
"walletConnect": { "bridge": "https://radicle.bridge.walletconnect.org" },
|
||||
"ceramic": { "api": "https://gateway.ceramic.network" },
|
||||
"radicle": { "api": "http://0.0.0.0:8888" },
|
||||
"radicle": { "seed": { "host": "0.0.0.0", "port": 8777 } },
|
||||
"ipfs": { "gateway": "https://ipfs.io/ipfs/" },
|
||||
"abi": {
|
||||
"registrar": [
|
||||
|
||||
+4
-5
@@ -55,7 +55,7 @@ export class Config {
|
||||
viewer: string | null;
|
||||
};
|
||||
abi: { [contract: string]: string[] };
|
||||
seed: { api?: string };
|
||||
seed: { host?: string; port: number };
|
||||
idx: { client: IDX };
|
||||
ceramic: { client: CeramicClient };
|
||||
tokens: string[];
|
||||
@@ -66,7 +66,6 @@ export class Config {
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
metamaskSigner: ethers.Signer & TypedDataSigner | null,
|
||||
) {
|
||||
const api = config.radicle.api;
|
||||
const cfg = (<Record<string, any>> config)[network.name];
|
||||
const ceramic = new CeramicClient(config.ceramic.api);
|
||||
const idx = new IDX({ ceramic });
|
||||
@@ -97,7 +96,7 @@ export class Config {
|
||||
signer: wc.signer,
|
||||
state: walletConnectState,
|
||||
};
|
||||
this.seed = { api };
|
||||
this.seed = config.radicle.seed;
|
||||
this.registrar = cfg.registrar;
|
||||
this.radToken = cfg.radToken;
|
||||
this.orgFactory = cfg.orgFactory;
|
||||
@@ -126,10 +125,10 @@ export class Config {
|
||||
}
|
||||
|
||||
// Return the config with an overwritten seed URL.
|
||||
withSeed(seed: string): Config {
|
||||
withSeed(seedHost: string): Config {
|
||||
const cfg = {} as Config;
|
||||
Object.assign(cfg, this);
|
||||
cfg.seed.api = seed.replace(/\/$/, "");
|
||||
cfg.seed.host = seedHost;
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ export class Profile {
|
||||
|
||||
// Using undefined as return type if nothing to be returned since it works better with <a href> links
|
||||
get seed(): string | undefined {
|
||||
return this.profile?.ens?.seedApi ?? undefined;
|
||||
return this.profile?.ens?.seedHost ?? undefined;
|
||||
}
|
||||
|
||||
// Return the profile-specific config. This sets various URLs in the config,
|
||||
|
||||
+3
-11
@@ -63,14 +63,6 @@ export function formatHash(hash: string): string {
|
||||
+ hash.substring(hash.length - 4, hash.length);
|
||||
}
|
||||
|
||||
export function formatSeedApi(input: string): string {
|
||||
const match = input.match(/^https?:\/\/([^:]+)/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
export function formatNetwork(input: { name: string }): string {
|
||||
let name = input.name;
|
||||
|
||||
@@ -256,13 +248,13 @@ export async function resolveEnsProfile(address: string, profileType: ProfileTyp
|
||||
}
|
||||
} else if (profileType === ProfileType.Project) {
|
||||
const avatar = await getAvatar(name, config);
|
||||
const seedApi = await getSeed(name, config);
|
||||
const seedHost = await getSeed(name, config);
|
||||
|
||||
return {
|
||||
name,
|
||||
address,
|
||||
avatar,
|
||||
seedApi,
|
||||
seedHost,
|
||||
url: null,
|
||||
seedId: null,
|
||||
twitter: null,
|
||||
@@ -277,7 +269,7 @@ export async function resolveEnsProfile(address: string, profileType: ProfileTyp
|
||||
avatar,
|
||||
url: null,
|
||||
seedId: null,
|
||||
seedApi: null,
|
||||
seedHost: null,
|
||||
twitter: null,
|
||||
github: null,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user