<?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>Forem: Valentin Madrid</title>
    <description>The latest articles on Forem by Valentin Madrid (@valentinmadrid).</description>
    <link>https://forem.com/valentinmadrid</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%2F1075623%2Fad656a0e-7464-4097-9baf-1159afb41c44.jpg</url>
      <title>Forem: Valentin Madrid</title>
      <link>https://forem.com/valentinmadrid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/valentinmadrid"/>
    <language>en</language>
    <item>
      <title>A deep dive into verifiable programs on Solana</title>
      <dc:creator>Valentin Madrid</dc:creator>
      <pubDate>Mon, 24 Jul 2023 16:40:28 +0000</pubDate>
      <link>https://forem.com/valentinmadrid/a-deep-dive-into-verifiable-programs-on-solana-4lod</link>
      <guid>https://forem.com/valentinmadrid/a-deep-dive-into-verifiable-programs-on-solana-4lod</guid>
      <description>&lt;p&gt;A big problem with blockchains is that you can't know the code behind an on chain program, meaning you would have to blindly trust a protocol with your signature, not being able to verify what's really going on behind the scenes.&lt;br&gt;
That's why a lot of companies and projects publish their programs code to build trust. But now the problem is, "how can I be sure the public source code is the same as the deployed programs source code ?".&lt;br&gt;
That's why Ellipsis Labs has built a build verification CLI, which can be used to compare an on-chain program byte code to the build output when you build its underlying program.&lt;/p&gt;

&lt;p&gt;Let's now take a look at how you can create a program and verify it using Ellipsis Labs verifiable builds.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a program
&lt;/h2&gt;

&lt;p&gt;First of all, initialise your program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;anchor init verifiable-build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add a little functionality to our program so it isn't the boring standard one.&lt;/p&gt;

&lt;p&gt;Replace the existing content with the following code in &lt;em&gt;programs/verifiable-build/src/lib.rs:&lt;/em&gt;&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="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;system_program&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;"AD62W7aAQETg11ajkadk57DYfPTWPzKLiXuLZVB4eQaw"&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;verifiable_build&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;transfer_sol&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;lt;&lt;/span&gt;&lt;span class="n"&gt;TransferSol&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="nb"&gt;u64&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="nn"&gt;system_program&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nn"&gt;CpiContext&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.accounts.system_program&lt;/span&gt;&lt;span class="nf"&gt;.to_account_info&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="nn"&gt;system_program&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Transfer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.accounts.payer&lt;/span&gt;&lt;span class="nf"&gt;.to_account_info&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.accounts.recipient&lt;/span&gt;&lt;span class="nf"&gt;.to_account_info&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="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&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="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;TransferSol&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="nd"&gt;#[account(mut)]&lt;/span&gt;
    &lt;span class="n"&gt;recipient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SystemAccount&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="nd"&gt;#[account(mut)]&lt;/span&gt;
    &lt;span class="n"&gt;payer&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="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;Let's build the program now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;anchor build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploying your program
&lt;/h2&gt;

&lt;p&gt;First, let's set the network we want to deploy our program on, I will be doing it on a local Solana validator.&lt;/p&gt;

&lt;p&gt;Set your network running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solana config set -c --url l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now launch a local solana validator in a separate terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solana-local-validator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now deploy your program&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;anchor deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verify the deployed program
&lt;/h2&gt;

&lt;p&gt;Now comes the important part. Let's verify that the byte-code of the program we just deployed matches the program we've written. &lt;/p&gt;

&lt;h3&gt;
  
  
  Install the verifiable-build CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install solana-verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get local executable hash
&lt;/h3&gt;

&lt;p&gt;First, let's get the hash of the build output from our program:&lt;br&gt;
Here, make sure to use the program's lib name, found under &lt;code&gt;[lib]&lt;/code&gt; in Cargo.toml.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solana-verify get-executable-hash target/deploy/verifiable_build.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the output we get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zusr5cuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/135jta41oqx6wrmgwjw7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zusr5cuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/135jta41oqx6wrmgwjw7.png" alt="Verifiable build executable hash" width="800" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Get hash from program bytecode
&lt;/h3&gt;

