<?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: Russell Oje</title>
    <description>The latest articles on DEV Community by Russell Oje (@russell_oje).</description>
    <link>https://dev.to/russell_oje</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%2F3846695%2F5f9b12d1-01cf-4a2a-ab89-b52838094707.jpg</url>
      <title>DEV Community: Russell Oje</title>
      <link>https://dev.to/russell_oje</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/russell_oje"/>
    <language>en</language>
    <item>
      <title>Trilogy in Solana: Transfer Fee, Interest-Bearing, and Nontransferable</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Sun, 14 Jun 2026 23:18:09 +0000</pubDate>
      <link>https://dev.to/russell_oje/trilogy-in-solana-transfer-fee-interest-bearing-and-nontransferable-5ddk</link>
      <guid>https://dev.to/russell_oje/trilogy-in-solana-transfer-fee-interest-bearing-and-nontransferable-5ddk</guid>
      <description>&lt;p&gt;Token-2022 is the upgraded SPL token program on Solana, bringing native extensions that allow a single mint to opt into advanced behaviors without custom programs. This week, I explored three powerful extensions: Transfer Fees, Interest-Bearing tokens, and Non-Transferable tokens. Think of these extensions as middleware for your tokens—enforced at the protocol level.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Transfer Fee Mint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mint Address:&lt;/strong&gt; &lt;code&gt;FeoMWHjNJgJM6iEQUnUjsJsdPtP3Cu9m99iiuz9RhALG&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I configured this token to skim a fee on every transfer. This is perfect for protocol treasuries or community currencies where a small percentage of every transaction supports the ecosystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkThT93YfkdY59uL35t4Z5Xl &lt;span class="nt"&gt;--transfer-fee&lt;/span&gt; 100 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command sets a 1% fee (100 basis points) with a maximum cap of 5000 lamports.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Interest-Bearing Mint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mint Address:&lt;/strong&gt; &lt;code&gt;6vZ9eXTTtGCpwRVLGg6uuyLXxk2yYEykroBTNybf6wT3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This extension allows a token to accrue interest over time. Crucially, it doesn't mint new supply; instead, the UI-displayed amount updates based on the on-chain rate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkThT93YfkdY59uL35t4Z5Xl &lt;span class="nt"&gt;--interest-rate&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NB: Remember that the rate is stored on-chain, but the principal balance remains the same until updated. It's a clever way to handle yield display natively.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Non-Transferable Mint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mint Address:&lt;/strong&gt; &lt;code&gt;3PWCwuiPauNhYxwArDGaRizKLpJHETLS7RNRqHL1AQvm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finally, I built a "Soul-bound" token. Once minted to an account, it cannot be transferred or moved. I tested this by attempting a transfer and received a satisfyingly firm error: &lt;code&gt;Program log: Transfer is disabled for this mint: custom program error: 0x25&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkThT93YfkdY59uL35t4Z5Xl &lt;span class="nt"&gt;--enable-non-transferable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Take Home&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;What caught my attention this week is how simple it is to compose these behaviors. Native extensions remove the need for "wrapped" versions of tokens to get simple features like fees or interest. I’m excited to see how these primitives will be used in real products for loyalty programs.&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>beginners</category>
      <category>web3</category>
    </item>
    <item>
      <title>NFTs in Solana: Another Week with Token Extensions</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Mon, 08 Jun 2026 18:11:03 +0000</pubDate>
      <link>https://dev.to/russell_oje/nfts-in-solana-another-week-with-token-extensions-2h5f</link>
      <guid>https://dev.to/russell_oje/nfts-in-solana-another-week-with-token-extensions-2h5f</guid>
      <description>&lt;p&gt;This week, I stepped away from the usual Extension system from last week, to creating NFTs, using only Solana's native Token Extensions (Token-2022). It turns out, you can build a fully functional, grouped, and mutable NFT collection entirely at the protocol level.&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%2Fjmdgirioo0h0z5zs7orh.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%2Fjmdgirioo0h0z5zs7orh.png" alt="Day 44 NFT" width="799" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Mental Model: What is a Solana NFT?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Coming from a Web2 background, I used to think of an NFT as a complex smart contract. On Solana, using Token Extensions, an NFT is simpler and more elegant: it's a token mint with &lt;strong&gt;supply 1&lt;/strong&gt;, &lt;strong&gt;decimals 0&lt;/strong&gt;, and a few specific extensions that handle metadata and grouping.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I Built This Week&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I spent the last few days moving from a single 1-of-1 token to a full-blown collection:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The 1-of-1 Mint&lt;/strong&gt;: I started by creating a mint with the &lt;code&gt;Metadata&lt;/code&gt; extension, ensuring it had zero decimals and a supply of exactly one.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Metadata Extension&lt;/strong&gt;: Instead of an external metadata account, I stamped the name, symbol, and URI (pointing to a JSON on a GitHub Gist) directly onto the mint.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Group and Member Extensions&lt;/strong&gt;: I created a collection mint and then linked my individual NFTs to it using the &lt;code&gt;Group&lt;/code&gt; and &lt;code&gt;Member&lt;/code&gt; extensions. This creates a "foreign key" relationship natively on the blockchain.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Surprising Part: Live Mutation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The most eye-opening moment was realizing how "alive" this data is. As long as you hold the update authority, you can mutate the metadata in real-time with a single CLI command.&lt;/p&gt;

