stellar / js-stellar-base

The lowest-level stellar helper library. It consists of classes to read, write, hash, and sign Stellar xdr
https://stellar.github.io/js-stellar-base/
Apache License 2.0
106 stars 138 forks source link

invalid encoding/decoding XDR in react-native #732

Closed divyangkhatri closed 5 months ago

divyangkhatri commented 6 months ago

Describe the bug Transaction builder does not encode/decode proper XDR base64 string in react-native. Due to this transaction API throw 400 "Transaction Malformed" error. I have read the note that only "JSC" and "V8" compiler will properly work. But in react-native greater than 70 it uses hermes engine. I have implemented "stellar-sdk": "^10.4.1" version in last December and at that time everyting was working. I faced issues in createWallet using this StellarHDWallet.fromMnemonic(mnemonic);. So, I updated to latest package. I checked the code in node-js and it is working fine.
Note this code return proper Buffer transaction.hash(); but this code does not return proper buffer transaction.toEnvelope().v1().toXDR('raw');

What version are you on? stellar-base: @stellar/js-xdr= ^3.1.0 @stellar/stellar-base = ^11.0.0 @stellar/stellar-sdk=^11.2.2 react-native: 0.72.7

To Reproduce Use following code to reproduce

const StellarSdk = require('@stellar/stellar-sdk');

async function main({to, from, amount, privateKey}) {
  try {
    const stellarProvider = new StellarSdk.Horizon.Server(
      'https://horizon-testnet.stellar.org',
    );
    const fee = await stellarProvider.fetchBaseFee();
    const sourceKeypair = StellarSdk.Keypair.fromSecret(privateKey);
    const sourceAccount = await stellarProvider.loadAccount(from);
    const transaction = new StellarSdk.TransactionBuilder(sourceAccount, {
      fee,
      networkPassphrase: StellarSdk.Networks.TESTNET,
    })
      // Add a payment operation to the transaction
      .addOperation(
        StellarSdk.Operation.payment({
          destination: to,
          asset: StellarSdk.Asset.native(),
          amount: amount?.toString(),
        }),
      )
      .setTimeout(30)
      .build();
    const hashBuffer = transaction.hash();
    console.log('hash buffer', hashBuffer);
    console.log('hash buffer hex', hashBuffer.toString('hex'));
    const buffer = transaction.toEnvelope().v1().toXDR('raw');
    console.log('final  buffer', buffer);
    console.log('final  buffe hex', buffer.toString('hex'));
    transaction.sign(sourceKeypair);
    console.log('dsadsa', buffer.toString('hex'));
    const isValid = StellarSdk.xdr.TransactionEnvelope.isValid(
      transaction.toEnvelope(),
    );
    console.log('is vlaid', isValid);
    const transactionResult = await stellarProvider.submitTransaction(
      transaction,
    );
    return transactionResult?.hash;
  } catch (e) {
    console.error('Error in send stellar transaction', e);
    console.error('Error in send stellar transactions', e.stack);
    console.error('Error in send stellar transactions', JSON.stringify(e));
  }
}
main({
  privateKey: $VALID_PRIVATE_KEY,
  from: $VALID_FROM_ADDRESS,
  to: $VALID_TO_ADDRESS,
  amount: '100',
});

Expected behavior encode or decode XDR should return the proper base64

overcat commented 6 months ago

Please check https://github.com/stellar/js-xdr/issues/117

overcat commented 6 months ago

Depending on how you load the stellar-sdk, if you are using a browser, you will need to wait for a new version to be released. If it is introduced in another way, you can patch the Buffer as shown here, which should solve your problem.

Shaptic commented 5 months ago

This should be solved by v11.0.1 (npm)! :+1: