Here is my entire main.rs,,
mod utils;
use actix_cors::Cors;
use actix_web::{web, App, HttpServer, Responder, HttpResponse, HttpRequest};
use serde::{Deserialize, Serialize};
use reqwest::Client;
use std::sync::Arc;
use tokio::sync::Mutex;
use solana_client::rpc_client::RpcClient;
use solana_program::{
pubkey::Pubkey,
system_instruction,
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
program::{invoke},
program_error::ProgramError,
msg,
};
use solana_sdk::signature::Keypair;
use solana_sdk::message::Message;
use solana_sdk::transaction::Transaction;
use utils::{get_launch_date, get_sol_price};
use std::str::FromStr;
use spl_token::instruction as token_instruction;
#[derive(Serialize, Deserialize, Debug)]
struct TransactionRequest {
public_key: String,
amount: f64,
currency: String,
}
#[derive(Serialize)]
struct TransactionResponse {
status: String,
message: String,
amount_in_lamports: u64,
destination: String,
}
async fn process_transaction(
_req: HttpRequest, // Prefixed with underscore to silence warning
body: web::Json<TransactionRequest>,
client: web::Data<Arc<Mutex<Client>>>,
) -> impl Responder {
let transaction = body.into_inner();
println!("Processing transaction: {:?}", transaction);
let client_guard = client.lock().await;
let sol_price = get_sol_price(&client_guard).await.unwrap();
let amount_in_sol = transaction.amount / sol_price;
let amount_in_lamports = (amount_in_sol * 1_000_000_000.0) as u64;
let destination_pubkey = Pubkey::from_str("14fbryUnN5Px4GGg1MMgTKawpyvBXUzk4p8JGbtMfNud").unwrap();
let sender_pubkey = Pubkey::from_str(&transaction.public_key).unwrap();
let sender_keypair = Keypair::new();
let rpc_client = RpcClient::new("https://api.mainnet-beta.solana.com");
let recent_blockhash = rpc_client.get_latest_blockhash().unwrap();
let transaction_instruction = system_instruction::transfer(
&sender_pubkey,
&destination_pubkey,
amount_in_lamports,
);
let message = Message::new(&[transaction_instruction], Some(&sender_pubkey));
let mut transaction = Transaction::new_unsigned(message);
transaction.try_sign(&[&sender_keypair], recent_blockhash).unwrap();
let signature = rpc_client.send_and_confirm_transaction(&transaction).unwrap();
let response = TransactionResponse {
status: "success".to_string(),
message: format!("Transaction processed successfully: {}", signature),
amount_in_lamports,
destination: "14fbryUnN5Px4GGg1MMgTKawpyvBXUzk4p8JGbtMfNud".to_string(),
};
HttpResponse::Ok().json(response)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let client = Arc::new(Mutex::new(Client::new()));
HttpServer::new(move || {
App::new()
.wrap(
Cors::default().allow_any_origin().allow_any_method().allow_any_header()
)
.app_data(web::Data::new(client.clone()))
.route("/launch-date", web::get().to(get_launch_date))
.route("/process-transaction", web::post().to(process_transaction))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
// Combined KRPL_Contract functions
entrypoint!(process_instruction);
pub fn process_instruction(
_program_id: &Pubkey, // Prefixed with underscore to silence warning
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let account_iter = &mut accounts.iter();
let sender = next_account_info(account_iter)?;
let recipient = next_account_info(account_iter)?;
let system_program = next_account_info(account_iter)?;
let token_program = next_account_info(account_iter)?;
let token_account = next_account_info(account_iter)?;
let (transfer_type, amount) = parse_instruction_data(instruction_data)?;
match transfer_type {
TransferType::Sol => {
let transfer_instruction = system_instruction::transfer(
sender.key,
recipient.key,
amount,
);
msg!("Invoking transfer instruction...");
invoke(
&transfer_instruction,
&[
sender.clone(),
recipient.clone(),
system_program.clone(),
],
)?;
},
TransferType::Usdc => {
let transfer_instruction = token_instruction::transfer(
token_program.key,
token_account.key,
recipient.key,
sender.key,
&[&sender.key],
amount,
)?;
msg!("Invoking token transfer instruction...");
invoke(
&transfer_instruction,
&[
token_program.clone(),
token_account.clone(),
recipient.clone(),
sender.clone(),
],
)?;
},
}
Ok(())
}
enum TransferType {
Sol,
Usdc,
}
fn parse_instruction_data(data: &[u8]) -> Result<(TransferType, u64), ProgramError> {
if data.len() != 9 {
return Err(ProgramError::InvalidInstructionData);
}
let transfer_type = match data[0] {
0 => TransferType::Sol,
1 => TransferType::Usdc,
_ => return Err(ProgramError::InvalidInstructionData),
};
let amount = u64::from_le_bytes(data[1..].try_into().unwrap());
Ok((transfer_type, amount))
}
pub fn create_transfer_instruction(
sender_pubkey: &Pubkey,
recipient_pubkey: &Pubkey,
amount: u64,
) -> solana_program::instruction::Instruction {
solana_program::system_instruction::transfer(sender_pubkey, recipient_pubkey, amount)
}
the full error below:
error: linking with `link.exe` failed: exit code: 1169
|
= note: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.39.33519\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "C:\\Users\\Keola\\AppData\\Local\\Temp\\rustcsit7vP\\symbols.o" "C:\\Users\\Keola\\Desktop\\MyToken-ICOWidget\\Main\\ProjectV2\\BackendV2\\target\\debug\\deps\\BackendV2.02w35narb1wcyx3f48a9qcf74.rcgu.o" "C:\\... [etc]
= note: libspl_token-9c38dd82029194be.rlib(spl_token-9c38dd82029194be.spl_token.26961209c36bf507-cgu.0.rcgu.o) : error LNK2005: entrypoint already defined in BackendV2.91eirpl2uxknzk9n40oimifb8.rcgu.o
C:\Users\Keola\Desktop\MyToken-ICOWidget\Main\ProjectV2\BackendV2\target\debug\deps\BackendV2.exe : fatal error LNK1169: one or more multiply defined symbols found
warning: `BackendV2` (bin "BackendV2") generated 2 warnings
error: could not compile `BackendV2` (bin "BackendV2") due to 1 previous error; 2 warnings emitted
PS C:\Users\Keola\Desktop\MyToken-ICOWidget\Main\ProjectV2\BackendV2>
my cargo.toml:
cargo-features = ["profile-rustflags"]
[package]
name = "BackendV2"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4.6.0"
actix-cors = "0.7.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
# Use compatible versions of Solana dependencies
solana-program = "1.18.14"
spl-token = "3.5.0"
solana-client = "1.18.14"
solana-sdk = "1.18.14"
[profile.dev]
rustflags = ["-C", "link-args=/STACK:16777216"]
[profile.release]
rustflags = ["-C", "link-args=/STACK:16777216", "-C", "target-cpu=native"]
[unstable]
profile-rustflags = true
[target.x86_64-pc-windows-msvc]
linker = "rust-lld"
I think I've narrowed down the problem being somewhere in,
entrypoint!(process_instruction);
pub fn process_instruction(
_program_id: &Pubkey, // Prefixed with underscore to silence warning
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let account_iter = &mut accounts.iter();
let sender = next_account_info(account_iter)?;
let recipient = next_account_info(account_iter)?;
let system_program = next_account_info(account_iter)?;
let token_program = next_account_info(account_iter)?;
let token_account = next_account_info(account_iter)?;
let (transfer_type, amount) = parse_instruction_data(instruction_data)?;
match transfer_type {
TransferType::Sol => {
let transfer_instruction = system_instruction::transfer(
sender.key,
recipient.key,
amount,
);
msg!("Invoking transfer instruction...");
invoke(
&transfer_instruction,
&[
sender.clone(),
recipient.clone(),
system_program.clone(),
],
)?;
},
TransferType::Usdc => {
let transfer_instruction = token_instruction::transfer(
token_program.key,
token_account.key,
recipient.key,
sender.key,
&[&sender.key],
amount,
)?;
msg!("Invoking token transfer instruction...");
invoke(
&transfer_instruction,
&[
token_program.clone(),
token_account.clone(),
recipient.clone(),
sender.clone(),
],
)?;
},
}
Ok(())
}
enum TransferType {
Sol,
Usdc,
}
fn parse_instruction_data(data: &[u8]) -> Result<(TransferType, u64), ProgramError> {
if data.len() != 9 {
return Err(ProgramError::InvalidInstructionData);
}
let transfer_type = match data[0] {
0 => TransferType::Sol,
1 => TransferType::Usdc,
_ => return Err(ProgramError::InvalidInstructionData),
};
let amount = u64::from_le_bytes(data[1..].try_into().unwrap());
Ok((transfer_type, amount))
}
pub fn create_transfer_instruction(
sender_pubkey: &Pubkey,
recipient_pubkey: &Pubkey,
amount: u64,
) -> solana_program::instruction::Instruction {
solana_program::system_instruction::transfer(sender_pubkey, recipient_pubkey, amount)
}
I've been dealing with this error for two days. I have no idea what I'm doing, I'm following guides and chat-gpt.4o
I did the front end, then started having errors when trying to initiate a transaction so, I said "hey lets do rust then a circumvent this bug all together." like holy hell I'm so close to making this damn thing yet I'm having the most stupid unreversible bugs last minute and it's driving me crazy so PLEASE help.
please and thank you.