<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John Fáwọlé </title>
    <description>The latest articles on DEV Community by John Fáwọlé  (@johnfawole).</description>
    <link>https://dev.to/johnfawole</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1197781%2Ffecc9c90-7362-4bfd-a90f-1947a8ed4c15.jpg</url>
      <title>DEV Community: John Fáwọlé </title>
      <link>https://dev.to/johnfawole</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/johnfawole"/>
    <language>en</language>
    <item>
      <title>How I Built an AI-Powered Content Workflow for My Agency Using Notion MCP</title>
      <dc:creator>John Fáwọlé </dc:creator>
      <pubDate>Fri, 27 Mar 2026 23:10:32 +0000</pubDate>
      <link>https://dev.to/johnfawole/how-i-built-an-ai-powered-content-workflow-for-my-agency-using-notion-mcp-23e</link>
      <guid>https://dev.to/johnfawole/how-i-built-an-ai-powered-content-workflow-for-my-agency-using-notion-mcp-23e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As a founder of a dev content marketing agency, one of the things I’ve had to deal with is optimizing workflow across the team. &lt;/p&gt;

&lt;p&gt;At one point, we introduced Trello and other management software, but they ended up adding more complications, and we had to strip them off. &lt;/p&gt;

&lt;p&gt;Came across the Notion MCP challenge and thought of spinning up a simple Notion-based workflow, where all our dev writers and editors can do their work easily. &lt;/p&gt;

&lt;p&gt;In this short blog, I’ll be walking you through what I built and how it’s set to work. &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;What Is Notion MCP and Why It Matters for Content Teams&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;MCP stands for &lt;strong&gt;Model Context Protocol&lt;/strong&gt;. It's a system that allows an AI assistant like ChatGPT or Claude to actually interact with your Notion workspace.&lt;/p&gt;

&lt;p&gt;Have you ever been in a situation where you gained clarity on something while chatting with Claude, and just wish you could commit it to a page on your Notion?&lt;/p&gt;

&lt;p&gt;Well, what you’d have most likely done in that case is to copy from Claude, open another tab for Notion and paste it. &lt;/p&gt;

&lt;p&gt;You’d agree such a simple action doesn’t have to be implemented through several screens. This is where feeding context across your different applications becomes imperative. &lt;/p&gt;

&lt;p&gt;Unlike the basic Notion API, MCP is not just a data retrieval tool. It is agentic and conversational. It understands context, reads pages, creates database entries, updates status fields, and links records together.&lt;/p&gt;

&lt;p&gt;Rather than asking Claude &lt;em&gt;how to&lt;/em&gt;, MCP gives you the power to invite Claude directly into your workspace as your personal assistant that does the actual work.&lt;/p&gt;

&lt;p&gt;This changes everything for content teams. While the basic API can store content in Notion, MCP allows AI to move content through a production pipeline from brief to draft to review to publication. MCP acts as an intelligent tool that facilitates coordination and structure.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Configuring Your MCP with Your Notion Account&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;You must connect your context protocol for you to connect your Notion account to any AI-powered IDE of your choice.&lt;/p&gt;

&lt;p&gt;For me, I used Cursor, and that will be the IDE of this article.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Click Settings and Navigate to Tools &amp;amp; MCP&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Navigate as indicated in the picture below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffoxlg8kpy2r473t5i7ia.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffoxlg8kpy2r473t5i7ia.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Add the MCP with JSON Format&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For some LLMs like ChatGPT, the connection is practically done in the UI as Notion is supported as one of the apps. As a result, the integration is granularly done, and you don’t have to bother about the JSON.&lt;/p&gt;

