import React , { FunctionComponent , useState } from "react" ; import { KeyRingStore } from "@keplr-wallet/stores" ; import { action , computed , flow , makeObservable , observable } from "mobx" ; import { Mnemonic , RNG } from "@keplr-wallet/crypto" ; import { BIP44HDPath } from "@keplr-wallet/background" ; export type RegisterMode = "create" | "add" ; export type RegisterOption = { type : string ; intro : FunctionComponent < { registerConfig : RegisterConfig ; } > ; page : FunctionComponent < { registerConfig : RegisterConfig ; } > ; } ; export class RegisterConfig { protected keyRingStore : KeyRingStore ; @ observable protected _isLoading : boolean = false ; @ observable . shallow protected options : RegisterOption [ ] = [ ] ; @ observable protected _type : string = "" ; @ observable protected _isFinalized : boolean = false ; constructor ( keyRingStore , options , protected readonly rng ) { this . keyRingStore = keyRingStore ; makeObservable ( this ) ; for ( const option of options ) { this . addRegisterOption ( option . type , option . intro , option . page ) ; } } @ computed get mode ( ) : RegisterMode { return this . keyRingStore . multiKeyStoreInfo . length === 0 ? "create" : "add" ; } get isLoading ( ) : boolean { return this . _isLoading ; } get isFinalized ( ) : boolean { return this . _isFinalized ; } @ action addRegisterOption ( type , intro , page ) { this . options . push ( { type , intro , page , } ) ; } @ action setType ( type ) { this . _type = type ; } get type ( ) : string { return this . _type ; } get isIntro ( ) : boolean { return this . _type === "" ; } @ action clear ( ) { this . setType ( "" ) ; } @ flow * createMnemonic ( name , mnemonic , password , bip44HDPath , meta = { } ) { this . _isLoading = true ; try { if ( this . mode === "create" ) { yield this . keyRingStore . createMnemonicKey ( mnemonic , password , { name , ... meta , } , bip44HDPath ) ; } else { yield this . keyRingStore . addMnemonicKey ( mnemonic , { name , ... meta , } , bip44HDPath ) ; } this . _isFinalized = true ; } finally { this . _isLoading = false ; } } @ flow * createLedger ( name , password , bip44HDPath ) { this . _isLoading = true ; try { if ( this . mode === "create" ) { yield this . keyRingStore . createLedgerKey ( password , { name , } , bip44HDPath ) ; } else { yield this . keyRingStore . addLedgerKey ( { name , } , bip44HDPath ) ; } this . _isFinalized = true ; } finally { this . _isLoading = false ; } } @ flow * createPrivateKey ( name , privateKey , password , meta = { } ) { this . _isLoading = true ; try { if ( this . mode === "create" ) { yield this . keyRingStore . createPrivateKey ( privateKey , password , { name , ... meta , } ) ; } else { yield this . keyRingStore . addPrivateKey ( privateKey , { name , ... meta , } ) ; } this . _isFinalized = true ; } finally { this . _isLoading = false ; } } async generateMnemonic ( strenth = 128 ) { return await Mnemonic . generateSeed ( this . rng , strenth ) ; } render ( ) { return ( < div > { this . isIntro ? this . options . map ( ( option ) => { return ( < React . Fragment key = { option . type } > < option . intro registerConfig = { this } /> < /React.Fragment>); } ) : ! this . isFinalized ? this . options . map ( ( option ) => { if ( option . type === this . type ) { return ( < React . Fragment key = { option . type } > < option . page registerConfig = { this } /> < /React.Fragment>); } } ) : null } < /div>); } } export const useRegisterConfig = ( keyRingStore , initialOptions , rng = ( array ) => { return Promise . resolve ( crypto . getRandomValues ( array ) ) ; } ) => { const [ txConfig ] = useState ( ( ) => new RegisterConfig ( keyRingStore , initialOptions , rng ) ) ; return txConfig ; } ;