NEU: Helius übernimmt Light Protocol
Solana Frames: Ein cNFT auf Farcaster minten
Blog/Entwicklung

Solana Frames: Ein cNFT auf Farcaster minten

Developer Experience Engineer0xIchigo auf X0xIchigo auf LinkedIn0xIchigo auf GitHub
12 Min. Lesezeit

Worum geht es in diesem Artikel?

Dezentrale soziale Medien markieren einen bedeutenden Wandel: Nutzer erhalten mehr Privatsphäre und Kontrolle über ihre Onlinedaten. Anders als bei herkömmlichen Social-Media-Plattformen können Menschen in dezentralen Netzwerken ihre sozialen Graphen und digitalen Identitäten direkt verwalten. Plattformen wie Farcaster sind Vorreiter und schaffen zensurresistente Netzwerke, die eine offene, interoperable Kommunikation über verschiedene Plattformen hinweg ermöglichen. Eine wichtige Innovation von Farcaster sind Frames. Sie verwandeln normale Social-Media-Beiträge in vollwertige Anwendungen und bereichern so soziale Erlebnisse im Netz.

Dieser Artikel behandelt Farcaster und die kürzlich hinzugefügte Unterstützung für Solana. Wir erklären, was Farcaster und Frames sind und wie du eine Solana-Adresse verifizierst. Anschließend zeigt ein kurzes Tutorial, wie du mit der Helius Mint API einen Frame erstellst, der ein cNFT an die verifizierte Solana-Adresse eines Nutzers mintet. Für das Tutorial setzen wir Erfahrung mit TypeScript und Next.js voraus.

Was ist Farcaster?

Farcaster ist ein ausreichend dezentralisiertes soziales Netzwerk, das das Ethereum-Netzwerk nutzt. Es bietet eine öffentliche Plattform, die beliebten sozialen Netzwerken wie Twitter und Reddit ähnelt. Nutzer können Profile erstellen, Beiträge teilen, die als Casts bezeichnet werden, und anderen Nutzern folgen. Farcaster zeichnet sich vor allem dadurch aus, dass Eigentum und Portabilität bei den Nutzern liegen: Sie besitzen ihre Accounts und ihre Beziehungen zu anderen. Dadurch können sie zwischen verschiedenen Anwendungen wechseln und ihre digitale Identität sowie ihren sozialen Graphen beibehalten.

Was sind Frames?

Mit Frames können Entwickler jeden Cast in eine interaktive Anwendung verwandeln. Sie erweitern den OpenGraph-Standard und machen aus statischen Einbettungen dynamische, interaktive Erlebnisse. So können Nutzer in jedem Farcaster-Client Funktionen wie Umfragen, Live-Feeds oder interaktive Galerien erstellen, auch in Warpcaster. Im Kern besteht ein Frame aus einer Reihe von <meta>-Tags, die mit dem <head> einer HTML-Seite zurückgegeben werden. Farcaster-Apps rendern die Seite als Frame, wenn sie alle erforderlichen Frame-Eigenschaften enthält. Die Frame-Spezifikation beschreibt diese erforderlichen Eigenschaften. Ein initialer Frame muss beispielsweise:

  • im Abschnitt HTML <head> einen gültigen Frame zurückgeben
  • ein gültiges HTML <body> zurückgeben, falls der Nutzer den Frame in einem Browser öffnet
  • auf dynamische Inhalte im initialen Frame verzichten, da Farcaster-Clients ihn zwischenspeichern
  • auf ein fc:frame:state-Tag verzichten

Eine Solana-Adresse auf Farcaster verifizieren

Farcaster unterstützt seit Kurzem Solana-Adressen. Entwickler können dadurch Frames erstellen, die mit dem Solana-Wallet eines Nutzers interagieren. Weniger als 24 Stunden nach der Einführung hatten über 9328 eindeutige Farcaster-FIDs eine Solana-Adresse verifiziert.

So können Nutzer ihre Solana-Adresse verifizieren:

  • Navigiere zu Einstellungen
  • Klicke auf Verifizierte Adressen und dann auf die Schaltfläche „Adresse verifizieren“
  • Verbinde dein Solana-Wallet und signiere eine Nachricht, um nachzuweisen, dass es dir gehört

Beachte, dass derzeit nur Phantom unterstützt wird.

