Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto.getRandomValues must be defined #4873

Open
windswrold opened this issue Apr 27, 2024 · 1 comment
Open

crypto.getRandomValues must be defined #4873

windswrold opened this issue Apr 27, 2024 · 1 comment

Comments

@windswrold
Copy link

使用 solana/web3.js ,开发uni app, 但是提示 crypto.getRandomValues must be defined

@xu-zhipeng
Copy link

可以试试我的这个解决办法,通过打补丁的方式,我参考的是之前的uni-app源码的提交记录,但是他们新版又给去除了。只能支持crypto.getRandomValuescrypto.randomBytes方法,如果你的第三方库用到crypto其他方法,那只能自己去实现了。
web3 的这些sdk底层都要获取随机数,应该都用了这一套,所以其他币也是同样解决办法。

提交记录参考:feat(app-plus): add crypto

crypto.ts 文件内容:

const lookup = [
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0,
  0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
  24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
  44, 45, 46, 47, 48, 49, 50, 51,
]

function base64Decode(source: string, target: Uint8Array) {
  const sourceLength = source.length
  const paddingLength =
    source[sourceLength - 2] === '=' ? 2 : source[sourceLength - 1] === '=' ? 1 : 0

  let tmp
  let byteIndex = 0
  const baseLength = (sourceLength - paddingLength) & 0xfffffffc

  for (var i = 0; i < baseLength; i += 4) {
    tmp =
      (lookup[source.charCodeAt(i)] << 18) |
      (lookup[source.charCodeAt(i + 1)] << 12) |
      (lookup[source.charCodeAt(i + 2)] << 6) |
      lookup[source.charCodeAt(i + 3)]

    target[byteIndex++] = (tmp >> 16) & 0xff
    target[byteIndex++] = (tmp >> 8) & 0xff
    target[byteIndex++] = tmp & 0xff
  }

  if (paddingLength === 1) {
    tmp =
      (lookup[source.charCodeAt(i)] << 10) |
      (lookup[source.charCodeAt(i + 1)] << 4) |
      (lookup[source.charCodeAt(i + 2)] >> 2)

    target[byteIndex++] = (tmp >> 8) & 0xff
    target[byteIndex++] = tmp & 0xff
  }

  if (paddingLength === 2) {
    tmp = (lookup[source.charCodeAt(i)] << 2) | (lookup[source.charCodeAt(i + 1)] >> 4)

    target[byteIndex++] = tmp & 0xff
  }
}

export default {
  getRandomValues(arr: {
    byteLength: number | undefined
    buffer: ArrayBufferLike
    byteOffset: number | undefined
  }) {
    if (
      !(
        arr instanceof Int8Array ||
        arr instanceof Uint8Array ||
        arr instanceof Int16Array ||
        arr instanceof Uint16Array ||
        arr instanceof Int32Array ||
        arr instanceof Uint32Array ||
        arr instanceof Uint8ClampedArray
      )
    ) {
      throw new Error('Expected an integer array')
    }
    if (arr.byteLength > 65536) {
      throw new Error('Can only request a maximum of 65536 bytes')
    }
    var crypto = uni.requireNativePlugin('DCloud-Crypto')
    base64Decode(
      crypto.getRandomValues(arr.byteLength),
      new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength),
    )
    return arr
  },
  randomBytes(arrSize: number) {
    if (arrSize > 65536) {
      throw new Error('Can only request a maximum of 65536 bytes')
    }
    var crypto = uni.requireNativePlugin('DCloud-Crypto')
    var arr = new Uint8Array(arrSize)
    base64Decode(
      crypto.getRandomValues(arr.byteLength),
      new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength),
    )
    return arr
  },
}

index.ts 文件内容

import crypto from "./crypto";

/**
 * 全局内置类型替换
 */
(function (scope) {
  'use strict';

  if(!(scope as any).crypto){
    (scope as any).crypto = crypto
    console.log('crypto不存在, 使用自定义crypto进行替换')
  }
})(typeof globalThis !== 'undefined'? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this)

console.log('crypto polyfill loaded for App environment.')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants