nova-ui/services/core/utils.ts

103 lines
2.8 KiB
TypeScript

import crypto from 'crypto'
import { BigNumber, utils } from 'ethers'
// @ts-expect-error
import { poseidon } from '@tornado/circomlib'
import { numbers, FIELD_SIZE } from '@/constants'
import { BaseUtxo } from './@types'
const BYTES_31 = 31
const BYTES_32 = 32
const ADDRESS_BYTES_LENGTH = 20
// eslint-disable-next-line
function poseidonHash(items: any[]) {
return BigNumber.from(poseidon(items).toString())
}
function poseidonHash2(a: string, b: string) {
return poseidonHash([a, b])
}
function randomBN(nbytes = BYTES_31) {
return BigNumber.from(crypto.randomBytes(nbytes))
}
interface Params {
recipient: string // address || 0
relayer: string // address || 0
encryptedOutput1: string
extAmount: string
fee: string
l1Fee: string
isL1Withdrawal: boolean
encryptedOutput2: string
}
function getExtDataHash({ recipient, extAmount, isL1Withdrawal, relayer, fee, l1Fee, encryptedOutput1, encryptedOutput2 }: Params) {
const abi = new utils.AbiCoder()
const encodedData = abi.encode(
[
'tuple(address recipient,int256 extAmount,address relayer,uint256 fee,bytes encryptedOutput1,bytes encryptedOutput2,bool isL1Withdrawal,uint256 l1Fee)',
],
[
{
recipient: toFixedHex(recipient, ADDRESS_BYTES_LENGTH),
extAmount: toFixedHex(extAmount),
relayer: toFixedHex(relayer, ADDRESS_BYTES_LENGTH),
fee: toFixedHex(fee),
encryptedOutput1: encryptedOutput1,
encryptedOutput2: encryptedOutput2,
isL1Withdrawal: isL1Withdrawal,
l1Fee: toFixedHex(l1Fee),
},
]
)
const hash = utils.keccak256(encodedData)
return BigNumber.from(hash).mod(FIELD_SIZE)
}
function toFixedHex(number?: number | Buffer | BigNumber | string, length = BYTES_32) {
let result =
'0x' +
(number instanceof Buffer ? number.toString('hex') : BigNumber.from(number).toHexString().replace('0x', '')).padStart(
length * numbers.TWO,
'0'
)
if (result.includes('-')) {
result = '-' + result.replace('-', '')
}
return result
}
function toBuffer(value: string | number | BigNumber, length: number) {
const number = BigNumber.from(value)
.toHexString()
.slice(numbers.TWO)
.padStart(length * numbers.TWO, '0')
return Buffer.from(number, 'hex')
}
function shuffle(array: BaseUtxo[]) {
let currentIndex = array.length
let randomIndex
// While there remain elements to shuffle...
while (currentIndex !== numbers.ZERO) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex)
currentIndex--
// And swap it with the current element.
;[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]
}
return array
}
export { randomBN, toFixedHex, toBuffer, poseidonHash, poseidonHash2, getExtDataHash, shuffle }