def check_text(self): self.errors = [] if self.is_pr: return # filter out empty lines lines = [i for i in self.lines() if i] outputs = [] total = 0 self.payto_address = None if len(lines) == 1: data = lines[0] if ':' in data and '?' in data and len(data) > 35: try: self.scan_f(data) except AddressError as e: self.errors.append((0, str(e))) else: return elif ':' not in data and len(data) > 35: self.setText(Address.prefix_from_address_string(data) + ':' + data) return try: self.parse_address(data) except Exception as e: self.errors.append((0, str(e))) try: self.payto_address = self.parse_output(data) self.address_string_for_slp_check = data except: self.address_string_for_slp_check = '' if self.payto_address: self.win.lock_amount(False) return is_max = False for i, line in enumerate(lines): try: _type, to_address, amount = self.parse_address_and_amount(line) except Exception as e: if len(self.errors) < 1: self.errors.append((i, line.strip())) continue outputs.append((_type, to_address, amount)) if amount == '!': is_max = True else: total += amount self.win.max_button.setChecked(is_max) self.outputs = outputs self.payto_address = None if self.win.max_button.isChecked(): self.win.do_update_fee() else: """ The following line is commented out for SLP. If this line is not commented out then the amount field will always be reset to 0 when the address text is edited. For SLP, an amount of 546 sat should be left in the amount_e field. """ #self.amount_edit.setAmount(total if outputs else None) self.win.lock_amount(total or len(lines)>1)
def check_text(self): self.errors = [] if self.is_pr: return # filter out empty lines lines = [i for i in self.lines() if i] outputs = [] total = 0 self.payto_address = None self.cointext = None if len(lines) == 1: data = lines[0] if ':' in data and '?' in data and len(data) > 35: try: self.scan_f(data) except AddressError as e: self.errors.append((0, str(e))) else: return elif ':' not in data and len(data) > 35: self.setText( Address.prefix_from_address_string(data) + ':' + data) return try: self.parse_address(data) except Exception as e: self.errors.append((0, str(e))) try: self.payto_address = self.parse_output(data) self.address_string_for_slp_check = data except: self.address_string_for_slp_check = '' try: self.cointext = self.parse_cointext(data) except: pass if self.payto_address or self.cointext: self.win.lock_amount(False) return is_max = False for i, line in enumerate(lines): try: _type, to_address, amount = self.parse_address_and_amount(line) except Exception as e: if len(self.errors) < 1: self.errors.append((i, line.strip())) continue outputs.append((_type, to_address, amount)) if amount == '!': is_max = True else: total += amount self.win.max_button.setChecked(is_max) self.outputs = outputs self.payto_address = None if self.win.max_button.isChecked(): self.win.do_update_fee() else: if not self.win.slp_token_id: self.amount_edit.setAmount(total if outputs else None) self.win.lock_amount(total or len(lines) > 1)
def __init__(self, main_window, *, nft_parent_id=None): #self.provided_token_name = token_name # We want to be a top-level window QDialog.__init__(self, parent=None) from .main_window import ElectrumWindow assert isinstance(main_window, ElectrumWindow) main_window._slp_dialogs.add(self) finalization_print_error(self) # track object lifecycle self.main_window = main_window self.wallet = main_window.wallet self.config = main_window.config self.network = main_window.network self.app = main_window.app self.nft_parent_id = nft_parent_id if nft_parent_id != None: self.token_type = 65 else: self.token_type = 1 if self.main_window.gui_object.warn_if_no_network(self.main_window): return self.setWindowTitle(_("Create a New Token")) vbox = QVBoxLayout() self.setLayout(vbox) grid = QGridLayout() grid.setColumnStretch(1, 1) vbox.addLayout(grid) row = 0 msg = _( 'An optional name string embedded in the token genesis transaction.' ) grid.addWidget(HelpLabel(_('Token Name (optional):'), msg), row, 0) self.token_name_e = QLineEdit() grid.addWidget(self.token_name_e, row, 1) row += 1 msg = _( 'An optional ticker symbol string embedded into the token genesis transaction.' ) grid.addWidget(HelpLabel(_('Ticker Symbol (optional):'), msg), row, 0) self.token_ticker_e = QLineEdit() self.token_ticker_e.setFixedWidth(110) self.token_ticker_e.textChanged.connect(self.upd_token) grid.addWidget(self.token_ticker_e, row, 1) row += 1 msg = _( 'An optional URL string embedded into the token genesis transaction.' ) grid.addWidget(HelpLabel(_('Document URL (optional):'), msg), row, 0) self.token_url_e = QLineEdit() self.token_url_e.setFixedWidth(560) self.token_url_e.textChanged.connect(self.upd_token) grid.addWidget(self.token_url_e, row, 1) row += 1 msg = _('An optional hash hexidecimal bytes embedded into the token genesis transaction for hashing') \ + 'the document file contents at the URL provided above.' grid.addWidget(HelpLabel(_('Document Hash (optional):'), msg), row, 0) self.token_dochash_e = QLineEdit() self.token_dochash_e.setInputMask( "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH") self.token_dochash_e.setFixedWidth(560) self.token_dochash_e.textChanged.connect(self.upd_token) grid.addWidget(self.token_dochash_e, row, 1) row += 1 msg = _('Sets the number of decimals of divisibility for this token (embedded into genesis).') \ + '\n\n' \ + _('Each 1 token is divisible into 10^(decimals) base units, and internally in the protocol') \ + _('the token amounts are represented as 64-bit integers measured in these base units.') grid.addWidget(HelpLabel(_('Decimal Places:'), msg), row, 0) self.token_ds_e = QDoubleSpinBox() self.token_ds_e.setRange(0, 9) self.token_ds_e.setDecimals(0) self.token_ds_e.setFixedWidth(50) self.token_ds_e.valueChanged.connect(self.upd_token) grid.addWidget(self.token_ds_e, row, 1) row += 1 msg = _('The number of tokens created during token genesis transaction,') \ + _('send to the receiver address provided below.') if nft_parent_id == None: self.token_qty_label = HelpLabel(_('Token Quantity:'), msg) else: self.token_qty_label = HelpLabel(_('Number of Child NFTs:'), msg) grid.addWidget(self.token_qty_label, row, 0) self.token_qty_e = SLPAmountEdit('', 0) self.token_qty_e.setFixedWidth(200) self.token_qty_e.textChanged.connect(self.check_token_qty) grid.addWidget(self.token_qty_e, row, 1) row += 1 msg = _( 'The \'simpleledger:\' formatted bitcoin address for the genesis receiver of all genesis tokens.' ) grid.addWidget(HelpLabel(_('Token Receiver Address:'), msg), row, 0) self.token_pay_to_e = ButtonsLineEdit() self.token_pay_to_e.setFixedWidth(560) grid.addWidget(self.token_pay_to_e, row, 1) row += 1 self.token_fixed_supply_cb = cb = QCheckBox(_('Fixed Supply')) self.token_fixed_supply_cb.setChecked(True) grid.addWidget(self.token_fixed_supply_cb, row, 1) cb.clicked.connect(self.show_mint_baton_address) row += 1 self.token_nft_parent_cb = cb = QCheckBox(_('Is NFT Parent?')) self.token_nft_parent_cb.setChecked(False) grid.addWidget(self.token_nft_parent_cb, row, 1) cb.clicked.connect(self.token_nft_parent_cb_update) row += 1 if self.nft_parent_id: self.token_nft_parent_cb.setDisabled(True) self.token_fixed_supply_cb.setDisabled(True) self.token_qty_e.setAmount(1) self.token_qty_e.setDisabled(True) self.token_ds_e.setDisabled(True) msg = _('The \'simpleledger:\' formatted bitcoin address for the "minting baton" receiver.') + '\n\n' \ + _('After the genesis transaction, further unlimited minting operations can be performed by the owner of') \ + ' the "minting baton" transaction output. This baton can be repeatedly used for minting operations but' \ + ' it cannot be duplicated.' self.token_baton_label = HelpLabel(_('Address for Baton:'), msg) self.token_baton_label.setHidden(True) grid.addWidget(self.token_baton_label, row, 0) self.token_baton_to_e = ButtonsLineEdit() self.token_baton_to_e.setFixedWidth(560) self.token_baton_to_e.setHidden(True) grid.addWidget(self.token_baton_to_e, row, 1) row += 1 try: slpAddr = self.wallet.get_unused_address().to_slpaddr() self.token_pay_to_e.setText( Address.prefix_from_address_string(slpAddr) + ":" + slpAddr) self.token_baton_to_e.setText( Address.prefix_from_address_string(slpAddr) + ":" + slpAddr) except Exception as e: pass if nft_parent_id: nft_parent_coin = get_nft_parent_coin(nft_parent_id, main_window) if not get_nft_parent_coin(nft_parent_id, main_window): hbox2 = QHBoxLayout() vbox.addLayout(hbox2) warnpm = QIcon(":icons/warning.png").pixmap(20, 20) self.warn1 = l = QLabel() l.setPixmap(warnpm) hbox2.addWidget(l) self.warn_msg = msg = QLabel( _(" NOTE: The parent token needs to be split before a new NFT can be created, click 'Prepare Group Parent'." )) hbox2.addWidget(msg) self.warn2 = l = QLabel() l.setPixmap(warnpm) hbox2.addStretch(1) hbox2.addWidget(l) hbox = QHBoxLayout() vbox.addLayout(hbox) self.cancel_button = b = QPushButton(_("Cancel")) self.cancel_button.setAutoDefault(False) self.cancel_button.setDefault(False) b.clicked.connect(self.close) hbox.addWidget(self.cancel_button) hbox.addStretch(1) # self.hash_button = b = QPushButton(_("Compute Document Hash...")) # self.hash_button.setAutoDefault(False) # self.hash_button.setDefault(False) # b.clicked.connect(self.hash_file) # b.setDefault(True) # hbox.addWidget(self.hash_button) self.tok_doc_button = b = QPushButton(_("Upload a Token Document...")) self.tok_doc_button.setAutoDefault(False) self.tok_doc_button.setDefault(False) b.clicked.connect(self.show_upload) b.setDefault(True) hbox.addWidget(self.tok_doc_button) if nft_parent_id: self.import_burn_tx_file_button = EnterButton( _("Import file..."), self.do_process_from_file) self.import_burn_tx_text_button = EnterButton( _("Import hex..."), self.do_process_from_text) hbox.addWidget(self.import_burn_tx_file_button) hbox.addWidget(self.import_burn_tx_text_button) self.preview_button = EnterButton(_("Preview"), self.do_preview) hbox.addWidget(self.preview_button) self.create_button = b = QPushButton( _("Create New Token" )) #if self.provided_token_name is None else _("Change")) b.clicked.connect(self.create_token) self.create_button.setAutoDefault(True) self.create_button.setDefault(True) hbox.addWidget(self.create_button) if nft_parent_id: self.create_button.setText("Create NFT") if not nft_parent_coin: self.create_button.setHidden(True) self.prepare_parent_bttn = QPushButton( _("Prepare Group Parent")) self.prepare_parent_bttn.clicked.connect( self.prepare_nft_parent) self.prepare_parent_bttn.setAutoDefault(True) self.prepare_parent_bttn.setDefault(True) hbox.addWidget(self.prepare_parent_bttn) self.token_name_e.setDisabled(True) self.token_ticker_e.setDisabled(True) self.token_url_e.setDisabled(True) self.token_dochash_e.setDisabled(True) self.token_pay_to_e.setDisabled(True) self.token_baton_to_e.setDisabled(True) dialogs.append(self) self.show() self.token_name_e.setFocus()
def __init__(self, main_window, token_id_hex): # We want to be a top-level window QDialog.__init__(self, parent=None) from .main_window import ElectrumWindow assert isinstance(main_window, ElectrumWindow) main_window._slp_dialogs.add(self) finalization_print_error(self) # Track object lifecycle self.main_window = main_window self.wallet = main_window.wallet self.network = main_window.network self.app = main_window.app if self.main_window.gui_object.warn_if_no_network(self.main_window): return self.setWindowTitle(_("Mint Additional Tokens")) vbox = QVBoxLayout() self.setLayout(vbox) grid = QGridLayout() grid.setColumnStretch(1, 1) vbox.addLayout(grid) row = 0 msg = _('Unique identifier for the token.') grid.addWidget(HelpLabel(_('Token ID:'), msg), row, 0) self.token_id_e = QLineEdit() self.token_id_e.setFixedWidth(490) self.token_id_e.setText(token_id_hex) self.token_id_e.setDisabled(True) grid.addWidget(self.token_id_e, row, 1) row += 1 msg = _('The number of decimal places used in the token quantity.') grid.addWidget(HelpLabel(_('Decimals:'), msg), row, 0) self.token_dec = QDoubleSpinBox() decimals = self.main_window.wallet.token_types.get( token_id_hex)['decimals'] self.token_dec.setRange(0, 9) self.token_dec.setValue(decimals) self.token_dec.setDecimals(0) self.token_dec.setFixedWidth(50) self.token_dec.setDisabled(True) grid.addWidget(self.token_dec, row, 1) row += 1 msg = _( 'The number of tokens created during token minting transaction, send to the receiver address provided below.' ) grid.addWidget(HelpLabel(_('Additional Token Quantity:'), msg), row, 0) name = self.main_window.wallet.token_types.get(token_id_hex)['name'] self.token_qty_e = SLPAmountEdit(name, int(decimals)) self.token_qty_e.setFixedWidth(200) self.token_qty_e.textChanged.connect(self.check_token_qty) grid.addWidget(self.token_qty_e, row, 1) row += 1 msg = _( 'The simpleledger formatted bitcoin address for the genesis receiver of all genesis tokens.' ) grid.addWidget(HelpLabel(_('Token Receiver Address:'), msg), row, 0) self.token_pay_to_e = ButtonsLineEdit() self.token_pay_to_e.setFixedWidth(490) grid.addWidget(self.token_pay_to_e, row, 1) row += 1 msg = _( 'The simpleledger formatted bitcoin address for the genesis baton receiver.' ) self.token_baton_label = HelpLabel(_('Mint Baton Address:'), msg) grid.addWidget(self.token_baton_label, row, 0) self.token_baton_to_e = ButtonsLineEdit() self.token_baton_to_e.setFixedWidth(490) grid.addWidget(self.token_baton_to_e, row, 1) row += 1 try: slpAddr = self.wallet.get_unused_address().to_slpaddr() self.token_pay_to_e.setText( Address.prefix_from_address_string(slpAddr) + ":" + slpAddr) self.token_baton_to_e.setText( Address.prefix_from_address_string(slpAddr) + ":" + slpAddr) except Exception as e: pass self.token_fixed_supply_cb = cb = QCheckBox( _('Permanently end issuance')) self.token_fixed_supply_cb.setChecked(False) grid.addWidget(self.token_fixed_supply_cb, row, 0) cb.clicked.connect(self.show_mint_baton_address) row += 1 hbox = QHBoxLayout() vbox.addLayout(hbox) self.cancel_button = b = QPushButton(_("Cancel")) self.cancel_button.setAutoDefault(False) self.cancel_button.setDefault(False) b.clicked.connect(self.close) b.setDefault(True) hbox.addWidget(self.cancel_button) hbox.addStretch(1) self.preview_button = EnterButton(_("Preview"), self.do_preview) self.mint_button = b = QPushButton(_("Create Additional Tokens")) b.clicked.connect(self.mint_token) self.mint_button.setAutoDefault(True) self.mint_button.setDefault(True) hbox.addWidget(self.preview_button) hbox.addWidget(self.mint_button) dialogs.append(self) self.show() self.token_qty_e.setFocus()
def __init__(self, main_window): #self.provided_token_name = token_name # We want to be a top-level window QDialog.__init__(self, parent=main_window) self.main_window = main_window self.wallet = main_window.wallet self.config = main_window.config self.network = main_window.network self.app = main_window.app self.setWindowTitle(_("Create a New Token")) vbox = QVBoxLayout() self.setLayout(vbox) grid = QGridLayout() grid.setColumnStretch(1, 1) vbox.addLayout(grid) row = 0 msg = _( 'An optional name string embedded in the token genesis transaction.' ) grid.addWidget(HelpLabel(_('Token Name (optional):'), msg), row, 0) self.token_name_e = QLineEdit() grid.addWidget(self.token_name_e, row, 1) row += 1 msg = _( 'An optional ticker symbol string embedded into the token genesis transaction.' ) grid.addWidget(HelpLabel(_('Ticker Symbol (optional):'), msg), row, 0) self.token_ticker_e = QLineEdit() self.token_ticker_e.setFixedWidth(110) self.token_ticker_e.textChanged.connect(self.upd_token) grid.addWidget(self.token_ticker_e, row, 1) row += 1 msg = _( 'An optional URL string embedded into the token genesis transaction.' ) grid.addWidget(HelpLabel(_('Document URL (optional):'), msg), row, 0) self.token_url_e = QLineEdit() self.token_url_e.setFixedWidth(560) self.token_url_e.textChanged.connect(self.upd_token) grid.addWidget(self.token_url_e, row, 1) row += 1 msg = _( 'An optional hash hexidecimal bytes embedded into the token genesis transaction for hashing the document file contents at the URL provided above.' ) grid.addWidget(HelpLabel(_('Document Hash (optional):'), msg), row, 0) self.token_dochash_e = QLineEdit() self.token_dochash_e.setInputMask( "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH") self.token_dochash_e.setFixedWidth(560) self.token_dochash_e.textChanged.connect(self.upd_token) grid.addWidget(self.token_dochash_e, row, 1) row += 1 msg = _('Sets the number of decimals of divisibility for this token (embedded into genesis).') + '\n\n'\ + _('Each 1 token is divisible into 10^(decimals) base units, and internally in the protocol the token amounts are represented as 64-bit integers measured in these base units.') grid.addWidget(HelpLabel(_('Decimal Places:'), msg), row, 0) self.token_ds_e = QDoubleSpinBox() self.token_ds_e.setRange(0, 9) self.token_ds_e.setDecimals(0) self.token_ds_e.setFixedWidth(50) self.token_ds_e.valueChanged.connect(self.upd_token) grid.addWidget(self.token_ds_e, row, 1) row += 1 msg = _( 'The number of tokens created during token genesis transaction, send to the receiver address provided below.' ) grid.addWidget(HelpLabel(_('Token Quantity:'), msg), row, 0) self.token_qty_e = SLPAmountEdit('', 0) self.token_qty_e.setFixedWidth(200) self.token_qty_e.textChanged.connect(self.check_token_qty) grid.addWidget(self.token_qty_e, row, 1) row += 1 msg = _( 'The \'simpleledger:\' formatted bitcoin address for the genesis receiver of all genesis tokens.' ) grid.addWidget(HelpLabel(_('Token Receiver Address:'), msg), row, 0) self.token_pay_to_e = ButtonsLineEdit() self.token_pay_to_e.setFixedWidth(560) grid.addWidget(self.token_pay_to_e, row, 1) try: slpAddr = self.wallet.get_unused_address().to_slpaddr() self.token_pay_to_e.setText( Address.prefix_from_address_string(slpAddr) + ":" + slpAddr) except: pass row += 1 self.token_fixed_supply_cb = cb = QCheckBox(_('Fixed Supply')) self.token_fixed_supply_cb.setChecked(True) grid.addWidget(self.token_fixed_supply_cb, row, 1) cb.clicked.connect(self.show_mint_baton_address) row += 1 msg = _('The \'simpleledger:\' formatted bitcoin address for the "minting baton" receiver.') + '\n\n'\ + _('After the genesis transaction, further unlimited minting operations can be performed by the owner of the "minting baton" transaction output. This baton can be repeatedly used for minting operations but it cannot be duplicated.') self.token_baton_label = HelpLabel(_('Address for Baton:'), msg) self.token_baton_label.setHidden(True) grid.addWidget(self.token_baton_label, row, 0) self.token_baton_to_e = ButtonsLineEdit() self.token_baton_to_e.setFixedWidth(560) self.token_baton_to_e.setHidden(True) grid.addWidget(self.token_baton_to_e, row, 1) row += 1 hbox = QHBoxLayout() vbox.addLayout(hbox) self.cancel_button = b = QPushButton(_("Cancel")) self.cancel_button.setAutoDefault(False) self.cancel_button.setDefault(False) b.clicked.connect(self.close) hbox.addWidget(self.cancel_button) hbox.addStretch(1) # self.hash_button = b = QPushButton(_("Compute Document Hash...")) # self.hash_button.setAutoDefault(False) # self.hash_button.setDefault(False) # b.clicked.connect(self.hash_file) # b.setDefault(True) # hbox.addWidget(self.hash_button) self.tok_doc_button = b = QPushButton(_("Upload a Token Document...")) self.tok_doc_button.setAutoDefault(False) self.tok_doc_button.setDefault(False) b.clicked.connect(self.show_upload) b.setDefault(True) hbox.addWidget(self.tok_doc_button) self.preview_button = EnterButton(_("Preview"), self.do_preview) self.create_button = b = QPushButton( _("Create New Token" )) #if self.provided_token_name is None else _("Change")) b.clicked.connect(self.create_token) self.create_button.setAutoDefault(True) self.create_button.setDefault(True) hbox.addWidget(self.preview_button) hbox.addWidget(self.create_button) dialogs.append(self) self.show() self.token_name_e.setFocus()