Tutorial: Einen Frame erstellen, der ein cNFT mintet

In diesem Artikel erstellen wir einen Frame, mit dem Nutzer mit einer verifizierten Solana-Adresse ein komprimiertes NFT (cNFT) minten können. Wir richten das Projekt mit frames.js ein, einem Next.js-Template zum Erstellen und Debuggen von Frames. Wenn ein Farcaster-Nutzer mit dem Frame interagiert, rufen wir seine Daten mit dem Frame Kit aus Coinbase OnchainKit ab. Anschließend übergeben wir diese Daten an die Helius Mint API, um dieses cNFT an das Solana-Wallet des Nutzers zu minten:

Unseren Frame einrichten

Einen Frame mit frame.js zu erstellen ist so einfach wie das Klonen des Starter-Templates. Führe einfach den folgenden Befehl aus und ersetze <name> durch den Namen des neuen Ordners, in den du das Template klonen möchtest:

Code
npx degit github:framesjs/frames.js/examples/framesjs-starter#main <name>

Ich habe mein Verzeichnis helius-frame genannt und daher <name> durch <helius-frame> ersetzt. Wechsle anschließend in das neue Verzeichnis, zum Beispiel cd helius-frame, und installiere die erforderlichen Abhängigkeiten mit dem Befehl yarn install. Führe nach Abschluss des Downloads yarn dev aus, um den Entwicklungsserver zu starten. Rufe http://localhost:3000 in deinem Browser auf. Du siehst Folgendes:

Wenn wir auf den Link Debug klicken, gelangen wir zu http://localhost:3000/debug:

Das ist hilfreich, weil wir unseren Frame lokal testen können, ohne ihn bereitzustellen. Wir können uns beispielsweise anmelden, um Schaltflächen zu testen, andere Nutzer imitieren und den Hub-Status simulieren. Warpcaster bietet außerdem mit dem Frame Validator ein hervorragendes Tool zum Validieren von Frames. Im weiteren Verlauf verwenden wir aus persönlicher Präferenz den Frame Validator für unsere Tests. 

Führe als Nächstes yarn install aus, um die relevanten Abhängigkeiten des Templates zu installieren. Führe außerdem yarn install @coinbase/onchainkit aus, um OnchainKit zu installieren.

Wir ordnen die Projektordner wie folgt neu an:

  • Lösche den Ordner examples. Die Beispiele geben zwar wertvolle Einblicke in die Entwicklung von Frames, sind für unser Vorhaben aber nicht erforderlich. Wenn du diesen Ordner entfernst, bleibt das Projekt schlank. Ich empfehle dir dennoch, die Beispiele anzusehen, um alternative Ansätze für gängige Frames kennenzulernen
  • Erstelle im Verzeichnis app einen Ordner namens api. Dieser Schritt folgt den Next.js-Konventionen für API-Routen, da er Frontend und Backend unserer Anwendung klar voneinander trennt. Verschiebe dann den Ordner frames samt Inhalt, also route.ts, in den neuen Ordner api.
  • Erstelle im Verzeichnis app einen Ordner namens utils. Lege darin eine Datei namens mint.ts an. Dort kommt unsere Logik zum Minten des cNFT hinein

Jetzt können wir endlich mit der Entwicklung unseres Frames beginnen!

Unseren Frame bearbeiten

layout.tsx

Wir beginnen mit der Datei layout.tsx. Lösche ihren gesamten Inhalt und ersetze ihn durch den folgenden Code:

Code
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    
      {children}
    
  );
}

Die Komponente RootLayout verfolgt einen minimalistischen Ansatz und umfasst die gesamte Anwendung mit einer einheitlichen Layout-Struktur. Sie ist flexibel und auf Wiederverwendbarkeit ausgelegt. Dieses minimalistische Layout dient Entwicklern als Vorlage, auf deren Basis sie eigene Frames erstellen und nach Bedarf anpassen können.

Beachte, dass Änderungen an der Datei layout.tsx Probleme bei der lokalen Verwendung des Debuggers verursachen. Du musst layout.tsx nicht bearbeiten. Wir tun es jedoch, um die Metadaten der Anwendung in page.tsx einzuführen. Alternativ könntest du die Metadaten in dieser Datei definieren. 

page.tsx

Lösche den Inhalt von page.tsx und ersetze ihn durch Folgendes:

