Written by
Team Turbin3
Published on
December 3, 2024
Copy link

Poseidon: Build Solana Programs with TypeScript

Poseidon is a new transpiler framework that empowers web developers to create Solana on-chain programs (i.e., smart contracts) using only TypeScript, a language familiar to millions worldwide. The framework significantly lowers the barrier to entry for on-chain development, making Solana more accessible to a broader audience of developers. Poseidon translates TypeScript code directly into Anchor, Solana's most widely adopted program framework.

This article will delve into Poseidon's origins, architectural design, key features, and potential positive impact on the Solana development landscape. Additionally, we’ll walk through a practical example of a simple token vault program written with Poseidon, highlighting some of the framework's capabilities.

Background

Toward the end of 2023, the Turbin3 team was approached by the Solana Foundation with an ambitious challenge: “Can you build a framework that enables developers to create Solana programs using TypeScript?” Naturally, the first response was to ask, “Why?”

TypeScript is a statically typed superset of JavaScript that helps developers catch errors earlier and write more maintainable code. As the de facto standard for modern web development, TypeScript and JavaScript have cultivated one of the largest developer communities globally. Introducing program development in TypeScript presents a significant opportunity to expand the pool of new Solana developers and lower the entry barriers to building on the blockchain.

Above: Data quantifying the prevalence of JavaScript (62.3%) and TypeScript (38.5%) among developers (source).

Mastering Solana program development is challenging compared to many other blockchains. New developers must tackle the dual hurdles of understanding Solana's accounts model and learning Rust simultaneously, which can be a steep learning curve. We at Turbin3 know this better than anyone; 15% of all new Solana developers come through our programs.

By introducing a TypeScript framework, developers can decouple these challenges, leveraging a language they already know to deploy their first programs to the testnet faster. A TypeScript-based framework for on-chain program development allows developers to build full-stack Solana applications in a single language seamlessly for the first time.

The Solution: Poseidon

The project began as a basic types library and transpiler concept but quickly grew into something far more robust after initial prototyping and thorough feedback from Solana and TypeScript experts. After months of building, testing, troubleshooting, and receiving invaluable input from industry experts, Poseidon reached a critical milestone earlier this year at Breakpoint 2024, where we unveiled our work to an audience of curious developers. 

In a live presentation. Shrinath, our lead developer of Poseidon demonstrated writing a Solana program in TypeScript. With a single build command, Poseidon transpiles the TypeScript code into full Anchor syntax—right before the audience’s eyes. The room buzzed with excitement, and whispers spread: “Could this really work?”

Since then, Poseidon’s open-source repository has grown rapidly, driven by contributions from our growing Poseidon Army on X and Discord. Community members have tackled issues, submitted pull requests, and collaborated on building new packages, helping Poseidon mature daily. Improvements include an enhanced CLI, added support for token program functions, and better error messaging. Though still in its early stages, Poseidon’s potential is undeniable.

From a technical standpoint, we look at the trajectory of Poseidon's development in four stages. We faced some key decisions after our original calls, brainstorming, and architectural designs. Most notably: 

  • Making assumptions about the libraries needed
  • Account derivations in the instruction body by chaining methods
  • Procedural macros (a new concept for many developers)

Then we worked heads down through the building and iteration stage leading up to the Breakpoint unveiling.  That moment of reveal, with tremendous aplomb, opened the floodgate to the current stage- we have put the framework in the hands of early adopters to tinker, discover and improve upon it.

As we wrap up 2024, we continue to nurture the framework's growth, focusing on core functionality improvements, community involvement for extending support, and identifying needed SPL functions and Anchor library support. These aims will allow the leading developers to focus on core improvements.

Looking ahead to 2025, we’re accelerating development by launching our first Turbin3 Poseidon Cohort in late Q1 (announcement soon). This initiative will advance the framework and focus on creating public packages, tutorials, and other educational resources. The goal is clear: make Poseidon the definitive tool for fast-tracking Solana program development with TypeScript.

Key Features

Poseidon offers several standout features:

  • Simplified Development: A TypeScript-based interface minimizes the learning curve for web developers, enabling them to concentrate on application logic instead of grappling with Rust
  • Increased Productivity: Poseidon empowers developers to work more efficiently by utilizing familiar tools and workflows, accelerating the development process
  • Enhanced Security and Performance: The framework ensures that the transpiled Rust code aligns with Solana's rigorous security and performance standards, maintaining the integrity of on-chain programs
  • Seamless Integration: Poseidon integrates seamlessly with the Solana ecosystem, allowing developers to leverage existing tools and libraries

System Architecture

Poseidon's architecture comprises several key components:

  • TypeScript-based Programming Interface: This layer provides a familiar syntax and tooling for developers to write Solana programs
  • Transpilation Engine: This engine converts TypeScript code into equivalent Rust code, leveraging the power of TypeScript's type system and language features
  • Anchor Code Generation: The transpiled Rust code is further processed to generate valid Anchor programs, which can be compiled and deployed to the Solana network
  • Account Management: Poseidon provides a streamlined way to manage accounts and their associated data, making interacting with the Solana blockchain easier

