RSA encryption between Node js and Web

TDLR I’m working on a node js server that uses the Crypto module to create a public and private RSA key. I need to be able to export the public key so my React app can communicate with the node server. The problem is that react uses a different module. I’m able to encrypt the message from React but when it gets to the server it’s either a mess of bits or the server outputs a padding error.

I’ve been trying to get it to work but the node js server keeps telling me the padding is wrong. I tried different combinations of paddings but it still had the same error.

Ps, They communicate through a WebSocket channel.

Error:

function: 'RSA_padding_check_PKCS1_OAEP_mgf1',
  reason: 'oaep decoding error',
  code: 'ERR_OSSL_RSA_OAEP_DECODING_ERROR'

Node Server code

const { publicKey, privateKey } = generateKeyPairSync('rsa', {
                modulusLength: 4096,
                publicKeyEncoding: {
                    type: 'spki',
                    format: 'pem'
                },
                privateKeyEncoding: {
                    type: 'pkcs8',
                    format: 'pem',
                    cipher: 'aes-256-cbc',
                    passphrase: 'Bob'
                }
            })
            this.rsa = privateKey.toString('hex')
            this.rsap = publicKey.toString('hex')
...
var decryptodata = crypto.privateDecrypt({
            'key': this.rsa,
            passphrase: 'Bob',
            'padding': crypto.constants.RSA_PKCS1_OAEP_PADDING
        },
            Buffer.from(data, "base64")
        )
        return decryptodata.toString()

Subtle code

var publicKey =`HAS THE PUBLIC KEY AS A STRING`
const pemHeader = "-----BEGIN PUBLIC KEY-----";
const pemFooter = "------END PUBLIC KEY-----";
const kBase64Digits ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function atob(input) {
                            // The implementation here has not been performance optimized in any way and
                            // should not be.
                            // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932
                            input = `${input}`;
                            var result = ``
                            for (let n = 0; n < input.length; n++) {
                                if (kBase64Digits.includes(input[n])) result += input[n];
                                
                            }
                            return Buffer.from(result, 'base64').toString('latin1');
                        }
const pemContents = publicKey.substring(pemHeader.length, publicKey.length - pemFooter.length);
const binaryDerString = atob(pemContents);
const binaryDer = str2ab(binaryDerString);
this.publicKey = await window.crypto.subtle.importKey(
                            "spki",
                            binaryDer,
                            {
                                name: "RSA-OAEP",
                                hash: "SHA-256"
                            },
                            true,
                            ["encrypt"]
                        )


...

const enc = new TextEncoder()
var msg = await window.crypto.subtle.encrypt({
            name: "RSA-OAEP"
        }, this.publicKey, enc.encode(message)
        );
        function ab2str(buf) {
            return String.fromCharCode.apply(null, new Uint8Array(buf));
        }
        const encryptedBase64 = window.btoa(ab2str(msg));
        console.log(encryptedBase64.replace(/(.{64})/g, "$1n"));