Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add support for ENS routes
Alexis Sellier committed 4 years ago
commit abc62b02fd696c58b16c8a777f00ed6483aac6c2
parent dad19066e0f5d0acf981519bf038f9709d52a7c1
4 files changed +52 -38
modified src/base/orgs/Org.ts
@@ -44,12 +44,14 @@ const GetOrgsByOwner = `
export class Org {
  address: string;
  owner: string;
+
  name?: string;

-
  constructor(address: string, owner: string) {
+
  constructor(address: string, owner: string, name?: string) {
    assert(ethers.utils.isAddress(address), "address must be valid");

    this.address = address.toLowerCase(); // Don't store address checksum.
    this.owner = owner;
+
    this.name = name;
  }

  async setName(name: string, config: Config): Promise<TransactionResponse> {
@@ -143,11 +145,11 @@ export class Org {
  }

  async getProfile(profileType: ProfileType, config: Config): Promise<Profile> {
-
    return Org.getProfile(this.address, profileType, config);
+
    return Org.getProfile(this.name ?? this.address, profileType, config);
  }

-
  static async getProjectProfile(addr: string, config: Config): Promise<Profile> {
-
    return Org.getProfile(addr, ProfileType.Project, config);
+
  static async getProjectProfile(addrOrName: string, config: Config): Promise<Profile> {
+
    return Org.getProfile(addrOrName, ProfileType.Project, config);
  }

  static async getAnchor(orgAddr: string, urn: string, config: Config): Promise<string | null> {
@@ -197,11 +199,11 @@ export class Org {
  }

  static async get(
-
    address: string,
+
    addressOrName: string,
    config: Config,
  ): Promise<Org | null> {
    const org = new ethers.Contract(
-
      address,
+
      addressOrName,
      config.abi.org,
      config.provider
    );
@@ -209,7 +211,14 @@ export class Org {
    try {
      const owner = await org.owner();
      const resolved = await org.resolvedAddress;
-
      return new Org(resolved, owner);
+

+
      // If what is resolved is not the same as the input, it's because we
+
      // were given a name.
+
      if (utils.isAddressEqual(addressOrName, resolved)) {
+
        return new Org(resolved, owner);
+
      } else {
+
        return new Org(resolved, owner, addressOrName);
+
      }
    } catch (e) {
      console.error(e);
      return null;
@@ -218,13 +227,13 @@ export class Org {

  // Return the org profile if there is one, otherwise try to get the profile
  // of its owner.
-
  static async getProfile(address: string, profileType: ProfileType, config: Config): Promise<Profile> {
-
    const profile = await Profile.get(address, profileType, config);
+
  static async getProfile(addressOrName: string, profileType: ProfileType, config: Config): Promise<Profile> {
+
    const profile = await Profile.get(addressOrName, profileType, config);

    if (profile.ens) { // Orgs only use ENS for profile information.
      return profile;
    }
-
    const org = await Org.get(address, config);
+
    const org = await Org.get(addressOrName, config);

    if (org) {
      const ownerProfile = await Profile.get(org.owner, profileType, config);
modified src/base/orgs/View.svelte
@@ -252,7 +252,7 @@
          {:then projects}
            {#each projects as project}
              <div class="project">
-
                <Project {project} org={org.address} config={profile.config(config)} />
+
                <Project {project} org={profile.name ?? org.address} config={profile.config(config)} />
              </div>
            {/each}
          {:catch err}
modified src/profile.ts
@@ -1,4 +1,3 @@
-
import { ethers } from "ethers";
import type { EnsProfile } from "@app/base/registrations/registrar";
import type { BasicProfile } from "@ceramicstudio/idx-constants";
import {
@@ -7,6 +6,7 @@ import {
import type { Config } from "./config";

export interface IProfile {
+
  address: string;
  ens: EnsProfile | null;
  idx: BasicProfile | null;
}
@@ -19,11 +19,14 @@ export enum ProfileType {

export class Profile {
  profile: IProfile;
-
  address: string;

-
  constructor(profile: IProfile, address: string) {
+
  constructor(profile: IProfile) {
    this.profile = profile;
-
    this.address = address;
+
  }
+

+
  // Get the Ethereum address
+
  get address(): string {
+
    return this.profile.ens?.address ?? this.profile.address;
  }

  // Get the ENS profile
@@ -86,43 +89,39 @@ export class Profile {
  }

  // Keeping this function private since the desired entrypoint is .get()
-
  private static async lookupAddress(
-
    address: string,
+
  private static async lookupProfile(
+
    addressOrName: string,
    profileType: ProfileType,
    config: Config
-
  ): Promise<[IProfile, string]> {
-
    const profile: IProfile = { ens: null, idx: null };
+
  ): Promise<IProfile> {
+
    const address = await config.provider.resolveName(addressOrName);
+
    const profile: IProfile = { address, ens: null, idx: null };

    try {
-
      address = ethers.utils.getAddress(address);
-
    } catch {
-
      address = await config.provider.resolveName(address);
-
    }
+
      profile.ens = await resolveEnsProfile(addressOrName, profileType, config);

-
    try {
-
      profile.ens = await resolveEnsProfile(address, profileType, config);
-
      if (!profile.ens) {
+
      if (! profile.ens) {
        profile.idx = await resolveIdxProfile(formatCAIP10Address(address, "eip155", config.network.chainId), config);
      }
    } catch (error) {
      console.error(error);
    }

-
    return [profile, address];
+
    return profile;
  }

  static async getMulti(addresses: string[], config: Config): Promise<Profile[]> {
-
    const profilePromises = addresses.map(address => this.lookupAddress(address, ProfileType.Minimal, config));
+
    const profilePromises = addresses.map(address => this.lookupProfile(address, ProfileType.Minimal, config));
    const profiles = await Promise.all(profilePromises);
-
    return profiles.map(profile => { return new Profile(...profile); });
+
    return profiles.map(profile => { return new Profile(profile); });
  }

  static async get(
-
    address: string,
+
    addressOrName: string,
    profileType: ProfileType,
    config: Config,
  ): Promise<Profile> {
-
    const profile = await this.lookupAddress(address, profileType, config);
-
    return new Profile(...profile);
+
    const profile = await this.lookupProfile(addressOrName, profileType, config);
+
    return new Profile(profile);
  }
}
modified src/utils.ts
@@ -249,26 +249,32 @@ export async function resolveIdxProfile(caip10: string, config: Config): Promise
}

// Resolves an ENS profile or return null
-
export async function resolveEnsProfile(address: string, profileType: ProfileType, config: Config): Promise<EnsProfile | null> {
-
  const name = await config.provider.lookupAddress(address);
-
  if (name) {
+
export async function resolveEnsProfile(addressOrName: string, profileType: ProfileType, config: Config): Promise<EnsProfile | null> {
+
  const name = ethers.utils.isAddress(addressOrName)
+
    ? await config.provider.lookupAddress(addressOrName)
+
    : addressOrName;

+
  if (name) {
    const resolver = await config.provider.getResolver(name);
+

    if (profileType === ProfileType.Full) {
      const registration = await getRegistration(name, config);
      if (registration) {
        return registration.profile;
      }
    } else if (profileType === ProfileType.Project) {
-
      const project = await Promise.allSettled([getAvatar(name, config, resolver), getSeed(name, config, resolver)]);
+
      const project = await Promise.allSettled([
+
        getAvatar(name, config, resolver),
+
        getSeed(name, config, resolver)
+
      ]);

      const [avatar, seedHost] =
        project.map(r => r.status == "fulfilled" ? r.value : null);

      return {
        name,
-
        address,
        avatar,
+
        address: null,
        seedHost,
        url: null,
        seedId: null,
@@ -280,8 +286,8 @@ export async function resolveEnsProfile(address: string, profileType: ProfileTyp

      return {
        name,
-
        address,
        avatar,
+
        address: null,
        url: null,
        seedId: null,
        seedHost: null,