import sodium from 'libsodium-wrappers' ; import type { KeyPair as SodiumKeyPair } from 'libsodium-wrappers' ; import Mnemonic from './Mnemonic' ; import Address from './Address' ; import { ED25519_KEY_TYPE } from './KeyType' ; import { MAINNET , NetType } from './NetType' ; export default class Keypair { public keypair ! : SodiumKeyPair ; public publicKey ! : Uint8Array ; public privateKey ! : Uint8Array ; public keyType ! : string ; public netType ! : NetType ; constructor ( keypair , netType ? ) { this . keypair = keypair ; this . publicKey = keypair . publicKey ; this . privateKey = keypair . privateKey ; this . keyType = keypair . keyType ; this . netType = netType || MAINNET ; } get address ( ) : Address { return new Address ( 0 , this . netType , ED25519_KEY_TYPE , this . publicKey ) ; } static async makeRandom ( netType ? ) { await sodium . ready ; const keypair = sodium . crypto_sign_keypair ( ) ; return new Keypair ( keypair , netType ) ; } static async fromWords ( words , netType ? ) { const mnenomic = new Mnemonic ( words ) ; const keypair = await this . fromMnemonic ( mnenomic , netType ) ; return keypair ; } static async fromMnemonic ( mnenomic , netType ? ) { await sodium . ready ; const entropy = mnenomic . toEntropy ( ) ; const seed = entropy . length === 16 ? Buffer . concat ( [ entropy , entropy ] ) : entropy ; return Keypair . fromEntropy ( seed , netType ) ; } static async fromEntropy ( entropy , netType ? ) { await sodium . ready ; const entropyBuffer = Buffer . from ( entropy ) ; if ( Buffer . byteLength ( entropyBuffer ) !== 32 ) throw new Error ( 'Invalid entropy, must be 32 bytes' ) ; const keypair = sodium . crypto_sign_seed_keypair ( entropy ) ; return new Keypair ( keypair , netType ) ; } async sign ( message ) { await sodium . ready ; const signature = sodium . crypto_sign_detached ( message , this . privateKey ) ; return signature ; } }