&lt;p&gt;And now let's get the hash of the program bytecode:&lt;br&gt;
Here, replace &lt;code&gt;$PROGRAM_ID&lt;/code&gt; by the program id of your deployed program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solana-verify get-program-hash -u http://localhost:8899 $PROGRAM_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PClT6xCx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0gaaw85cqzl0dslx1rz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PClT6xCx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0gaaw85cqzl0dslx1rz.png" alt="Verifiable build program hash" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see here that both of the hashes are the same, meaning we've proven that the program you've built locally corresponds to the one you've deployed. &lt;/p&gt;

&lt;h2&gt;
  
  
  Verify an on chain program from a Github repository
&lt;/h2&gt;

&lt;p&gt;For this, I've created a Github repository with the program we've just built and also deployed it onto the Solana devnet. &lt;br&gt;
You can do the same but don't need to, as you can just use this with the repository I have created.&lt;/p&gt;
&lt;h3&gt;
  
  
  Verify hash between repo and program
&lt;/h3&gt;

&lt;p&gt;To verify a hash between an on-chain program and a GitHub repository, run this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solana-verify verify-from-repo -ud --program-id AD62W7aAQETg11ajkadk57DYfPTWPzKLiXuLZVB4eQaw https://github.com/valentinmadrid/solana-verifiable-builds-example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the hash from both of these programs match, you can consider a program's source code to be verified.&lt;/p&gt;

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

&lt;p&gt;Verifiable builds are really important. That's why it's great to see companies like Ellipsis Labs coming up with amazing ways of verifying if the code of an open-source program matches it's deployed version.&lt;/p&gt;

&lt;p&gt;This is a great step forward for achieving a better open source culture on Solana. But, we still have ways to go. It would be amazing to see projects take  initiatives to build tools such as a registry of verified programs for explorers, GitHub workflows that can update a verifiable hash in a database each time a program is updated or even wallets that integrate verifiable builds to spot harmful program interactions.&lt;/p&gt;

&lt;p&gt;Thanks for reading this post. Feel free to drop any feedback on my Twitter: @valentinmadrid_.&lt;/p&gt;

</description>
      <category>solana</category>
      <category>verifiablebuild</category>
      <category>devguide</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Interact with your Solana programs in Python</title>
      <dc:creator>Valentin Madrid</dc:creator>
      <pubDate>Fri, 05 May 2023 08:38:52 +0000</pubDate>
      <link>https://forem.com/valentinmadrid/interact-with-your-solana-programs-in-python-29lc</link>
      <guid>https://forem.com/valentinmadrid/interact-with-your-solana-programs-in-python-29lc</guid>
      <description>&lt;p&gt;Most of client side interaction with Solana Programs is done in Typescript for now. That makes sense, because most frontend frameworks are built on top of Javascript.&lt;br&gt;
But what if you want to use Python to interact with your program ? Let's see how this can be done in this short tutorial.&lt;/p&gt;

&lt;p&gt;The library we'll be using is called AnchorPy, and was made by &lt;a href="https://github.com/kevinheavey"&gt;Kevin Heavey&lt;/a&gt;.&lt;br&gt;
Link to the AnchorPy documentation: &lt;a href="https://kevinheavey.github.io/anchorpy/"&gt;https://kevinheavey.github.io/anchorpy/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create some tests for an Anchor program in Python. Here's a link to the &lt;a href="https://github.com/solana-developers/program-examples/tree/main/tokens/transfer-tokens/seahorse"&gt;program's repo&lt;/a&gt; we will the interacting with.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install AnchorPy
&lt;/h3&gt;

&lt;p&gt;First of all, install anchorpy and solders:&lt;br&gt;
&lt;code&gt;pip3 install anchorpy&lt;/code&gt;&lt;br&gt;
&lt;code&gt;pip3 install solders&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, let's create a test file at &lt;code&gt;tests/test.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First of all, let's import some dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;anchorpy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;close_workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;solders.system_program&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;SYS_PROGRAM_ID&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;solders.pubkey&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Pubkey&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;solders.keypair&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Keypair&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;solders.sysvar&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RENT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing our Anchor program
&lt;/h3&gt;

