Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { getThirdwebClient } from "@/constants/thirdweb.server";
import { fetchPublishedContractVersions } from "components/contract-components/fetch-contracts-with-versions";
import {
fetchLatestPublishedContractVersion,
fetchPublishedContractVersions,
} from "components/contract-components/fetch-contracts-with-versions";
import { isAddress } from "thirdweb";
import type { FetchDeployMetadataResult } from "thirdweb/contract";
import { resolveAddress } from "thirdweb/extensions/ens";
import invariant from "tiny-invariant";
import type { ModuleMeta } from "./install-module-params";
Expand All @@ -14,16 +18,24 @@ export async function getModuleInstalledParams(ext: ModuleMeta) {
client: getThirdwebClient(),
name: ext.publisherAddress,
});
const allPublishedModules = await fetchPublishedContractVersions(
publisherAddress,
ext.moduleName,
);

// find the version we want
const publishedModule =
ext.moduleVersion === "latest"
? allPublishedModules[0]
: allPublishedModules.find((v) => v.version === ext.moduleVersion);
let publishedModule: FetchDeployMetadataResult | undefined = undefined;

if (ext.moduleVersion === "latest") {
publishedModule = await fetchLatestPublishedContractVersion(
publisherAddress,
ext.moduleName,
);
} else {
const allPublishedModules = await fetchPublishedContractVersions(
publisherAddress,
ext.moduleName,
);

publishedModule = allPublishedModules.find(
(v) => v.version === ext.moduleVersion,
);
}

invariant(
publishedModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ContractPublishForm } from "components/contract-components/contract-pub
import { revalidatePath } from "next/cache";
import { notFound, redirect } from "next/navigation";
import { fetchDeployMetadata } from "thirdweb/contract";
import { getPublishedContractsWithPublisherMapping } from "../../../published-contract/[publisher]/[contract_id]/utils/getPublishedContractsWithPublisherMapping";
import { getLatestPublishedContractsWithPublisherMapping } from "../../../published-contract/[publisher]/[contract_id]/utils/getPublishedContractsWithPublisherMapping";

