How to sign a Solana Raydium swap? - rust

I am getting a NotEnoughSigners error using amm_instruction::swap_base_in() for Raydium swap in Solana (https://github.com/raydium-io/raydium-contract-instructions). What am I doing wrong here? As far as I can tell, one signer is required and one is being submitted, but I get a NotEnoughSigners error.
// pubkey
use std::{str::FromStr};
use solana_program::{pubkey, pubkey::Pubkey};
// rpc
use solana_client::rpc_client::RpcClient;
mod amm_instruction;
fn main() {
// pool info
let program_id: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
let amm_id: Pubkey = pubkey!("58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2");
let amm_authority: Pubkey = pubkey!("5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1");
let amm_open_orders: Pubkey = pubkey!("HRk9CMrpq7Jn9sh7mzxE8CChHG8dneX9p475QKz4Fsfc");
let amm_target_orders: Pubkey = pubkey!("CZza3Ej4Mc58MnxWA385itCC9jCo3L1D7zc3LKy1bZMR");
let pool_coin_token_account: Pubkey = pubkey!("DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz");
let pool_pc_token_account: Pubkey = pubkey!("HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz");
let serum_program_id: Pubkey = pubkey!("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin");
let serum_market: Pubkey = pubkey!("9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT");
let serum_bids: Pubkey = pubkey!("14ivtgssEBoBjuZJtSAPKYgpUK7DmnSwuPMqJoVTSgKJ");
let serum_asks: Pubkey = pubkey!("CEQdAFKdycHugujQg9k2wbmxjcpdYZyVLfV9WerTnafJ");
let serum_event_queue: Pubkey = pubkey!("5KKsLVU6TcbVDK4BS6K1DGDxnh4Q9xjYJ8XaDCG5t8ht");
let serum_coin_vault_account: Pubkey = pubkey!("36c6YqAwyGKQG66XEp2dJc5JqjaBNv7sVghEtJv4c7u6");
let serum_pc_vault_account: Pubkey = pubkey!("8CFo8bL8mZQK8abbFyypFMwEDd8tVJjHTTojMLgQTUSZ");
let serum_vault_signer: Pubkey = pubkey!("F8Vyqk3unwxkXukZFQeYyGmFfTG3CAX4v24iyrjEYBJV");
let uer_source_token_account: Pubkey = pubkey!("AgzZJAiniqwX4MAkf7KGuza4oYk5XNBHUZ4XZeca7osC");
let uer_destination_token_account: Pubkey = pubkey!("ENJH5ho47pbHmMcoerGtRywQpkcbtWtnCfsKdHesf5E5");
let user_source_owner: Pubkey = pubkey!("FBH3xoEVNF85pkmpfsgevyTW9ewtL2M1xuHzJwaxdLm5");
let amount_in: u64 = 1_000_000;
let minimum_amount_out: u64 = 10_321_182;
// connect to cluster
//let url = "https://api.mainnet-beta.solana.com".to_string();
let url = "https://api.devnet.solana.com".to_string();
let rpc_client = RpcClient::new(url);
let latest_blockhash = rpc_client.get_latest_blockhash().unwrap();
let alice = solana_sdk::signer::keypair::read_keypair_file("/Users/Me/.config/solana/id.json").unwrap();
let swap_instructions = amm_instruction::swap_base_in(
&program_id,
&amm_id,
&amm_authority,
&amm_open_orders,
&amm_target_orders,
&pool_coin_token_account,
&pool_pc_token_account,
&serum_program_id,
&serum_market,
&serum_bids,
&serum_asks,
&serum_event_queue,
&serum_coin_vault_account,
&serum_pc_vault_account,
&serum_vault_signer,
&uer_source_token_account,
&uer_destination_token_account,
&user_source_owner,
amount_in,
minimum_amount_out
).unwrap();
let payer: Option<Pubkey> = Some(solana_program::pubkey::Pubkey::from_str("5C8rbEJUuLR2nTkEqiyjzmyBtxAiseS2Aoq7YU3c8cgL").unwrap());
let tx = solana_sdk::transaction::Transaction::new_signed_with_payer(&[swap_instructions], payer.as_ref(), &[&alice], latest_blockhash);
let signature = rpc_client.send_and_confirm_transaction(&tx);
println!("swap: {:?}",signature);
}

If you look at the code that you linked, you'll see that this instruction expects only one signature from user_source_owner: https://github.com/raydium-io/raydium-contract-instructions/blob/cbd7affe245166f7baceb7e68d123220e0fcd331/amm_instruction.rs#L594
This means that your transaction must be declared as:
let payer = Keypair::from_bytes(<INSERT_BYTES_HERE>); // this must be a some Signer in order to be declared as a payer, so use whichever method you need to get that keypair
let user_source_owner = Keypair::form_bytes(<PUT_BYTES_HERE>); // same here
let tx = solana_sdk::transaction::Transaction::new_signed_with_payer(&[swap_instructions], Some(&payer.pubkey()), &[&payer, &user_source_owner], latest_blockhash);

Related

Rust openssl rsa OAEP Padding not working

I am playing around with RSA encryption and I have just been using the standard PCKS1 padding which works fine, but I would like to use the more advanced OAEP or PSS Padding schemes. But for some reason when I switch the constant from PCKS1 to PKCS1_OAEP, it compiles but I get a run-time error. Which implies to me that the functionality is there but I am doing something wrong.
Here's my code
use openssl::{rsa::{Rsa, Padding}, symm::Cipher};
use bincode;
fn main() {
let rsa = Rsa::generate(512).unwrap();
let password = "password";
let source = "hello paul".to_string();
let data = bincode::serialize(&source).unwrap();
let private = rsa.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), password.as_bytes()).unwrap();
//encrypt
let private_key = Rsa::private_key_from_pem_passphrase(&private, password.as_bytes()).unwrap();
let mut enc_data = vec![0; private_key.size() as usize];
match private_key.private_encrypt(&data, &mut enc_data, Padding::PKCS1_OAEP) {
Ok(_) => {},
Err(e) => {
println!("{e}");
return;
}
}
}
and my Cargo.toml dependencies
[dependencies]
openssl-sys = "0.9.79"
openssl = "0.10.44"
chrono = "0.4"
bincode = "1.0"
serde = { version = "1.0", features = ["derive"] }
and here is the error I am getting.
error:04066076:rsa routines:rsa_ossl_private_encrypt:unknown padding type:crypto/rsa/rsa_ossl.c:273:
So I am getting this from this resource(https://docs.rs/openssl/latest/openssl/rsa/struct.Padding.html#associatedconstant.PKCS1_OAEP)
I ahve also tried it with PKCS1_PSS and get the same error.
Does anyone know whats up, maybe they never actually finished OAEP or PSS, or is there something wrong on my end? Maybe I need to use a different Cipher than aes_128_cbc? Thanks for reading any help is appreciated.

DISCORD.JS own.map is not a function

Heyy, I want to make an owner command with embed, my script is simple to understand but I have an error with the description the embed, I don't know why, there is my code:
let own = await db.get(`${process.env.owner}.owner`)
let ownc = await db.get(`${process.env.owner}.ownercount`)
if(ownc === null|| "Nan" )ownc=1
let p0 = 0;
let p1 = 30;
let page = 1;
let embed = new Discord.MessageEmbed()
embed.setTitle("Owner")
.setColor(color)
.setDescription(!own ? "None":own.map((user, i) => `[${i}] <#${user}>`).slice(0, 30).join("\n")
)
.setFooter(`${page}/${Math.ceil(ownc||1/ 30)} • ${footer}`)
message.channel.send(embed)
Version of discord.js: 12.5.3
Module for db: #turph/quickmongo
Database: MongoDB

Create web_sys::RtcPeerConnection with customized configuration

I am trying to figure how to create a RtcPeerConnection with the web-sys crate. In JavaScript I can write the following:
const pc = new RTCPeerConnection({'iceServers': [{'urls': ['stun:stun.l.google.com:19302']}]});
How does this translate to rust? I have tried the following:
let mut rtc = RtcConfiguration::new();
let config = RtcConfiguration::ice_servers(&mut rtc, &JsValue::from_serde(&json!({"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]})).unwrap());
let pc = RtcPeerConnection::new_with_configuration(&config).unwrap();
But it fails when creating pc. The json! macro is from serde_json::json.
For anyone with the same issue, the following works:
let mut rtc = RtcConfiguration::new();
let config = rtc.ice_servers(&JsValue::from_serde(&json!([{"urls": "stun:stun.l.google.com:19302"}])).unwrap());
let pc = RtcPeerConnection::new_with_configuration(&config).unwrap();

Rust: Thread panics when run inside an iframe but not in a regular browser tab

I'm playing around with building an app on Zendesk using Rust. Below is a server-side rust function that gets called in a route
pub fn oktaredirectprocessor(mut cookies: Cookies, code: String, state: String) -> bool {
let cookie_state_string = cookies.get_private("state").unwrap().value().to_string();
println!("cookie retrieved in oktaredirectprocessor is {}", cookie_state_string);
if state != cookie_state_string {
debug!("State did not match");
false
}else if code == ""{
debug!("Code is empty");
false
}else{
let oktarequest: Oktarequest = Oktarequest::new();
let http = reqwest::Client::new();
let config = oidc::discovery::discover(&http, oktarequest.issuer).expect("error in config-discovery-oidc");
let jwks = oidc::discovery::jwks(&http, config.jwks_uri.clone()).expect("error in jwks-discovery-oidc");
let provider = oidc::discovery::Discovered(config);
let client = oidc::Client::new(oktarequest.id, oktarequest.secret, oktarequest.redirect, provider, jwks);
let mut token = client.request_token(&http, code.as_str()).expect("error in request token-oidc");
client.decode_token(&mut token.id_token).expect("error in decode token oidc");
client.validate_token(&token.id_token, Some(cookies.get_private("nonce").unwrap().value()), None).expect("error in validate token oidc"); cookies.add_private(Cookie::new("access_token", token.access_token().to_string()));
true
}
}
It works when I run localhost directly from a browser tab. However, the thread panics if I run the app from inside Zendesk. Below is the backtrace. I'm a novice coder and don't understand it entirely.
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:214:60
stack backtrace:
0: rust_begin_unwind
at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/std/src/panicking.rs:493:5
1: core::panicking::panic_fmt
at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/panicking.rs:92:14
2: core::panicking::panic
at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/panicking.rs:50:5
3: core::option::Option<T>::unwrap
at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/option.rs:386:21
4: app_remote::oktaredirecthandler
at ./src/main.rs:214:28
5: app_remote::rocket_route_fn_oktaredirecthandler
at ./src/main.rs:213:4
6: core::ops::function::Fn::call
at /rustc/7efc097c4fe6e97f54a44cee91c56189e9ddb41c/library/core/src/ops/function.rs:70:5
7: <F as rocket::handler::Handler>::handle
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/handler.rs:177:9
8: rocket::rocket::Rocket::route
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:296:27
9: rocket::rocket::Rocket::route_and_process
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:242:34
10: rocket::rocket::Rocket::dispatch
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:217:28
11: <rocket::rocket::Rocket as hyper::server::Handler>::handle
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.5/src/rocket.rs:82:24
12: hyper::server::Worker<H>::keep_alive_loop
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/mod.rs:340:13
13: hyper::server::Worker<H>::handle_connection
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/mod.rs:282:15
14: hyper::server::handle::{{closure}}
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/mod.rs:242:34
15: hyper::server::listener::spawn_with::{{closure}}
at /Users/nalinnarayan/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.10.16/src/server/listener.rs:50:31
Weirdly, the problematic "cookies.get_private("state").unwrap()" works in another function even when run inside Zendesk. Below is the function where it works
fn oktalogin(mut cookies: Cookies) -> Redirect {
let oktarequest: Oktarequest = Oktarequest::new();
cookies.add_private(Cookie::new("state", oktarequest.state.clone()));
cookies.add_private(Cookie::new("nonce", oktarequest.nonce.clone()));
println!("stored state cookie from random gen is: {}", cookies.get_private("state").unwrap().value().to_string());
let http = reqwest::Client::new();
let config = oidc::discovery::discover(&http, oktarequest.issuer).expect("error in config-discovery-oidc");
let jwks = oidc::discovery::jwks(&http, config.jwks_uri.clone()).expect("error in jwks-discovery-oidc");
let provider = oidc::discovery::Discovered(config);
let client = oidc::Client::new(oktarequest.id, oktarequest.secret, oktarequest.redirect, provider, jwks);
let options = Options{
scope: Some("openid profile email".to_string()),
state: Some(oktarequest.state.clone()),
nonce: Some(oktarequest.nonce.clone()),
..Default::default()
};
let auth_url = client.auth_url(&options);
Redirect::to(auth_url.into_string())
}
My cargo.toml
[dependencies]
rocket = { version = "0.4.5", features = ["private-cookies"] }
rocket_codegen = "0.4.5"
serde = "1.0.116"
serde_derive = "1.0.116"
diesel = { version = "1.4.5", features = ["postgres"] }
dotenv = "0.15.0"
serde_urlencoded = "0.7.0"
oidc = "0.3.0"
ring = "=0.16.15"
log = "0.4.8"
rand = "0.7.3"
reqwest = "=0.9.24"
inth-oauth2 = "0.16.0"
url = "=1.7.2"
serde_json = "1.0"
console_log = { version = "0.2", features = ["color"] }
[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["tera_templates", "json"]
Why it worked in localhost was that cookie remained. To work correctly needs to add code when cookie doesn't exist, without unwrap().
let cookie_state_string = match cookies.get_private("state") {
Ok(v) => v.value().to_string(),
Err(_) => return false,
};

How to push the file to TFS using azure-devops-node-api library in NodeJS?

I'm trying to push the files to repository in Azure Repos. I'm using azure-devops-node-api library to connect and push the file to the repository. I'm beginner in NodeJS. Please find the below code. I'm not sure how to proceed further.
Please help!
const orgUrl = "https://dev.azure.com/orgname";
const azure = require('azure-devops-node-api');
var accessToken = "ACCESS_TOKEN";
var authHandler = azure.getPersonalAccessTokenHandler(accessToken);
var connection = new azure.WebApi(orgUrl, authHandler);
connection.getGitApi().then( gitapi1 => {
// I don't know how to use gitapi1 to commit and push the file
});
How to push the file to TFS using azure-devops-node-api library in NodeJS?
To push the files to repository in Azure Repos, we could use the git.createPush to push the code to the repository in Azure Repos. To use the git.createPush, we need to get the repostoryId. You can check below sample demo for some more details:
import * as azdev from "azure-devops-node-api";
import * as gitclient from "azure-devops-node-api/GitApi"
//import { GitRepository } from 'azure-devops-node-api/interfaces/TfvcInterfaces';
import { GitRepository, GitPush,GitCommitRef,GitCommit, GitChange, ItemContent, GitItem, GitRefUpdate } from 'azure-devops-node-api/interfaces/GitInterfaces';
let orgUrl = 'https://dev.azure.com/yourorg'
let repostories:GitRepository[];
let token: string = "PATTokne";//patToken
let project:string = 'projectName'
let repostoryName = 'repostoryName';
let authHandler = azdev.getPersonalAccessTokenHandler(token);
let connection = new azdev.WebApi(orgUrl, authHandler);
let file:string = 'C:\\Users\\xxx\\typescript-node\\test.png';
let refName:string = 'refs/heads/master';
var fs = require('fs');
var base64str = base64_encode(file);
console.log(base64str);
// function to encode file data to base64 encoded string
function base64_encode(filePath:string) {
// read binary data
var bitmap = fs.readFileSync(file);
// convert binary data to base64 encoded string
return new Buffer(bitmap).toString('base64');
}
async function run(filePath:string,refName:string,project:string,repostoryName:string)
{
let git:gitclient.IGitApi = await connection.getGitApi();
repostories = await git.getRepositories(project);
let gitrepo = repostories.find(element => element.name === repostoryName);
let repostoryId = gitrepo?.id;
let gitChanges:GitChange[] = [<GitChange>{
changeType:1,
newContent:<ItemContent>{content:base64str,contentType:1 }, //0-> RawText = 0, Base64Encoded = 1,
item:<GitItem>{
path:'/testUpdate.png'
}
}];
if(typeof(repostoryId) ==="string")
{
let ref = (await git.getRefs(repostoryId,project)).find(element => element.name === refName)
let refUpdates:GitRefUpdate[] = [<GitRefUpdate> {
name:ref?.name,
oldObjectId:ref?.objectId //get ref->object id
}];
let gitCommitRef:GitCommitRef[] = [
<GitCommitRef>{
changes:gitChanges,
comment:'Add a file'
}
]
let gitPush:GitPush = <GitPush>{
commits:gitCommitRef,
refUpdates:refUpdates,
repository:gitrepo
};
console.log(repostoryId)
await git.createPush(gitPush,repostoryId,project);
}
}
run(file,refName,project,repostoryName);
console.log("test");
Hope this helps.

Resources