Skip to main content

Hello World


Initializing a new Znap project:

To initialize a new project, simply run:

  1. Run the following command, replacing with your desired project name: znap init <project-name>
  2. Navigate to your newly created project directory: cd <project-name>

Creating a new Solana Action collection:

Use the following command, replacing with your desired collection name: znap new <collection-name>.

This command will generate a directory structure for your collection:

· /collections
· /<collection-name>
· Cargo.toml
· /src
· lib.rs

The structure of your collection follows the Rust project standard. The workspace /collections/<collection-name> contains a Cargo.toml file that acts as the project manifest, specifying dependencies and configuration. The /src directory houses the source code, with lib.rs being the entry point of the Rust library that defines your Solana Action.

use solana_sdk::{
message::Message, native_token::LAMPORTS_PER_SOL, pubkey, pubkey::Pubkey,
system_instruction::transfer, transaction::Transaction,
};
use std::str::FromStr;
use znap::prelude::*;

#[collection]
pub mod test {

use super::*;

pub fn say_hello(ctx: Context<HelloWorld>) -> Result<ActionTransaction> {
let account_pubkey = Pubkey::from_str(&ctx.payload.account)
.or_else(|_| Err(Error::from(ActionError::InvalidAccountPublicKey)))?;

let receiver_pubkey = pubkey!("9vPm6wd795YQRd2Ae1ZHuBESanEmiqbfgtJ5bbfyvy5J");

let transfer_instruction = transfer(
&account_pubkey,
&receiver_pubkey,
(0.000001 * LAMPORTS_PER_SOL as f32) as u64,
);

let transaction_message = Message::new(&[transfer_instruction], None);
let transaction = Transaction::new_unsigned(transaction_message);

Ok(ActionTransaction {
transaction,
message: Some("Hello World!".to_string()),
})
}
}

#[derive(Action)]
#[action(
icon = "https://media.discordapp.net/attachments/1205590693041541181/1212566609202520065/icon.png?ex=667eb568&is=667d63e8&hm=0f247078545828c0a5cf8300a5601c56bbc9b59d3d87a0c74b082df0f3a6d6bd&=&format=webp&quality=lossless&width=660&height=660",
title = "Hello World",
description = "This is a greeting",
label = "Say hello",
link = {
label = "Say hello",
href = "/api/hello_world"
},
)]
pub struct HelloWorld;

#[derive(ErrorCode)]
enum ActionError {
#[error(msg = "Invalid account public key")]
InvalidAccountPublicKey,
}

Note: Inside the lib.rs file, you'll need to replace the receiver_pubkey value with your Solana wallet public key. This is the wallet that will receive the SOL amount once the transaction is signed and submitted.

Testing our Solana Action API:

To interact with our Solana Action, start by running the command znap serve <collection-name>. This will initiate a local development server. Once the server is up and running, you can send HTTP requests to your Solana Action to perform desired operations.

GET Method

If you run the following command in your terminal:

curl http://127.0.0.1:3000/api/hello_world

You will receive the following JSON response:

{
"icon":"https://media.discordapp.net/attachments/1205590693041541181/1212566609202520065/icon.png?ex=667eb568&is=667d63e8&hm=0f247078545828c0a5cf8300a5601c56bbc9b59d3d87a0c74b082df0f3a6d6bd&=&format=webp&quality=lossless&width=660&height=660",
"title":"Hello World",
"description":"This is a greeting",
"label":"Say hello",
"links":{
"actions":[
{
"label":"Say hello",
"href":"/api/hello_world",
"parameters":[

]
}
]
},
"disabled":false,
"error":null
}

POST Method

To obtain an unsigned transaction using a POST request, run the following command:

curl -X POST -H "Content-Type: application/json" -d '{"account": "8byTaGAbftXnv7FWt6zhR8zTpy9t7fitFRgbtW7EWcAt"}' http://127.0.0.1:3000/api/hello_world

Note: Replace the account value with the public key of the wallet you want to send SOL from.

You will receive the following JSON response containing our "Hello World" message:

{
"transaction":"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQGcPdkuJpytnAJJPkZPmoN+AHwIoLTv85WOfeT7VJ+VQGEiwN3lFs03v5rMh14RkppSphcxxnqyxno9sGGLTe34QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUpTWpkpIQZNJOhxYNo4fHw1td28kruB5B+oQEEFRI2dQeAIc0PFGKpcl+gDFc3oN7bjAe/AY7l/fQgPDoaHVKy/Eq9t3+pnqEttexDqyAmLyMTopTiLrMA94to6MUbimnbBgaj40d2YXO953qbEkUbxFkjCDinyfOZUn/AbC9UCAgQAAQQFDAIAAADoAwAAAAAAAAMAvwFzb2xhbmEtYWN0aW9uOkNkTDdOcGhnR3VKeDYxTmVVcDZQN29TNjd4VlZHQmlZN3JIVTVqWEhqdWJGOkJhc0diUUJKd0NWcWo4S2tmcExvZERxSmsxZmJ3MTJrZWJWNWZmUHZiUExGOmVuZ2hOcmkyaW9jeXltajlacVd0R0xqOFhaWEFXQ2NKb2Q0SFlGbWp2aHd3UEtNd3lCaWtWVEVxNXg5VE5OSmpNb2hESlRyY3FEdTZhRFN6S1VSWkNFaA==",
"message":"Hello World!"
}