type DirectDeployPageProps = {
params: Promise<{
Expand Down Expand Up @@ -46,18 +46,16 @@ export default async function PublishContractPage(
// - get the publish metadata with name+publisher address
// - merge the two objects with publishMetadataFromUri taking higher precedence
if (!publishMetadataFromUri.version) {
const publishedContractVersions =
await getPublishedContractsWithPublisherMapping({
const publishedContract =
await getLatestPublishedContractsWithPublisherMapping({
publisher: address,
contract_id: publishMetadataFromUri.name,
});

if (!publishedContractVersions) {
if (!publishedContract) {
notFound();
}

const publishedContract = publishedContractVersions[0];

if (publishedContract) {
publishMetadata = {
...publishedContract,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,5 @@ export default async function ExploreCategoryPage(
</div>
);
}

export const dynamic = "force-static";
2 changes: 2 additions & 0 deletions apps/dashboard/src/app/(dashboard)/explore/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ export default async function ExplorePage() {
</div>
);
}

export const dynamic = "force-static";
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { notFound } from "next/navigation";
import { PublishedContractBreadcrumbs } from "./components/breadcrumbs.client";
import { getPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping";
import { getLatestPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping";

type Params = { publisher: string; contract_id: string };

Expand All @@ -20,16 +19,11 @@ export async function generateMetadata(props: { params: Promise<Params> }) {
const params = await props.params;
const { publisher, contract_id } = params;

const publishedContracts = await getPublishedContractsWithPublisherMapping({
publisher: publisher,
contract_id: contract_id,
});

if (!publishedContracts) {
notFound();
}

const publishedContract = publishedContracts[0];
const publishedContract =
await getLatestPublishedContractsWithPublisherMapping({
publisher: publisher,
contract_id: contract_id,
});

if (!publishedContract) {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { format } from "date-fns/format";
import { resolveEns } from "lib/ens";
import { correctAndUniqueLicenses } from "lib/licenses";
import { getSocialProfiles } from "thirdweb/social";
import { getPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping";
import { getLatestPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping";
import { publishedContractOGImageTemplate } from "./utils/publishedContractOGImageTemplate";

export const runtime = "edge";
Expand All @@ -22,8 +22,8 @@ export default async function Image(props: {
const client = getThirdwebClient();
const { publisher, contract_id } = props.params;

const [publishedContracts, socialProfiles] = await Promise.all([
getPublishedContractsWithPublisherMapping({
const [publishedContract, socialProfiles] = await Promise.all([
getLatestPublishedContractsWithPublisherMapping({
publisher: publisher,
contract_id: contract_id,
}),
Expand All @@ -42,12 +42,6 @@ export default async function Image(props: {
};
})();

if (!publishedContracts) {
return null;
}

const publishedContract = publishedContracts[0];

if (!publishedContract) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { getThirdwebClient } from "@/constants/thirdweb.server";
import { fetchPublishedContractVersions } from "components/contract-components/fetch-contracts-with-versions";
import {
fetchLatestPublishedContractVersion,
fetchPublishedContractVersions,
} from "components/contract-components/fetch-contracts-with-versions";
import { isAddress } from "thirdweb";
import { resolveAddress } from "thirdweb/extensions/ens";

Expand Down Expand Up @@ -36,3 +39,24 @@ export async function getPublishedContractsWithPublisherMapping(options: {
return undefined;
}
}

export async function getLatestPublishedContractsWithPublisherMapping(options: {
publisher: string;
contract_id: string;
}) {
const { publisher, contract_id } = options;

try {
// resolve ENS
const publisherAddress = isAddress(publisher)
? publisher
: await resolveAddress({
client: getThirdwebClient(),
name: mapThirdwebPublisher(publisher),
});

return fetchLatestPublishedContractVersion(publisherAddress, contract_id);
} catch {
return undefined;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getThirdwebClient } from "@/constants/thirdweb.server";
import { isAddress } from "thirdweb";
import { type ThirdwebClient, isAddress } from "thirdweb";
import { fetchDeployMetadata } from "thirdweb/contract";
import { resolveAddress } from "thirdweb/extensions/ens";
import {
Expand All @@ -20,22 +20,10 @@ export async function fetchPublishedContractVersions(
contractId: string,
) {
const client = getThirdwebClient();
const allVersions = await getPublishedContractVersions({
contract: getContractPublisher(client),
publisher: isAddress(publisherAddress)
? publisherAddress
: await resolveAddress({
client,
name: mapThirdwebPublisher(publisherAddress),
}),
contractId: contractId,
});

const sortedVersions = allVersions.toSorted((a, b) => {
if (a.publishTimestamp === b.publishTimestamp) {
return 0;
}
return a.publishTimestamp > b.publishTimestamp ? -1 : 1;
const sortedVersions = await getSortedPublishedContractVersions({
publisherAddress,
contractId,
client,
});

const responses = await Promise.allSettled(
Expand All @@ -61,21 +49,81 @@ export async function fetchPublishedContractVersions(
return uniquePublishedContracts;
}

async function getSortedPublishedContractVersions(params: {
publisherAddress: string;
contractId: string;
client: ThirdwebClient;
}) {
const { publisherAddress, contractId, client } = params;

const allVersions = await getPublishedContractVersions({
contract: getContractPublisher(client),
publisher: isAddress(publisherAddress)
? publisherAddress
: await resolveAddress({
client,
name: mapThirdwebPublisher(publisherAddress),
}),
contractId: contractId,
});

const sortedVersions = allVersions.toSorted((a, b) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw this toSorted was throwing an error for me locally. I had to temporarily set it to [...allVersions].sort() to get it working locally. Not sure if it's an issue.

if (a.publishTimestamp === b.publishTimestamp) {
return 0;
}
return a.publishTimestamp > b.publishTimestamp ? -1 : 1;
});

return sortedVersions;
}

export async function fetchLatestPublishedContractVersion(
publisherAddress: string,
contractId: string,
) {
const client = getThirdwebClient();

const sortedVersions = await getSortedPublishedContractVersions({
publisherAddress,
contractId,
client,
});

const latestVersion = sortedVersions[0];

if (!latestVersion) {
return undefined;
}

return fetchDeployMetadata({
client,
uri: latestVersion.publishMetadataUri,
}).then((m) => ({ ...m, ...latestVersion }));
}

export async function fetchPublishedContractVersion(
publisherAddress: string,
contractId: string,
version = "latest",
) {
if (version === "latest") {
const latestVersion = await fetchLatestPublishedContractVersion(
publisherAddress,
contractId,
);

return latestVersion || null;
}

const allVersions = await fetchPublishedContractVersions(
publisherAddress,
contractId,
);

if (allVersions.length === 0) {
return null;
}
if (version === "latest") {
return allVersions[0];
}

return allVersions.find((v) => v.version === version) || allVersions[0];
}

Expand Down
55 changes: 30 additions & 25 deletions apps/dashboard/src/components/explore/contract-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { moduleToBase64 } from "app/(dashboard)/published-contract/utils/module-
import { replaceDeployerAddress } from "lib/publisher-utils";
import { RocketIcon, ShieldCheckIcon } from "lucide-react";
import Link from "next/link";
import { ClientOnly } from "../../ClientOnly/ClientOnly";
import { fetchPublishedContractVersion } from "../../contract-components/fetch-contracts-with-versions";
import { ContractPublisher } from "../publisher";

Expand Down Expand Up @@ -109,25 +110,6 @@ export async function ContractCard({
"relative flex min-h-[220px] flex-col rounded-lg border border-border bg-card p-4 hover:border-active-border"
}
>
<TrackedLinkTW
className="absolute inset-0 z-0 cursor-pointer"
href={getContractUrl({
publisher,
contractId,
version,
modules,
titleOverride,
})}
category="contract_card"
label={contractId}
trackingProps={{
publisher,
contractId,
version,
...(tracking || {}),
}}
/>

{/* Audited + Version + Tags */}
<div className="flex justify-between">
<div className="flex items-center gap-1.5">
Expand Down Expand Up @@ -167,11 +149,30 @@ export async function ContractCard({

{/* Title */}
<h3 className="font-semibold text-lg tracking-tight">
{(
titleOverride ||
publishedContractResult.displayName ||
publishedContractResult.name
).replace("[Beta]", "")}
<TrackedLinkTW
className="cursor-pointer before:absolute before:inset-0 before:z-0"
href={getContractUrl({
publisher,
contractId,
version,
modules,
titleOverride,
})}
category="contract_card"
label={contractId}
trackingProps={{
publisher,
contractId,
version,
...(tracking || {}),
}}
>
{(
titleOverride ||
publishedContractResult.displayName ||
publishedContractResult.name
).replace("[Beta]", "")}
</TrackedLinkTW>
</h3>

{/* Desc */}
Expand All @@ -198,7 +199,11 @@ export async function ContractCard({
)}
>
{publishedContractResult.publisher && (
<ContractPublisher addressOrEns={publishedContractResult.publisher} />
<ClientOnly ssr={<Skeleton className="size-5 rounded-full" />}>
<ContractPublisher
addressOrEns={publishedContractResult.publisher}
/>
</ClientOnly>
)}

<div className="flex items-center justify-between">
Expand Down
Loading