&lt;p&gt;Now, in Cursor, click on “Add MCP.” Once you do that, you’d be taken to a file where you can go ahead to paste this JSON file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;{
  "mcpServers": {
    "notion": {
      "url": "https://mcp.notion.com/mcp"
    }
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you paste this, you’d be taken to a browser to login to your Notion.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;The Content Management Workflow&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Here are the steps I took to create the workflow:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating the Linked Database&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;While in Cursor, paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a page named work. It should be a linked database with 3 tags: Briefs, Drafts, Editorial Review.
Each should be able to host a Google Drive link or plain text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then after the execution of your prompt, you should have something like this: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcoox275xsl21zxh4sxuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcoox275xsl21zxh4sxuk.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Creating a Brief From the IDE&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can create the brief right from Cursor, just that you have to specify all the parameters you want the writers to take note of as well as other instructions.&lt;/p&gt;

&lt;p&gt;First of all, let’s prompt out the parameters. In the instant case, we want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Topic (text): The subject of the content. This becomes your working title.

Audience (select): Who you're writing for. Create options like "HR leaders," "marketing managers," "executives."

Keywords (text): Target SEO keywords you want to rank for.

Tone (select): The voice of the piece. Options like "authoritative," "conversational," "technical."

Assignee (person): Which content leader or writer owns this brief.

Due Date (date): When the draft is due.

Status (select): Options: "Draft Needed," "In Progress," "In Review," "Approved," "Published."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will serve as the basis for future briefs. Now that we have the minimal style guide ready. We can go ahead to request the agentic briefing on a topic like x402. &lt;/p&gt;

&lt;p&gt;Here is the result: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxj90ygwsyulnn9a06gdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxj90ygwsyulnn9a06gdn.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you are done with this, you can instruct your Cursor agent to move the brief from Brief to Draft.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;AI-assisted Drafting with Notion AI&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Even though it is unethical to quantitatively draft a blog content with AI, it is permissible to get assisted with AI. On this note, the writer can draft and also use the Notion AI.&lt;/p&gt;

&lt;p&gt;Here is a sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X402: the Missing Payment Layer for the Internet (and Why AI Agents Care)
The internet has always had a clean way to ask for resources: send an HTTP request, get a response.
But it never had a native way to ask for payment.
For more than two decades, the HTTP spec has included a status code for this exact problem: 402 Payment Required. The catch is that 402 was reserved but never standardized into a real, interoperable payment flow.
x402 is an open payment protocol (developed by Coinbase) that brings that idea to life: an internet-native, pay-per-use mechanism for APIs and digital services, where a client can be prompted to pay and then immediately retry the request--programmatically, without setting up accounts, subscriptions, or complex billing integrations.[1]
If you're building products that serve other developers--or you're building agentic systems that need to buy data and actions on-demand--x402 is worth understanding.
What is x402?
x402 is an open standard that lets a server require payment before serving a response, using the HTTP 402 Payment Required status code as the trigger.
At a high level:
A client requests a resource (an API endpoint, data payload, compute, etc.)
If payment is required and hasn't been provided, the server responds with HTTP 402 and payment instructions
The client pays (typically with stablecoins like USDC) and retries the request
The server verifies payment and returns the resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5ln9sq3pcfvs9875vnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5ln9sq3pcfvs9875vnv.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Editorial Review&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;This is where the editor comes in. First of all, an editor might prompt Cursor to benchmark the draft with the brief details. &lt;/p&gt;

&lt;p&gt;This gives your Editors a single place to review, comment, and approve content. They're not chasing drafts or digging through email for feedback threads. &lt;/p&gt;

&lt;p&gt;The AI handles the basic checklist items, so editors can focus on the feedback that actually improves the content.&lt;/p&gt;

&lt;p&gt;This is a preliminary stage where the superficial editorial issues are discovered. Then the editor can leave comments for the writers to improve. &lt;/p&gt;

&lt;p&gt;Once that is done, the editor can now manually read and review the whole document, and move it to &lt;em&gt;Done&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;My View About the MCP&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Notion MCP saves a lot of time and context-switching, which I found quite helpful.&lt;/p&gt;

&lt;p&gt;Especially now that we all ship code from Copilot or chat with Claude. &lt;/p&gt;

&lt;p&gt;It is not easy to circle our conclusions or whatever back to Notion for proper journaling; all that achieved with a simple command that activates agentic automation. &lt;/p&gt;

&lt;p&gt;In the context of my content management workflow, I believe it will also be helpful to bunch up the style guide into a Claude Skill.&lt;/p&gt;

&lt;p&gt;The Skill should make the editorial review faster as I can prompt from Cursor or Claude with the Skill, and get more contextual editorial review. &lt;/p&gt;

&lt;p&gt;With that, our team can ensure that all of the outputs don’t fall below our editorial thresholds. &lt;/p&gt;

&lt;p&gt;At the end of the day, Notion AI, MCP, Skills are separate innovations that are converging and getting every field ready for AI-boosted productivity. &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;I haven’t introduced this new Notion-based workflow to the team yet, but it seems to be a promising one. &lt;/p&gt;

&lt;p&gt;Indeed, the swift connection of LLMs and AI-powered IDE to Notion is such a superpower to technical content creation teams. &lt;/p&gt;

&lt;p&gt;This system provides a faster turnaround because briefs take two minutes instead of twenty. Fewer context switches because editors never leave Notion. &lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>notionchallenge</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>CSS Shorthands: How to Write Shorter and Smarter Styles</title>
      <dc:creator>John Fáwọlé </dc:creator>
      <pubDate>Sat, 12 Jul 2025 22:56:22 +0000</pubDate>
      <link>https://dev.to/johnfawole/css-shorthands-how-to-write-shorter-and-smarter-styles-30mm</link>
      <guid>https://dev.to/johnfawole/css-shorthands-how-to-write-shorter-and-smarter-styles-30mm</guid>
      <description>&lt;p&gt;Whether you’re building your frontend with HTML or React frameworks, styles remain the beautification component of your application. &lt;/p&gt;

&lt;p&gt;Speaking of CSS, one of the gaps between junior and senior frontend engineers is the understanding of shorthand. &lt;/p&gt;

&lt;p&gt;First of all, it helps you write shorter and cleaner code. After all, why should you use 7 lines instead of 1?&lt;/p&gt;

&lt;p&gt;Secondly, it shows you have a better grasp of how CSS and browsers work. &lt;/p&gt;

&lt;p&gt;Hence, you have to master CSS Shorthand. In this tutorial, you’ll learn how to shorten the styles of your margin, padding, background, and other aspects of your decoration. &lt;/p&gt;

&lt;p&gt;Such that in your next web development projects, you’ll write cleaner styles with shorthand. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;18 Powerful CSS Shorthand Properties to Know&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here are some incredible shorthands that will take your styling to the next level. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Margin&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We use margin to create space on the outside of an element. Meaning that the effect of the margin is seen around an element we are working on. &lt;/p&gt;

&lt;p&gt;The value can be anything from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auto&lt;/code&gt;: left for the browser to decide&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inherit&lt;/code&gt;: by law of inheritance, the child element should have the properties of the parent element&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;percentage&lt;/code&gt;: calculates the width of the element in percentage &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;length&lt;/code&gt;: to calculate the margin in pixels, centimetres, or similar values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That said, the browser calculates margin, once it’s specified, in a clockwise direction. Thus, it goes from top =&amp;gt; right =&amp;gt; bottom =&amp;gt; left. In that order. &lt;/p&gt;

&lt;p&gt;Ideally, the shorthand should be applied to the four areas for clarity. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;40&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meanwhile, there will be different decorations if not up to four, but more than one values are given. &lt;/p&gt;

&lt;p&gt;First, if you give two values, it will be calculated thus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first value is for the top and bottom&lt;/li&gt;
&lt;li&gt;second value is for right and left&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Secondly, if you give three values, the one in the middle will apply to the right and left. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Padding&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Earlier, we discussed margin. If you understand it correctly, flip it over, and you get padding. &lt;/p&gt;

&lt;p&gt;In essence, padding is the decoration property used to create space within an element. &lt;/p&gt;

&lt;p&gt;There is one thing you must know about the values of padding: it doesn’t have &lt;code&gt;auto&lt;/code&gt;, unlike margin. &lt;/p&gt;

&lt;p&gt;All four corners of an element can be padded. You can write a shorthand of this by spelling out the padding decoration in a clockwise direction. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like margin, specification of 2 values means the first one will apply to top and bottom, and the second will apply to both sides. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Background&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The simplest way to create a background is to simply say the background color should be black or whatever color of your choice. &lt;/p&gt;

&lt;p&gt;This is where CSS gets interesting. There are many ways you can style up your background aside color. &lt;/p&gt;

&lt;p&gt;This includes &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;repeat&lt;/code&gt;, and &lt;code&gt;attachment&lt;/code&gt;. If you want to go into this level of detail in your backgrounds, you’d have to define a lot of things. &lt;/p&gt;

&lt;p&gt;And this is where shorthand makes background properties simpler to write at a go. &lt;/p&gt;

&lt;p&gt;Emphatically, there is an order to CSS backgrounds; you have to be conscious of it. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;color &lt;/li&gt;
&lt;li&gt;image &lt;/li&gt;
&lt;li&gt;repeat&lt;/li&gt;
&lt;li&gt;attachment&lt;/li&gt;
&lt;li&gt;position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fff&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"developer.jpg"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;repeat&lt;/span&gt; &lt;span class="nt"&gt;center&lt;/span&gt; &lt;span class="nt"&gt;center&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nt"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, there are other properties for backgrounds which are not in this order. They are quite rarely used ones you’d have to input with longhand. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Border&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A border is the demarcation around an element. By the way, every element has a bother, whether or not you specify it. &lt;/p&gt;

&lt;p&gt;Interestingly, you can set a border to none. There are different ways borders can appear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;solid&lt;/li&gt;
&lt;li&gt;groove&lt;/li&gt;
&lt;li&gt;inset&lt;/li&gt;
&lt;li&gt;double&lt;/li&gt;
&lt;li&gt;dotted, and so on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That said, when we say border, it is a single name that refers to a collection of properties. It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;width&lt;/li&gt;
&lt;li&gt;style&lt;/li&gt;
&lt;li&gt;color&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In that order. Among these three, the most important is style. You can write shorthand for the border, and the decorations will be applied in all directions. &lt;/p&gt;

&lt;p&gt;Also, you can selectively write a shorthand of the border to a particular side, such as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;border&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;solid&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Border-radius&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Border-radius bring more life to your elements. Essentially, you can use border-radius to create rounded corners. &lt;/p&gt;

&lt;p&gt;It’s calculated in an anti-clockwise manner.  Such that the first value will go to the first angle by the top-left, and so on. &lt;/p&gt;

&lt;p&gt;When you shorthand border-radius, you should spell out all four values. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;border-radius&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;15&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;15&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other than that, there will be a different decoration. &lt;/p&gt;

&lt;p&gt;In the case of three values: the first value will apply to the first angle, the second will apply to second and third angle, while the third value will apply to the fourth angle. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Outline&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An outline is an external line—for the lack of a better word—on the outside of an element, and is immediately after the border.&lt;/p&gt;

&lt;p&gt;You might be like, “Well, that sounds like what the borders do?” That’s a brilliant observation.&lt;/p&gt;

&lt;p&gt;Here is what you need to know: borders are quite part of the element. In contrast, outlines are external and not part of the element’s box. Hope that clarifies it.&lt;/p&gt;

&lt;p&gt;That said, there are 3 properties of an outline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Color&lt;/li&gt;
&lt;li&gt;Width&lt;/li&gt;
&lt;li&gt;Style&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The order doesn’t matter in the instant case, meaning you can say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;dashed&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or write it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;outline&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt; &lt;span class="nt"&gt;dashed&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And both will do the same thing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Overflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In reality, there are times you will want to fit some content into your card components, and they will overlap, thus making your website look disorganized and unprofessional. &lt;/p&gt;

&lt;p&gt;In such cases, you can use overflow to gracefully contain the mishap. &lt;/p&gt;

&lt;p&gt;Generally, it has a couple of properties, including visible, hidden, auto, clip and scroll. &lt;/p&gt;

&lt;p&gt;That said, overflow is calculated graphically as we have both &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; axes. &lt;/p&gt;

&lt;p&gt;As a result, here is how you can shorthand both axes with the available properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;overflow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;hidden&lt;/span&gt; &lt;span class="nt"&gt;scroll&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Gap&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When we’re talking of &lt;code&gt;gap&lt;/code&gt; in Nextjs or CSS, we practically use it in grid or flexbox. &lt;/p&gt;

&lt;p&gt;If you’re a senior engineer reading this, you should remember the time of &lt;code&gt;grid-row-gap&lt;/code&gt; and &lt;code&gt;grid-column-gap&lt;/code&gt;. They were deprecated for what we now know as the grid today. &lt;/p&gt;

&lt;p&gt;Unlike overflow, which is graphical, the grid is theoretically tabular. Meaning it works in rows and columns. &lt;/p&gt;

&lt;p&gt;The order is that rows come before columns; keep that in mind. Therefore, instead of writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;row-gap&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;

&lt;span class="nt"&gt;column-gap&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can shorthand it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;gap&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Font&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For engineers who want to have a greater level of specificity in their typography, you will want to outline many properties you want in your fonts. &lt;/p&gt;

&lt;p&gt;Meanwhile, it can be quite lengthy. One thing you should keep in mind is that you must always include size and family in your font family for it to be successfully shortened. &lt;/p&gt;

&lt;p&gt;So you can have something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;font&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;bold&lt;/span&gt; &lt;span class="nt"&gt;small-caps&lt;/span&gt; &lt;span class="nt"&gt;bold&lt;/span&gt; &lt;span class="err"&gt;16&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt; &lt;span class="nt"&gt;Calibri&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;List&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you have a fair HTML background, you’ll agree that the major types of lists we have are ordered and unordered lists. &lt;/p&gt;

&lt;p&gt;CSS takes it a notch higher by adding other properties to make lists more attractive. The first property is &lt;code&gt;style&lt;/code&gt;. In practice, this is a glorified bullet, but with other specs. &lt;/p&gt;

&lt;p&gt;For instance, you can set the style to square, and the list will appear with a square-shaped bullet. &lt;/p&gt;

&lt;p&gt;Secondly, there is the &lt;code&gt;image-property&lt;/code&gt;. This allows you to customize the listing with any image of your choice. &lt;/p&gt;

&lt;p&gt;Finally, there is &lt;code&gt;position&lt;/code&gt;, which can either be outside or inside. The former will create a tab after the bullet, while the latter will vertically align all the items in the list. &lt;/p&gt;

&lt;p&gt;Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;list-style&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;round&lt;/span&gt; &lt;span class="nt"&gt;inside&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'exampl.png'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Flex&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For you to use flex, there has to be a container or a card. Now, what &lt;code&gt;flex&lt;/code&gt; does is to control the items within the container so they can behave properly and fit gracefully into the container. &lt;/p&gt;

&lt;p&gt;There are 3 properties you’ll need to set. The first is &lt;code&gt;flex-grow&lt;/code&gt;. It is the determinant of how much space an item can have within a container. &lt;/p&gt;

&lt;p&gt;Secondly, there is &lt;code&gt;flex-shrink&lt;/code&gt;. This relates to how much an item should minimise itself about other items within the container. &lt;/p&gt;

&lt;p&gt;Finally, we have &lt;code&gt;flex-basis&lt;/code&gt;. This works more like length. Thus, its value can be auto, inherit, or in pixels. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;flex&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Mask&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Masks allow you to get creative with your images. For example, you can have a triangle and mask an image on it. &lt;/p&gt;

&lt;p&gt;This will make the image fit into the triangle and appear as such. &lt;/p&gt;

&lt;p&gt;In reality, you most likely wouldn’t need many other properties of a mask, just the simple one will do. &lt;/p&gt;

&lt;p&gt;But for edge cases, here are some of its properties you should know: size, repeat, position, and image. By the way, &lt;code&gt;image&lt;/code&gt; is the most important of them all. &lt;/p&gt;

&lt;p&gt;Here is an example of the shorthand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;example&lt;/span&gt;&lt;span class="nc"&gt;.png&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;repeat&lt;/span&gt; &lt;span class="nt"&gt;center&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Animation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;By enabling animations, you can add spicy effects to your elements by putting them be on motion. &lt;/p&gt;

&lt;p&gt;Animation has different properties you can include, such as duration, delay, and direction. There’s no strict order. &lt;/p&gt;

&lt;p&gt;This is an example of how to shorthand animated elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;animation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;slideIn&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;ease-in&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;fadeIn&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;linear&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Transition&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the ways to make your buttons and cards grab user attention is by understanding how to use transitions well. &lt;/p&gt;

&lt;p&gt;It is mostly used for hovers. There are different properties in transition. But the most important ones are delay and duration. &lt;/p&gt;

&lt;p&gt;Let me show you how to spell out all your transition properties in a single line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;transition&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;opacity&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;ease&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;transform&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Grid&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you understand this grid shorthand, it will save you a lot of time manually inputting many grid properties. &lt;/p&gt;

&lt;p&gt;You must have been familiar with &lt;code&gt;grid-template-column&lt;/code&gt;, &lt;code&gt;grid-template-row&lt;/code&gt;, &lt;code&gt;grid-auto-flow&lt;/code&gt; and so on. &lt;/p&gt;

&lt;p&gt;With grid shorthand, you can easily specify rows and columns at a single go, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="py"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Inset&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Inset, in itself, is a shorthand. &lt;/p&gt;

&lt;p&gt;The orthodox approach is to set the values of all four sides of a container or card. For example, you can say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;top: 10px&lt;/li&gt;
&lt;li&gt;left: 10px&lt;/li&gt;
&lt;li&gt;bottom: 10px&lt;/li&gt;
&lt;li&gt;right: 10px&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meanwhile, this could have been simplified by using an inset, as in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="py"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, &lt;code&gt;inset&lt;/code&gt; helps you set all the required positions of an element with a single strike!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Columns&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is very straightforward to grab. As you’re aware, you can choose to outline some parts of your frontend on a columnar basis. &lt;/p&gt;

&lt;p&gt;There are two essential components involved: &lt;code&gt;column-width&lt;/code&gt; and &lt;code&gt;count&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The former deals with the horizontal length of your outlook, while the latter defines the number of columnal arrangements that can be. &lt;/p&gt;

&lt;p&gt;Thus, here is a shorthand of the columns property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;auto&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Text-decoration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your applications will look spicier if you take the text styling to the next level. &lt;/p&gt;

&lt;p&gt;This is where text-decoration might be helpful; it simply makes your text more beautiful. &lt;/p&gt;

&lt;p&gt;There are different properties such as color, thickness, and style. Most importantly, you must indicate the decoration line. &lt;/p&gt;

&lt;p&gt;Here is an example of how to shorten it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;text-decoration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;underline&lt;/span&gt; &lt;span class="nt"&gt;wavy&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt; &lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Performance &amp;amp; Maintenance Drawbacks of CSS Shorthand&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So far, we have examined smart ways to write CSS with shorthands. However, it’s not all as shiny as it seems, and this is where you need to pay attention. &lt;/p&gt;

&lt;p&gt;First of all, new engineers on your team might not fully understand some of the properties you have heavily abbreviated, especially when it relates to edge-cases. &lt;/p&gt;

&lt;p&gt;For this reason, some engineering teams often prefer to keep things orthodox; in this instance, to write everything longhand and straightforward. &lt;/p&gt;

&lt;p&gt;Secondly, you should know that unspecified values will be at default. Meanwhile, their “default” nature can override some existing specified properties. &lt;/p&gt;

&lt;p&gt;This is what I mean. If you say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;border-radius&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might expect it to have a rounded corner all around, but that will not be the case. Instead, it will be an uneven, rounded corner because of the direction of implementation.&lt;/p&gt;




&lt;p&gt;If you enjoyed reading this, consider sharing this on Twitter and tagging me - &lt;a class="mentioned-user" href="https://dev.to/jofawole"&gt;@jofawole&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>softwaredevelopment</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to Get Started with Anchor on Solana | And Write First "Hello World"</title>
      <dc:creator>John Fáwọlé </dc:creator>
      <pubDate>Thu, 10 Jul 2025 12:42:56 +0000</pubDate>
      <link>https://dev.to/johnfawole/how-to-get-started-with-anchor-on-solana-and-write-first-hello-world-34kb</link>
      <guid>https://dev.to/johnfawole/how-to-get-started-with-anchor-on-solana-and-write-first-hello-world-34kb</guid>
      <description>&lt;p&gt;Building programs on Solana with pure Rust can have a lot of learning curve; you’ll have to import this, write that way and so on.&lt;/p&gt;

&lt;p&gt;More importantly, such programs are more susceptible to security breaches, especially when written by a Junior SVM dev and the code was not audited by cracked SVM security researchers.&lt;/p&gt;

&lt;p&gt;For this and many other reasons, we have Anchor. I prefer to call Anchor the lightweight Rust framework for the SVM.&lt;/p&gt;

&lt;p&gt;One of the major reasons you might want to get interested in Anchor is that a good number of top Solana protocols were built with it. Examples include Drift V2, MarginFi, and Marinade Finance.&lt;/p&gt;

&lt;p&gt;So far, these protocols have been largely unbroken. In addition, the source code are very easy to read.&lt;/p&gt;

&lt;p&gt;That is another thing to know about Anchor; you can read it even if you are not so cracked, all you need to do is calm down and maybe check the docs here and there.&lt;/p&gt;

&lt;p&gt;That said, the main goal of this tutorial is to help you write your first “Hello World” with Anchor. I’ll break it down to the lowest bit.&lt;/p&gt;

&lt;p&gt;Trust me, once you can confidently write this “Hello World” and understood why you wrote each word, you’re set to have a strong foundation building with Anchor.&lt;/p&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step-by-step Guide to Writing First “Hello World” with Anchor on Solana&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this subheading, we’ll be getting straight to the business.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Prerequisite&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before you can run any program on the Solana Virtual Machine, you need to have these things on your machine:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Install Solana&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The best way to install Solana is to simply run this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;
curl --proto '=https' --tlsv1.2 -sSfL https://solana-install.solana.workers.dev | bash

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, ensure you use Ubuntu as your terminal for this to be successful.&lt;/p&gt;

&lt;p&gt;You should see this on your terminal once it’s done:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Installed Versions:

Rust: rustc 1.85.0 (4d91de4e4 2025-02-17)

Solana CLI: solana-cli 2.1.15 (src:53545685; feat:3271415109, client:Agave)

Anchor CLI: anchor-cli 0.31.1

Node.js: v23.9.0

Yarn: 1.22.1

Installation complete. Please restart your terminal to apply all changes.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run into any error, you can check my video, which is more elaborate on this:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gFlzGUOF-9k"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Solana Playground&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If you’re coming from the EVM background, you know we all started off with Remix for writing, compiling, and deployment of smart contracts.&lt;/p&gt;

&lt;p&gt;Something similar is on Solana, and that is the &lt;a href="https://beta.solpg.io/" rel="noopener noreferrer"&gt;Solana Playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You don’t need to download anything. You can access it via your browser and it will work fine.&lt;/p&gt;

&lt;p&gt;Another alternative to this is building locally with VS Code or any code editor of your choice. While there is nothing wrong with that, you most likely shouldn’t use that for a start.&lt;/p&gt;

&lt;p&gt;More like the way you didn’t start writing Solidity with Foundry; at least, most of us didn’t.&lt;/p&gt;

&lt;p&gt;In short, it’s better to kick-off with the Playground.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Using the Prelude&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Open the Solana Playground, create a file called &lt;code&gt;&lt;a href="//hello.rs"&gt;hello.rs&lt;/a&gt;&lt;/code&gt;, and paste this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might want to ask, why did we write that? Or, what does it mean? There is quite a long explanation to that.&lt;/p&gt;

&lt;p&gt;Like we mentioned earlier, Anchor is a lightweight version of Rust on Solana. Meaning many things have been compressed or made easier, so Anchor can have a smoother sail (smile if you got the pun).&lt;/p&gt;

&lt;p&gt;We use the &lt;code&gt;prelude&lt;/code&gt; of Anchor as a way to import all the simplified components, macros, types, and error handlings of Anchor into our program.&lt;/p&gt;

&lt;p&gt;Let me give you an example:&lt;/p&gt;

&lt;p&gt;Imagine all the every important thing you’ll need on a trip is in your bag; laptop, power station, duvet and so on.&lt;/p&gt;

&lt;p&gt;You have arrived at your destination.&lt;/p&gt;

&lt;p&gt;Instead of picking each item one by one, is it not smarter to carry the entire bag?&lt;/p&gt;

&lt;p&gt;That’s the same thing we did with &lt;code&gt;prelude&lt;/code&gt; of Anchor. &lt;/p&gt;

&lt;p&gt;It imported all the macros we need such as &lt;code&gt;#[program], #[derive(Accounts)&lt;/code&gt; and so on. In the same way, all the types and error handling are also brought into the scope of our program.&lt;/p&gt;

&lt;p&gt;The longer route of what we wrote above is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;Accounts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// and so on&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will keep writing this individual imports based on what you want to do in your protocol. But &lt;code&gt;use anchor_lang::prelude::*;&lt;/code&gt; has simplified and embedded everything.&lt;/p&gt;

&lt;p&gt;Meanwhile, using the prelude is not the end. You have to call the types in your program later on, and we will get to that.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Declaration of ID&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="nd"&gt;declare_id!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the macros in Anchor, and there is an orthodox approach to it; it has to be at the root of any program you write.&lt;/p&gt;

&lt;p&gt;Think of it as both the deployment address. In practice, you can generate this address before deployment with &lt;code&gt;keypair-json&lt;/code&gt; command, and then use it as your ID.&lt;/p&gt;

&lt;p&gt;But for the scope of this tutorial, you only need to write &lt;code&gt;declare_id!("");&lt;/code&gt; and the Playground will automatically generate one for you.&lt;/p&gt;

&lt;p&gt;This is the source with which the SVM as well as users will interact with your program. Hence, your OpSec has to be tight so it won’t be breached.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Write the Program Macro&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="nd"&gt;#[program]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without inputting this macro, the compiler will not understand where the actual contract is located within your program.&lt;/p&gt;

&lt;p&gt;In short, you need to write &lt;code&gt;#[program]&lt;/code&gt;for the compiler to know anything within this macro is part of the core logic of your protocol.&lt;/p&gt;

&lt;p&gt;As you’ll later know, there are other macros in a program, and each one of them has what it does.&lt;/p&gt;

&lt;p&gt;In the instant case, &lt;code&gt;#[program]&lt;/code&gt;is a blanket of logic under which you write how you expect your application to work.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Create the Hello World Module&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;hello_world&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created a module for proper organization of our code and named it &lt;code&gt;hello_world&lt;/code&gt;. Then we &lt;code&gt;use super::*;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember how we brought in the essential components of Anchor into the program in step 1 through &lt;code&gt;use anchor_lang::prelude::*;;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, those components are only available globally and not locally.&lt;/p&gt;

&lt;p&gt;What that mean is that the macros we imported through it won’t be automatically recognizable in this module we created.&lt;/p&gt;

&lt;p&gt;If you were to write &lt;code&gt;Context, Result&lt;/code&gt; or any other component, the compiler will throw an error.&lt;/p&gt;

&lt;p&gt;For this reason, we imported those components locally via &lt;code&gt;use super::*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By &lt;code&gt;super&lt;/code&gt;, we mean what is above or outside of the module; above it. This will make the SVM catch that we are trying to use the simplified Anchor components we brought into the scope of this program from the beginning at this stage.&lt;/p&gt;

&lt;p&gt;Hope you got that. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Hello World Function&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
   &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;msg!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World, this is John the Dev"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a public function named &lt;code&gt;hello&lt;/code&gt;, with a contextual parameter called &lt;code&gt;Hello&lt;/code&gt;. This is a null returning function; meaning we are not expecting it to return a number or anything else.&lt;/p&gt;

&lt;p&gt;Hence, there is nothing indicated within the bracket after &lt;code&gt;Result.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We input a message there that says, &lt;code&gt;Hello World, this is John the Dev&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Then we input &lt;code&gt;Ok(())&lt;/code&gt;, which indicates that we intentionally do not want the function to return anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5: Account Validation&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="nd"&gt;#[derive(Accounts)]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For performance and security reasons, you don’t want all accounts to interact with your program, and this is where this macro is important.&lt;/p&gt;

&lt;p&gt;Or even if you want them to, you might want to bounce off accounts that do not have the minimum amount of SOL to interact with your program.&lt;/p&gt;

&lt;p&gt;Whatever commercial or security considerations you might have.&lt;/p&gt;

&lt;p&gt;In the instant case, we want don’t want anyone to interact with our Hello World. Hence, we put an empty &lt;code&gt;Hello&lt;/code&gt; struct.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Full Code:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’ve done everything above correctly, this should be your full code by now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;declare_id!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nd"&gt;#[program]&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;hello_world&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;msg!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World, this is John the Dev"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Accounts)]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 6: Compilation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that you are done with your program. Click on the &lt;code&gt;Build&lt;/code&gt; button, and your program will be compiled.&lt;/p&gt;