&lt;p&gt;Our code will compose of a base that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Read the deployed program from the workspace.
&lt;/span&gt;    &lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_workspace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# The program from the workspace we want to use
&lt;/span&gt;    &lt;span class="n"&gt;program&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"seahorse"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Close all HTTP clients in the workspace.
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;close_workspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now we can get to our test's logic. We have three instructions in our Anchor program. Let's get through them and document everything that is happening.&lt;/p&gt;

&lt;p&gt;First, we define the two Program addresses for the Token program and the Associated Token Program. Then we generate a Keypair for the Token Mint we're going to create afterwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;TOKEN_PROGRAM_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pubkey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ASSOCITAED_TOKEN_PROGRAM_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pubkey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a Mint keypair. This will be our token mint.
&lt;/span&gt;&lt;span class="n"&gt;mint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Keypair&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Invoking instructions
&lt;/h3&gt;

&lt;p&gt;Now, we call the create_token instruction from our program and print the transaction signature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;create_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"create_token"&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"mint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mint&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="s"&gt;"signer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&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="s"&gt;"system_program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SYS_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"rent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"token_program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TOKEN_PROGRAM_ID&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;signers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create token signature: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see some similarities with the Typescript Anchor library here. "create_token" is the instruction to be executed and the "accounts" context are the accounts passed into our instruction. The signers here are the Anchor workspace keypair and the Mint Keypair, needed to sign the creation of a Mint account. Pretty straightforward right ?&lt;/p&gt;

&lt;h3&gt;
  
  
  Derive PDA's
&lt;/h3&gt;

&lt;p&gt;We want to create an associated token account now, for that we will need it's Public Key. You can do that by using &lt;code&gt;find_program_adress&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;associated_token_account_pubkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pubkey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_program_address&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&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="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mint&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="n"&gt;ASSOCITAED_TOKEN_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now use this Pubkey in the instruction's accounts. This would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;create_associated_token_account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"create_associated_token_account"&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"mint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mint&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="s"&gt;"token_account"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;associated_token_account_pubkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"signer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&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="s"&gt;"system_program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SYS_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"rent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"token_program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TOKEN_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"associated_token_program"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ASSOCITAED_TOKEN_PROGRAM_ID&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;signers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create associated token account signature: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_associated_token_account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pass arguments to instruction
&lt;/h3&gt;

&lt;p&gt;Last, let's see how we can add additional arguments into our instruction by minting some tokens to our workspace Keypair. Here we are mining 1000 tokens to the Token Account created before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mint_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"mint_token"&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"mint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mint&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="s"&gt;"recipient"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;associated_token_account_pubkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"signer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&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="s"&gt;"system_program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SYS_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"rent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"token_program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TOKEN_PROGRAM_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;signers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mint token signature: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mint_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we could run our tests in the command line, but let's do something more convenient. Let's go to the &lt;code&gt;Anchor.toml&lt;/code&gt; file and change the current test script to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[scripts]&lt;/span&gt;
&lt;span class="py"&gt;test&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"python3 tests/test.py"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now run &lt;code&gt;anchor test --skip-local-validator&lt;/code&gt; and run the tests we wrote.&lt;/p&gt;

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

&lt;p&gt;Thanks for reading this guide. &lt;br&gt;
If you have any more questions, please contact me on &lt;a href="https://twitter.com/valentinmadrid_"&gt;Twitter&lt;/a&gt; or join the &lt;a href="https://discord.gg/solanau"&gt;SolanaU&lt;/a&gt; Discord Server.&lt;/p&gt;

</description>
      <category>solana</category>
      <category>python</category>
      <category>anchor</category>
      <category>testing</category>
    </item>
    <item>
      <title>A guide to Solana Geyser Plugins</title>
      <dc:creator>Valentin Madrid</dc:creator>
      <pubDate>Wed, 03 May 2023 10:29:32 +0000</pubDate>
      <link>https://forem.com/valentinmadrid/a-guide-to-solana-geyser-plugins-452k</link>
      <guid>https://forem.com/valentinmadrid/a-guide-to-solana-geyser-plugins-452k</guid>
      <description>&lt;h2&gt;
  
  
  What even is Geyser ?