&lt;p&gt;On Friday, I renamed my NFT, updated the metadata's JSON uri (to update the image icon) and added custom fields like &lt;code&gt;rarity: legendary&lt;/code&gt; directly from my terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Adding a custom metadata field live on devnet&lt;/span&gt;
spl-token update-metadata &lt;span class="nv"&gt;$MINT_ADDRESS&lt;/span&gt; rarity &lt;span class="s2"&gt;"legendary"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watching Solana Explorer update the "legendary" tag seconds after my transaction confirmed felt like running an &lt;code&gt;UPDATE&lt;/code&gt; statement on a production database, but the "database" is a global public network.&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%2Fe8yuii8hnmktn8v5vp3w.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%2Fe8yuii8hnmktn8v5vp3w.png" alt="Update NFT" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Week Digest&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Using Token Extensions for NFTs feels like the "bare metal" way to build. It's fast, cost-effective, and removes the dependency on third-party programs for basic collection management. I’m excited to see how these primitives will be used to build more complex "programmable" NFTs that react to on-chain events.&lt;/p&gt;

&lt;p&gt;Follow along on my &lt;code&gt;#100DaysOfSolana&lt;/code&gt; journey!&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>nft</category>
      <category>blockchain</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Soulbound Credentials on Solana</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Mon, 01 Jun 2026 11:25:53 +0000</pubDate>
      <link>https://dev.to/russell_oje/soulbound-credentials-on-solana-b5c</link>
      <guid>https://dev.to/russell_oje/soulbound-credentials-on-solana-b5c</guid>
      <description>&lt;p&gt;&lt;em&gt;"Combining Non-Transferable and Permanent Delegate Extensions to Build a Soulbound Token System on Solana"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're issuing a digital certificate or a compliance-gated membership. In traditional web2 systems, you have absolute control over a database record and can decide who holds it and when it should be revoked or expired. In web3, assets are typically owned by the wallet holding them, so once they are transferred, the issuer loses control.&lt;/p&gt;

&lt;p&gt;But what if you need an on-chain credential that the holder can't sell or transfer, and the only issuer can revoke if necessary?&lt;/p&gt;

&lt;p&gt;This week I explored Solana's Token Extensions (Token-2022) to build exactly this: &lt;em&gt;A Soulbound Token with a Permanent Delegate&lt;/em&gt;.&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%2Fvquxwne7k8g1ekbekwqb.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%2Fvquxwne7k8g1ekbekwqb.png" alt="Soulbound Token" width="799" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Token Extensions Involved&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To achieve a revocable credential, we combine three Token Extensions at the protocol level:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Non-transferable&lt;/strong&gt;: Enforces that the token cannot be moved from the recipient's wallet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permanent Delegate&lt;/strong&gt;: Allows an authority (us, the issuer) to burn or transfer the token regardless of who holds it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata&lt;/strong&gt;: Binds the credential's details directly to the mint.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Creating and Revoking the Credential&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here is the exact code snippet I used to generate the token mint with these extensions enabled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create the mint with non-transferable and permanent-delegate extensions&lt;/span&gt;
spl-token &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token &lt;span class="nt"&gt;--decimals&lt;/span&gt; 0 &lt;span class="nt"&gt;--enable-non-transferable&lt;/span&gt; &lt;span class="nt"&gt;--enable-permanent-delegate&lt;/span&gt; &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;--decimals 0&lt;/code&gt; makes sense here because credentials are whole units—you either hold the certification or you don't.&lt;/p&gt;

