Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wallet V5R1 Error When Sending Transaction #9

Open
NicklausFW opened this issue Jan 15, 2025 · 9 comments
Open

Wallet V5R1 Error When Sending Transaction #9

NicklausFW opened this issue Jan 15, 2025 · 9 comments

Comments

@NicklausFW
Copy link

NicklausFW commented Jan 15, 2025

When i use:

use base64::{engine::general_purpose::STANDARD as Base64Standard, Engine};
use chrono::{Duration, Utc};
use dotenvy::dotenv;
use num_bigint::BigUint;
use num_traits::FromPrimitive;
use reqwest::Client;
use serde_json::json;
use std::{env, str::FromStr, sync::Arc};
use toner::{
    contracts::wallet::{mnemonic::Mnemonic, v5r1::V5R1, Wallet},
    tlb::{bits::ser::pack_with, ser::CellSerializeExt},
    ton::{
        action::SendMsgAction,
        boc::{BagOfCells, BagOfCellsArgs},
        message::Message,
    },
};

pub async fn wallet_transfer_controller() -> Result<String, String> {
    // Load environment variables
    dotenv().ok();

    // Parse the mnemonic
    let mnemonic_phrase = env::var("MNEMONIC").map_err(|_| "MNEMONIC environment variable is not set".to_string())?;
    let mnemonic = Mnemonic::from_str(&mnemonic_phrase).map_err(|e| format!("Error parsing mnemonic: {}", e))?;
    println!("Mnemonic parsed successfully.");

    // Generate the keypair and derive the wallet
    let keypair = mnemonic.generate_keypair(None).map_err(|e| format!("Error generating keypair: {}", e))?;
    println!("Keypair generated.");

    let wallet = Wallet::<V5R1>::derive(0, keypair, 0x7FFFFF11).map_err(|e| format!("Error deriving wallet: {}", e))?;
    println!("Wallet derived: {}", wallet.address());

    // Fetch the current seqno from TON API
    let client = Client::new();
    let api_key = env::var("TON_API_KEY").map_err(|_| "TON_API_KEY environment variable is not set".to_string())?;
    let response = client
        .get(format!(
            "https://testnet.toncenter.com/api/v2/getWalletInformation?address={}&api_key={}",
            wallet.address(), api_key
        ))
        .send()
        .await
        .map_err(|e| format!("Error fetching wallet information: {}", e))?;

    if !response.status().is_success() {
        return Err(format!("Error from TON API: {:?}", response.text().await.unwrap()));
    }

    let wallet_info = response.json::<serde_json::Value>().await.map_err(|e| format!("Error parsing wallet info response: {}", e))?;
    println!("Wallet info: {:?}", wallet_info);

    let seqno = wallet_info["result"]["seqno"]
        .as_u64()
        .ok_or_else(|| "Seqno not found in response".to_string())?;
    println!("Fetched seqno: {}", seqno);

    // Prepare the transfer
    let destination_address = "SOME RANDOM DESTINATION ADDRESS"
        .parse()
        .map_err(|_| "Invalid destination address".to_string())?;
    let amount = BigUint::from_u64(10_000_000u64).unwrap(); // 10,000,000 nanoTON

    println!("Sending transaction to address: {}", destination_address);
    println!("Amount to send: {}", amount);

    let transfer_action = SendMsgAction {
        mode: 3,
        message: Message::transfer(destination_address, amount, false)
            .normalize()
            .map_err(|e| format!("Error normalizing message: {}", e))?,
    };

    let expire_at = Utc::now() + Duration::hours(1);

    let external_message = wallet
        .create_external_message(
            expire_at,
            seqno.try_into().map_err(|_| "Seqno exceeds u32 range".to_string())?,
            vec![transfer_action],
            true,
        )
        .map_err(|e| format!("Error creating transaction: {}", e))?;

    let root_cell = external_message.to_cell().map_err(|e| format!("Error converting to cell: {}", e))?;

    // Serialize the external message to a BOC
    let boc = BagOfCells::from_root(Arc::new(root_cell));
    let packed = pack_with(
        boc,
        BagOfCellsArgs {
            has_idx: false,
            has_crc32c: false,
        },
    )
    .map_err(|e| format!("Error serializing BOC: {}", e))?;

    // Log the packed BOC
    println!("Packed BOC: {:?}", packed);

    // Convert the packed data to raw bytes and encode as base64
    let boc_bs64 = Base64Standard.encode(packed.as_raw_slice());
    println!("Base64 BOC: {}", boc_bs64);

    // Submit the BOC to the TON network
    let response = client
        .post("https://testnet.toncenter.com/api/v3/sendBocReturnHash")
        .json(&json!({ "boc": boc_bs64 }))
        .send()
        .await
        .map_err(|e| format!("Error sending message to network: {}", e))?;

    if response.status().is_success() {
        let response_body = response.json::<serde_json::Value>().await.unwrap();
        Ok(format!("Transaction sent successfully: {:?}", response_body))
    } else {
        Err(format!("Error from TON network: {:?}", response.text().await.unwrap()))
    }
}

