Skip to content

Commit

Permalink
add success page to ai minter
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenmarcus committed Feb 19, 2024
1 parent 29581d9 commit f459f2d
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 48 deletions.
6 changes: 3 additions & 3 deletions ai-minter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
},
"dependencies": {
"@hookform/resolvers": "^3.3.2",
"@mintbase-js/react": "0.5.4-beta.0",
"@mintbase-js/sdk": "0.5.4-beta.0",
"@mintbase-js/storage": "0.5.4-beta.0",
"@mintbase-js/react": "0.5.5-beta.2",
"@mintbase-js/sdk": "0.5.5-beta.2",
"@mintbase-js/storage": "0.5.5-beta.2",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2",
Expand Down
30 changes: 15 additions & 15 deletions ai-minter/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 55 additions & 21 deletions ai-minter/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,64 @@
"use client";

import { Inter } from "next/font/google";
import { AppProvider } from "@/components/Provider";
import { Metadata } from "next";
import { headers } from "next/headers";
import "./globals.css";
import { MintbaseWalletContextProvider } from "@mintbase-js/react";
import { MintbaseWalletSetup } from "@/config/setup";
import "@near-wallet-selector/modal-ui/styles.css";
import { ReplicateProvider } from "@/providers/replicate";

const inter = Inter({ subsets: ["latin"] });
const extractSignMeta = (url: string): string | null => {
const signMetaIndex = url.indexOf("signMeta=");
if (signMetaIndex === -1) {
return null; // signMeta not found
}

const startIndex = signMetaIndex + "signMeta=".length;
const endIndex = url.indexOf("&", startIndex);
if (endIndex === -1) {
return url.substring(startIndex); // signMeta is the last parameter in the URL
} else {
return url.substring(startIndex, endIndex);
}
};

export async function generateMetadata(): Promise<Metadata> {
const headersList = headers();
const referer = headersList.get("referer");

let pageTitle = "Mintbase Minter Example";
let pageDescription =
"Learn how to Mint NFTs on NEAR with Mintbase Minter Example";

// Check if signMeta exists in the URL
const signMeta = referer ? extractSignMeta(referer) : "";
if (signMeta) {
const signMetaData = JSON.parse(decodeURIComponent(signMeta));

pageTitle = `Success! You just minted: ${signMetaData?.args?.title}`;
pageDescription = `Just Minted ${signMetaData?.args?.title} on Mintbase`;
// Now you can further process the extracted signMeta value
}

return {
metadataBase: new URL("https://minter.mintbase.xyz"),
title: pageTitle,
openGraph: {
title: pageTitle,
description: pageDescription,
images: ["https://i.imgur.com/QDJPsAA.png"],
},
twitter: {
title: pageTitle,
description: pageDescription,
siteId: "1467726470533754880",
creator: "Mintbase",
card: "summary_large_image",
images: "https://i.imgur.com/QDJPsAA.png",
},
};
}

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<MintbaseWalletContextProvider {...MintbaseWalletSetup}>
<ReplicateProvider>
<html lang="en">
<body className={`${inter.className} dark`}>
<div className="flex flex-1 flex-col min-h-screen text-gray-500 gradient w-full h-full flex justify-center items-center bold text-white">
{children}
</div>
</body>
</html>
</ReplicateProvider>
</MintbaseWalletContextProvider>
);
return <AppProvider> {children} </AppProvider>;
}
28 changes: 28 additions & 0 deletions ai-minter/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,38 @@ import { NearWalletConnector } from "@/components/NearWalletSelector";

import Head from "next/head";
import Minter from "@/components/Minter";
import { useSearchParams } from "next/navigation";
import { mbUrl, nearblocksUrl } from "@/config/setup";
import { SuccessPage } from "@/components/Success";