&lt;p&gt;If the credential owner attempts to transfer the token, the non-transferable extension outright blocks it. The transaction fails on-chain.&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%2F6ypvtdiju1z7hterd243.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%2F6ypvtdiju1z7hterd243.png" alt="Blocked Transfer" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If a credential expires or the user violates compliance, the issuer can revoke it using their permanent delegate authority. We do this by burning the token directly from the recipient’s token account—no signature from the recipient required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Burning the credential from the recipient's account&lt;/span&gt;
spl-token burn &lt;span class="nv"&gt;$RECIPIENT_TOKEN_ACCOUNT_ADDRESS&lt;/span&gt; 1 &lt;span class="nt"&gt;--owner&lt;/span&gt; ~/.config/solana/id.json &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Surprised Me
&lt;/h2&gt;

&lt;p&gt;What surprised me the most was how deeply these extensions remove the need for custom smart contracts. Previously, I imagined that the "Soulbound" logic would require deploying a custom Anchor program to intercept transfers, but, the protocol inherently understands these rules natively, making the execution safer and cheaper. &lt;/p&gt;

&lt;p&gt;It was incredibly satisfying to watch a transfer attempt legally fail on-chain because the token was minted with the non-transferable flag!&lt;/p&gt;

&lt;p&gt;If you want to dive deeper and experiment with these configurations, check out the official Token-2022 extensions guide in the Solana documentation. &lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>beginners</category>
      <category>web3</category>
    </item>
    <item>
      <title>Week5 Recap of #100DaysOfSolana</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Tue, 26 May 2026 21:49:54 +0000</pubDate>
      <link>https://dev.to/russell_oje/week5-recap-of-100daysofsolana-2mf3</link>
      <guid>https://dev.to/russell_oje/week5-recap-of-100daysofsolana-2mf3</guid>
      <description>&lt;p&gt;This week I created a custom SPL token on Solana with metadata, transfer fees, and non-transferable extensions!&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%2Fl1swakjkz56gc77uoi6y.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%2Fl1swakjkz56gc77uoi6y.png" alt="Rule Enforcement" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I didn't expect the Token Extensions Program to let you enforce economic rules directly at the protocol level, no off-chain logic needed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#100DaysOfSolana&lt;/code&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title># Week5 of #100DaysOfSolana: A Tour of Solana Token Extensions</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Tue, 26 May 2026 21:47:31 +0000</pubDate>
      <link>https://dev.to/russell_oje/-week5-of-100daysofsolana-a-tour-of-solana-token-extensions-1mk6</link>
      <guid>https://dev.to/russell_oje/-week5-of-100daysofsolana-a-tour-of-solana-token-extensions-1mk6</guid>
      <description>&lt;p&gt;If you come from Web2, the idea of a token might seem like a simple integer variable stored in a database. But on Solana, tokens are deeply integrated into the programming model. This week, I went from compiling my first dependencies to creating fully featured tokens using Solana's Token Extensions Program (Token 2022).&lt;/p&gt;

&lt;p&gt;In this post, I want to walk you through what I learned, how token extensions change the game, and why enforcing economic rules on-chain instead of off-chain is so powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Starting Point: Why The Token Extensions Program?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When I first started looking into Solana, I learned about the standard Token Program. It's the original program that handles SPL tokens. But then I discovered the &lt;strong&gt;Token Extensions Program&lt;/strong&gt; (often referred to as Token-2022).&lt;/p&gt;

&lt;p&gt;Why do we need a new program? Because the original program was simple by design. If you wanted to do something complex-like enforcing transfer fees, tying metadata directly to the token mint, or making a token non-transferable, you had to build an entire custom smart contract to act as an intermediary. &lt;/p&gt;

&lt;p&gt;The Token Extensions Program brings these powerful features directly to the protocol level. You can just configure the mint to utilize specific extensions, and the protocol handles the rest. This drastically reduces the surface area for bugs and the barrier to entry for developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adding Metadata Directly to the Mint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Previously, token metadata (like the name, symbol, and URI for an image) was typically handled by Metaplex programs off to the side. With the &lt;code&gt;MetadataPointer&lt;/code&gt; and &lt;code&gt;TokenMetadata&lt;/code&gt; extensions, you can embed this directly.&lt;/p&gt;