&lt;p&gt;Or, you can rather input &lt;code&gt;anchor build&lt;/code&gt; into the terminal. You should see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;
Build successful

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;How to Test Anchor Programs with Solana Playground&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is a simple aspect. Click on the test tube icon, then click on Test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;
Testing 'hello'...

Loading Solana CLI...

Success.

RPC URL: https://api.devnet.solana.com

Default Signer: Playground Wallet

Commitment: confirmed

&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="go"&gt;
Transaction executed in slot 393363660:

Block Time: 2025-07-10T13:28:16+01:00

Version: Legacy

Recent Blockhash: EyX2KcqJAoemP25AzDN8PaTsP8F015nm76XttLqftz6A

Signature 0: mmBbogbTagy3AoR1TzPnF4TY7CZzUg5MfJ7va4UWo2zrv8ME7Jy6aBCPZYMYYpTT06TDX1urGck6g7snTKgiR3W Account 0: srw- HWMSXjDBaUCqCygDXs5UHBX2zUxwnVMeguArfpgVK18 (fee payer)

Account 1: -r-x Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz Instruction 0

Program: Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz (1)

Data: [149, 118, 59, 220, 196, 127, 161, 179]

Status: OK

Fee: 0.000005

&lt;/span&gt;&lt;span class="gp"&gt;Account 0 balance: 6.8147046 -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6.8146996
&lt;span class="go"&gt;
Account 1 balance: 0.00139896

