Add support for ENS routes

Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
Alexis Sellier
2021-09-22 10:38:57 +02:00
parent dad19066e0
commit abc62b02fd
4 changed files with 52 additions and 38 deletions
+19 -10
View File
@@ -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);
+1 -1
View File
@@ -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}
+20 -21
View File
@@ -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);
}
}
+12 -6
View File
@@ -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,