&lt;p&gt;Here is what the flow looks like when initializing a mint with token extensions via the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana-keygen new &lt;span class="nt"&gt;--outfile&lt;/span&gt; token-keypair.json
spl-token create-token &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="nt"&gt;--transfer-fee-basis-points&lt;/span&gt; 200 &lt;span class="nt"&gt;--transfer-fee-maximum-fee&lt;/span&gt; 5000 &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt; &lt;span class="nt"&gt;--decimals&lt;/span&gt; 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By linking metadata directly to the mint, building indexers, wallets, or explorers becomes so much simpler. Everything you need is right there in the token's core data structure. No hunting across different accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Enforcing Transfer Fees at the Protocol Level&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most fascinating extensions I experimented with is the &lt;code&gt;TransferFeeConfig&lt;/code&gt;. Let's say you want to build a token that burns 1% of every transaction, or sends a 1% royalty to the creator's treasury.&lt;/p&gt;

&lt;p&gt;In traditional Web2 logic, you'd write a server route that deducts this amount before updating the database. But blockchains are public; users can bypass your server and transact directly. With the transfer fee extension, the rule is baked into the token's DNA.&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%2Ft27lemvg996tigcmmimy.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%2Ft27lemvg996tigcmmimy.png" alt="Token Instruction" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you attach this extension, the blockchain &lt;em&gt;will not allow&lt;/em&gt; a transfer to succeed unless the fee is properly calculated and withheld. This is what it means to enforce economic rules in code rather than policy documents. It requires zero custom smart contracts—just standard configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Soulbound: Non-Transferable Tokens&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The final extension that blew my mind was creating a non-transferable token. In the Web3 world, these are sometimes called "Soulbound" tokens. They are permanent credentials glued to your wallet.&lt;/p&gt;

&lt;p&gt;Think about a university degree or an event ticket. You want the person to own it, but you definitely don't want them selling it on an exchange. &lt;/p&gt;

&lt;p&gt;By applying the &lt;code&gt;NonTransferable&lt;/code&gt; extension during mint creation, the token becomes forever locked to the account it is minted to. If someone tries to &lt;code&gt;solana transfer &amp;lt;mint&amp;gt; &amp;lt;amount&amp;gt; &amp;lt;recipient&amp;gt;&lt;/code&gt;, the transaction will simply fail. The blockchain itself rejects it. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Surprised Me Most&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The biggest moment for me was realizing just how much heavy lifting the Solana protocol can do for developers out of the box. Coming from an environment where I normally have to write an entire backend service to manage custom tokenomics, the fact that I could enable transfer fees and non-transferability just by passing a few flags during initialization was stunning. &lt;/p&gt;

&lt;p&gt;It feels less like writing complex financial software and more like configuring a highly secure, decentralized operating system. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What’s Next?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Building these tokens locally and via the CLI on devnet was an incredible foundation. Next week, I plan to dive into how these tokens interact with actual custom on-chain programs (smart contracts). Now that I understand the assets, I want to write the logic that trades, manages, and interacts with them.&lt;/p&gt;

&lt;p&gt;If you are a Web2 developer sitting on the fence, jump in. The water is fine, and the tooling has never been better. Follow along on my #100DaysOfSolana journey!&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>blockchain</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>#100DaysOfSolana Week4 Recap</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Sun, 17 May 2026 21:57:29 +0000</pubDate>
      <link>https://dev.to/russell_oje/100daysofsolana-week4-recap-4ack</link>
      <guid>https://dev.to/russell_oje/100daysofsolana-week4-recap-4ack</guid>
      <description>&lt;p&gt;I opened my devnet account in Solana Explorer today and it clicked how much the explorer reveals: balance, owner, executable flag, and full transaction history in one view. I like Solana Explorer for this clarity.&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%2Fy0y57att1yuoxrcc87mx.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%2Fy0y57att1yuoxrcc87mx.png" alt="Solana Explorer" width="800" height="912"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#100DaysOfSolana&lt;/code&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
    </item>
    <item>
      <title>Week4 of #100DaysOfSolana: Solana's Account Model</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Sun, 17 May 2026 21:47:11 +0000</pubDate>
      <link>https://dev.to/russell_oje/week4-of-100daysofsolana-solanas-account-model-4254</link>
      <guid>https://dev.to/russell_oje/week4-of-100daysofsolana-solanas-account-model-4254</guid>
      <description>&lt;p&gt;If you come from Web2, Solana's account model can feel strange at first. The first time I inspected an account with the CLI, I saw fields like &lt;code&gt;lamports&lt;/code&gt;, &lt;code&gt;owner&lt;/code&gt;, and &lt;code&gt;data&lt;/code&gt; all sitting together and thought, "Wait, where is the smart contract state stored?"&lt;/p&gt;