I got error:

{
  "ok": false,
  "error": "LITE_SERVER_UNKNOWN: cannot apply external message to current state : External message was not accepted\nCannot run message on account: inbound external message rejected by transaction B0155BBFB7E37BC7C0EEDC17742B48517A2352CDDF4F71C6042087165E6B70D0:\nexitcode=135, steps=45, gas_used=0\nVM Log (truncated):\n...HG s10\nexecute HASHSU\nexecute XCHG3 s0,s12,s12\nexecute CHKSIGNU\nexecute PUSHCONT x28945F0ADB31E1F2C087\nexecute IFNOT\nexecute PUSH s8\nexecute PUSHCONT x5F0ADB31\nexecute IFNOTJMP\nexecute THROW 135\ndefault exception handler, terminating vm with exit code 135\n",
  "code": 500
}
@NicklausFW
Copy link
Author

NicklausFW commented Jan 15, 2025

It seems 135 means invalid signature, is there an issue with my code?
@akostylev0 @mitinarseny

Repository owner deleted a comment Jan 15, 2025
@NicklausFW
Copy link
Author

I think this repo has an issue regarding transaction for V5R1 wallet

@NicklausFW
Copy link
Author

NicklausFW commented Jan 15, 2025

Because it works with V4R2, but not with V5R1

@NicklausFW
Copy link
Author

I wasn't able to send Ton using V5R1 wallet

Repository owner deleted a comment Jan 16, 2025
Repository owner deleted a comment Jan 16, 2025
Repository owner deleted a comment Jan 16, 2025
Repository owner deleted a comment from NicklausFW Jan 16, 2025
Repository owner deleted a comment Jan 16, 2025
Repository owner deleted a comment Jan 16, 2025
Repository owner deleted a comment from NicklausFW Jan 16, 2025
Repository owner deleted a comment Jan 16, 2025
Repository owner deleted a comment Jan 16, 2025
@mitinarseny
Copy link
Owner

mitinarseny commented Jan 16, 2025

Hey @NicklausFW ! I haven't really tested V5R1 wallet version yet, so there can be some inconsistency in its TLB-serialization. Please, check that your wallet address matches the one generated by toner

@NicklausFW
Copy link
Author

NicklausFW commented Jan 18, 2025

Hi @mitinarseny , thank you for answering!

When i use "Wallet::derive(0, keypair, 0x7FFFFF11)" (not the derive_default)

The address matches https://ton-address-converter.com/ and the telegram wallet bot

So i'm confused why the code works when i use V4R2 and not the V5R1.

@mitinarseny
Copy link
Owner

I see, DEFAULT_WALLET_ID seems to be different for each wallet version.

Please, feel free to create PR, I appreciate your contribution!

@NicklausFW
Copy link
Author

NicklausFW commented Jan 18, 2025

I have made the pull request for the derive_default @mitinarseny

@NicklausFW
Copy link
Author

NicklausFW commented Jan 18, 2025

Hey @NicklausFW ! I haven't really tested V5R1 wallet version yet, so there can be some inconsistency in its TLB-serialization. Please, check that your wallet address matches the one generated by toner

So will there be a future fix for the V5R1? @mitinarseny

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants