stellar / js-stellar-sdk

Main Stellar client library for the JavaScript language.
https://stellar.github.io/js-stellar-sdk/
Apache License 2.0
641 stars 312 forks source link

Issue txMalformed #1007

Open quankori opened 4 months ago

quankori commented 4 months ago

I have a code example. I tried the same document, but I still got an issue: Transaction successful: {"status":"ERROR","hash":"9a707f5b4f49b35313c6ed26cf2f3988a7cf9f06baf124c6e802db37996694f7","latestLedger":496366,"latestLedgerCloseTime":"1720750899","errorResult":{"_attributes":{"feeCharged":{"_value":"0"},"result":{"_switch":{"name":"txMalformed","value":-16}},"ext":{"_switch":0}}}}

I don't know if it is a bug or an issue in my code :(( I used stellar-sdk version 12.1.0 and node version 22.3.0

import {
  TransactionBuilder,
  Keypair,
  BASE_FEE,
  TimeoutInfinite,
  Contract,
  Address,
  scValToNative,
  SorobanRpc,
  xdr,
  nativeToScVal,
  Networks,
} from 'stellar-sdk';
import StellarHDWallet from 'stellar-hd-wallet';
try {
    const wallet = StellarHDWallet.fromMnemonic('passphare');

    // Derive key pair
    const keyPair = Keypair.fromSecret(wallet.getSecret(0));

    // const keyPair = Keypair.fromRawEd25519Seed(derivedKey.privateKey);
    console.log('Public key:', keyPair.publicKey());
    // Get the source keypair
    console.log('Source keypair loaded:', keyPair.publicKey());

    // Load the source account
    const account = await server.getAccount(keyPair.publicKey());
    console.log('Source account loaded:', account.accountId());

    // Create a transaction builder
    const transactionBuilder = new TransactionBuilder(account, {
      fee: BASE_FEE,
      networkPassphrase: Networks.TESTNET,
    });

    const contract = new Contract('SMART_CONTRACT_ADDRESS');
    // Add the operation to the transaction
    transactionBuilder.addOperation(
      contract.call(
        'set_user',
        new Address(wallet_address).toScVal(),
        nativeToScVal(WalletStatusEnum.APPROVED, { type: 'u32' }),
      ),
    );
    console.log('Operation added to the transaction');

    // Set timeout
    transactionBuilder.setTimeout(TimeoutInfinite);

    // Build the transaction
    const tx = transactionBuilder.build();

    // Sign the transaction
    tx.sign(keyPair);
    console.log('Transaction built:', JSON.stringify(tx));

    // Check if signatures are properly added
    if (!tx.signatures || tx.signatures.length === 0) {
      throw new Error('Transaction not signed correctly');
    }
    const transactionXDR = tx.toEnvelope().toXDR('base64');
    console.log('Transaction XDR:', transactionXDR);
    // Submit the transaction
    const sendResponse = await server.sendTransaction(tx);
    console.log('Transaction successful:', JSON.stringify(sendResponse));
    if (sendResponse.status === 'PENDING') {
      let txResponse = await server.getTransaction(sendResponse.hash);

      // Poll this until the status is not "NOT_FOUND"
      while (txResponse.status === 'NOT_FOUND') {
        // See if the transaction is complete
        txResponse = await server.getTransaction(sendResponse.hash);
        // Wait a second
        await new Promise((resolve) => setTimeout(resolve, 1000));
      }

      return sendResponse.hash;
    } else {
      throw new Error(
        `Unabled to submit transaction, status: ${sendResponse.status}`,
      );
    }
  } catch (error) {
    console.error('Error preparing or sending transaction:', error?.message);
    throw error;
  }
janewang commented 3 months ago

This error usually has to do the fees for this transaction is not sufficient.

More about the txMalformed error here: https://developers.stellar.org/docs/learn/encyclopedia/errors-and-debugging/debugging-errors#2-core-accepts-the-transaction

To be clear, the transaction is not successful.