&lt;/h2&gt;

&lt;p&gt;Geyser consists of something called the "Solana Geyser Plugin Interface". This interface enables developers to build Plugins into validators. The Plugin interface will then listen to events on the Solana Blockchain and notify the Plugin of those events.&lt;br&gt;
These events can be: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;account updates, meaning every time an account is updated on the chain, it will notify your Plugin.&lt;/li&gt;
&lt;li&gt;new transactions&lt;/li&gt;
&lt;li&gt;new slots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This enables amazing use cases, such as streaming all account changes for your specific program to a database. This means you could perform initially high load RPC requests such as getProgramAccounts directly from your favourite database, which is pretty cool and makes the process up to 10 times faster&lt;/p&gt;
&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;There are several already developed Geyser Plugins which you can run, here is a quick overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/solana-labs/solana-accountsdb-plugin-postgres"&gt;AccountsDB Postgres&lt;/a&gt;: Stores your accounts and transactions in a Postgres database.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Blockdaemon/solana-accountsdb-plugin-kafka"&gt;AccountsDB Kafka&lt;/a&gt;: Streams account changes to Kafka.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/lijunwangs/solana-accountsdb-plugin-bigtable"&gt;AccountsDB Plugin Bigtable&lt;/a&gt;: Streams tx + accounts to Google Bigtable.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rpcpool/yellowstone-grpc"&gt;Yellowstone gRPC&lt;/a&gt;: gRPC interface for Solana.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nautilus-project/waverider"&gt;Waverider&lt;/a&gt;: Streams account data from specific programs (PDA's) to a Supabase instance, which can then be queried via Supabase realtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;To run a Geyser Plugin, you will need to run a validator or an RPC node, which is essentially a non voting validator that can index data from the chain.&lt;br&gt;
The hardware requirements will vary on the cluster you want to run your validator on. I strongly recommend you take a look at the recommended specifications to run a non voting validator.&lt;br&gt;
In this post, we are going to use the Solana Local Validator, which you can run with pretty much every hardware.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to run a Plugin ?
&lt;/h2&gt;

&lt;p&gt;It's pretty straightforward, you just have to start a Solana validator with the Geyser Plugin you want to run attached. Here is an example:&lt;br&gt;
&lt;code&gt;solana-test-validator --geyser-plugin-config &amp;lt;path to your plugin config&amp;gt;&lt;/code&gt;&lt;br&gt;
Let's take a look at an example plugin scaffold, &lt;a href="https://github.com/mwrites/solana-geyser-plugin-scaffold.git"&gt;here&lt;/a&gt;.&lt;br&gt;
Create a file where you want your plugin to live, and open a terminal in it. Then clone the Plugin.&lt;br&gt;
&lt;code&gt;git clone https://github.com/mwrites/solana-geyser-plugin-scaffold.git .&lt;/code&gt;&lt;br&gt;
We are now ready to go, but there is something important to take notice of:&lt;br&gt;
⚠️ You need to build the Plugin with the same Rust version as you've build your Solana CLI. Also, your Solana CLI version should match the &lt;code&gt;solana-geyser-plugin-interface&lt;/code&gt; in the plugin's Cargo.toml file.&lt;br&gt;
The Interface version of this plugin is: 11.1.1. To install the corresponding Solana CLI version, run:&lt;br&gt;
&lt;code&gt;sh -c "$(curl -sSfL https://release.solana.com/v1.11.1/install)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now  run &lt;code&gt;cargo build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There's one more thing to do, in your config/config.json file, make sure to set your file extension for "libpath" to &lt;code&gt;.so&lt;/code&gt; if you are on Linux or Windows or &lt;code&gt;.dylib&lt;/code&gt; if you are on mac.&lt;/p&gt;

&lt;p&gt;Your plugin should now run and log every single account change happening on the ledger, including it's Public Key and the current slot. You can also get way more information such as the account's data Buffer. Pretty cool right ?&lt;/p&gt;
&lt;h2&gt;
  
  
  Build your own plugin