Code
import type { Metadata } from "next";
import { getFrameMetadata } from "@coinbase/onchainkit";

const baseURL = "https://helius-frame.vercel.app/";

const frameMetadata = getFrameMetadata({
  image: {
    src: `${baseURL}/default.jpg`,
    aspectRatio: "1:1",
  },
  buttons: [
    {
      label: "Click to mint a cNFT on Solana!",
      action: "post",
    },
  ],
  postUrl: `${baseURL}api/frames`,
});

export const metadata: Metadata = {
  title: "Mint a cNFT on Solana",
  description: "Mint a cNFT to your verified Solana address using the Helius Mint API",
  openGraph: {
    title: "Mint a cNFT on Solana",
    description: "Mint a cNFT to your verified Solana address using the Helius Mint API",
    images: ["https://helius-frame.vercel.app/default.jpg"],
  },
  other: {
    ...frameMetadata,
  },
};

export default function Page() {
  return (
    
      Mint a cNFT on Farcaster using the Helius Mint API
      
        Built by 0xIchigo
      
      
        GitHub Repo
      
    
  );
}

Der obige Code richtet unseren initialen Frame ein, der unter einer URL auf einem Webserver bereitgestellt wird. In meinem Fall wird der initiale Frame bei Vercel unter https://helius-frame.vercel.app/ gehostet. Wie du die Anwendung mit Vercel bereitstellst, erklären wir später in diesem Tutorial.  

Zuerst importieren wir den Typ Metadata aus Next.js, um den Export metadata in dieser Datei zu typisieren. Außerdem importieren wir getFrameMetadata aus @coinbase/onchainkit. Anschließend definieren wir die Basis-URL der Anwendung, um Codewiederholungen zu vermeiden.

Danach rufen wir getFrameMetadata auf, um die Metadaten unseres initialen Frames zu konfigurieren. Diese Metadaten enthalten:

  • Ein Bild, also src, das als visuelles Element des Frames dient und ein Seitenverhältnis von 1:1 hat
  • Eine Schaltfläche mit der Beschriftung „Klicke, um ein cNFT auf Solana zu minten!“. Ein Klick darauf sendet eine POST-Anfrage an den angegebenen postUrl, also ${baseURL}api/frames. Diese Aktion startet den Minting-Prozess

Danach exportieren wir ein metadata-Objekt. Es enthält den Titel und die Beschreibung der Seite, OpenGraph-Metadaten, also openGraph, sowie das zuvor definierte frameMetadata, das in die Eigenschaft other eingefügt wird.

Zum Schluss definiert und exportiert page die standardmäßige Seitenkomponente. Wir geben ein einfaches h1 zurück, das zum Minten eines cNFT auffordert. Das ist nötig, weil Farcaster die Rückgabe von HTML verlangt. Die primäre Interaktion erfolgt über Frames und nicht durch direkten Zugriff auf die Website. Wenn ein Nutzer die Website dennoch öffnet, muss dort etwas vorhanden sein. 

mint.ts 

Füge den folgenden Code in mint.ts ein:

Code
const url = `Get a URL at dev.helius.xyz`;

export const mintCompressedNFT = async (address: string) => {
    const response = await fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            jsonrpc: "2.0",
            id: "frames-sol-mint",
            method: "mintCompressedNft",
            params: {
                name: "Solana Soldier",
                symbol: "HELIUS",
                owner: address,
                description: "A decentralized warrior backed by Solana's most loved RPC Nodes, APIs, Webhooks, and Developer Tooling",
                attributes: [
                    {
                        trait_type: "RPCs",
                        value: "Fast",
                    },
                    {
                        trait_type: "Company",
                        value: "Helius"
                    },
                ],
                imageUrl: "https://shdw-drive.genesysgo.net/HmvVwYAy7cxWECLbu2cjWBSHysVoriTqgdugyePVg3rY/cnftmint.jpg",
                externalUrl: "https://www.helius.dev/",
                sellerFeeBasisPoints: 6900,
            },
        }),
    });

    const data = await response.json();
    console.log(`data: ${JSON.stringify(data, null, 2)}`);

    if (!response.ok) {
        throw new Error(`The response was not okay - ${response.status}`);
    }

    if (!data.result || !data.result.assetId) {
        throw new Error(`The response did not include the expected data.result.assetId field`);
    }

    return data.result;
};

