Skip to content

Commit

Permalink
fix: Fetch Contributable Worlds
Browse files Browse the repository at this point in the history
  • Loading branch information
cyaiox committed Oct 8, 2024
1 parent d28f3a9 commit 70b86f7
Show file tree
Hide file tree
Showing 4 changed files with 381 additions and 138 deletions.
224 changes: 224 additions & 0 deletions packages/renderer/src/lib/ens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import { type ChainId } from '@dcl/schemas/dist/dapps/chain-id';
import { isDev } from '../modules/store/ens/utils';

const BATCH_SIZE = 1000;

export type Domain = { name: string };
export type DomainsQueryResult = { data: { domains: Domain[] } } | { errors: any };

export type OwnerByENSTuple = {
name: string;
wrappedOwner: {
id: string;
};
};
export type OwnerByENSQueryResult =
| {
data: {
domains: OwnerByENSTuple[];
};
}
| { errors: any };

export class ENS {
private subgraph = 'https://subgraph.decentraland.org/ens';
constructor(chainId: ChainId) {
if (isDev(chainId)) {
this.subgraph = 'https://subgraph.decentraland.org/ens-sepolia';
}
}

public async fetchNames(address: string) {
const response: Response = await fetch(this.subgraph, {
method: 'POST',
body: JSON.stringify({
query: `{
domains(
where: {or: [
{ wrappedOwner: "${address.toLowerCase()}" },
{ registrant: "${address.toLowerCase()}" }
]}
) {
name
}
}`,
}),
});

if (!response.ok) {
throw new Error(response.status.toString());
}

const queryResult: DomainsQueryResult = await response.json();

if ('errors' in queryResult) {
throw new Error(JSON.stringify(queryResult.errors));
}

return queryResult.data.domains.map(domain => domain.name);
}

public async fetchNamesOwners(domains: string[]): Promise<Record<string, string>> {
if (!domains) {
return {};
}

const response: Response = await fetch(this.subgraph, {
method: 'POST',
body: JSON.stringify({
query: `query getOwners($domains: [String]) {
domains(where: { name_in: $domains }) {
name
wrappedOwner {
id
}
}
}`,
variables: { domains },
}),
});

if (!response.ok) {
throw new Error(response.status.toString());
}

const queryResult: OwnerByENSQueryResult = await response.json();

if ('errors' in queryResult) {
throw new Error(JSON.stringify(queryResult.errors));
}

const results: Record<string, string> = {};
queryResult.data.domains.forEach(({ wrappedOwner, name }) => {
results[name] = wrappedOwner.id;
});
return results;
}
}

export type DCLDomainsQueryResult =
| { data: { nfts: { ens: { subdomain: string } }[] } }
| { errors: any };

export type DCLOwnerByNameTuple = {
owner: {
address: string;
};
ens: {
subdomain: string;
};
};
export type DCLOwnerByNameQueryResult = {
data: {
nfts: DCLOwnerByNameTuple[];
};
};

export class DCLNames {
private subgraph = 'https://subgraph.decentraland.org/marketplace';
constructor(chainId: ChainId) {
if (isDev(chainId)) {
this.subgraph = 'https://subgraph.decentraland.org/marketplace-sepolia';
}
}

public async fetchNames(address: string) {
let results: string[] = [];
let offset = 0;
let nextPage = true;

while (nextPage) {
const response: Response = await fetch(this.subgraph, {
method: 'POST',
body: JSON.stringify({
query: `{
nfts(
first: ${BATCH_SIZE},
skip: ${offset},
where: {
owner_: { id: "${address.toLowerCase()}" },
category: ens
}
) {
ens {
subdomain
}
}
}`,
}),
});

if (!response.ok) {
throw new Error(response.status.toString());
}

const queryResult: DCLDomainsQueryResult = await response.json();

if ('errors' in queryResult) {
throw new Error(JSON.stringify(queryResult.errors));
}
const domains: string[] = queryResult.data.nfts.map(
nft => `${nft.ens.subdomain.toString()}.dcl.eth`,
);
results = results.concat(domains);

if (domains.length === BATCH_SIZE) {
offset += BATCH_SIZE;
} else {
nextPage = false;
}
}

return results;
}

public async fetchNamesOwners(domains: string[]) {
if (!domains) {
return {};
}

const results: Record<string, string> = {};
let offset = 0;
let nextPage = true;

while (nextPage) {
const response: Response = await fetch(this.subgraph, {
method: 'POST',
body: JSON.stringify({
query: `query getOwners($domains: [String!], $offset: Int) {
nfts(first: ${BATCH_SIZE}, skip: $offset, where: { name_in: $domains, category: ens }) {
owner {
address
}
ens {
subdomain
}
}
}`,
variables: { domains, offset },
}),
});

if (!response.ok) {
throw new Error(response.status.toString());
}

const queryResult: DCLOwnerByNameQueryResult = await response.json();

if ('errors' in queryResult) {
throw new Error(JSON.stringify(queryResult.errors));
}
queryResult.data.nfts.forEach(({ ens, owner }) => {
results[ens.subdomain] = owner.address;
});

if (queryResult.data.nfts.length === BATCH_SIZE) {
offset += BATCH_SIZE;
} else {
nextPage = false;
}
}

return results;
}
}
27 changes: 17 additions & 10 deletions packages/renderer/src/lib/worlds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fetch from 'decentraland-crypto-fetch';
import type { AuthIdentity } from '@dcl/crypto';
import { localStorageGetIdentity } from '@dcl/single-sign-on-client';
import { DEPLOY_URLS } from '/shared/types/deploy';

import type { ContributableDomain } from '../modules/store/ens/types';
Expand Down Expand Up @@ -145,6 +146,14 @@ export class Worlds {
}
}

private withIdentity(address: string): AuthIdentity {
const identity = localStorageGetIdentity(address);
if (!identity) {
throw new Error('No identity found');
}
return identity;
}

public async fetchWorld(name: string) {
try {
const result = await fetch(`${this.url}/entities/active`, {
Expand Down Expand Up @@ -187,7 +196,7 @@ export class Worlds {
};

public postPermissionType = async (
identity: AuthIdentity,
address: string,
worldName: string,
worldPermissionNames: WorldPermissionNames,
worldPermissionType: WorldPermissionType,
Expand All @@ -199,48 +208,46 @@ export class Worlds {
metadata: {
type: worldPermissionType,
},
identity,
identity: this.withIdentity(address),
},
);
return result.status === 204;
};

public putPermissionType = async (
identity: AuthIdentity,
address: string,
worldName: string,
worldPermissionNames: WorldPermissionNames,
address: string,
) => {
const result = await fetch(
`${this.url}/world/${worldName}/permissions/${worldPermissionNames}/${address}`,
{
method: 'PUT',
identity,
identity: this.withIdentity(address),
},
);
return result.status === 204;
};

public deletePermissionType = async (
identity: AuthIdentity,
address: string,
worldName: string,
worldPermissionNames: WorldPermissionNames,
address: string,
) => {
const result = await fetch(
`${this.url}/world/${worldName}/permissions/${worldPermissionNames}/${address}`,
{
method: 'DELETE',
identity,
identity: this.withIdentity(address),
},
);
return result.status === 204;
};

public fetchContributableDomains = async (identity: AuthIdentity) => {
public fetchContributableDomains = async (address: string) => {
const result = await fetch(`${this.url}/wallet/contribute`, {
method: 'GET',
identity,
identity: this.withIdentity(address),
});

if (result.ok) {
Expand Down
Loading

0 comments on commit 70b86f7

Please sign in to comment.