export default function Home() {
const { isConnected } = useMbWallet();


const params = useSearchParams();

const mintedParams = params.get("signMeta")
? JSON.parse(params.get("signMeta") as string)
: "";
const txnHashes = params.get("transactionHashes")
? params.get("transactionHashes")
: "";


if (mintedParams) {
const metaPage = `${mbUrl}/ref/${mintedParams.args.ref}?type=meta`;
const txnHashUrl = `${nearblocksUrl}/txns/${txnHashes}`;

const successPageData = {
nftTitle: mintedParams.args.title as string,
mediaUrl: mintedParams.args.mediaUrl as string,
metaPage,
txnHashUrl,
};

return <SuccessPage data={successPageData} />;
}

if (isConnected)
return (
<main className="flex flex-col items-center justify-center mt-2 ">
Expand Down
30 changes: 30 additions & 0 deletions ai-minter/src/components/Provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client"

import { MintbaseWalletContextProvider } from "@mintbase-js/react";
import { MintbaseWalletSetup } from "@/config/setup";
import "@near-wallet-selector/modal-ui/styles.css";
import { ReplicateProvider } from "@/providers/replicate";
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export const AppProvider = ({
children,
}: {
children: React.ReactNode;
}) => {

return (
<MintbaseWalletContextProvider {...MintbaseWalletSetup}>
<ReplicateProvider>
<html lang="en">
<body className={`${inter.className} dark`}>
<div className="flex flex-1 flex-col min-h-screen text-gray-500 gradient w-full h-full flex justify-center items-center bold text-white">
{children}
</div>
</body>
</html>
</ReplicateProvider>
</MintbaseWalletContextProvider>
)
}
45 changes: 45 additions & 0 deletions ai-minter/src/components/Success.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as React from "react";

import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import Link from "next/link";

interface SuccessPageData {
nftTitle: string;
mediaUrl: string;
metaPage: string;
txnHashUrl: string;
}

export function SuccessPage({ data }: { data: SuccessPageData }): JSX.Element {
const { nftTitle, mediaUrl, metaPage, txnHashUrl } = data;

return (
<Card className="w-[350px]">
<CardHeader>
<CardDescription> Success you just Minted! </CardDescription>
<CardTitle>{nftTitle}</CardTitle>
</CardHeader>
<CardContent>
<div className="flex w-full relative">
<img src={mediaUrl} width="100%" height="auto" alt={nftTitle} />
</div>
</CardContent>
<CardFooter className="flex justify-between">
<Link target="_blank" href={txnHashUrl} className="text-xs">
View Transaction
</Link>
<Link target="_blank" href={metaPage}>
<Button> View Nft on Mintbase</Button>
</Link>
</CardFooter>
</Card>
);
}
12 changes: 11 additions & 1 deletion ai-minter/src/config/setup.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
export const proxyAddress = process?.env?.NEXT_PUBLIC_PROXY_CONTRACT_ADDRESS || "0.minsta.proxy.mintbase.testnet";
const contractAddress = process?.env?.NEXT_PUBLIC_MINT_CONTRACT_ADDRESS || "aiminter.mintspace2.testnet";
const network = process?.env?.NEXT_PUBLIC_NETWORK || "testnet";
const callbackUrl = network === "testnet" ? `https://testnet.mintbase.xyz/contract/${contractAddress}/nfts/all/0` : `https://mintbase.xyz/contract/${contractAddress}/nfts/all/0`;

const isTestnet = network === "testnet";
const callbackUrl = !isTestnet
? `https://mintbase.xyz/contract/${contractAddress}/nfts/all/0`
: `https://testnet.mintbase.xyz/contract/${contractAddress}/nfts/all/0`;
export const mbUrl = !isTestnet
? "https://www.mintbase.xyz"
: "https://testnet.mintbase.xyz";
export const nearblocksUrl = !isTestnet
? "https://nearblocks.io"
: "https://testnet.nearblocks.io";

export const MintbaseWalletSetup = {
contractAddress,
Expand Down
24 changes: 22 additions & 2 deletions ai-minter/src/hooks/useMint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ArweaveResponse, uploadFile, uploadReference } from "@mintbase-js/stora
import { formSchema } from "./formSchema";
import { MintbaseWalletSetup, proxyAddress } from "@/config/setup";
import { Wallet } from "@near-wallet-selector/core";
import { cbUrl } from "./utils";

const useMintImage = () => {
const { selector, activeAccountId } = useMbWallet();
Expand Down Expand Up @@ -56,7 +57,14 @@ const useMintImage = () => {
});
const file = uploadFile(media);

await handleMint(reference.id, file, activeAccountId as string, wallet);
await handleMint(
reference.id,
file,
activeAccountId as string,
wallet,
reference.media_url as string,
data.title
);
};

const form = useForm<z.infer<typeof formSchema>>({
Expand All @@ -67,12 +75,24 @@ const useMintImage = () => {
reference: string,
media: Promise<ArweaveResponse>,
activeAccountId: string,
wallet: Wallet
wallet: Wallet,
mediaUrl: string,
nftTitle: string
) {
if (reference) {

const callbackArgs = {
contractAddress: MintbaseWalletSetup.contractAddress.toString(),
amount: 1,
ref: `${reference}`,
mediaUrl: mediaUrl,
title: nftTitle,
};

await wallet.signAndSendTransaction({
signerId: activeAccountId,
receiverId: proxyAddress,
callbackUrl: cbUrl(reference, callbackArgs),
actions: [
{
type: "FunctionCall",
Expand Down
16 changes: 15 additions & 1 deletion ai-minter/src/hooks/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

import { ChangeEvent } from "react";

export enum TransactionSuccessEnum {
MINT = 'mint',
}

interface CallbackArgs {
contractAddress: string;
amount: number;
ref: string;
}

export function getImageData(event: ChangeEvent<HTMLInputElement>) {
// FileList is immutable, so we need to create a new one
const dataTransfer = new DataTransfer();
Expand All @@ -15,4 +25,8 @@ export function getImageData(event: ChangeEvent<HTMLInputElement>) {
const displayUrl = URL.createObjectURL(event.target.files![0]);

return { files, displayUrl };
}
}

export const cbUrl = (hash: string, callbackArgs: CallbackArgs) =>
callbackUrl(hash, TransactionSuccessEnum.MINT, callbackArgs)

2 changes: 0 additions & 2 deletions minter/src/hooks/useMint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ const useMintImage = () => {
media: data?.media as unknown as File,
});

console.log(reference, "reference");

const file = uploadFile(data?.media as unknown as File);

await handleMint(
Expand Down
Loading

0 comments on commit f459f2d

Please sign in to comment.