toncenter / tonweb

JavaScript SDK for TON (The Open Network)
MIT License
432 stars 107 forks source link

oneFromBoc is not working because isomorphic-webcrypto is not defined in nextjs #122

Open samyarkd opened 6 months ago

samyarkd commented 6 months ago

The oneFromBoc is not working as expected and returns an error

⨯ TypeError: Cannot read properties of undefined (reading 'digest')
    at sha256 (webpack-internal:///(rsc)/../../node_modules/tonweb/src/utils/Utils.js:19:32)
    at Cell.hash (webpack-internal:///(rsc)/../../node_modules/tonweb/src/boc/Cell.js:130:37)
    at async Cell.getRepr (webpack-internal:///(rsc)/../../node_modules/tonweb/src/boc/Cell.js:118:28)
    at async Cell.hash (webpack-internal:///(rsc)/../../node_modules/tonweb/src/boc/Cell.js:130:44)
    at async bocToTransactionHash (webpack-internal:///(rsc)/../../libs/shared/src/lib/ton.ts:30:84)

const BN = require("bn.js");
const nacl = require("tweetnacl");
const ethunit = require("ethjs-unit");

const isCryptoAvailable = typeof self !== 'undefined' && self.crypto && self.crypto.subtle;

let myCrypto = null;

if (isCryptoAvailable) { // web
    // nothing to do
} else { // nodejs or react-native
    myCrypto = require('isomorphic-webcrypto');
}

/**
 * @param bytes {Uint8Array}
 * @return  {Promise<ArrayBuffer>}
 */
function sha256(bytes) {
    if (isCryptoAvailable) { // web
        return crypto.subtle.digest("SHA-256", bytes);
    } else {  // nodejs or react-native
        return myCrypto.subtle.digest({name:"SHA-256"}, bytes);
    }
}

the sha256 is where the error happens and it's mostlikely that is happening here

} else { // nodejs or react-native
    myCrypto = require('isomorphic-webcrypto');
}

Solution

we could fix it using an alternative that does the same but works in both nodejs and browser

samyarkd commented 6 months ago

here is a reproduction of the error (sandbox)

it looks like isomorphic-webcrypto does not work with NextJs server side

go to localhost:3000/api and check the terminal output for the error

in Nextjs we can just do const crypto = require('crypto') but I'm not sure if it's going to work in other environments too

Solution

I cloned the repo and used globalThis to fix this problem but based on the MDN docs it's supported in node 19 and higher

di-sukharev commented 3 months ago

same here

di-sukharev commented 3 months ago
FAILED_TO_CALL TypeError: Cannot read properties of undefined (reading 'digest')
    at sha256 (webpack-internal:///(rsc)/./node_modules/tonweb/src/utils/Utils.js:18:32)
    at Cell.hash (webpack-internal:///(rsc)/./node_modules/tonweb/src/boc/Cell.js:130:37)
    at async Cell.getRepr (webpack-internal:///(rsc)/./node_modules/tonweb/src/boc/Cell.js:118:28)
    at async Cell.hash (webpack-internal:///(rsc)/./node_modules/tonweb/src/boc/Cell.js:130:44)
    at async WalletV3ContractR2.createStateInit (webpack-internal:///(rsc)/./node_modules/tonweb/src/contract/index.js:43:31)
    at async WalletV3ContractR2.getAddress (webpack-internal:///(rsc)/./node_modules/tonweb/src/contract/index.js:18:29)

"tonweb": "^0.0.64", "tonweb-mnemonic": "^1.0.1", "next": "^14.0.3",

895268679long commented 3 months ago

May I ask how to convert mnemonics into public and private keys?