initial commit
This commit is contained in:
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "grin-finalize"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
warp = { version = "0.3", features = ["tls"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-rustls = "0.22"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
chrono = "0.4"
|
||||
simplelog = "0.11"
|
||||
log = "0.4"
|
44
finalize.py
Normal file
44
finalize.py
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Script Name: finalize.py
|
||||
Author: transatoshi
|
||||
Date Created: 2025-05-11
|
||||
Description: This script takes care of finalizing a Grin transaction via slatepack
|
||||
"""
|
||||
|
||||
|
||||
import pexpect
|
||||
import time
|
||||
|
||||
def run_grin_wallet():
|
||||
# Start the grin-wallet finalize command
|
||||
command = "/usr/local/bin/grin-wallet finalize"
|
||||
child = pexpect.spawn(command)
|
||||
|
||||
# Expect the password prompt and send the password
|
||||
child.expect("Password:")
|
||||
child.sendline("<password>")
|
||||
|
||||
# Expect the slatepack message prompt
|
||||
child.expect("Please paste your encoded slatepack message:")
|
||||
|
||||
# Read the contents of the slatepack file
|
||||
with open("/home/grin/grin-finalize/slatepack.tmp", "r") as file:
|
||||
slatepack_content = file.read()
|
||||
|
||||
# Send the contents of the slatepack file
|
||||
child.sendline(slatepack_content)
|
||||
|
||||
# Finalize by hitting return
|
||||
child.sendline()
|
||||
|
||||
# Wait for the command to complete
|
||||
child.expect(pexpect.EOF)
|
||||
|
||||
# Print the output
|
||||
print(child.before.decode('utf-8'))
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_grin_wallet()
|
103
src/main.rs
Normal file
103
src/main.rs
Normal file
@ -0,0 +1,103 @@
|
||||
// ... (other imports remain unchanged)
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
use log::{info, error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use simplelog::{Config, LevelFilter, ColorChoice, TermLogger, WriteLogger, CombinedLogger, TerminalMode};
|
||||
use warp::Filter;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SendRequest {
|
||||
slatepack: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Response {
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize logging
|
||||
let log_file = File::create("finalize.log").unwrap();
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed, ColorChoice::Auto),
|
||||
WriteLogger::new(LevelFilter::Info, Config::default(), log_file),
|
||||
]).unwrap();
|
||||
|
||||
// Define the POST route
|
||||
let send_finalize = warp::post()
|
||||
.and(warp::path("finalize"))
|
||||
.and(warp::body::json())
|
||||
.map(|request: SendRequest| {
|
||||
// Extract the slatepack message from the request
|
||||
let slatepack = request.slatepack;
|
||||
|
||||
// Write slatepack to a file
|
||||
let file_path = "/home/grin/grin-finalize/slatepack.tmp";
|
||||
if let Err(e) = write_to_file(file_path, &slatepack) {
|
||||
error!("Failed to write slatepack to file: {:?}", e);
|
||||
return warp::reply::json(&Response {
|
||||
message: "Failed to write slatepack to file".to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
// Execute the command
|
||||
let output = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(format!(
|
||||
"python /home/grin/grin-finalize/finalize.py"
|
||||
))
|
||||
.output()
|
||||
.expect("Failed to execute command");
|
||||
|
||||
// Process the command output
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
|
||||
// Check for specific error message
|
||||
if stderr.contains("Wallet command failed: LibWallet Error: Couldn't decrypt Slatepack: Could not decrypt slatepack with any provided index on the address derivation path") {
|
||||
return warp::reply::json(&Response {
|
||||
message: "Please receive the slatepack in your wallet then finalize that slatepack".to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
if stderr.is_empty() {
|
||||
info!("Transaction finalized: {}", stdout);
|
||||
return warp::reply::json(&Response {
|
||||
message: "Grin transaction successfully finalized ツ".to_string(),
|
||||
});
|
||||
} else {
|
||||
error!("Failed to finalize transaction: {}", stderr);
|
||||
return warp::reply::json(&Response {
|
||||
message: format!("Error: {}", stderr),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Load SSL keys and certs
|
||||
let cert_path = "/etc/ssl/cert.pem";
|
||||
let key_path = "/etc/ssl/cert.key";
|
||||
|
||||
// Enable CORS
|
||||
let cors = warp::cors()
|
||||
.allow_origin("https://spigot.grinminer.net")
|
||||
.allow_methods(vec!["POST"])
|
||||
.allow_headers(vec!["Content-Type"]);
|
||||
|
||||
// Start the Warp server with CORS and TLS
|
||||
warp::serve(send_finalize.with(cors))
|
||||
.tls()
|
||||
.cert_path(cert_path)
|
||||
.key_path(key_path)
|
||||
.run(([0, 0, 0, 0], 3032)) // Listen on all interfaces
|
||||
.await;
|
||||
}
|
||||
|
||||
// Function to write slatepack to a file
|
||||
fn write_to_file(file_path: &str, content: &str) -> std::io::Result<()> {
|
||||
let mut file = File::create(file_path)?;
|
||||
file.write_all(content.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
Reference in New Issue
Block a user