&lt;/h2&gt;

&lt;p&gt;Now while this is pretty cool, you might think of a lot of use cases this plugin framework enables. While I recommend that you work up from this Plugin Scaffold, I can still give you a little insight on how the plugin interface works.&lt;br&gt;
After defining an entrypoint to your program, for which you can find an example &lt;a href="https://github.com/mwrites/solana-geyser-plugin-scaffold/blob/main/src/entrypoint.rs"&gt;here&lt;/a&gt;.&lt;br&gt;
Now the validator will call a couple functions whenever certain events are triggered. Some examples are:&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="c1"&gt;// This gets called while the validator is still starting up&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;on_load&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="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;solana_geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This gets called when startup has ended&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;notify_end_of_startup&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="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;solana_geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This gets called every time account data gets changed&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update_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="k"&gt;self&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="n"&gt;ReplicaAccountInfoVersions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slot&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="n"&gt;is_startup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;solana_geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This gets called each time there is a new transaction&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;notify_transaction&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="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&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;ReplicaTransactionInfoVersions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slot&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="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;solana_geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;geyser_plugin_interface&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// These two are basically the configuration deciding if the interface should notify account changes and transaction notifications&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;account_data_notifications_enabled&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;self&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;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;transaction_notifications_enabled&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;self&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;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;As you've probably noticed, this Geyser thing is pretty cool. Go build something with it !&lt;br&gt;
Feel free to tag me on &lt;a href="https://twitter.com/valentinmadrid_"&gt;Twitter&lt;/a&gt; if you need any help.&lt;/p&gt;

&lt;p&gt;-- &lt;br&gt;
Speaking of Geyser ! I have built this validator extension called &lt;a href="https://github.com/nautilus-project/waverider"&gt;Waverider&lt;/a&gt;. It essentially allows you to stream your program's account changes to a Supabase Database, making gPa's 10 times faster and you're even able to listen to realtime account changes, which is essential to a lot of dApps. Again, feel free to contact me if you have any questions on this.&lt;/p&gt;

</description>
      <category>solana</category>
      <category>geyser</category>
      <category>devtool</category>
      <category>database</category>
    </item>
    <item>
      <title>Amman - Your Solana development workflow on steroids</title>
      <dc:creator>Valentin Madrid</dc:creator>
      <pubDate>Tue, 02 May 2023 22:38:48 +0000</pubDate>
      <link>https://forem.com/valentinmadrid/amman-your-solana-development-workflow-on-steroids-56ck</link>
      <guid>https://forem.com/valentinmadrid/amman-your-solana-development-workflow-on-steroids-56ck</guid>
      <description>&lt;p&gt;Hello fellow Solana dev !&lt;/p&gt;

&lt;p&gt;In this blog post, we will cover a tool which is going to simplify your development workflow when testing your programs locally. It’s called Amman. Amman describes itself as a Toolbelt to help test Solana SDK Libraries and apps on a local running validator.&lt;/p&gt;

&lt;p&gt;To put it simply, it takes the existing Solana local validator and adds a couple really great features to it, such as loading programs from other clusters like the Solana mainnet, labelling key pairs or making airdrops in your anchor tests. Amman also comes with its own explorer to match all of its additional features.&lt;/p&gt;

&lt;p&gt;If that didn’t make sense to you, it’s all good, we’re going to explore them the further we go down this post.&lt;/p&gt;

&lt;p&gt;Let’s get started!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: If you don’t want to read the whole post. There is a very short guide at the end to cover all Amman basics without explanations.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;You’ve already read the Anchor documentation&lt;br&gt;
You have the Solana Tool suite installed&lt;br&gt;
If you want to follow along with the same Anchor program as the one I will be covering today, clone it by clicking &lt;a href="https://github.com/valentinmadrid/amman-example"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Amman
&lt;/h2&gt;