Die Hilfsfunktion mintCompressedNFT ist für unsere Anwendung entscheidend, da sie ein vordefiniertes cNFT an eine angegebene Adresse mintet. Mit der Helius Mint API erstellen wir eine einfache, wiederverwendbare und asynchrone Funktion, die den Minting-Prozess des cNFT kapselt. Wir müssen unsere allgemeine Helius RPC-URL anfordern, die als url definiert ist. Falls du noch keine hast, kannst du in deinem Helius-Dashboard kostenlos eine RPC-URL für url generieren.

Beachte, dass mein Repository meine SecureRPC-URL verwendet. Achte darauf, deinen API-Schlüssel nicht offenzulegen, und erwäge den Einsatz eines Proxys. Eine vollständige Aufschlüsselung des Anfrageschemas findest du hier.

Beachte außerdem, dass ich das Bild für das cNFT bereits zu ShdwDrive hochgeladen habe. Zum Zeitpunkt der Erstellung dieses Artikels unterstützt Farcaster Transaktionen noch nicht vollständig. Die Helius Mint API lädt Off-Chain-Metadaten zu Arweave hoch, sofern ein Signierer angegeben ist.

Die Funktion bietet außerdem eine robuste Fehlerbehandlung. So werden Probleme während des Minting-Prozesses erkannt und gemeldet. Zu Debugging-Zwecken protokolliert sie auch die Antwortdaten.

route.ts 

Füge in api/frames/route.ts den folgenden Code ein:

Code
import { NextRequest, NextResponse} from "next/server";
import { getFrameMessage, getFrameHtmlResponse } from "@coinbase/onchainkit/frame";
import { mintCompressedNFT } from "../../utils/mint";

const baseURL = "https://helius-frame.vercel.app/";

export async function POST(req: NextRequest): Promise {
    const body = await req.json();

    // Validate the frame message and extract the user ID
    const { isValid, message } = await getFrameMessage(body, {
        neynarApiKey: "NEYNAR_ONCHAIN_KIT",
    });

    console.log(JSON.stringify(message, null, 2));

    // Make sure they're following us before they can mint the cNFT
    if (isValid && !message.following) {
        return new NextResponse(getFrameHtmlResponse({
            image: {
                src: `${baseURL}/error.jpg`,
                aspectRatio: "1:1",
            },
            buttons: [
                {
                  label: "You need to be following to mint! Click to retry",
                  action: "post",
                },
            ],
            postUrl: `${baseURL}api/frames`,
        }));
    // Make sure they have a verified Solana address
    } else if (isValid && message.interactor.verified_addresses.sol_addresses) {
        const solanaAddresses = message.interactor.verified_addresses.sol_addresses;
        console.log(`SOLANA ADDRESSES: ${solanaAddresses}`);

        if (solanaAddresses.length !== 0) {
            try {
                console.log(`MINTING to ${solanaAddresses[0]}`);
                // We take the first address address, in case there's more than one
                const mintResult = await mintCompressedNFT(solanaAddresses[0]!);
              
                return new NextResponse(getFrameHtmlResponse({
                    image: {
                        src: `${baseURL}/success.jpg`,
                        aspectRatio: "1:1",
                    },
                    buttons: [
                        {
                            label: "Success! View your cNFT on XRAY",
                            action: "link",
                            target: `https://xray.helius.xyz/token/${mintResult.assetId}?network=mainnet`
                        },
                    ],
                }));
            } catch (e: any) {
                console.log(`Minting failed: ${e}`);
                return new NextResponse(getFrameHtmlResponse({
                    image: {
                        src: `${baseURL}/error.jpg`,
                        aspectRatio: "1:1",
                    },
                    buttons: [
                        {
                          label: "Minting failed. Click to retry",
                          action: "post",
                        },
                    ],
                    postUrl: `${baseURL}api/frames`,
                }));
            }
        } else {
            console.log(`No Solana address found`);
            return new NextResponse(getFrameHtmlResponse({
                image: {
                    src: `${baseURL}/error.jpg`,
                    aspectRatio: "1:1",
                },
                buttons: [
                    {
                      label: "No Solana address found. Click to retry",
                      action: "post",
                    },
                ],
                postUrl: `${baseURL}api/frames`
            }));
        }
    } else {
        return new NextResponse(getFrameHtmlResponse({
            image: {
                src: `${baseURL}/error.jpg`,
                aspectRatio: "1:1",
            },
            buttons: [
                {
                  label: "Invalid frame message. Click to retry",
                  action: "post",
                },
            ],
            postUrl: `${baseURL}api/frames`,
        }));
    }
}