Log Messages:

Program Af1mHQijv9vDdQtzukBNZTC9RgezfuQyWVoZzn3HMvxz invoke [1]

Program Log: Instruction: Hello

Program Log: Hello World

Program Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz consumed 443 of 200000 compute units Program Af1mHQijv9vDdQtzukBNzTC9RgezfuQyWVoZzn3HMvxz success

&lt;/span&gt;&lt;span class="gp"&gt;Confirmed $&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="go"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Congratulations! You just got your feet into Anchor. Now, that you’ve written your first &lt;code&gt;Hello World&lt;/code&gt; in Anchor, don’t stay there.&lt;/p&gt;

&lt;p&gt;Take a step further to learn how to &lt;a href="https://dev.to/johnfawole/how-to-build-an-expense-tracker-on-solana-with-anchor-5g05"&gt;create an expense tracker with Anchor&lt;/a&gt;. Building this next project will make you understand Anchor better and be more creative with it.&lt;/p&gt;

&lt;p&gt;Since you’ve read to this stage, you can as well check out the video format on YouTube; comment and subscribe!&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/3cC0VXkanaw"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>solana</category>
      <category>anchor</category>
      <category>svm</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>How to Build an Expense Tracker on Solana with Anchor</title>
      <dc:creator>John Fáwọlé </dc:creator>
      <pubDate>Fri, 04 Jul 2025 11:10:53 +0000</pubDate>
      <link>https://dev.to/johnfawole/how-to-build-an-expense-tracker-on-solana-with-anchor-5g05</link>
      <guid>https://dev.to/johnfawole/how-to-build-an-expense-tracker-on-solana-with-anchor-5g05</guid>
      <description>&lt;p&gt;How would you feel if there were an application on Solana for you to track your expenses? Great, right? That is the goal of this tutorial – to build an expense tracking program with Anchor.&lt;/p&gt;

