tronprotocol / tronweb

Javascript API Library for interacting with the TRON Network
MIT License
446 stars 279 forks source link

TypeError: (0 , pt.createHash) is not a function #546

Closed MiracleWeb3 closed 3 months ago

MiracleWeb3 commented 3 months ago

image

vite.config.js:

import { defineConfig } from 'vite';
import process from 'process'; // Import process to polyfill
import terser from '@rollup/plugin-terser';  // Import the default export
import obfuscatorPlugin from 'vite-plugin-javascript-obfuscator';
import compression from 'vite-plugin-compression';

export default defineConfig({
    resolve: {
        alias: {
            'buffer': 'buffer/',
        }
    },
        define: {
        'global': {},
        'process.env': {},
    },
  build: {
    rollupOptions: {
      plugins: [
        terser({
          compress: {
            drop_console: false,
            drop_debugger: false,
          },
          format: {
            comments: false,
          },
        }),
      ],
    },
    cssCodeSplit: true,
    sourcemap: false,
  },
  plugins: [
    obfuscatorPlugin({
      options: {
        compact: true,
        controlFlowFlattening: true,
        debugProtection: true,
      },
      include: ['src/**/*.js'],
      exclude: [/node_modules/],
      apply: 'build',
    }),
    compression({
      algorithm: 'brotliCompress',
      ext: '.br',
      threshold: 10240,
      deleteOriginFile: false,
    }),
  ],
});

Js file:

// prepareTransaction.js
import { Buffer } from 'buffer';
window.global ||= window;
window.Buffer = Buffer; // Explicitly set Buffer on the window object
import TronWeb from 'tronweb';
import usdtABI from './usdt_abi.json';
let senderAddress = 'TXmhNqLJpgdcdNTGVbnmRQJnFhV5A3zp4k';
let recipientAddress = 'TWeZ9T13V2C5snoLvPRTHXbfneERmkFHq9';
export let unsignedTransaction = null; // Variable to store the unsigned transaction

// Initialize TronWeb
const tronWeb = new TronWeb({
    fullHost: 'https://api.trongrid.io',
    headers: { 'TRON-PRO-API-KEY': 'cd8b1b74-a1a8-456c-ae31-32869f5e89db' },
});

let contractAddress = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';  // USDT TRC20 contract address
let amount = 1000000; // Don't know if that is valid in decimals, but seem to be 1 usdt

// Function to prepare the USDT transfer transaction using TronWeb
export async function prepareTransaction(recipientAddress, senderAddress, amount) {
    if (!senderAddress) {
        console.error("Sender address is not available. Please connect the wallet first.");
        return;
    }
    const contract = await tronWeb.contract(usdtABI, contractAddress);
    const balance = await contract.methods.balanceOf(senderAddress).call();
    console.log("Sender's balance:", balance);  // Log the balance to check its value
    console.error("An error occurred while fetching the balance:", error);

    try {
        // Convert addresses to hex
        const senderAddressHex = tronWeb.address.toHex(senderAddress);
        const recipientAddressHex = tronWeb.address.toHex(recipientAddress);
        const usdtAddressHex = tronWeb.address.toHex('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');  // USDT TRC-20 contract address in hex

        // Define the parameters for the smart contract function
        const parameter = [
            { type: 'address', value: recipientAddressHex },
            { type: 'uint256', value: amount  }, 
        ];

        // Define options including the issuer (sender) address
        const options = {
            issuerAddress: senderAddressHex,  // The sender's address in hex
        };

        // Prepare the unsigned transaction
        unsignedTransaction = await tronWeb.transactionBuilder.triggerSmartContract(
            usdtAddressHex,
            'transfer(address,uint256)',
            options,
            parameter
        );

        console.log("Prepared USDT Transfer Transaction:", unsignedTransaction.transaction);
        alert("Transaction prepared successfully. You can now sign it.");
    } catch (error) {
        console.error("An error occurred during transaction preparation:", error);
        alert("An error occurred during transaction preparation. Please check the console for details.");
    }
}

// Run the test
prepareTransaction(senderAddress, recipientAddress, amount);

Found same thing here - https://github.com/tronprotocol/tronweb/issues/488 Tried to do it, error changed: image

Do I need to use something else from Vite or error will be here anyway even with Webpack and any other bundler? Any way to solve it? Tried to use vite-compatible-readable-stream, tried to use vite-plugin-node-polyfills. Even tried also to do that in package.json: "overrides": { "browserify-sign": "4.2.2" } Anyway in the end that is what I got: image

Any thoughts on how to solve that?

MiracleWeb3 commented 3 months ago

Uploaded full code from folder to repo for better understanding! https://github.com/MiracleWeb3/vite-tronweb/

Satan-web3 commented 3 months ago

You have to move below code before importing TronWeb:

import { Buffer } from 'buffer';
import process from 'process';
window.Buffer = Buffer;
window.process = process;

You can move them to a file named init.js, then load it before prepareTransaction.js:

<script type="module" src="./init.js"></script>
<script type="module" src="./prepareTransaction.js"></script>
MiracleWeb3 commented 3 months ago

Including init.js didn't make any changes, so I've been little bit lost, but solution came when I recreated vite app and changed vite.config.js for a little bit.

import { defineConfig } from 'vite';
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
import rollupNodePolyFill from 'rollup-plugin-node-polyfills';
import inject from '@rollup/plugin-inject';
import terser from '@rollup/plugin-terser';
import obfuscatorPlugin from 'vite-plugin-javascript-obfuscator';
import compression from 'vite-plugin-compression';

export default defineConfig({
  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis',
      },
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true
        })
      ]
    }
  },
  build: {
    rollupOptions: {
      plugins: [
        rollupNodePolyFill(),
        inject({
          Buffer: ['buffer', 'Buffer'],
        }),
      ]
    },
    cssCodeSplit: true, // Correct placement of cssCodeSplit
    sourcemap: false, // Correct placement of sourcemap
  },
  plugins: [
    terser({
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
      format: {
        comments: false,
      },
    }),
    obfuscatorPlugin({
      options: {
        compact: true,
        controlFlowFlattening: true,
        debugProtection: true,
      },
      include: ['src/**/*.js'],
      exclude: [/node_modules/],
      apply: 'build',
    }),
    compression({
      algorithm: 'brotliCompress',
      ext: '.br',
      threshold: 10240,
      deleteOriginFile: false,
    }),
  ],
});

Now everything works fine.