&lt;p&gt;That question is the whole lesson. On Solana, everything is an account. Wallets are accounts. Program code lives in accounts. Application state lives in accounts. There is no separate world of contract accounts versus externally owned accounts like you may have seen elsewhere. Solana uses one flat key-value store where the key is a 32-byte address and the value is the account itself.&lt;/p&gt;

&lt;p&gt;That design clicked for me when I started thinking about accounts like files in a filesystem. Each file has metadata, contents, and permissions. Solana accounts work the same way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the address is the filename&lt;/li&gt;
&lt;li&gt;the owner is the program allowed to manage it&lt;/li&gt;
&lt;li&gt;the data is the file contents&lt;/li&gt;
&lt;li&gt;the balance is the lamports stored alongside it&lt;/li&gt;
&lt;li&gt;the executable flag tells you whether the file is runnable code or just data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That analogy is not perfect, but it gets you close fast. The System Program is like the operating system kernel. It creates accounts, assigns ownership, and handles basic bookkeeping. Other programs then read and write the accounts they own.&lt;/p&gt;

&lt;p&gt;Every Solana account has the same five fields:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;lamports&lt;/code&gt; - the balance stored in the account. One SOL equals 1 billion lamports.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt; - a byte array that can hold arbitrary state.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;owner&lt;/code&gt; - the program that controls the account.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;executable&lt;/code&gt; - whether the account contains runnable program code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rent_epoch&lt;/code&gt; - a legacy field that is now effectively retired and set to the maximum value.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most important rule is ownership. Only the owner program can modify an account's data or debit its lamports. That means a token program can update token accounts it owns, but nobody else can casually rewrite those bytes. At the same time, anyone can credit lamports to a writable account. That combination is simple, but it creates a very clear security model.&lt;/p&gt;

&lt;p&gt;What surprised me most was the statelessness of programs. In Web2 terms, a program is not a server that keeps its own memory forever. It is more like a web server binary that reads from and writes to a database. The executable account stores the code, and separate data accounts store the application state. That separation is why the account model matters so much: if you understand who owns the account and what data it contains, you understand how the program behaves.&lt;/p&gt;

&lt;p&gt;Here is the kind of output I kept seeing while exploring accounts:&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%2F7efzo1a28y91axwcgqik.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%2F7efzo1a28y91axwcgqik.png" alt="Account" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each field tells a story. A zero-length &lt;code&gt;data&lt;/code&gt; field means the account is just holding value. The owner &lt;code&gt;11111111111111111111111111111111&lt;/code&gt; is the System Program. &lt;code&gt;executable: false&lt;/code&gt; means this is not a program account. And the huge &lt;code&gt;rentEpoch&lt;/code&gt; value is a clue that rent exemption has taken over the old rent schedule.&lt;/p&gt;

&lt;p&gt;Rent exemption is another detail that makes Solana feel different from a traditional backend. Every account must hold a minimum lamport balance proportional to its data size if it wants to stay on-chain. If the account drops below that threshold, it risks being purged over time. For a tiny basic account, the minimum is around 0.00089 SOL, though the exact value depends on the account size. You can check it with &lt;code&gt;solana rent&lt;/code&gt; or the &lt;code&gt;getMinimumBalanceForRentExemption&lt;/code&gt; RPC method.&lt;/p&gt;

&lt;p&gt;That idea matters because it forces you to think about storage costs up front. If you create a larger state account, you need to fund it accordingly. In Web2, disk space is usually someone else's problem. On Solana, the cost of storage is part of the design.&lt;/p&gt;

&lt;p&gt;The account model also explains why Solana feels so composable. Programs do not hide their state inside private memory. They operate on explicit accounts that can be inspected, passed around, and reasoned about independently. Once I stopped thinking in terms of "a contract with internal state" and started thinking in terms of "a program that manages files," the architecture made much more sense.&lt;/p&gt;