&lt;p&gt;Anchor is quite a dynamic language for any developer to express their ideas and build them into products on Solana.&lt;/p&gt;

&lt;p&gt;Apart from the use case, this tutorial will also help you become more comfortable with Anchor and also learn more about the language along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Scope of this Tutorial&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This tutorial is more of a CRUD onchain application. It enables users to create an expense, modify, or delete it.&lt;/p&gt;

&lt;p&gt;In the process of creating this application, you will also learn more about both Anchor and how SVM works.&lt;/p&gt;

&lt;p&gt;For instance, you'd get to know more about the practical application of seed bumps, contexts, PDA and so on.&lt;/p&gt;

&lt;p&gt;After writing the program, you'd also test it with a TypeScript client to be sure the program works as expected.&lt;/p&gt;

&lt;p&gt;Obviously, this will also make you more comfortable with TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up Anchor&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before you can build a program with Anchor, you obviously should have it running on your machine. It’s so simple to setup.&lt;/p&gt;

&lt;p&gt;Simply run this command in your Ubuntu [or perhaps Bash]:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;proto&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tlsv1&lt;/span&gt;&lt;span class="na"&gt;.2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sSfL&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//solana-install.solana.workers.dev | bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will not only install Anchor, but every other dependency you need to have it run. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Solana CLI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://node.js" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yarn&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rust&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you are done running this, you should have this printed on your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;Installed&lt;/span&gt; &lt;span class="n"&gt;Versions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rustc&lt;/span&gt; &lt;span class="mf"&gt;1.85&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;d91de4e4&lt;/span&gt; &lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Solana&lt;/span&gt; &lt;span class="n"&gt;CLI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solana&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt; &lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="na"&gt;.15&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;53545685&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;feat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3271415109&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;Agave&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Anchor&lt;/span&gt; &lt;span class="n"&gt;CLI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt; &lt;span class="mf"&gt;0.31&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="py"&gt;.js&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v23&lt;/span&gt;&lt;span class="na"&gt;.9.0&lt;/span&gt;
&lt;span class="n"&gt;Yarn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.22&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;

