nova-ui/services/core/keypair.ts
2022-12-04 07:02:30 +01:00

65 lines
1.9 KiB
TypeScript

import { BigNumber, Wallet, BigNumberish } from 'ethers'
import { encrypt, decrypt, getEncryptionPublicKey } from 'eth-sig-util'
import { numbers } from '@/constants'
import { packEncryptedMessage, unpackEncryptedMessage } from '@/utilities'
import { poseidonHash, toFixedHex } from './utils'
import { BaseKeypair, KeypairStatic } from './@types'
const PUB_KEY_LENGTH = 64
const STRING_WITH_0X_LENGTH = 130
const ENCRYPTION_KEY_LENGTH = 128
class Keypair extends KeypairStatic implements BaseKeypair {
public privkey: string
public pubkey: BigNumber
public encryptionKey: string
public constructor(privkey = Wallet.createRandom().privateKey) {
super()
this.privkey = privkey
this.pubkey = poseidonHash([privkey])
this.encryptionKey = getEncryptionPublicKey(privkey.slice(numbers.OX_LENGTH))
}
public toString() {
return toFixedHex(this.pubkey) + Buffer.from(this.encryptionKey, 'base64').toString('hex')
}
public address() {
return this.toString()
}
public static fromString(str: string) {
if (str.length === STRING_WITH_0X_LENGTH) {
str = str.slice(numbers.OX_LENGTH)
}
if (str.length !== ENCRYPTION_KEY_LENGTH) {
throw new Error('Invalid key length')
}
return Object.assign(new Keypair(), {
privkey: null,
pubkey: BigNumber.from('0x' + str.slice(numbers.ZERO, PUB_KEY_LENGTH)),
encryptionKey: Buffer.from(str.slice(PUB_KEY_LENGTH, ENCRYPTION_KEY_LENGTH), 'hex').toString('base64'),
})
}
public encrypt(bytes: Buffer) {
return packEncryptedMessage(encrypt(this.encryptionKey, { data: bytes.toString('base64') }, 'x25519-xsalsa20-poly1305'))
}
public decrypt(data: string) {
return Buffer.from(decrypt(unpackEncryptedMessage(data), this.privkey.slice(numbers.OX_LENGTH)), 'base64')
}
public sign(commitment: BigNumber, merklePath: BigNumberish) {
return poseidonHash([this.privkey, commitment, merklePath])
}
}
export { Keypair }