Let's create a digital burn book that actually puts privacy first.
π Your mission
Build a Web5 Burn Book, based on Mean Girls, but this one is actual private.
π οΈ Your toolkit
To build this app, you will wield the following technologies:
- React - A JavaScript library, your brush to paint user interfaces, craft reusable components, and manage the state of your creation.
- Next.js - A React metaframework, your compass to guide you through creating pages, managing routes, and managing server-side rendering.
- Web5.js - A Web5 JavaScript SDK, your key to creating decentralized applications, facilitating direct communication between users, and granting them sovereignty over their data and identity.
Good news! You don't have to start from scratch. There is a pre-built application that contains the user interface for our Burn Book. Right now, the functions in the code donβt do much. They just print messages to the console and donβt have any real actions. As you progress through the tutorial, you will add logic to the functions.
To access the starter code, follow the instructions below or explore the project directly in CodeSandbox.
git clone https://github.com/galaxy-bytes/starter-burn-book-mean-girls
cd starter-burn-book-mean-girls
npm install
npm run dev
- Navigate to the
src/pages/index.js
file. - Identify the functions that currently only print console.logs.
- Try to understand how each function interacts.
Locate the line:
console.log(`this log is in initWeb5`);
and replace it with the following code snippet:
const { web5, did } = await Web5.connect({sync: '5s'});
setWeb5(web5);
setMyDid(did);
- Web5.connect() returns a Web5 instance: It initializes and returns an instance of Web5, allowing you to interact with the Web5 ecosystem.
- Web5.connect() also creates or connects to a DID: A DID (Decentralized Identifier) is a userβs unique ID card for the decentralized, digital world. It belongs only to you.
Web5.connect()
will either connect to an existing DID that you have or create a new one for you if you don't have one yet. A DID acts as an authenticator for Web5 apps, removing the need for login credentials.
Learn more about DID authentication.
Locate the line:
console.log('this is where we define our protocol')
And replace it with the following code snippet:
return {
protocol: "https://blackgirlbytes.dev/burn-book-finale",
published: true,
types: {
secretMessage: {
schema: "https://example.com/secretMessageSchema",
dataFormats: ["application/json"],
},
directMessage: {
schema: "https://example.com/directMessageSchema",
dataFormats: ["application/json"],
},
},
structure: {
secretMessage: {
$actions: [
{ who: "anyone", can: ["create"] },
{ who: "author", of: "secretMessage", can: ["read"] },
],
},
directMessage: {
$actions: [
{ who: "author", of: "directMessage", can: ["read"] },
{ who: "recipient", of: "directMessage", can: ["read"] },
{ who: "anyone", can: ["create"] },
],
},
},
};
- protocolDefinition: This object defines the protocol, its structure, and it grants permissions outlining who can perform specific actions like reading or writing a ding.
- Learn more about protocols.
Locate this line:
console.log('this is in query local protocol')
Replace:
return await web5.dwn.protocols.query({
message: {
filter: {
protocol: "https://blackgirlbytes.dev/burn-book-finale",
},
},
});
Locate this line
console.log('this is where Query remote protocol is')
Replace:
return await web5.dwn.protocols.query({
from: did,
message: {
filter: {
protocol: "https://blackgirlbytes.dev/burn-book-finale",
},
},
});
Locate this line:
console.log('this is where we install local protocol')
Replace
return await web5.dwn.protocols.configure({
message: {
definition: protocolDefinition,
},
});
Locate this line:
console.log('this is where we install remote protocol')
cons Replace:
const { protocol } = await web5.dwn.protocols.configure({
message: {
definition: protocolDefinition,
},
});
return await protocol.send(did);
Locate the line:
console.log('this is where we configure our protocol')
And replace it with the following code snippet:
const protocolDefinition = defineNewProtocol();
const protocolUrl = protocolDefinition.protocol;
const { protocols: localProtocols, status: localProtocolStatus } = await queryLocalProtocol(web5, protocolUrl);
if (localProtocolStatus.code !== 200 || localProtocols.length === 0) {
const result = await installLocalProtocol(web5, protocolDefinition);
console.log({ result })
console.log("Protocol installed locally");
}
const { protocols: remoteProtocols, status: remoteProtocolStatus } = await queryRemoteProtocol(web5, did, protocolUrl);
if (remoteProtocolStatus.code !== 200 || remoteProtocols.length === 0) {
const result = await installRemoteProtocol(web5, did, protocolDefinition);
console.log({ result })
console.log("Protocol installed remotely");
}
Locate the line:
console.log('this is where we Write the secret message')
Replace:
try {
const secretMessageProtocol = defineNewProtocol();
const { record, status } = await web5.dwn.records.write({
data: messageObj,
message: {
protocol: secretMessageProtocol.protocol,
protocolPath: "secretMessage",
schema: secretMessageProtocol.types.secretMessage.schema,
recipient: myDid,
},
});
if (status.code === 200) {
return { ...messageObj, recordId: record.id };
}
console.log('Secret message written to DWN', { record, status });
return record;
} catch (error) {
console.error('Error writing secret message to DWN', error);
}
Locate the line
console.log('this is where we Write the direct message')
Replace:
try {
const directMessageProtocol = defineNewProtocol();
const { record, status } = await web5.dwn.records.write({
data: messageObj,
message: {
protocol: directMessageProtocol.protocol,
protocolPath: "directMessage",
schema: directMessageProtocol.types.directMessage.schema,
recipient: messageObj.recipientDid,
},
});
if (status.code === 200) {
return { ...messageObj, recordId: record.id };
}
console.log('Direct message written to DWN', { record, status });
return record;
} catch (error) {
console.error('Error writing direct message to DWN', error);
}try {
const directMessageProtocol = defineNewProtocol();
const { record, status } = await web5.dwn.records.write({
data: messageObj,
message: {
protocol: directMessageProtocol.protocol,
protocolPath: "directMessage",
schema: directMessageProtocol.types.directMessage.schema,
recipient: messageObj.recipientDid,
},
});
if (status.code === 200) {
return { ...messageObj, recordId: record.id };
}
console.log('Direct message written to DWN', { record, status });
return record;
} catch (error) {
console.error('Error writing direct message to DWN', error);
}