&lt;span class="n"&gt;Installation&lt;/span&gt; &lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="py"&gt;. Please&lt;/span&gt; &lt;span class="n"&gt;restart&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;terminal&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step-by-step Guide on Building An Expense Tracker with Anchor&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you have Anchor setup, it’s time to commence writing our program. For this tutorial, I’ll recommend using the Solana playground online IDE.&lt;/p&gt;

&lt;p&gt;You can create a program file with &lt;code&gt;lib.rs&lt;/code&gt; In this program, we will be utilizing structs to pack our application's features.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Importing Anchor and Kickstarting the Program&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;anchor_lang&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;declare_id!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nd"&gt;#[program]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;etracker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first line above, we imported the &lt;code&gt;prelude&lt;/code&gt; of Anchor. Essentially, this acts more like a library that contains everything we need to build our program with Anchor.&lt;/p&gt;

&lt;p&gt;Remember that we are not using native Rust, so prelude importation gives us access to types and macros we will need to use Anchor conveniently and without have an unduly verbose program.&lt;/p&gt;

&lt;p&gt;Some of the types and macros in &lt;code&gt;prelude&lt;/code&gt; include &lt;code&gt;#[program], Context, system&lt;/code&gt; and so on.&lt;/p&gt;

&lt;p&gt;Immediately after importing Anchor, we declared [or rather set] our program ID – this is the public key of your program. If it were to be in the EVM world, program ID could have been called contract address.&lt;/p&gt;

