Building a Next.js App with DataverseOS, Typescript, and Next.js: A Step-by-Step Guide
In this tutorial, we'll walk through the process of creating a Next.js application using DataverseOS along with Typescript. DataverseOS is a decentralized application platform that leverages blockchain technology to manage and store data securely. We'll use the powerful @dataverse/dataverse-connector
package to interact with DataverseOS and handle data models.
Prerequisites:
Node.js >=16 version installed
Metamask or Dataverse keypair
Basic knowledge of Next.js, Typescript, and pnpm
Step 1: Setting up the Next.js App
npx create-next-app@latest demo-app
Step 2: Initializing Dataverse
npm install -g pnpm
pnpm install create-dataverse-app
Step 3: Creating Data Models
Create a model for a social platform post in the 'data-app/models' directory using the provided GraphQL syntax.
dataverseos init data-app
type post @createModel(accountRelation: LIST, description: "post") {
modelVersion: String! @string(maxLength: 100)
text: String @string(maxLength: 300000000)
images: [String] @list(maxLength: 10000000) @string(maxLength: 2000000)
videos: [String] @list(maxLength: 10000000) @string(maxLength: 2000000)
options: String @string(maxLength: 300000000)
createdAt: DateTime!
updatedAt: DateTime!
}
Step 4: Registering Models
Navigate to 'data-app' and deploy the Dataverse application.
cd data-app
pnpm install
dataverseos deploy
Take note of the generated 'app-id' and 'model-id' for later use.
Step 5: Connecting to Dataverse Wallet
Now, we will navigate back again to our demo-app. Implement the connection to the Dataverse wallet in your Next.js project. Update the page.tsx
file with the provided code, replacing 'app-id' with your actual app ID.
"use client";
import { DataverseConnector, SYSTEM_CALL, RESOURCE } from "@dataverse/dataverse-connector";
import React, { useState } from "react";
export default function Home() {
const [pkh, setPkh] = useState("");
const dataverseConnector = new DataverseConnector();
const login = async () => {
await createCapability();
};
const createCapability = async () => {
await dataverseConnector.connectWallet();
const pkh = await dataverseConnector.runOS({
method: SYSTEM_CALL.createCapability,
params: {
appId: "app_id",
resource: RESOURCE.CERAMIC,
},
});
console.log("pkh:", pkh);
setPkh(pkh);
return pkh;
};
return (
<div>
<div className=" mb-4">
{pkh ? (
<p>{pkh}</p>
) : (
<button onClick={login}>Connect Wallet</button>
)}
</div>
</div>
);
}
Step 6: Uploading Files
Extend your Next.js app to include file uploads. Implement the code provided for uploading files, replacing 'model-id' with the ID of the deployed post model.
const [fileId, setFileId] = useState<String | undefined>();
const [loading, setLoading] = useState(false);
const [inputs, setInputs] = useState({
text: "",
fileId: "",
});
const uploadWithDataverse = async () => {
setLoading(true);
const encrypted = JSON.stringify({
text: false,
images: false,
videos: false,
});
await dataverseConnector.connectWallet();
const res = await dataverseConnector.runOS({
method: SYSTEM_CALL.createIndexFile,
params: {
modelId: "model-id",
fileName: "test",
fileContent: {
modelVersion: "0",
text: inputs.text,
images: [],
videos: [],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
encrypted,
},
},
})
setFileId(res.fileContent.file.contentId);
setLoading(false);
};
return (
<div className=" mb-4">
<p>Upload File</p>
<input
type="text"
className="text-black"
onChange={(e) =>
setInputs({ ...inputs, text: e.target.value })
}
/>
<button onClick={uploadWithDataverse}>Upload</button>
{loading ? <p>Loading..</p> : <p>file id: {fileId}</p>}
</div>
</div>
);
Step 7: Loading Files
Further, enhance your application by adding file loading functionality. Use the provided code to load files from DataverseOS, displaying the fetched data.
const [fetchedData, setFetchedData] = useState<any>();
const loadWithDataverse = async () => {
const res = await dataverseConnector.runOS({
method: SYSTEM_CALL.loadFile,
params: inputs.fileId,
});
console.log(res);
setFetchedData(res.fileContent.content.text);
};
return (
<div className=" mb-4">
<p>Load File</p>
<input
type="text"
className="text-black"
onChange={(e) =>
setInputs({ ...inputs, fileId: e.target.value })
}
/>
<button onClick={loadWithDataverse}>Load</button>
<p>data: {fetchedData}</p>
</div>
</div>
);
Conclusion:
🔥 Congratulations! You've successfully integrated DataverseOS into your Next.js application, allowing for secure and decentralized data storage. This tutorial provides a foundation for building more complex applications with DataverseOS, giving you the tools to create powerful decentralized solutions.
Feel free to explore additional features and functionalities offered by DataverseOS to tailor your application to specific needs. Happy coding!