UNPKG

@aladas-org/cryptocalc

Version:
1,226 lines (963 loc) 105 kB
// ===================================================================================== // ================================ renderer_gui.js ================================ // ===================================================================================== // https://www.electronjs.org/docs/latest/tutorial/quick-start // password in HD wallet: // https://help.blockstream.com/hc/en-us/articles/8712301763737-What-is-a-BIP39-passphrase "use strict"; // =============================== RendererGUI class =============================== // NB: "Singleton" class // * static GetInstance() // ------------------------------------------------------ // * async newWallet( json_data ) // * async openWallet( json_data ) // // * async generateHDWalletAddress( blockchain, entropy ) // * async generateSimpleWalletAddress( blockchain, entropy ) // // * async getSaltedEntropySource() // * async didFinishLoadInit() // * async localizeHtmlNodes() // * registerCallbacks() // * async propagateFields( entropy, wif ) // // updateFieldsVisibility() // * async updateOptionsFields( json_data ) // * async updateFields() // * async updateWalletMode( wallet_mode ) // * async updatePassword( password ) // * async updateEntropySize( entropy_size ) // * async updateEntropy( entropy ) // * updateBlockchain( blockchain ) // * updateWalletURL( blockchain, wallet_address ) // * updateWIF( blockchain, wif ) // * updatePrivateKey( blockchain, PRIV_KEY ) // * async updateChecksum( entropy ) // * async updateMnemonics( entropy ) // * async updateLanguage( lang ) // * async updateWordIndexes() // // * async generateSalt() // * async generateRandomFields() // * async getWalletInfo() // * clearFields( field_ids ) // // * async onGUIEvent( data ) // // * GuiClearPassword() // * GuiGeneratePassword() // * GuiTogglePasswordVisibility() // * GuiSetPasswordApplyState() // // * async fileSaveWallet() // * async fileOpenWallet() // // showSaveWalletInfoDialog() // // * async onGuiUpdateEntropySize( evt ) // * async onGuiUpdateWordCount( evt ) // * async onGuiUpdateLang( evt ) // * async onGuiSwitchWalletMode( evt ) // * async onGuiUpdateBlockchain( evt ) // onEntropyKeydown( evt ) // onEntropyKeypress( evt ) // onEntropyPaste( evt ) // * async onKeyDown( evt ) // * async onInput( evt ) // * onGuiFocus( evt ) // // setSaveCmdState(); // setRefreshCmdState(); // // * setEventHandler( elt_id, event_name, handler_function )// // * openTabPage( pageName, elt, color ) // * setFocus( elt_id ) // * async importRawData() const ALLOWED_ALPHABETS = { [ENTROPY_ID]: HEX_ALPHABET }; const FIELD_IDS = [ ENTROPY_SRC_FORTUNES_ID, SALT_ID, ENTROPY_ID, MNEMONICS_ID, MNEMONICS_4LETTER_ID ]; const WATERFALL_IDS = [ ENTROPY_SRC_FORTUNES_ID, SALT_ID, ENTROPY_ID, MNEMONICS_ID, MNEMONICS_4LETTER_ID ]; const WATERFALL_FROM_SEED_IDS = [ ENTROPY_ID, MNEMONICS_ID, MNEMONICS_4LETTER_ID ]; const EDITABLE_FIELD_IDS = [ ENTROPY_SRC_FORTUNES_ID, ENTROPY_ID, MNEMONICS_ID ]; const ON_GUI_EVENT_LOG_PREFIX = ">> " + _CYAN_ + "RendererGUI.onGUIEvent: "; const trigger_event = ( elt, event_type ) => elt.dispatchEvent( new CustomEvent( event_type, {} ) ); const getChecksumBitCount = ( word_count ) => { if ( word_count == undefined ) word_count = 12; let checksum_bit_count = 4; // default case is 12 words / 4 bits switch ( word_count ) { case 12: checksum_bit_count = 4; break; case 15: checksum_bit_count = 5; break; case 18: checksum_bit_count = 6; break; case 21: checksum_bit_count = 7; break; case 24: checksum_bit_count = 8; break; default: checksum_bit_count = 8; break; } return checksum_bit_count; }; // getChecksumBitCount() const getWordCount = ( entropy_size ) => { switch ( entropy_size ) { case 128: return 12; break; case 160: return 15; break; case 192: return 18; break; case 224: return 21; break; case 256: return 24; break; default: return 24; break; } // entropy_size }; // getWordCount() // ============================== RendererGUI class ============================== class RendererGUI { //static #key = {}; static #key = Symbol(); static #_Singleton = new RendererGUI( this.#key ); static GetInstance() { if ( RendererGUI.#_Singleton == undefined ) { RendererGUI.#_Singleton = new RendererGUI(); } return RendererGUI.#_Singleton; } // RendererGUI.GetInstance() // ** Private constructor ** constructor( key ) { if ( key !== RendererGUI.#key ) { throw new TypeError("RendererGUI constructor is private."); } this.wallet_info = new Wallet( this ); this.wallet_info.setAttribute( WORD_COUNT, 24 ); this.first_time = true; this.password_visible = false; this.wits_path = ""; this.new_cmd_count = 0; this.cb_enabled = true; this.Options = {}; this.entropy_source_type = IMAGE_ENTROPY_SRC_TYPE; this.expected_entropy_bytes = 32; this.entropy_source_is_user_input = false; this.img_data_asURL = ""; trace2Main( pretty_func_header_format( "RendererGUI.constructor" ) ); window.ipcMain.receive( "fromMain", async (data) => { await this.onGUIEvent(data); } ); } // ** Private constructor ** async newWallet( options_json_data ) { trace2Main( "===== rGUI.newW> ===============================================================" ); trace2Main( pretty_func_header_format( "RendererGUI.newWallet" ) ); trace2Main( pretty_format( "RendererGUI.newWallet" ) ); this.new_cmd_count++; this.cb_enabled = false; this.setSaveCmdState( true ); this.wallet_info.setOptions( options_json_data ); // trace2Main( pretty_format( "rGUI.newW> first_time ", this.first_time ) ); // trace2Main( pretty_format( "rGUI.newW> wits_path", this.wits_path ) ); this.wallet_info.reset(); this.wallet_info.setAttribute( CMD, CMD_NEW_WALLET ); this.setEntropySourceIsUserInput( false ); this.entropy_source_type = IMAGE_ENTROPY_SRC_TYPE; this.setRefreshCmdState( false ); await this.drawEntropySource(); //---------------------------------------------------------- //---------- Wallet Mode ---------- let wallet_mode = options_json_data[WALLET_MODE]; await this.updateWalletMode( wallet_mode ); trace2Main( pretty_format( "rGUI.newW> wallet_mode", wallet_mode ) ); //---------- Wallet Mode // ---------- Blockchain ---------- trace2Main( pretty_format( "rGUI.newW> b4 blockchain" ) ); let blockchain = options_json_data[DEFAULT_BLOCKCHAIN][wallet_mode]; await this.updateBlockchain( blockchain ); trace2Main( pretty_format( "rGUI.newW> blockchain", blockchain ) ); // ---------- Blockchain // ---------- Coin ---------- let coin = COIN_ABBREVIATIONS[blockchain]; HtmlUtils.SetNodeValue( WALLET_COIN_ID, coin ); // trace2Main( pretty_format( "rGUI.newW> coin", coin ) ); // ---------- Coin // ---------- Coin Type ---------- let coin_type = COIN_TYPES[blockchain]; this.wallet_info.setAttribute( COIN_TYPE, coin_type ); // trace2Main( pretty_format( "rGUI.newW> coin_type", coin_type ) ); // ---------- Coin Type // ---------- Entropy Size ---------- let entropy_size = options_json_data[ENTROPY_SIZE][wallet_mode]; this.wallet_info.setAttribute( ENTROPY_SIZE, entropy_size ); await this.updateEntropySize( entropy_size ); trace2Main( pretty_format( "rGUI.newW> entropy_size", entropy_size ) ); // ---------- Entropy Size // ---------- Entropy ---------- // let entropy_1 = HtmlUtils.GetNodeValue( ENTROPY_ID ); // trace2Main( pretty_format( "rGUI.newW> entropy 1", entropy_1 ) ); let entropy = await this.generateEntropyFromEntropySource(); this.wallet_info.setAttribute( ENTROPY, entropy ); trace2Main( pretty_format( "rGUI.newW> entropy", entropy ) ); await this.updateChecksum( entropy ); // ---------- Entropy if ( wallet_mode == HD_WALLET_TYPE ) { this.wallet_info.setAttribute( ACCOUNT, 0 ); // trace2Main( pretty_format( "rGUI.newW> account", 0 ) ); this.wallet_info.setAttribute( ADDRESS_INDEX, 0 ); // trace2Main( pretty_format( "rGUI.newW> address_index", 0 ) ); } // HD_WALLET_TYPE //---------- lang ---------- let lang = options_json_data[LANG]; await this.updateLanguage( lang ); // trace2Main( pretty_format( "rGUI.newW> lang", lang ) ); //---------- lang // ---------- Update Window Title ---------- // trace2Main( pretty_format( "rGUI.newW> coin", coin ) ); let data = { coin, wallet_mode }; window.ipcMain.SetWindowTitle( data ); // ---------- Update Window Title // -------------------------------- await this.updateFields( entropy ); // -------------------------------- this.wallet_info.setAttribute( CMD, CMD_NONE ); // trace2Main( pretty_func_header_format( "<END> RendererGUI.newWallet" ) ); this.updateFieldsVisibility(); this.cb_enabled = true; // trace2Main( pretty_format( "<END> RendererGUI.newWallet first_time", this.first_time) ); // trace2Main( pretty_format( "<END> RendererGUI.newWallet wits_path", "'" + this.wits_path + "'") ); //---------- Note: Request "Min" to 'Open WITS' with 'wits_path' ---------- if ( this.wits_path != "" && this.first_time ) { trace2Main( pretty_format( "<END> RendererGUI.newWallet Ask 'Main' to'Open WITS' ", this.wits_path) ); let cmd_name = CMD_OPEN_WALLET; let cmd_args = this.wits_path; data = { cmd_name, cmd_args }; await window.ipcMain.ExecuteCommand( data ); this.wits_path = ""; this.first_time = false; } } // async newWallet() async openWallet( json_data ) { trace2Main( "===== rGUI.openW> ===============================================================" ); trace2Main( pretty_func_header_format( "RendererGUI.openWallet" ) ); trace2Main( JSON.stringify(json_data) ); this.cb_enabled = false; this.setEntropySourceIsUserInput( true ); this.setSaveCmdState( false ); this.wallet_info.reset(); this.wallet_info.setAttribute( CMD, CMD_OPEN_WALLET ); // ---------- Entropy ---------- let entropy = json_data[ENTROPY]; this.wallet_info.setAttribute( ENTROPY, entropy ); trace2Main( pretty_format( "rGUI.openW> entropy", entropy ) ); // ---------- Entropy // ---------- Entropy Size ---------- let entropy_size = json_data[ENTROPY_SIZE]; if ( isString( entropy_size ) ) entropy_size = parseInt( entropy_size ); this.wallet_info.setAttribute( ENTROPY_SIZE, entropy_size ); await this.updateEntropySize( entropy_size ); trace2Main( pretty_format( "rGUI.openW> entropy_size", entropy_size ) ); // ---------- Entropy Size // ---------- Wallet Mode ---------- let wallet_mode = json_data[WALLET_MODE]; this.wallet_info.setAttribute( WALLET_MODE, wallet_mode ); trace2Main( pretty_format( "rGUI.openW> wallet_mode", wallet_mode ) ); await this.updateWalletMode( wallet_mode ); // ---------- Wallet Mode // ---------- Blockchain ---------- // Note: order is important: 'blockchain' must be updated after 'wallet_mode' let blockchain = json_data[BLOCKCHAIN]; this.wallet_info.setAttribute( BLOCKCHAIN, blockchain ); await this.updateBlockchain( blockchain ); trace2Main( pretty_format( "rGUI.openW> blockchain", blockchain ) ); // ---------- Blockchain //---------- lang ---------- let lang = json_data[LANG]; await this.updateLanguage( lang ); trace2Main( pretty_format( "rGUI.openW> lang", lang ) ); //---------- lang // ---------- Coin ---------- let coin = COIN_ABBREVIATIONS[blockchain]; this.wallet_info.setAttribute( COIN, coin ); // trace2Main( pretty_format( "rGUI.openW> coin", coin ) ); // ---------- Coin // ---------- Coin Type ---------- let coin_type = COIN_TYPES[blockchain]; this.wallet_info.setAttribute( COIN_TYPE, coin_type ); trace2Main( pretty_format( "rGUI.openW> coin(coin_type)" , coin + "(" + coin_type + ")" ) ); // ---------- Coin Type // ---------- Word Count ---------- let word_count = getWordCount( entropy_size ); this.wallet_info.setAttribute( WORD_COUNT, word_count ); // ---------- Word Count // ---------- Checksum ---------- // Note: requires 'word_count' updated in 'wallet_info' await this.updateChecksum( entropy ); // ---------- Checksum if ( wallet_mode == HD_WALLET_TYPE ) { // ---------- Password ---------- if ( json_data[PASSWORD] != undefined ) { let password = json_data[PASSWORD]; this.wallet_info.setAttribute( PASSWORD, password ); trace2Main( pretty_format( "rGUI.openW> password", password ) ); } // ---------- Password let account = json_data[ACCOUNT]; this.wallet_info.setAttribute( ACCOUNT, account ); // trace2Main( pretty_format( "rGUI.openW> account", account ) ); let address_index = json_data[ADDRESS_INDEX]; this.wallet_info.setAttribute( ADDRESS_INDEX, address_index ); // trace2Main( pretty_format( "rGUI.openW> address_index", address_index ) ); } // HD_WALLET_TYPE // ---------- Mnemonics ---------- let mnemonics = json_data[MNEMONICS]; this.wallet_info.setAttribute( MNEMONICS, mnemonics ); trace2Main( pretty_format( "rGUI.openW> mnemonics", mnemonics ) ); // ---------- Mnemonics // ---------- Address ---------- let address = json_data[ADDRESS]; this.wallet_info.setAttribute( ADDRESS, address ); trace2Main( pretty_format( "rGUI.openW> address", address ) ); // ---------- Address //---------- Update 'Address Hardened Suffix ("" or "'") in "Wallet" Tab ---------- if ( blockchain == SOLANA ) HtmlUtils.SetNodeValue( ADDRESS_HARDENED_SUFFIX_ID, "'" ); else HtmlUtils.SetNodeValue( ADDRESS_HARDENED_SUFFIX_ID, "" ); //---------- Update 'Address' in "Wallet" Tab // ---------- Word_Indexes ---------- let word_indexes = json_data[WORD_INDEXES]; this.wallet_info.setAttribute( WORD_INDEXES, word_indexes ); trace2Main( pretty_format( "rGUI.openW> word_indexes", word_indexes ) ); // ---------- Word_Indexes // ---------- WIF ---------- let wif = json_data[WIF]; this.wallet_info.setAttribute( WIF, wif ); trace2Main( pretty_format( "rGUI.openW> wif", wif ) ); // ---------- WIF // ---------- Private Key ---------- let private_key = json_data[PRIVATE_KEY]; this.wallet_info.setAttribute( PRIVATE_KEY, private_key ); trace2Main( pretty_format( "rGUI.openW> private key", private_key ) ); // ---------- Private Key // ---------- Update Window Title ---------- let data = { coin, wallet_mode }; window.ipcMain.SetWindowTitle( data ); // ---------- Update Window Title this.wallet_info.setAttribute( CMD, CMD_NONE ); this.updateFieldsVisibility(); this.cb_enabled = true; // trace2Main( pretty_func_header_format( "<END> RendererGUI.openWallet" ) ); } // async openWallet() async generateSimpleWalletAddress( blockchain, entropy_hex ) { trace2Main( pretty_func_header_format( "RendererGUI.generateSimpleWalletAddress", blockchain + " " + this.entropy_source_type ) ); this.cb_enabled = false; let entropy_src_type = HtmlUtils.GetNodeValue( ENTROPY_SRC_TYPE_SELECTOR_ID ); this.entropy_source_type = entropy_src_type; let entropy_src = "XX"; if ( this.entropy_source_type == FORTUNES_ENTROPY_SRC_TYPE ) { entropy_src = HtmlUtils.GetNodeValue( ENTROPY_SRC_FORTUNES_ID ); } else if ( this.entropy_source_type == IMAGE_ENTROPY_SRC_TYPE ) { entropy_src = this.img_data_asURL; } // trace2Main( pretty_format( "rGUI.genSW> entropy_src", getShortenedString( entropy_src ) ) ); let new_wallet = {}; let salt_uuid = HtmlUtils.GetNodeValue(SALT_ID); let wif = ""; let private_key = entropy_hex; // trace2Main( pretty_format("rGUI.genSW> MAINNET", MAINNET) ); trace2Main( pretty_format("rGUI.genSW> private_key", private_key) ); if ( private_key == undefined || private_key == "" ) { throw new Error("RendererGUI.generateSimpleWalletAddress 'private_key' NOT DEFINED"); } if ( blockchain == ETHEREUM || blockchain == AVALANCHE || blockchain == BITCOIN || blockchain == DOGECOIN || blockchain == LITECOIN || blockchain == SOLANA ) { let crypto_net = MAINNET; let data = { private_key, salt_uuid, blockchain, crypto_net }; // NB: take care of field names and order new_wallet = await window.ipcMain.GetSimpleWallet( data ); private_key = new_wallet[PRIVATE_KEY]; wif = new_wallet[WIF]; trace2Main( pretty_format("rGUI.genSW> new_wallet[WIF]", new_wallet[WIF]) ); //---------- Update 'Private Key' in 'Wallet' Tab ---------- this.updatePrivateKey( blockchain, private_key ); this.wallet_info.setAttribute(PRIVATE_KEY, private_key); // HtmlUtils.SetNodeValue( PRIVATE_KEY_ID, private_key ); //---------- Update 'Private Key' in 'Wallet' Tab let wallet_address = new_wallet[ADDRESS]; //---------- Update 'Address' in 'Wallet' Tab ---------- trace2Main( pretty_format( "rGUI.genSW> wallet_address", wallet_address) ); this.wallet_info.setAttribute( ADDRESS, wallet_address ); //---------- Update 'Address' in 'Wallet' Tab //---------- Update 'WIF' in 'Wallet' Tab ---------- trace2Main( pretty_format( "rGUI.genSW> WIF", wif ) ); this.wallet_info.setAttribute( WIF, wif ); //---------- Update 'WIF' in 'Wallet' Tab // ** Note **: 'mnemonics' is used for 'Simple Wallet' / Solana if ( blockchain == SOLANA ) { let mnemonics = HtmlUtils.GetNodeValue( MNEMONICS_ID ); if (this.wallet_info.getAttribute('lang') == "JP") { let mnemonic_jp = mnemonics.replaceAll(' ', '\u3000'); //let mnemonic_jp = mnemonics.replaceAll(' ', '*'); HtmlUtils.SetNodeValue( SW_MNEMONICS_ID, mnemonic_jp ); } else { HtmlUtils.SetNodeValue( SW_MNEMONICS_ID, mnemonics ); } } this.updateWalletURL( blockchain, wallet_address ); } this.updateFieldsVisibility(); this.cb_enabled = true; return new_wallet; } // async generateSimpleWalletAddress() async generateHDWalletAddress( blockchain, entropy_hex ) { trace2Main( pretty_func_header_format( "RendererGUI.generateHDWalletAddress", blockchain + " " + this.entropy_source_type ) ); trace2Main( pretty_format("rGUI.genHDW> entropy_hex", entropy_hex ) ); this.cb_enabled = false; let entropy_src_type = HtmlUtils.GetNodeValue( ENTROPY_SRC_TYPE_SELECTOR_ID ); this.entropy_source_type = entropy_src_type; let entropy_src = "XX"; if ( this.entropy_source_type == FORTUNES_ENTROPY_SRC_TYPE ) { entropy_src = HtmlUtils.GetNodeValue( ENTROPY_SRC_FORTUNES_ID ); } else if ( this.entropy_source_type == IMAGE_ENTROPY_SRC_TYPE ) { entropy_src = this.img_data_asURL; } trace2Main( pretty_format( "rGUI.genHDW> entropy_src", getShortenedString( entropy_src ) ) ); let new_wallet = {}; let options = {}; let hd_private_key = undefined; let data = undefined; let mnemonics = HtmlUtils.GetNodeValue( MNEMONICS_ID ); let words = mnemonics.split(' '); let word_count = words.length; let separator = '\n'; let mnemonics_as_2parts = asTwoParts( mnemonics, 15 ); trace2Main( pretty_format( "rGUI.genHDW> mnemonics(" + word_count + ")", mnemonics_as_2parts[0] ) ); if ( mnemonics_as_2parts.length > 1 ) { trace2Main( pretty_format("", mnemonics_as_2parts[1] ) ); } let wif = ""; let PRIV_KEY = ""; let salt_uuid = HtmlUtils.GetNodeValue( SALT_ID ); let derivation_path = ""; let crypto_net = MAINNET; let password = ""; let account = "0"; let address_index = "0"; let wallet_mode = this.wallet_info.getAttribute(WALLET_MODE); this.wallet_info.setAttribute( BLOCKCHAIN, blockchain ); if ( blockchain == ETHEREUM || blockchain == AVALANCHE || blockchain == BITCOIN || blockchain == DOGECOIN || blockchain == LITECOIN || blockchain == CARDANO || blockchain == SOLANA || blockchain == RIPPLE || blockchain == TRON || blockchain == BITCOIN_CASH || blockchain == DASH || blockchain == FIRO || blockchain == ZCASH) { // trace2Main( pretty_format( "rGUI.genHDW> entropy_source_is_user_input", this.entropy_source_is_user_input ) ); let salt_uuid = HtmlUtils.GetNodeValue( SALT_ID ); // ---------- get 'Password' ---------- password = this.wallet_info.getAttribute(PASSWORD); trace2Main( pretty_format( "rGUI.genHDW> password", "'" + password + "'") ); // ---------- get 'Password' // ---------- get 'Account' ---------- if ( wallet_mode == HD_WALLET_TYPE ) account = this.wallet_info.getAttribute(ACCOUNT); else if ( wallet_mode == SWORD_WALLET_TYPE ) account = Math.floor( Math.random() * (ACCOUNT_MAX + 1) ); // trace2Main( pretty_format( "rGUI.genHDW> account", account ) ); // ---------- get 'Account' // ---------- get 'Address Index' ---------- if ( wallet_mode == HD_WALLET_TYPE ) address_index = this.wallet_info.getAttribute(ADDRESS_INDEX); else if ( wallet_mode == SWORD_WALLET_TYPE ) address_index = Math.floor( Math.random() * (ADDRESS_INDEX_MAX + 1) ); // trace2Main( pretty_format( "rGUI.genHDW> address_index", address_index ) ); // ---------- get 'Address Index' // ========== Wallet Generation ========== const data = { entropy_hex, salt_uuid, blockchain, crypto_net, password, account, address_index }; // trace2Main( pretty_format( "rGUI.genHDW> data", JSON.stringify(data) ) ); new_wallet = await window.ipcMain.GetHDWallet( data ); // ========== Wallet Generation wif = ""; PRIV_KEY = ""; if ( blockchain == CARDANO ) { HtmlUtils.ShowNode( TR_SW_MNEMONICS_ID ); HtmlUtils.SetNodeValue( PK_LABEL_ID, 'XPRIV' ); HtmlUtils.RemoveClass( ADDRESS_ID, 'NormalAddressField' ); HtmlUtils.AddClass( ADDRESS_ID, 'LongAddressField' ); } else { HtmlUtils.SetNodeValue( PK_LABEL_ID, 'Private Key' ); HtmlUtils.AddClass( ADDRESS_ID, 'NormalAddressField' ); HtmlUtils.RemoveClass( ADDRESS_ID, 'LongAddressField' ); } if ( blockchain == BITCOIN || blockchain == LITECOIN || blockchain == DOGECOIN || blockchain == BITCOIN_CASH || blockchain == DASH || blockchain == FIRO || blockchain == ZCASH ) { wif = ( new_wallet[WIF] != undefined ) ? new_wallet[WIF] : ""; trace2Main( pretty_format( "rGUI.genHDW> WIF", wif ) ); } else if ( blockchain == TRON ) { PRIV_KEY = new_wallet[PRIVATE_KEY]; } else if ( blockchain == RIPPLE ) { wif = ( new_wallet[WIF] != undefined ) ? new_wallet[WIF] : ""; PRIV_KEY = new_wallet[PRIVATE_KEY]; } } this.updateWIF( blockchain, wif ); // ==================== Update 'Derivation Path' in "Wallet" Tab ==================== derivation_path = new_wallet[DERIVATION_PATH]; trace2Main( pretty_format( "rGUI.genHDW> derivation_path", derivation_path ) ); let coin_type = COIN_TYPES[blockchain]; if ( wallet_mode == HD_WALLET_TYPE ) { if ( derivation_path == undefined ) { GuiUtils.ShowQuestionDialog( "'derivation_path' is UNDEFINED", {"CloseButtonLabel": "OK", "BackgroundColor": "#FFCCCB" } ); } else { let derivation_path_nodes = derivation_path.split('/'); trace2Main( pretty_format( "rGUI.genHDW> Get account/address_index from *Derivation Path*", "" ) ); coin_type = derivation_path_nodes[2]; //trace2Main( pretty_format( "rGUI.genHDW> coin_type", coin_type ) ); account = derivation_path_nodes[3].replace("'",''); //trace2Main( pretty_format( "rGUI.genHDW> account", account ) ); address_index = derivation_path_nodes[5]; //trace2Main( pretty_format( "rGUI.genHDW> address_index", address_index ) ); } } // if 'wallet_mode' is HD_WALLET_TYPE HtmlUtils.SetNodeValue( COIN_TYPE_ID, coin_type + '/' ); this.wallet_info.setAttribute( ACCOUNT, account ); this.wallet_info.setAttribute( ADDRESS_INDEX, address_index ); //---------- Update 'Purpose' in "Wallet" Tab ---------- if ( blockchain == CARDANO ) HtmlUtils.SetNodeValue( PURPOSE_ID, ADA_PURPOSE + "'"); else HtmlUtils.SetNodeValue( PURPOSE_ID, "44'" ); //---------- Update 'Purpose' in "Wallet" Tab //---------- Update 'Change' in "Wallet" Tab ---------- if ( blockchain == SOLANA ) HtmlUtils.SetNodeValue( CHANGE_ID, "0'/" ); else HtmlUtils.SetNodeValue( CHANGE_ID, "0/" ); //---------- Update 'Change' in "Wallet" Tab //---------- Update 'Address' in "Wallet" Tab ---------- let wallet_address = new_wallet[ADDRESS]; this.wallet_info.setAttribute( ADDRESS, wallet_address ); trace2Main( pretty_format( "rGUI.genHDW> new_wallet_address", wallet_address ) ); //---------- Update 'Address' in "Wallet" Tab //---------- Update 'Address Hardened Suffix ("" or "'") in "Wallet" Tab ---------- if ( blockchain == SOLANA ) HtmlUtils.SetNodeValue( ADDRESS_HARDENED_SUFFIX_ID, "'" ); else HtmlUtils.SetNodeValue( ADDRESS_HARDENED_SUFFIX_ID, "" ); //---------- Update 'Address' in "Wallet" Tab //==================== Update 'Derivation Path' in "Wallet" Tab //---------- Update 'Private Key' in "Wallet" Tab ---------- hd_private_key = new_wallet[PRIVATE_KEY]; trace2Main( pretty_format( "rGUI.genHDW> hd_private_key", hd_private_key ) ); this.wallet_info.setAttribute(PRIVATE_KEY, hd_private_key); // HtmlUtils.SetNodeValue( PRIVATE_KEY_ID, hd_private_key ); //---------- Update 'Private Key' in "Wallet" Tab this.updateWalletURL( blockchain, wallet_address ); this.updateFieldsVisibility(); this.cb_enabled = true; // trace2Main( "rGUI.genHDW> ------ END OF RendererGUI.generateHDWalletAddress ------" ); return new_wallet; } // async generateHDWalletAddress() async didFinishLoadInit() { trace2Main( pretty_func_header_format( "RendererGUI.didFinishLoadInit" ) ); this.registerCallbacks(); this.setSaveCmdState( true ); // https://www.w3schools.com/howto/howto_js_full_page_tabs.asp // Get the element with id="seed_tab_link_id" and click on it let seed_tab_link_elt = document.getElementById(SEED_TAB_LINK_ID); seed_tab_link_elt.click(); if ( HtmlUtils.HasClass( SEED_TAB_LINK_ID, "ThreeBordersTabLink" ) ) { HtmlUtils.AddClass( SEED_TAB_LINK_ID, "ThreeBordersTabLink" ); } if ( ! HtmlUtils.HasClass( WALLET_TAB_LINK_ID, "FourBordersTabLink" ) ) { HtmlUtils.RemoveClass( WALLET_TAB_LINK_ID, "FourBordersTabLink"); } } // async didFinishLoadInit() async localizeHtmlNodes() { trace2Main( pretty_func_header_format( "RendererGUI.localizeHtmlNodes" ) ); this.cb_enabled = false; let L10n_key = ""; let L10n_msg = ""; let L10N_KEYPAIRS = await window.ipcMain.GetL10nKeyPairs(); let L10N_KEYS = Object.keys( L10N_KEYPAIRS ); for ( let i=0; i < L10N_KEYS.length; i++ ) { //trace2Main("---------->>"); L10n_key = L10N_KEYS[i]; L10n_msg = await window.ipcMain.GetLocalizedMsg( L10n_key ); //trace2Main(" L10n_key: " + L10n_key + " L10n_msg: " + L10n_msg); HtmlUtils.SetNodeValue( L10n_key, L10n_msg ); } this.cb_enabled = true; } // async localizeHtmlNodes() registerCallbacks() { trace2Main( pretty_func_header_format( "RendererGUI.registerCallbacks" ) ); // -------------------- Toolbar icon buttons -------------------- this.setEventHandler( FILE_NEW_ICON_ID, 'click', async (evt) => { trace2Main( pretty_format( "rGUI.evtHandler> " + FILE_NEW_ICON_ID ) ); if ( this.cb_enabled ) { await this.onFileNewWallet(); } } ); this.setEventHandler( FILE_OPEN_ICON_ID, 'click', async (evt) => { trace2Main( pretty_format( "rGUI.evtHandler> " + FILE_OPEN_ICON_ID ) ); if ( this.cb_enabled ) { await this.fileOpenWallet(); } } ); this.setEventHandler( SAVE_ICON_ID, 'click', async (evt) => { if (this.cb_enabled) await this.fileSaveWallet(); } ); this.setEventHandler( REGENERATE_ICON_ID, 'click', async (evt) => { if (this.cb_enabled) await this.generateRandomFields(); } ); this.setEventHandler( TOGGLE_DEVTOOLS_ICON_ID, 'click', (evt) => { if (this.cb_enabled) this.onToggleDebug(evt); } ); // -------------------- Toolbar icon buttons this.setEventHandler( ENTROPY_SRC_FORTUNES_ID, 'focus', (evt) => { if (this.cb_enabled) this.onGuiFocus(evt); } ); //this.setEventHandler( entropy_src_fortunes_id, 'keydown', async (evt) => { await this.onKeyDown(evt); } ); this.setEventHandler( ENTROPY_ID, 'keypress', (evt) => { if (this.cb_enabled) this.onEntropyKeypress(evt); } ); this.setEventHandler( ENTROPY_ID, 'keydown', (evt) => { if (this.cb_enabled) this.onEntropyKeydown(evt); } ); this.setEventHandler( ENTROPY_ID, 'paste', async (evt) => { if (this.cb_enabled) await this.onEntropyPaste(evt); } ); this.setEventHandler( ENTROPY_ID, 'focus', (evt) => { if (this.cb_enabled) this.onGuiFocus(evt); } ); // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop this.setEventHandler( ENTROPY_SOURCE_IMG_ID, 'drop', (evt) => { if (this.cb_enabled) this.onDropImage(evt); } ); this.setEventHandler( ENTROPY_SOURCE_IMG_ID, 'dragover', (evt) => { if (this.cb_enabled) evt.preventDefault(); evt.stopPropagation(); } ); this.setEventHandler( ENTROPY_SRC_TYPE_SELECTOR_ID, 'change', async (evt) => { if (this.cb_enabled) await this.onGuiSwitchEntropySourceType(); } ); this.setEventHandler( ENTROPY_COPY_BTN_ID, 'click', (evt) => { if (this.cb_enabled) this.onCopyButton(ENTROPY_COPY_BTN_ID); } ); this.setEventHandler( ENTROPY_SIZE_SELECT_ID, 'change', async (evt) => { if (this.cb_enabled) await this.onGuiUpdateEntropySize(evt); } ); this.setEventHandler( WORD_COUNT_SELECT_ID, 'change', async (evt) => { if (this.cb_enabled) await this.onGuiUpdateWordCount(evt); } ); this.setEventHandler( LANG_SELECT_ID, 'change', async (evt) => { if (this.cb_enabled) await this.onGuiUpdateLang(evt); } ); // -------------------- Password -------------------- this.setEventHandler( PASSWORD_ID, 'keyup', (evt) => { this.onGuiChangePassword(); } ); this.setEventHandler( APPLY_PASSWORD_BTN_ID, 'click', async (evt) => { if (this.cb_enabled) await this.GuiApplyPassword(); } ); this.setEventHandler( GENERATE_PASSWORD_BTN_ID, 'click', async (evt) => { if (this.cb_enabled) await this.GuiGeneratePassword(); } ); this.setEventHandler( CLEAR_PASSWORD_BTN_ID, 'click', async (evt) => { if (this.cb_enabled) await this.GuiClearPassword(); } ); this.setEventHandler( EYE_BTN_ID, 'click', (evt) => { if (this.cb_enabled) this.GuiTogglePasswordVisibility(); } ); // -------------------- Password this.setEventHandler( WALLET_MODE_SELECT_ID, 'change', async (evt) => { if (this.cb_enabled) await this.onGuiSwitchWalletMode(evt); } ); this.setEventHandler( WALLET_BLOCKCHAIN_ID, 'change', async (evt) => { if (this.cb_enabled) await this.onGuiUpdateBlockchain(evt); } ); this.setEventHandler( PK_COPY_BTN_ID, 'click', (evt) => { if (this.cb_enabled) this.onCopyButton(PK_COPY_BTN_ID); } ); this.setEventHandler( MNEMONICS_ID, 'paste', async (evt) => { if (this.cb_enabled) await this.onMnemonicsPaste(evt); } ); this.setEventHandler( MNEMONICS_4LETTER_ID, 'focus', (evt) => { if (this.cb_enabled) this.onGuiFocus(evt); } ); this.setEventHandler( MNEMONICS_COPY_BTN_ID, 'click', (evt) => { if (this.cb_enabled) this.onCopyButton(MNEMONICS_COPY_BTN_ID); } ); this.setEventHandler( SW_MNEMONICS_COPY_BTN_ID, 'click', (evt) => { if (this.cb_enabled) this.onCopyButton(SW_MNEMONICS_COPY_BTN_ID); } ); this.setEventHandler( SW_WIF_COPY_BTN_ID, 'click', (evt) => { if (this.cb_enabled) this.onCopyButton(SW_WIF_COPY_BTN_ID); } ); //this.setEventHandler( WORD_INDEXES_BASE_ID, 'change', async (evt) => { await this.updateWordIndexes(); } ); this.setEventHandler( RANDOM_BTN_ID, 'click', async (evt) => { if (this.cb_enabled) await this.generateRandomFields(); } ); this.setEventHandler( REFRESH_BTN_ID, 'click', async (evt) => { if (this.cb_enabled) await this.onRefreshButton(); } ); this.setEventHandler( ACCOUNT_ID, 'keypress', async (evt) => { if (this.cb_enabled) await this.onBIP32FieldKeypress(evt); } ); this.setEventHandler( ADDRESS_INDEX_ID, 'keypress', async (evt) => { if (this.cb_enabled) await this.onBIP32FieldKeypress(evt); } ); //trigger_event( HtmlUtils.GetNode( RANDOM_BTN_ID ), 'click' ); } // registerCallbacks() async propagateFields( entropy ) { trace2Main( pretty_func_header_format( "RendererGUI.propagateFields", entropy ) ); this.cb_enabled = false; if ( entropy == undefined ) { entropy = getRandomHexValue( this.entropy_expected_bytes ); trace2Main( pretty_format( "entropy UNDEFINED >> Generate Random Entropy", entropy ) ); } trace2Main( pretty_format( "rGUI.propF> CMD", this.wallet_info.getAttribute(CMD) ) ); if ( this.wallet_info.getAttribute(CMD) == CMD_OPEN_WALLET || this.entropy_source_is_user_input ) { this.setEntropySourceIsUserInput( true ); } else { this.setEntropySourceIsUserInput( false ); await this.generateSalt(); } if ( this.wallet_info.getAttribute(CMD) != CMD_OPEN_WALLET ) { await this.updateEntropy( entropy ); await this.updateMnemonics( entropy ); } // trace2Main( pretty_func_header_format( "<END> RendererGUI.propagateFields", entropy ) ); this.cb_enabled = true; } // async propagateFields() // ============================================================================================ // ==================================== Updates ===================================== // ============================================================================================ // Note: Wallet manahgers: Guarda, Yoroi, Phantom Wallet updateFieldsVisibility() { // ============== SIMPLE WALLET ============== // PK WIF MNK // SPEC OK ----------------- // * * BTC, DOGE, LTC : X X X // * * ETH : X - X // * * AVA : X - X // * * SOL : X X X // // ================ HD WALLET ================ // PK WIF MNK // SPEC OK ----------------- // * * BTC, DOGE, LTC : - X - // * * ETH : X - - // * * AVA : X - - // * * SOL : X - - NB: validated with "Phantom Wallet" // * * ADA : - - X NB: validated with "Guarda" and "Yoroi" // 24 words 'account' and 'address_index' hard-coded to 0 // * * XRP : - X - // * * TRON : - X - // * * BITCOIN CASH : - X - // * * DASH : - X - // * * FIRO : - X - // trace2Main( pretty_func_header_format( "RendererGUI.updateFieldsVisibility" ) ); HtmlUtils.HideNode( TR_SW_MNEMONICS_ID ); let wallet_mode = this.wallet_info.getAttribute(WALLET_MODE); let blockchain = this.wallet_info.getAttribute(BLOCKCHAIN); HtmlUtils.HideNode( TR_PRIV_KEY_ID ); HtmlUtils.HideNode( TR_1ST_PK_ID ); if ( wallet_mode == SIMPLE_WALLET_TYPE ) { HtmlUtils.ShowNode( SW_ENTROPY_SIZE_ID ); HtmlUtils.ShowNode( WORD_COUNT_SELECT_ID ); HtmlUtils.ShowNode( SW_WORD_COUNT_ID ); HtmlUtils.ShowNode( TR_SW_MNEMONICS_ID ); HtmlUtils.HideNode( PASSWORD_ROW_ID ); HtmlUtils.HideNode( ENTROPY_SIZE_SELECT_ID ); HtmlUtils.HideNode( WORD_COUNT_SELECT_ID ); HtmlUtils.HideNode( DERIVATION_PATH_ROW ); // HtmlUtils.ShowNode( TR_PRIV_KEY_ID ); HtmlUtils.ShowNode( TR_1ST_PK_ID ); } else if ( wallet_mode == HD_WALLET_TYPE || wallet_mode == SWORD_WALLET_TYPE ) { HtmlUtils.ShowNode( PASSWORD_ROW_ID ); HtmlUtils.ShowNode( ENTROPY_SIZE_SELECT_ID ); if ( wallet_mode == HD_WALLET_TYPE ) HtmlUtils.ShowNode( DERIVATION_PATH_ROW ); else if ( wallet_mode == SWORD_WALLET_TYPE ) { HtmlUtils.HideNode( PASSWORD_ROW_ID ); HtmlUtils.HideNode( DERIVATION_PATH_ROW ); } HtmlUtils.ShowNode( TR_WIF_ID ); HtmlUtils.HideNode( TR_SW_MNEMONICS_ID ); HtmlUtils.HideNode( SW_ENTROPY_SIZE_ID); HtmlUtils.HideNode( WORD_COUNT_SELECT_ID ); HtmlUtils.HideNode( SW_WORD_COUNT_ID ); if ( blockchain == TRON ) { HtmlUtils.HideNode( TR_PRIV_KEY_ID ); } if ( blockchain == CARDANO ) { HtmlUtils.HideNode(ACCOUNT_ID); HtmlUtils.HideNode(ACCOUNT_SUFFIX_ID); HtmlUtils.HideNode(ADDRESS_INDEX_ID); HtmlUtils.ShowNode(ACCOUNT_READONLY_ID); HtmlUtils.ShowNode(ADDRESS_INDEX_READONLY_ID); HtmlUtils.ShowNode( TR_SW_MNEMONICS_ID ); } else { HtmlUtils.ShowNode(ACCOUNT_ID); HtmlUtils.ShowNode(ACCOUNT_SUFFIX_ID); HtmlUtils.ShowNode(ADDRESS_INDEX_ID); HtmlUtils.HideNode(ACCOUNT_READONLY_ID); HtmlUtils.HideNode(ADDRESS_INDEX_READONLY_ID); } // HtmlUtils.HideNode( TR_1ST_PK_ID ); HtmlUtils.HideNode( TR_PRIV_KEY_ID ); if ( blockchain == RIPPLE ) { HtmlUtils.ShowNode( TR_1ST_PK_ID ); } if ( blockchain == ETHEREUM || blockchain == AVALANCHE || blockchain == SOLANA ) { HtmlUtils.ShowNode( TR_1ST_PK_ID ); // HtmlUtils.ShowNode( TR_PRIV_KEY_ID ); } } // ------------------- WIF -------------------- let wif = this.wallet_info.getAttribute(WIF); if ( ( wallet_mode == HD_WALLET_TYPE || wallet_mode == SWORD_WALLET_TYPE ) && blockchain == SOLANA) { HtmlUtils.HideNode( TR_WIF_ID ); } else { if ( wif != undefined && wif != "" && blockchain != ETHEREUM && blockchain != AVALANCHE ) { HtmlUtils.ShowNode( TR_WIF_ID ); } else { HtmlUtils.HideNode( TR_WIF_ID ); } } // ------------------- WIF // ------------------- Entropy Source ------------------- if ( this.entropy_source_type == FORTUNES_ENTROPY_SRC_TYPE) { HtmlUtils.ShowNode( ENTROPY_SRC_FORTUNES_ID ); HtmlUtils.HideNode( ENTROPY_SRC_IMG_CONTAINER_ID ); } else if ( this.entropy_source_type == IMAGE_ENTROPY_SRC_TYPE) { HtmlUtils.ShowNode( ENTROPY_SRC_IMG_CONTAINER_ID ); HtmlUtils.HideNode( ENTROPY_SRC_FORTUNES_ID ); } // ------------------- Entropy Source let is_user_input = this.entropy_source_is_user_input; //this.updateStatusbarInfo( is_user_input ); if ( is_user_input ) { HtmlUtils.HideNode( ENTROPY_SRC_ROW ); HtmlUtils.HideNode( TR_SALT_ID ); HtmlUtils.HideNode( ENTROPY_SIZE_SELECT_ID ); HtmlUtils.HideNode( WORD_COUNT_SELECT_ID ); } else { HtmlUtils.ShowNode( ENTROPY_SRC_ROW ); HtmlUtils.ShowNode( TR_SALT_ID ); // trace2Main( pretty_format( "rGUI.upFieldVisib> is_user_input", is_user_input ) ); if ( this.wallet_info.getAttribute(WALLET_MODE) == HD_WALLET_TYPE ) { HtmlUtils.ShowNode( ENTROPY_SIZE_SELECT_ID ); HtmlUtils.ShowNode( WORD_COUNT_SELECT_ID ); } } } // updateFieldsVisibility() async updateFields( entropy ) { trace2Main( pretty_func_header_format( "RendererGUI.updateFields", entropy ) ); this.cb_enabled = false; //trace2Main(" this.entropy_source_type: " + this.entropy_source_type); //trace2Main( pretty_format( "rGUI.updFields> entropy", entropy ) ); trace2Main( pretty_format( "rGUI.upFields> wallet[ENTROPY]", this.wallet_info.getAttribute(ENTROPY) ) ); if ( entropy == undefined ) { entropy = this.wallet_info.getAttribute(ENTROPY); this.wallet_info.setAttribute(ENTROPY, entropy); // to update GUI } // trace2Main( pretty_format( "rGUI.upFields> entropy", entropy ) ); //let entropy_elt = HtmlUtils.GetNode( ENTROPY_ID ); this.setRefreshCmdState( false ); // trace2Main( pretty_format( "entropy_source_is_user_input", this.entropy_source_is_user_input ) ); trace2Main( pretty_format( "rGUI.upFields> CMD", this.wallet_info.getAttribute(CMD)) ); if ( this.wallet_info.getAttribute(CMD) == CMD_OPEN_WALLET || this.entropy_source_is_user_input ) { trace2Main( pretty_format( "rGUI.upFields> entropy_source *IS* user_input", "") ); await this.propagateFields( entropy ); } else { trace2Main( pretty_format( "rGUI.upFields> entropy_source *IS NOT* user_input", "") ); //trace2Main(" expected_entropy_bytes: " + this.expected_entropy_bytes); let salted_entropy_src_str = await this.getSaltedEntropySource(); //trace2Main( pretty_format( "Salted Entropy", getShortenedString( salted_entropy_src_str ) ) ); if ( salted_entropy_src_str.length > 0 ) { const options = { [LANG]: "EN", [WORD_COUNT]: this.wallet_info.getAttribute(WORD_COUNT) }; const data = { salted_entropy_src_str, options }; entropy = await window.ipcMain.EntropySourceToEntropy( data ); trace2Main( pretty_format( "rGUI.upFields> entropy", entropy ) ); this.wallet_info.setAttribute( ENTROPY, entropy ); await this.propagateFields( entropy ); //await this.propagateFields(entropy_elt.value, wif); } //else if ( entropy_elt.value.length == expected_entropy_hex_digits ) { // await this.propagateFields( entropy_value ); //} } HtmlUtils.SetNodeValue( SB_MSG_ID, "" ); trace2Main( pretty_func_header_format( "<END> RendererGUI.updateFields", entropy ) ); this.cb_enabled = true; } // updateFields() async updateWalletMode( wallet_mode ) { trace2Main( pretty_func_header_format("RendererGUI.updateWalletMode") ); this.cb_enabled = false; if ( wallet_mode != undefined ) { this.Options[WALLET_MODE] = wallet_mode; } else { wallet_mode = this.Options[WALLET_MODE]; } trace2Main( pretty_format( "rGUI.upWmode> wallet_mode", wallet_mode) ); let blockchain = HtmlUtils.GetNodeValue( WALLET_BLOCKCHAIN_ID ); if ( wallet_mode == SIMPLE_WALLET_TYPE ) { this.Options[ENTROPY_SIZE][SIMPLE_WALLET_TYPE] = 256; } HtmlUtils.InitializeNode( WALLET_BLOCKCHAIN_ID, this.Options['Blockchains'][wallet_mode], this.Options['Blockchains'][wallet_mode] ); let default_blockchain = this.Options[DEFAULT_BLOCKCHAIN][wallet_mode]; trace2Main( pretty_format( "rGUI.upWmode> default_blockchain", default_blockchain ) ); this.wallet_info.setAttribute( WALLET_MODE, wallet_mode ); this.wallet_info.setAttribute( BLOCKCHAIN, default_blockchain ); this.updateFieldsVisibility(); // HtmlUtils.SetNodeValue( WALLET_BLOCKCHAIN_ID, default_blockchain); // ---------- Update Window Title ---------- let coin = COIN_ABBREVIATIONS[default_blockchain]; let data = { coin, wallet_mode }; window.ipcMain.SetWindowTitle( data ); // ---------- Update Window Title this.updateFieldsVisibility(); this.cb_enabled = true; // trace2Main( pretty_func_header_format( "<END> RendererGUI.updateWalletMode" ) ); } // async updateWalletMode() async updateBlockchain( blockchain ) { trace2Main( pretty_func_header_format( "RendererGUI.updateBlockchain", blockchain ) ); if ( blockchain == undefined ) { blockchain = this.wallet_info.getAttribute( BLOCKCHAIN ); } let entropy_hex = this.wallet_info.getAttribute( ENTROPY ); let wallet_mode = this.wallet_info.getAttribute( WALLET_MODE ); trace2Main( pretty_format( "rGUI.upBlkCHN> wallet_mode", wallet_mode ) ); trace2Main( pretty_format( "rGUI.upBlkCHN> CMD", this.wallet_info.getAttribute(CMD) ) ); let wallet = {}; if ( this.wallet_info.getAttribute( CMD ) != CMD_OPEN_WALLET ) { if ( wallet_mode == SIMPLE_WALLET_TYPE ) { wallet = await this.generateSimpleWalletAddress( blockchain, entropy_hex ); } else if ( wallet_mode == HD_WALLET_TYPE || wallet_mode == SWORD_WALLET_TYPE ) { wallet = await this.generateHDWalletAddress( blockchain, entropy_hex ); } } this.wallet_info.setAttribute( ACCOUNT, 0 ); this.wallet_info.setAttribute( ADDRESS_INDEX, 0 ); this.wallet_info.setAttribute( WIF, wallet[WIF] ); trace2Main( pretty_format( "rGUI.upBlkCHN> WIF", wallet[WIF] ) ); // ---------- Update Window Title ---------- let coin = COIN_ABBREVIATIONS[blockchain]; let data = { coin, wallet_mode }; window.ipcMain.SetWindowTitle( data ); // ---------- Update Window Title trace2Main( pretty_format( "rGUI.upBlkCHN> coin", coin ) ); HtmlUtils.SetNodeValue( WALLET_COIN_ID, coin ); let wallet_address = this.wallet_info.getAttribute( ADDRESS ); trace2Main( pretty_format( "rGUI.upBlkCHN> wallet_address", wallet_address ) ); this.updateWalletURL( blockchain, wallet_address ); this.updateFieldsVisibility(); } // updateBlockchain() async updateOptionsFields( options_data ) { trace2Main( pretty_func_header_format( "RendererGUI.updateOptionsFields" ) ); this.cb_enabled = false; if ( options_data == undefined ) { trace2Main(" " + _RED_ + "**ERROR** options_data: " + options_data + _END_); await window.ipcMain.QuitApp(); } //trace2Main(" *!!* options_data: " + JSON.stringify(options_data)); this.wallet_info.setOptions( options_data ); let wallet_mode = options_data[WALLET_MODE]; trace2Main( pretty_format( "rGUI.upOpt> wallet_mode", wallet_mode ) ); let default_blockchain = options_data[DEFAULT_BLOCKCHAIN][wallet_mode]; trace2Main( pretty_format( "rGUI.upOpt> default_blockchain", default_blockchain ) ); HtmlUtils.SetNodeValue( WALLET_BLOCKCHAIN_ID, default_blockchain ); HtmlUtils.SetNodeValue( WALLET_COIN_ID, COIN_ABBREVIATIONS[default_blockchain] ); await this.updateWalletMode( wallet_mode ); let entropy_size = options_data[ENTROPY_SIZE][wallet_mode]; trace2Main( pretty_format( "rGUI.upOpt> entropy_size", entropy_size ) ); await this.updateEntropySize( entropy_size ); this.cb_enabled = true; } // async updateOptionsFields() async updateWalletAddress() { trace2Main( pretty_func_header_format( "RendererGUI.updateWalletAddress" ) ); let entropy = HtmlUtils.GetNodeValue( ENTROPY_ID ); trace2Main( pretty_format( "rGUI.upWadr> entropy", entropy ) ); let password = HtmlUtils.GetNodeValue( PASSWORD_ID ); this.wallet_info.setAttribute( PASSWORD, password ); let account = parseInt( HtmlUtils.GetNodeValue( ACCOUNT_ID ) ); this.wallet_info.setAttribute( ACCOUNT, account ); //trace2Main( pretty_format( "rGUI.uWadr> account", account ) ); let address_index = parseInt( HtmlUtils.GetNodeValue( ADDRESS_INDEX_ID ) ); this.wallet_info.setAttribute( ADDRESS_INDEX, address_index ); //trace2Main( pretty_format( "rGUI.uWadr> address_index", address_index) ); this.setEntropySourceIsUserInput( true ); //this.updateStatusbarInfo( true );