&lt;p&gt;Hope you get it.&lt;/p&gt;

&lt;p&gt;Now, your program ID will be needed to generate Program Derived Address (PDA) and also for validation when you are writing a client test.&lt;/p&gt;

&lt;p&gt;In a test project like this, Solana playground automatically supplies one. All you have to do is just put the &lt;code&gt;””&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;#[program]&lt;/code&gt; macro we wrote next tells the compiler [and SVM by extension] that the block of code next to this should be treated as the core part of the code.&lt;/p&gt;

&lt;p&gt;These are the functions that users can call and interact with.&lt;/p&gt;

&lt;p&gt;Once that was done, we went ahead to create the etracker public module. Meanwhile, the way pub works in SVM is similar to public functions on Ethereum.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Mod&lt;/code&gt; there refers to a module, which is more like a packet for functions and or instructions.&lt;/p&gt;

&lt;p&gt;And here is where you must pay attention:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;use super::*&lt;/code&gt; has a close connection with the anchor prelude we set at the beginning of the program. It allows our local functions to use the types that anchor prelude imported.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Creating the Initialize Expense Function&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;initialize_expense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;InitializeExpense&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;merchant_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ExpenseAccount&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.accounts.expense_account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;   &lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="py"&gt;.merchant_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merchant_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="py"&gt;.amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="py"&gt;.owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.accounts.authority.key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a public function named &lt;code&gt;initialize_expense&lt;/code&gt;. It has 2 main parameters: &lt;code&gt;context&lt;/code&gt; and &lt;code&gt;ID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The work of &lt;code&gt;Context&lt;/code&gt; above is deeper than it appears. It is an Anchor type, which works on account validation and access security constraints before a user can call a public function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://solana.com/developers/courses/onchain-development/intro-to-anchor#instruction-context" rel="noopener noreferrer"&gt;&lt;em&gt;NB: You can read more about Context here&lt;/em&gt;&lt;/a&gt; &lt;em&gt;or I might write another technical blog on it soon.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The id contains the details a user must pass into the function as arguments. In the instant case, we demand id, name, and amount.&lt;/p&gt;

&lt;p&gt;We want this function to return something, hence the reason we included &lt;code&gt;Result&lt;/code&gt;. This is why we have &lt;code&gt;Ok(())&lt;/code&gt; at the end of the program.&lt;/p&gt;

&lt;p&gt;We could have gone on another route of error handling, where we set the error in case anything in the function fails.&lt;/p&gt;

&lt;p&gt;Moving on, we created a variable called &lt;code&gt;expense_account&lt;/code&gt; within the &lt;code&gt;initialize_expense&lt;/code&gt; function, and made it mutable so we can modify it later as we want.&lt;/p&gt;

&lt;p&gt;Subsequently, we assigned the parameters of the function to their respective types.&lt;/p&gt;

&lt;p&gt;But if you notice, we set the owner to &lt;code&gt;*ctx.accounts.authority.key&lt;/code&gt;. This simply means the owner has access to the authority key of the context accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Creating a Modification Function&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="err"&gt;   &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;modify_expense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ModifyExpense&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;merchant_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;   &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ExpenseAccount&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.accounts.expense_account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="py"&gt;.merchant_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merchant_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="py"&gt;.amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;

&lt;span class="err"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a function that modifies expenses. It takes in some parameters like &lt;code&gt;id, name, and amount&lt;/code&gt;. Then these parameters were assigned in the body of the function.&lt;/p&gt;

&lt;p&gt;For context, this function makes it possible to change anything on an already initialized expense.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Creating the Initialize Expense Struct&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We have created an initialize expense function above. Nonetheless, we will also create an initialize expense struct.&lt;/p&gt;

&lt;p&gt;Don’t confuse both of them.&lt;/p&gt;

&lt;p&gt;The first one defines what accounts can do when they call the function, while the latter is more about the accounts that can interact in the first place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Accounts)]&lt;/span&gt;