&lt;p&gt;First of all, head to the root of your Anchor project.&lt;br&gt;
If you want to install Amman only for this specific project, run this inside your terminal:&lt;br&gt;
&lt;code&gt;yarn add @metaplex-foundation/amman&lt;/code&gt;&lt;br&gt;
or&lt;br&gt;
&lt;code&gt;npm install @metaplex-foundation/amman&lt;/code&gt;&lt;br&gt;
If you want to have Amman installed globally, run&lt;br&gt;
&lt;code&gt;npm install -g @metaplex-foundation/amman&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configurating Amman
&lt;/h2&gt;

&lt;p&gt;Once you have successfully installed Amman, create a file called &lt;code&gt;.ammanrc.js&lt;/code&gt; in your project root. Add the following code to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;killRunningValidators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;programs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;jsonRpcUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;websocketUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;commitment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ledgerDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./test-ledger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resetLedger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;verifyFees&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;detached&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;relay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;killlRunningRelay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;storageId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mock-storage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;clearOnStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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 where the configuration of your Amman instance lives. For now, all you need to know is that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the killRunningValidators field will stop any running local validator process&lt;/li&gt;
&lt;li&gt;jsonRpcUrl is the url where your validator should listen to rpc requests&lt;/li&gt;
&lt;li&gt;ledgerDir is where the validators ledger will be created or used(if it already exists). By default it will be stored in the your projects root.&lt;/li&gt;
&lt;li&gt;resetLedger determines if you want to reset the validators existing state every time you start Amman.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, you’re ready to start Amman. Run &lt;code&gt;amman start&lt;/code&gt; inside your terminal.&lt;br&gt;
The output should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Loading config from /Users/devenv/Documents/GitHub/amman-example/.ammanrc.js&lt;br&gt;
Running validator with 0 custom program(s) and 0 remote account(s) preloaded&lt;br&gt;
Killed currently running solana-test-validator&lt;br&gt;
Launching new solana-test-validator with programs predeployed and ledger at ./test-ledger&lt;br&gt;
Successfully launched Relay at :::50474&lt;br&gt;
ws error: connect ECONNREFUSED 127.0.0.1:8900&lt;br&gt;
Successfully launched MockStorageServer at :::50475&lt;br&gt;
ws error: connect ECONNREFUSED 127.0.0.1:8900&lt;br&gt;
ws error: connect ECONNREFUSED 127.0.0.1:8900&lt;br&gt;
Waiting for fees to stabilize 1...&lt;br&gt;
Waiting for fees to stabilize 2...&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Use Amman in your testing workflow
&lt;/h2&gt;

&lt;p&gt;Good, you have a running Amman instance now. We’ll be able to run some cool tests for our program. We only care about one instruction, to send a token which we will send from one person to another.&lt;/p&gt;

&lt;p&gt;Again, I have created an example repository for what I will explain in this post, you can find the code here.&lt;/p&gt;
&lt;h2&gt;
  
  
  Loading mainnet programs
&lt;/h2&gt;

&lt;p&gt;By taking a look at the test file, we can see that we need to pass in the Token Program to call both instructions.&lt;/p&gt;

&lt;p&gt;But how do I use the token program when testing locally ? We can tell amman what programs we want to load by passing them into the programs or the accounts field.&lt;/p&gt;

&lt;p&gt;This is how to add the mainnet Token Program to your Local Validator:&lt;/p&gt;

&lt;p&gt;Add the following program into the “accounts” field in &lt;code&gt;.ammanrc.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;accounts&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Token Program&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;executable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Random other example account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4VLgNs1jXgdciSidxcaLKfrR9WjATkj6vmTm5yCwNwui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// You can set the cluster on a per account basis&lt;/span&gt;
    &lt;span class="na"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://metaplex.devnet.rpcpool.com&lt;/span&gt;&lt;span class="dl"&gt;"&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;It‘s important to set "executable" to "true" in this context, because we want to clone a program. If you just want to load data from a non executable account, set it to false. You can also specify the RPC URL from where you want to load these accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anchor tests in Typescript with Amman
&lt;/h2&gt;

&lt;p&gt;First of all, import Amman at the top of your test file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Amman&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@metaplex-foundation/amman-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize an Amman instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Labeled Keypairs
&lt;/h2&gt;

