Hello World
Initializing a new Znap project:
To initialize a new project, simply run:
- Run the following command, replacing with your desired project name:
znap init <project-name>
- 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!"
}