Diese Datei ist eine Next.js-API-Route, die alle POST-Anfragen für unseren Frame verarbeitet. Zuerst importiert die Datei NextRequest und NextResponse aus next/server, um eingehende Anfragen zu verarbeiten und Antworten zu senden. Außerdem importieren wir getFrameMessage und getFrameHtmlResponse aus @coinbase/onchainkit/frame, um Frame-Nachrichten zu validieren und HTML-Antworten für Frame-Interaktionen zu generieren. Zusätzlich importieren wir unsere Hilfsfunktion mintCompressedNFT.

baseURL wird definiert, um Codewiederholungen zu vermeiden. Damit erstellen wir Pfade für Ressourcen und API-Endpunkte.

Die Datei exportiert die Funktion POST. Sie parst den Body der eingehenden Anfrage, um die Frame-Nachricht zu extrahieren. Mit getFrameMessage prüfen wir, ob die eingehende Frame-Interaktion und die Nutzlast der Nachricht gültig sind. Dazu übergeben wir den Anfrage-Body als JSON und den standardmäßigen Neynar-API-Schlüssel, also „NEYNAR_ONCHAIN_KIT“. Neynar ist eine Entwicklerplattform, die die Entwicklung für Farcaster vereinfacht. getFrameMessage gibt ein Promise zurück, das zu einem FrameValidationResponse aufgelöst wird. Es ist wie folgt definiert:

Code
export type FrameValidationResponse =
  | { isValid: true; message: FrameValidationData }
  | { isValid: false; message: undefined };

Ist die Frame-Interaktion gültig, wird somit die Nachricht vom Typ FrameValidationData zurückgegeben. Sie ist wie folgt definiert:

Code
export interface FrameValidationData {
  button: number; // Number of the button clicked
  following: boolean; // Indicates if the viewer clicking the frame follows the cast author
  input: string; // Text input from the viewer typing in the frame
  interactor: {
    fid: number; // Viewer Farcaster ID
    custody_address: string; // Viewer custody address
    verified_accounts: string[]; // Viewer account addresses
    verified_addresses: {
      eth_addresses: string[] | null;
      sol_addresses: string[] | null;
    };
  };
  liked: boolean; // Indicates if the viewer clicking the frame liked the cast
  raw: NeynarFrameValidationInternalModel;
  recasted: boolean; // Indicates if the viewer clicking the frame recasted the cast
  valid: boolean; // Indicates if the frame is valid
}

Das ist äußerst wertvoll, da die Nachricht relevante Daten enthält: die Farcaster-ID des Nutzers, mögliche verifizierte Ethereum- oder Solana-Adressen und die Information, ob er den Cast mit „Gefällt mir“ markiert hat. In diesem Tutorial prüfen wir, ob der Nutzer, der minten möchte, meinem Profil folgt. Falls ja, darf er das cNFT minten. Außerdem müssen wir sicherstellen, dass er eine verifizierte Solana-Adresse besitzt, an die wir das cNFT minten können.

Zuerst prüfen wir, ob die Interaktion gültig ist und der Nutzer meinem Account folgt. Andernfalls sieht er eine Fehlermeldung und eine Schaltfläche, die ihn zu einem erneuten Versuch auffordert. Danach prüfen wir, ob der Nutzer eine verifizierte Solana-Adresse besitzt. Sind eine oder mehrere Adressen vorhanden, setzen wir den Minting-Prozess fort. Wir nehmen die erste verifizierte Solana-Adresse und übergeben sie an mintCompressedNFT. Bei Erfolg geben wir ein Erfolgsbild und einen Link zurück, über den sich das cNFT auf Orb ansehen lässt. Bei einem Fehler protokollieren wir ihn und senden eine Nachricht, die den Nutzer zu einem erneuten Versuch auffordert. Werden keine verifizierten Solana-Adressen gefunden, senden wir eine Fehlermeldung über die fehlende verifizierte Solana-Adresse und fordern den Nutzer zu einem erneuten Versuch auf. Ist die Frame-Nachricht ungültig, senden wir eine entsprechende Fehlermeldung und fordern den Nutzer ebenfalls auf, es erneut zu versuchen.