&lt;p&gt;If you are a Web2 developer, that is the mental model I would keep: Solana is a filesystem for programmable state. Accounts are the files. Programs are the executables. The System Program is the kernel. And ownership is the permission system that keeps everything safe.&lt;/p&gt;

&lt;p&gt;That framing turned Solana from something mysterious into something structured. The account model is not just an implementation detail. It is the core abstraction that makes the rest of Solana understandable.&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Recap of Week3</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Thu, 14 May 2026 10:55:19 +0000</pubDate>
      <link>https://dev.to/russell_oje/recap-of-week3-2ipf</link>
      <guid>https://dev.to/russell_oje/recap-of-week3-2ipf</guid>
      <description>&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%2Fzfnq07yqxg63fcdzrt3l.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%2Fzfnq07yqxg63fcdzrt3l.png" alt="Recap of Week3" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week I built my some Solana tools: a CLI transfer app and a confirmation UI, and I deep-dived into transaction anatomy: signatures, blockhashes, and atomicity. &lt;/p&gt;

&lt;p&gt;I broke transactions to understand failure. Now I can send SOL, verify it on-chain, and explain exactly what's happening at every step.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#100DaysOfSolana&lt;/code&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
    </item>
    <item>
      <title>Week3 of #100DaysOfSolana: Understanding Solana Transactions</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Thu, 14 May 2026 10:49:35 +0000</pubDate>
      <link>https://dev.to/russell_oje/week3-of-100daysofsolana-understanding-solana-transactions-12mp</link>
      <guid>https://dev.to/russell_oje/week3-of-100daysofsolana-understanding-solana-transactions-12mp</guid>
      <description>&lt;p&gt;By the end of Week 2, I understood how data lives on accounts, public keys, and the absence of a backend. This week was about understanding &lt;em&gt;change&lt;/em&gt;: how transactions work, how to build them, and what happens when they fail.&lt;/p&gt;

&lt;p&gt;The turning point: transactions aren't requests to a server. They're cryptographically signed messages that prove you own the keypair and authorize a specific state change. And if they fail, the whole thing rolls back (even though you still pay the fee :)).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Week 3 Journey&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 15: Understand transaction anatomy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I started by taking apart an actual transaction on devnet. I sent a small transfer and then inspected it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pulled the transaction signature from the terminal&lt;/li&gt;
&lt;li&gt;Ran &lt;code&gt;solana confirm -v SIGNATURE&lt;/code&gt; to see the raw structure&lt;/li&gt;
&lt;li&gt;Opened the same transaction in Solana Explorer and compared the two views.&lt;/li&gt;
&lt;/ul&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%2Fj2yienp0qh29m6lgbzv3.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%2Fj2yienp0qh29m6lgbzv3.png" alt="Day 15" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I discovered: a transaction has exactly five parts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Web2 analogy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Signatures&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;64-byte Ed25519 signatures proving you own the keypair&lt;/td&gt;
&lt;td&gt;Auth token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Header&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Three bytes describing how many signers and read-only accounts&lt;/td&gt;
&lt;td&gt;HTTP headers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Account Keys&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every account the transaction may touch, in order&lt;/td&gt;
&lt;td&gt;Paths / query params&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recent Blockhash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A recent block hash that expires in ~60-90 seconds&lt;/td&gt;
&lt;td&gt;CSRF token with expiry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Instructions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The actual program calls with program ID, accounts, and data&lt;/td&gt;
&lt;td&gt;Request body&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The constraint clicked immediately: a serialized transaction must fit within &lt;strong&gt;1,232 bytes&lt;/strong&gt;. That's the maximum. And if any instruction fails, the whole transaction rolls back atomically (and like I stated before, you will still pay the fee).&lt;/p&gt;

&lt;p&gt;In Web2, I'm used to stateless request/response. This is different. A transaction is atomic, expiring, and size-limited. Those aren't bugs; they're features that make on-chain state changes safe and deterministic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 16: Send your first SOL transfer&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, I built the practical skill: actually sending SOL on devnet.&lt;/p&gt;