Use Cases

Poseidon is designed to accelerate developers' understanding of the Solana accounts model, significantly reducing the time for new developers to deploy their first programs to the testnet. Due to the stringent security demands of blockchain applications, Poseidon is not suitable today for building production-grade mainnet applications. Aspiring Solana protocol engineers will ultimately need to learn Anchor and Rust to understand Solana's underlying architecture better.

The framework can be used to explore and experiment with a wide range of decentralized applications, including:

  • Decentralized Finance (DeFi): Develop innovative financial applications such as lending protocols, decentralized exchanges, and yield farming platforms
  • Non-Fungible Tokens (NFTs): Create and manage digital assets on the Solana blockchain
  • Gaming: Develop blockchain-based games and virtual worlds
  • Supply Chain Management: Track and verify the provenance of products and materials

We focused first on foundational programs that underpin nearly every blockchain application: Counter, Vault, and Escrow. These core building blocks are the basis for countless protocols, making them the perfect starting point.

Sample Poseidon Program

Let’s dive into the code and examine in detail an example vault program built in TypeScript with Poseidon, breaking down the program into its composite parts. The complete code for this program and others can be found in the Poseidon GitHub repository.

Imports and Program Declaration

The program is defined as a TypeScript class with a static PROGRAM_ID specifying the program ID. The @solanaturbine/poseidon package provides the necessary types for defining instructions, such as Rust types (u8, u64, i8, i128, boolean, string), SPL types (Pubkey, AssociatedTokenAccount, Mint, TokenAccount, TokenProgram) and Anchor account types (Signer, UncheckedAccount, SystemAccount).

import { Account, Pubkey, Result, Signer, SystemAccount, SystemProgram, UncheckedAccount, u64, u8 } from "@solanaturbine/poseidon";

export default class VaultProgram {
    static PROGRAM_ID = new Pubkey("11111111111111111111111111111111");

Instructions

We typically define methods inside the program class to define instructions with Poseidon. The context for each instruction is implicit in the method parameters. To define an account as a program derived address (PDA) with @solanaturbine/poseidon, we use the derive method to specify the seed as the first parameter within an array.

    initialize(
        owner: Signer,
        state: Vault,
        auth: UncheckedAccount,
        vault: SystemAccount
    ): Result {
        
        auth.derive(['auth', state.key])
        state.derive(['state', owner.key]).init(owner)
        vault.derive(['vault', auth.key])

        // assign an argument of type Pubkey by calling the key property
        state.owner = owner.key;

        // to store bumps in the custom_Acc(state), we can simply call getBump
        state.stateBump = state.getBump()
        state.authBump = auth.getBump()
        state.vaultBump = vault.getBump()
    }

    deposit(
        owner: Signer,
        state: Vault,
        auth: UncheckedAccount,
        vault: SystemAccount,
        amount: u64
    ) {
        state.deriveWithBump(['state', owner.key], state.stateBump)
        auth.deriveWithBump(['auth', state.key], state.authBump)
        vault.deriveWithBump(['vault', auth.key], state.vaultBump)


        SystemProgram.transfer(
            owner, // from
            vault, // to
            amount // amount to be sent
        )
    }

    withdraw(
        owner: Signer,
        state: Vault,
        auth: UncheckedAccount,
        vault: SystemAccount,
        amount: u64
    ) {        
        state.deriveWithBump(['state', owner.key], state.stateBump)
        auth.deriveWithBump(['auth', state.key], state.authBump)
        vault.deriveWithBump(['vault', auth.key], state.vaultBump)

        SystemProgram.transfer(
            vault,
            owner,
            amount,
            ['vault', state.key, state.authBump]
        )
    }
}

Account State

Custom state accounts are defined as an interface that extends Account. The fields of the custom state account can be defined using types from the @solanaturbine/Poseidon package.

export interface Vault extends Account {
    owner: Pubkey
    stateBump: u8
    authBump: u8
    vaultBump: u8
}

Poseidon’s Impact

Poseidon has the potential to impact the blockchain development landscape by:

  • Expanding the Solana Developer Community: Attracting a larger pool of developers to the Solana ecosystem
  • Accelerating Development: Reducing development time and effort for Solana projects
  • Improving Developer Experience: Providing a more intuitive and efficient development experience

Future Directions

In the future, Poseidon aims to further enhance its capabilities by:

  • Expanding Language Support: Supporting additional languages like JavaScript and Python
  • Improving Performance: Optimizing the transpilation process and generated Rust code
  • Enhancing Security: Rigorously testing the framework and generated code for vulnerabilities

Conclusion

Poseidon marks a major advancement in making Solana program development accessible to a broader audience. Bridging the gap between web development and blockchain programming enables developers to create innovative and impactful applications on the Solana blockchain. As the blockchain space evolves, Poseidon has the potential to become an essential tool for budding new Solana developers.

Additional Resources