&lt;p&gt;In our program, there should be one Keypair that mints a Token and sends it to the other. We‘re going to call the sending Keypair Alice, and the receiver should be called Bob.&lt;/p&gt;

&lt;p&gt;This is once again where Ammans magic comes in. You can label Keypairs, which makes it easier to understand the different accounts inside the Amman Explorer. This is how you generate a new labeled Keypair:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;aliceAmman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;genLabeledKeypair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bobAmman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;genLabeledKeypair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&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 output of this will be an object with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Public Key&lt;/li&gt;
&lt;li&gt;The Keypair&lt;/li&gt;
&lt;li&gt;A string&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The actual Solana Keypair is at the index of 1 of the Keypair:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aliceAmman&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also label any existing accounts like this:&lt;/p&gt;

&lt;p&gt;// publicKey will be the public Key of the account you want to label.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Airdrop SOL
&lt;/h2&gt;

&lt;p&gt;Now we have another problem, your Keypairs will not have any SOL, and will therefore not be able to pay the transaction fees.&lt;/p&gt;

&lt;p&gt;But you can easily handle airdrops with Amman, just add this to your existing code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Airdrop 1 SOL to Alice&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airdrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should be good to run our tests now.&lt;br&gt;
If you don’t have a running Amman instance yet, start one in a seperate Terminal using &lt;code&gt;amman start&lt;/code&gt;. Then, run your tests with Anchor by running: &lt;code&gt;anchor test --skip-local-validator&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Amman explorer
&lt;/h2&gt;

&lt;p&gt;You can find it at: &lt;a href="https://amman-explorer.metaplex.com/"&gt;https://amman-explorer.metaplex.com/&lt;/a&gt;&lt;br&gt;
If Brave doesn’t work, try disabling the Brave Shield.&lt;br&gt;
The explorer is a copy of the Solana explorer that includes Amman’s features.&lt;br&gt;
If everything worked well, it should be connected to your running Amman instance, you can see that in the top left of your screen.&lt;br&gt;
Find the transaction you want to inspect, you will be able to see Token movements and involved accounts thanks to their label. Here’s an example:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--68kaZ2Br--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wej6fszdyzqrj5wetcz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--68kaZ2Br--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wej6fszdyzqrj5wetcz2.png" alt="Solana Amman local developement" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Read deserialized account data
&lt;/h2&gt;

&lt;p&gt;You can read account data directly from the explorer. For that, head to any account and click on the Resolved Info Tab. This should look similar to this image.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3XTbUZJo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i84rdnxlggz5gd7hcojo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3XTbUZJo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i84rdnxlggz5gd7hcojo.png" alt="Deserialized Solana Account Data" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Amman is amazing&lt;br&gt;
Amman is an amazing Solana Dev Tool and I recommend to make usage of it. Here’s a really short guide if you don’t want to read trough the whole tutorial:&lt;/p&gt;
&lt;h2&gt;
  
  
  Short guide
&lt;/h2&gt;

&lt;p&gt;I’ve made a quick recap for you here:&lt;/p&gt;
&lt;h3&gt;
  
  
  Install Amman
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;metaplex&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;foundation&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;amman&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Add Amman Configuration
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.ammanrc.js&lt;/code&gt; file in your project root. Add the &lt;a href="https://github.com/valentinmadrid/amman-example/blob/main/.ammanrc.js"&gt;following code&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Start Amman
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;amman start&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Use Amman in Tests
&lt;/h3&gt;

&lt;p&gt;1 Import Amman Client&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Amman&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@metaplex-foundation/amman-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 Initialize Amman instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 Generate Keypair&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;aliceAmman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;genLabeledKeypair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aliceAmman&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 Label Accounts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 Airdrop SOL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;amman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airdrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;program&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Amman explorer&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the Amman explorer &lt;a href="https://amman-explorer.metaplex.com/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The explorer has a lot of great features like being able to display deserialized account data, go and see what it can do.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>solana</category>
      <category>amman</category>
      <category>tutorial</category>
      <category>devtool</category>
    </item>
  </channel>
</rss>