&lt;p&gt;The steps felt straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the CLI to devnet: &lt;code&gt;solana config set -ud&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Airdrop 2 SOL (devnet only)&lt;/li&gt;
&lt;li&gt;Create a recipient keypair&lt;/li&gt;
&lt;li&gt;Send 0.5 SOL: &lt;code&gt;solana transfer RECIPIENT_PUBKEY 0.5 --allow-unfunded-recipient&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Verify both balances changed on-chain&lt;/li&gt;
&lt;/ul&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%2Fotdwn5hi732viuuftv7a.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%2Fotdwn5hi732viuuftv7a.png" alt="Day 16" width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 17: Build a transfer tool&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Then I wrote a reusable CLI tool that accepts a recipient and amount. This wasn't just wrapping the CLI command. The tool worked. I could send SOL with three lines of code. But the real insight was seeing the transaction signature in the output. That signature is both the receipt and the transaction's unique ID. I can search it on Solana Explorer forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 18: Add transaction confirmation UI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;On this day, I added a confirmation layer to transaction implementation:&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%2Fd1y9zqyyhruqago6qpa0.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%2Fd1y9zqyyhruqago6qpa0.png" alt="Day 18" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This added complexity, but it taught me something crucial: transactions are asynchronous. You send it, you get a signature immediately, but the transaction isn't confirmed until validators include it in a block. That can take seconds or fail entirely if the blockhash is too old.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 19: Explore failed transactions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Finally, I broke transactions on purpose to understand failure modes.&lt;/p&gt;

&lt;p&gt;I forced invalid scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sending more SOL than I had&lt;/li&gt;
&lt;li&gt;Sending to invalid addresses&lt;/li&gt;
&lt;/ul&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%2Fjg60cyrd5w69z3dywdga.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%2Fjg60cyrd5w69z3dywdga.png" alt="Day 19" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each failure gave me a different error message on-chain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;InsufficientFunds&lt;/code&gt; — clear and expected&lt;/li&gt;
&lt;li&gt;Invalid address formats — caught during construction before sending&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Clicked for Me&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transactions as cryptographic proof&lt;/strong&gt;: In Web2, a request is just data sent to a trusted server. On Solana, a transaction is a cryptographically signed message that proves I authorized it and that it hasn't been tampered with. That's a fundamentally more trustless model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, &lt;strong&gt;confirmation is different from sending&lt;/strong&gt;: The signature appears immediately, but confirmation requires validators to include the transaction in a block. Polling for confirmation taught me that devnet sometimes takes a few seconds, and mainnet is even less predictable. I can't assume a transaction is final just because I have the signature.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What about you?&lt;/strong&gt; Have you built with Solana transactions yet? What surprised you most about how they work? Drop a comment below.&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Day 16 of #100DaysOfSolana</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Tue, 05 May 2026 23:14:06 +0000</pubDate>
      <link>https://dev.to/russell_oje/day-16-of-100daysofsolana-3554</link>
      <guid>https://dev.to/russell_oje/day-16-of-100daysofsolana-3554</guid>
      <description>&lt;p&gt;I just made a transfer to a new Solana account in less than a second.&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%2F1u9vrxc68ci2sptn8twv.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%2F1u9vrxc68ci2sptn8twv.png" alt="Terminal Image" width="800" height="166"&gt;&lt;/a&gt;&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%2Fmv0n6ii4xamali4pqzl6.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%2Fmv0n6ii4xamali4pqzl6.png" alt="Explorer Image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
    </item>
    <item>
      <title>Week2 Recap of #100DaysOfSolana</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Mon, 04 May 2026 14:14:04 +0000</pubDate>
      <link>https://dev.to/russell_oje/week2-recap-of-100daysofsolana-4ml</link>
      <guid>https://dev.to/russell_oje/week2-recap-of-100daysofsolana-4ml</guid>
      <description>&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%2Fsm0ub9hm3w9yl5b3i0hf.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%2Fsm0ub9hm3w9yl5b3i0hf.png" alt="My Solana Account" width="800" height="135"&gt;&lt;/a&gt;&lt;br&gt;
This week I queried on-chain data, built a dashboard, and mapped traditional databases to Solana's account model. The biggest shift: I don't need a backend. The RPC is the API. The ledger is the database. Wallets are auth. Same address, different networks, same architecture. It finally made sense. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;#100DaysOfSolana&lt;/code&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>solana</category>
      <category>web3</category>
    </item>
    <item>
      <title>Week2 of #100DaysOfSolana: The Account Model</title>
      <dc:creator>Russell Oje</dc:creator>
      <pubDate>Mon, 04 May 2026 14:11:03 +0000</pubDate>
      <link>https://dev.to/russell_oje/week2-of-100daysofsolana-the-account-model-2af5</link>
      <guid>https://dev.to/russell_oje/week2-of-100daysofsolana-the-account-model-2af5</guid>
      <description>&lt;p&gt;By the end of Week 1, I understood identity on Solana. This week was about understanding &lt;em&gt;state&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In traditional Web2 development, I was trained to think in two separate layers: code lives on a server, data lives in a database. They talk to each other through the database queries and middleware. It felt natural because I built that way for years. But Solana doesn't work that way, and this week it finally made sense why.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Week 2 Journey: From RPC Queries to Account Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 8: "Read your first on-chain data"&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I wrote a simple script that connected to devnet's RPC and queried a balance. It felt like calling a REST API, just pointing at a different kind of backend.&lt;/p&gt;