&lt;span class="nd"&gt;#[instruction(id:&lt;/span&gt; &lt;span class="nd"&gt;u64)]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;InitializeExpense&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;#[account(mut)]&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;#[account(&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;init,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;payer&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;authority,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;space&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nd"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nd"&gt;)&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;seeds&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="s"&gt;b"expense"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;authority&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;key()&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;as_ref(),&lt;/span&gt; &lt;span class="nd"&gt;id&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;to_le_bytes()&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;as_ref()]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;bump&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ExpenseAccount&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;system_program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;#[derive(Accounts)]&lt;/code&gt; is a macro in Anchor that deals more with the cryptographic security of the interacting accounts. It validates accounts, verifies signatures, and does general safety-check.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#[instruction(id: u64)]&lt;/code&gt; essentially passes args into the #[derive] struct. The id that the instruction passes will be used in the struct of accounts.&lt;/p&gt;

&lt;p&gt;Then we created a public struct called &lt;code&gt;InitializeExpense&lt;/code&gt; and passed info as a lifetime annotation.&lt;/p&gt;

&lt;p&gt;Since info has quite an infinite duration, it makes the struct enjoy the same attribute.&lt;/p&gt;

&lt;p&gt;Then we created a mutable account, meaning we can change its state, and gave the Signer public authority.&lt;/p&gt;

&lt;p&gt;Once that was done, we initialized our account and assign various account authority variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5: Modify and Delete Expenses Struct&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Accounts)]&lt;/span&gt;

&lt;span class="nd"&gt;#[instruction(id&lt;/span&gt; &lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;u64)]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ModifyExpense&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;#[account(mut)]&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;#[account(&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;mut,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;seeds&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="s"&gt;b"expense"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;authority&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;key()&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;as_ref(),&lt;/span&gt; &lt;span class="nd"&gt;id&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;to_le_bytes()&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;as_ref()]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;bump&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ExpenseAccount&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;system_program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Accounts)]&lt;/span&gt;

&lt;span class="nd"&gt;#[instruction(id:&lt;/span&gt; &lt;span class="nd"&gt;u64)]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;DeleteExpense&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;#[account(mut)]&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="nd"&gt;#[account(&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;mut,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;close&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;authority,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="nd"&gt;seeds&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="s"&gt;b"expense"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;authority&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;key()&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;as_ref(),&lt;/span&gt; &lt;span class="nd"&gt;id&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;to_le_bytes()&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nd"&gt;as_ref()]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;bump&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ExpenseAccount&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;system_program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is similar to what we explained above. Only that, in the instant case, it is for expenses modification.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 6:  Expense Account Struct&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[account]&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Default)]&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ExpenseAccount&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Pubkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;merchant_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#[derive(Default)]&lt;/code&gt; macro here creates default values for the struct even when no tangible has been passed into them. This will be quite useful when we are testing.&lt;/p&gt;

&lt;p&gt;Then we created some public variables, such as id, owner, name, and amount.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Testing the Expense Tracker Application with TypeScript&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It is not enough to write a program, we should also write end-to-end tests to ensure it works as expected and catches low-hanging security vulnerabilities. &lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;index.test.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Setting Up The PDA&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expense Tracker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;merchantName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;merchantName2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"test 2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;amount2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="py"&gt;.web3.PublicKey&lt;/span&gt;&lt;span class="nf"&gt;.findProgramAddressSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="nf"&gt;.from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expense"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.wallet.publicKey&lt;/span&gt;&lt;span class="nf"&gt;.toBuffer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.toArrayLike&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"le"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.program.programId&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we setup [or rather describe] the sample variables along with their assigned values.&lt;/p&gt;

&lt;p&gt;Up next, we simulated a Program Derived Address (PDA)j we will later use in our test.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Initialize Expense Test&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Initialize Expense"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.program.methods&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.initializeExpense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="nf"&gt;.BN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;merchantName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="nf"&gt;.BN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.accounts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expenseAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.wallet.publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.rpc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test calls the &lt;code&gt;initializeExpense&lt;/code&gt; function in our program and passes the parameters it needs. Once that was set, we initialized an expense by calling &lt;code&gt;.rpc()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Modify Expense Test&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Modify Expense"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.program.methods&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.modifyExpense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="nf"&gt;.BN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;merchantName2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="nf"&gt;.BN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.accounts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expenseAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.wallet.publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.rpc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is similar to the test above. In this case, we are trying to modify something and want to test if it will be successful.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Delete Expense Test&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Delete Expense"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="err"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.program.methods&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.deleteExpense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;anchor&lt;/span&gt;&lt;span class="nf"&gt;.BN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.accounts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;expenseAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expense_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;        &lt;/span&gt;&lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.wallet.publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="err"&gt;      &lt;/span&gt;&lt;span class="nf"&gt;.rpc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you remember, we passed 3 values in our &lt;code&gt;initializeExpense&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expense_account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authority&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will try to delete for a particular user.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Demo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Load up your &lt;a href="http://lib.rs" rel="noopener noreferrer"&gt;lib.rs&lt;/a&gt; program by clicking the Build button:. You should get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;Loading&lt;/span&gt; &lt;span class="n"&gt;Anchor&lt;/span&gt; &lt;span class="n"&gt;CLI&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the test by clicking the Test button. You should get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;Running&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="py"&gt;.test.ts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt; &lt;span class="n"&gt;Tracker&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Initialize&lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt;✔&lt;/span&gt; &lt;span class="n"&gt;Modify&lt;/span&gt; &lt;span class="nf"&gt;Expense&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1593&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Delete&lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nf"&gt;passing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;failing&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt; &lt;span class="n"&gt;Tracker&lt;/span&gt;
 &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Initialize&lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;simulation&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;processing&lt;/span&gt; &lt;span class="n"&gt;Instruction&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0x0&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt; &lt;span class="n"&gt;Tracker&lt;/span&gt;
 &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;Delete&lt;/span&gt; &lt;span class="n"&gt;Expense&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pg&lt;/span&gt;&lt;span class="py"&gt;.program.methods.deleteExpense&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, some of our tests failed probably due to network errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This Expense Tracker project is a great one for anyone trying to program on Solana with Anchor. &lt;/p&gt;

&lt;p&gt;Apart from the use cases of the project, you get to encounter concepts—such as PDA—that will spur you to learn more about how the Solana Virtual Machine works.&lt;/p&gt;

&lt;p&gt;The more you write friendly programs like this, the more fluent you become with Anchor. If you enjoyed reading this, share it on Twitter and tag me – &lt;a class="mentioned-user" href="https://dev.to/jofawole"&gt;@jofawole&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Keep hacking!&lt;/p&gt;

</description>
      <category>solana</category>
      <category>blockchain</category>
      <category>defi</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