Der Code verwendet getFrameHtmlResponse, um HTML-Antworten zu generieren, die auf die jeweiligen Ergebnisse des Minting-Prozesses oder der Validierungsprüfungen zugeschnitten sind. Dazu gehören Bilder, Seitenverhältnisse und Schaltflächen für bestimmte Nutzerinteraktionen.

In die Produktion überführen

Nachdem der Code fertig ist, erstelle ein neues GitHub-Repository und pushe den Code dorthin. Führe die folgenden Befehle in deiner Kommandozeile aus, um den Code zu GitHub zu pushen:

Code
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/<username>/<new repo name>.git
git branch -M main
git push -u origin main

Nachdem du den Code zu GitHub gepusht hast, musst du die Anwendung bereitstellen. Vercel lässt sich nahtlos mit GitHub integrieren und vereinfacht dadurch den gesamten Bereitstellungsprozess. Deshalb verwenden wir Vercel. Gehe wie folgt vor:

  • Melde dich auf der Vercel-Website bei deinem Account an. Falls du noch keinen Account hast, musst du einen erstellen. Der großzügige und kostenlose Hobby-Tarif reicht für unsere Zwecke aus
  • Öffne nach der Anmeldung das Dashboard und klicke auf die Schaltfläche Neues Projekt. Vercel fordert dich auf, ein Projekt aus deinem GitHub-Account zu importieren. Wähle das Repository aus, das du im vorherigen Schritt erstellt hast
  • Vercel erkennt das verwendete Framework automatisch und schlägt Build-Einstellungen vor. Vercel stammt von den Entwicklern von Next.js und bietet erstklassige Unterstützung. Eine aufwendige Konfiguration ist daher nicht nötig
  • Klicke nach dem Konfigurieren der Projekteinstellungen auf die Schaltfläche Bereitstellen. Vercel startet den Bereitstellungsprozess automatisch, erstellt das Projekt und stellt es unter einer eindeutigen Vercel-URL bereit. 
  • Nach der Bereitstellung erhältst du von Vercel diese eindeutige URL, über die du auf die Live-Anwendung zugreifen kannst. Mein Projekt wurde unter https://helius-frame.vercel.app/ bereitgestellt: der Name des GitHub-Repositorys, gefolgt von .vercel.app. In den Projekteinstellungen unterstützt Vercel auch benutzerdefinierte Domains

Das war's! Mit diesen Schritten haben wir unseren Farcaster-Frame zu GitHub gepusht und auf Vercel gehostet. Du kannst die Funktion des Frames mit den zuvor genannten Test-Tools prüfen, etwa dem Frames-Validator. Jetzt musst du nur noch einen Cast mit der URL des Frames erstellen!

Fazit

Die Verbindung von Blockchains und sozialen Medien ist ein bedeutender Fortschritt für unsere Vorstellung von digitalen Räumen und die Art, wie wir darin interagieren. Die Beliebtheit von Farcaster und Frames verwandelt ehemals statische Beiträge auf herkömmlichen Social-Media-Plattformen in interaktive Erlebnisse. Dieser Artikel stellt Farcaster und Frames vor. Das Tutorial zeigt, wie du die kürzlich hinzugefügte Solana-Unterstützung von Farcaster nutzt, damit Nutzer mit nur einem Klick cNFTs minten können. Ganz gleich, ob du als Entwickler Anwendungen für Farcaster erstellen oder deinen Social-Media-Feed auf eine neue und spannende Weise entdecken möchtest: Die Möglichkeiten sind grenzenlos.

Wenn du bis hierhin gelesen hast: Danke, Anon! Wenn du Farcaster beitreten möchtest, nutze diesen Einladungslink!

Trage unten deine E-Mail-Adresse ein, damit du keine Neuigkeiten rund um Solana verpasst. Bereit, tiefer einzusteigen? Entdecke die neuesten Artikel im Helius-Blog und setze deine Solana-Reise noch heute fort.

Weitere Ressourcen

Helius abonnieren

Bleib bei der Solana-Entwicklung auf dem Laufenden und erhalte Updates, wenn wir neue Beiträge veröffentlichen

Vergrößertes Bild