&lt;p&gt;The key moment: I realized I wasn't querying a database. I was asking the Solana network for the state of an &lt;em&gt;account&lt;/em&gt;. That account is not a row in a table somewhere. It's a first-class entity on the ledger itself.&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%2Fs5lpz4x12efgovdfin6w.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%2Fs5lpz4x12efgovdfin6w.png" alt="Day 8" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 9: "Fetch transactions"&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next, I pulled transaction history for an address. Seeing block times, signatures, and slot numbers make me realize: every state change is a transaction, and every transaction is immutable history on-chain.&lt;/p&gt;

&lt;p&gt;For the first time, I understood audit logs at the protocol level. There's no way to delete a transaction. No way to "update" the past. If a balance changed, that change is forever stored on-chain, visible to everyone.&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%2Fugkbira1lb684ilmspvs.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%2Fugkbira1lb684ilmspvs.png" alt="Day 9" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 10: "Build a dashboard"&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Similar to Day 4 of Week1, I also built a browser app, but this one displays account data. Nothing fancy, just RPC calls in the frontend, rendered on the page.&lt;/p&gt;

&lt;p&gt;What clicked: the dashboard talks directly to the network. No backend API needed. No session management. The wallet in the browser is the auth. The RPC endpoint is the database. This is genuinely different.&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%2F8f3pv8y9d7syi4te594l.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%2F8f3pv8y9d7syi4te594l.png" alt="Day 10" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 11: "Compare accounts vs databases"&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;On this day, I mapped Web2 database concepts to Solana accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rows → Accounts&lt;/li&gt;
&lt;li&gt;Tables → A flat space of accounts identified by public key&lt;/li&gt;
&lt;li&gt;Auto-increment IDs → Base58 public keys&lt;/li&gt;
&lt;li&gt;Middleware auth → Program ownership rules&lt;/li&gt;
&lt;li&gt;Storage costs → Rent-exempt deposits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seeing the comparison table made it real. The account model isn't just a different API. It's a fundamentally different way to think about data architecture. And like I leaned here, in web3, there's no "join" operation because you organize data differently from the start. You fetch accounts by address, not by filtering queries. And you pay explicitly for storage, which makes you think carefully about what you store.&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%2F4ejy6t0jxr9xlwy3n5hj.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%2F4ejy6t0jxr9xlwy3n5hj.png" alt="Day 11" width="800" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Day 12: "Compare networks"&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Finally, I queried the same address on both devnet and mainnet. Different balances, different transaction histories, same address model.&lt;/p&gt;

&lt;p&gt;The insight: the architecture is identical, but the state is independent. Devnet is a sandbox. Mainnet is production. Both follow the same rules. I could deploy the same program to both and it would work. Same address derivation, same account queries, different network validators securing different state.&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%2Fhnyzkr48hes8u6hbxu3x.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%2Fhnyzkr48hes8u6hbxu3x.png" alt="Day 12" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Surprised Me&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The biggest surprise was realizing I could build a complete on-chain app without writing a backend. In Web2, "no backend" means leaning on a third-party service (Firebase, Supabase, etc.). On Solana, "no backend" means the network &lt;em&gt;is&lt;/em&gt; the backend. The RPC is the API. The ledger is the database. Wallets handle identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What's Still Confusing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;PDAs (Program Derived Addresses) and how they relate to accounts. I saw them mentioned but haven't built with them yet. The concept of accounts owned by programs, and how programs use PDAs to derive deterministic addresses.&lt;/p&gt;

&lt;p&gt;Also, the economics of rent. I understand the concept, but I haven't felt the weight of deploying a large program or managing multiple accounts yet. When do rent costs become a serious consideration? When do I need to optimize?&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>solana</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
