diff --git a/src/assets/assets.cpp b/src/assets/assets.cpp index 806e128e6b..3ff11d2141 100644 --- a/src/assets/assets.cpp +++ b/src/assets/assets.cpp @@ -846,10 +846,7 @@ bool CAssetsCache::TrySpendCoin(const COutPoint& out, const CTxOut& txOut) // Update the cache so we can save to database vSpentAssets.push_back(spend); - } else { - return error("%s : ERROR Failed to find current assets address amount. Asset %s: , Address : %s", __func__, assetName, address); } - } else { return error("%s : ERROR Failed to get asset from the OutPoint: %s", __func__, out.ToString()); } @@ -1952,12 +1949,17 @@ void GetAssetData(const CScript& script, CAssetOutputEntry& data) } } -void GetAllOwnedAssets(std::vector& names) +void GetAllOwnedAssets(CWallet* pwallet, std::vector& names) { - for (auto owned : passets->mapMyUnspentAssets) { - if (IsAssetNameAnOwner(owned.first)) { - names.emplace_back(owned.first); - } + if(!pwallet) + return; + + std::map > mapAssets; + pwallet->AvailableAssets(mapAssets); + + for (auto item : mapAssets) { + if (IsAssetNameAnOwner(item.first)) + names.emplace_back(item.first); } } diff --git a/src/assets/assets.h b/src/assets/assets.h index 3e3041d253..66d2d5a83c 100644 --- a/src/assets/assets.h +++ b/src/assets/assets.h @@ -338,7 +338,7 @@ bool IsScriptTransferAsset(const CScript& scriptPubKey); bool IsNewOwnerTxValid(const CTransaction& tx, const std::string& assetName, const std::string& address, std::string& errorMsg); -void GetAllOwnedAssets(std::vector& names); +void GetAllOwnedAssets(CWallet* pwallet, std::vector& names); void GetAllMyAssets(std::vector& names); void UpdatePossibleAssets(); diff --git a/src/assets/assettypes.h b/src/assets/assettypes.h index f304703cf4..c64c29db57 100644 --- a/src/assets/assettypes.h +++ b/src/assets/assettypes.h @@ -27,6 +27,13 @@ enum AssetType REISSUE }; +enum IssueAssetType +{ + ISSUE_ROOT = 0, + ISSUE_SUB = 1, + ISSUE_UNIQUE = 2 +}; + class CNewAsset { public: std::string strName; // MAX 31 Bytes diff --git a/src/qt/createassetdialog.cpp b/src/qt/createassetdialog.cpp index 3bf963a30b..572b8717cc 100644 --- a/src/qt/createassetdialog.cpp +++ b/src/qt/createassetdialog.cpp @@ -41,9 +41,13 @@ CreateAssetDialog::CreateAssetDialog(const PlatformStyle *_platformStyle, QWidge connect(ui->unitBox, SIGNAL(valueChanged(int)), this, SLOT(onUnitChanged(int))); connect(ui->rvnChangeBox, SIGNAL(clicked()), this, SLOT(onCustomAddressClicked())); connect(ui->changeAddressText, SIGNAL(textChanged(QString)), this, SLOT(onChangeAddressChanged(QString))); + connect(ui->assetType, SIGNAL(activated(int)), this, SLOT(onAssetTypeActivated(int))); + connect(ui->assetList, SIGNAL(activated(int)), this, SLOT(onAssetListActivated(int))); // Setup the default values setUpValues(); + + format = "%1%2%3"; } CreateAssetDialog::~CreateAssetDialog() @@ -67,6 +71,30 @@ void CreateAssetDialog::setUpValues() CheckFormState(); ui->unitExampleLabel->setStyleSheet("font-weight: bold"); + + // Setup the asset types + QStringList list; + list.append(tr("Main Asset")); + list.append(tr("Sub Asset")); +// list.append(tr("Unique Asset")); + ui->assetType->addItems(list); + type = ISSUE_ROOT; + ui->assetTypeLabel->setText(tr("Asset Type") + ":"); + + // Setup the asset list + ui->assetList->hide(); + std::vector names; + GetAllOwnedAssets(model->getWallet(), names); + for (auto item : names) { + std::string name = QString::fromStdString(item).split("!").first().toStdString(); + if (name.size() != 30) + ui->assetList->addItem(QString::fromStdString(name)); + } + ui->assetFullName->setTextFormat(Qt::RichText); + ui->assetFullName->setStyleSheet("font-weight: bold"); + + ui->assetType->setStyleSheet("font-weight: bold"); + } void CreateAssetDialog::toggleIPFSText() @@ -129,8 +157,19 @@ void CreateAssetDialog::CheckFormState() const CTxDestination dest = DecodeDestination(ui->addressText->text().toStdString()); + QString name = GetAssetName(); + AssetType assetType; - bool assetNameValid = IsAssetNameValid(ui->nameText->text().toStdString(), assetType) && assetType == AssetType::ROOT; + bool assetNameValid = IsAssetNameValid(name.toStdString(), assetType); + if (assetNameValid && assetType == ROOT && type != ISSUE_ROOT) + return; + + if (assetNameValid && assetType == SUB && type != ISSUE_SUB) + return; + + if (assetNameValid && assetType == UNIQUE && type != ISSUE_UNIQUE) + return; + if (!(IsValidDestination(dest) || ui->addressText->text().isEmpty()) && assetNameValid) { ui->addressText->setStyleSheet("border: 1px solid red"); showMessage("Warning: Invalid Raven address"); @@ -170,7 +209,7 @@ void CreateAssetDialog::ipfsStateChanged() void CreateAssetDialog::checkAvailabilityClicked() { - QString name = ui->nameText->text(); + QString name = GetAssetName(); LOCK(cs_main); if (passets) { @@ -197,26 +236,60 @@ void CreateAssetDialog::checkAvailabilityClicked() void CreateAssetDialog::onNameChanged(QString name) { + // Update the displayed name to uppercase if the type only accepts uppercase + name = name.toUpper(); + UpdateAssetNameToUpper(); + + QString assetName = name; + + // Get the identifier for the asset type + QString identifier = GetSpecialCharacter(); + if (name.size() == 0) { hideMessage(); + ui->availabilityButton->setDisabled(true); + updatePresentedAssetName(name); return; } - if (name.size() < 3) { - ui->nameText->setStyleSheet("border: 1px solid red"); - showMessage("Invalid: Minimum of 3 character in length"); - return; - } + if (type == ISSUE_ROOT) { + if (name.size() < 3) { + ui->nameText->setStyleSheet("border: 1px solid red"); + showMessage("Invalid: Minimum of 3 character in length"); + ui->availabilityButton->setDisabled(true); + return; + } - AssetType assetType; - if (!IsAssetNameValid(name.toStdString(), assetType) || assetType != AssetType::ROOT) { - ui->nameText->setStyleSheet("border: 1px solid red"); - showMessage("Invalid: Max Size 30 Characters. Allowed characters include: A-Z 0-9 . _"); - } else { - hideMessage(); - ui->availabilityButton->setDisabled(false); + AssetType assetType; + if (IsAssetNameValid(name.toStdString(), assetType) && assetType == ROOT) { + hideMessage(); + ui->availabilityButton->setDisabled(false); + + } else { + ui->nameText->setStyleSheet("border: 1px solid red"); + showMessage("Invalid: Max Size 30 Characters. Allowed characters include: A-Z 0-9 . _"); + } + } else if (type == ISSUE_SUB || type == ISSUE_UNIQUE) { + if (name.size() == 0) { + hideMessage(); + ui->availabilityButton->setDisabled(true); + return; + } + + AssetType assetType; + if (IsAssetNameValid(ui->assetList->currentText().toStdString() + identifier.toStdString() + name.toStdString(), assetType) && (assetType == SUB || assetType == UNIQUE)) { + hideMessage(); + ui->availabilityButton->setDisabled(false); + } else { + ui->nameText->setStyleSheet("border: 1px solid red"); + showMessage("Invalid: Max Size 30 Characters. Allowed characters include: A-Z 0-9 . _"); + ui->availabilityButton->setDisabled(true); + } } + // Set the assetName + updatePresentedAssetName(format.arg(type == ISSUE_ROOT ? "" : ui->assetList->currentText(), identifier, name)); + checkedAvailablity = false; disableCreateButton(); } @@ -244,8 +317,8 @@ void CreateAssetDialog::onCreateAssetClicked() } else { address = ui->addressText->text(); } + QString name = GetAssetName(); - QString name = ui->nameText->text(); CAmount quantity = ui->quantitySpinBox->value() * COIN; int units = ui->unitBox->value(); bool reissuable = ui->reissuableBox->isChecked(); @@ -398,4 +471,88 @@ void CreateAssetDialog::onCustomAddressClicked() void CreateAssetDialog::onChangeAddressChanged(QString changeAddress) { CheckFormState(); +} + +void CreateAssetDialog::onAssetTypeActivated(int index) +{ + // Update the selected type + type = index; + + // Get the identifier for the asset type + QString identifier = GetSpecialCharacter(); + + if (index != 0) { + ui->assetList->show(); + } else { + ui->assetList->hide(); + } + + UpdateAssetNameMaxSize(); + + // Set assetName + updatePresentedAssetName(format.arg(type == ISSUE_ROOT ? "" : ui->assetList->currentText(), identifier, ui->nameText->text())); + + if (ui->nameText->text().size()) + ui->availabilityButton->setDisabled(false); + else + ui->availabilityButton->setDisabled(true); + ui->createAssetButton->setDisabled(true); +} + +void CreateAssetDialog::onAssetListActivated(int index) +{ + // Get the identifier for the asset type + QString identifier = GetSpecialCharacter(); + + UpdateAssetNameMaxSize(); + + // Set assetName + updatePresentedAssetName(format.arg(type == ISSUE_ROOT ? "" : ui->assetList->currentText(), identifier, ui->nameText->text())); + + if (ui->nameText->text().size()) + ui->availabilityButton->setDisabled(false); + else + ui->availabilityButton->setDisabled(true); + ui->createAssetButton->setDisabled(true); +} + +void CreateAssetDialog::updatePresentedAssetName(QString name) +{ + ui->assetFullName->setText(name); +} + +QString CreateAssetDialog::GetSpecialCharacter() +{ + if (type == ISSUE_SUB) + return "/"; + else if (type == ISSUE_UNIQUE) + return "#"; + + return ""; +} + +QString CreateAssetDialog::GetAssetName() +{ + if (type == ISSUE_ROOT) + return ui->nameText->text(); + else if (type == ISSUE_SUB) + return ui->assetList->currentText() + "/" + ui->nameText->text(); + else if (type == ISSUE_UNIQUE) + return ui->assetList->currentText() + "#" + ui->nameText->text(); +} + +void CreateAssetDialog::UpdateAssetNameMaxSize() +{ + if (type == ISSUE_ROOT) { + ui->nameText->setMaxLength(30); + } else if (type == ISSUE_SUB || type == ISSUE_UNIQUE) { + ui->nameText->setMaxLength(30 - (ui->assetList->currentText().size() + 1)); + } +} + +void CreateAssetDialog::UpdateAssetNameToUpper() +{ + if (type == ISSUE_ROOT || type == ISSUE_SUB) { + ui->nameText->setText(ui->nameText->text().toUpper()); + } } \ No newline at end of file diff --git a/src/qt/createassetdialog.h b/src/qt/createassetdialog.h index 060fb72cce..681a538c2f 100644 --- a/src/qt/createassetdialog.h +++ b/src/qt/createassetdialog.h @@ -28,6 +28,9 @@ Q_OBJECT explicit CreateAssetDialog(const PlatformStyle *platformStyle, QWidget *parent = 0, WalletModel *model = NULL); ~CreateAssetDialog(); + int type; + QString format; + private: Ui::CreateAssetDialog *ui; WalletModel *model; @@ -35,7 +38,6 @@ Q_OBJECT bool checkedAvailablity = false; - void toggleIPFSText(); void setUpValues(); void showMessage(QString string); @@ -44,6 +46,11 @@ Q_OBJECT void disableCreateButton(); void enableCreateButton(); void CheckFormState(); + void updatePresentedAssetName(QString name); + QString GetSpecialCharacter(); + QString GetAssetName(); + void UpdateAssetNameMaxSize(); + void UpdateAssetNameToUpper(); private Q_SLOTS: void ipfsStateChanged(); @@ -56,6 +63,8 @@ private Q_SLOTS: void onUnitChanged(int value); void onCustomAddressClicked(); void onChangeAddressChanged(QString changeAddress); + void onAssetTypeActivated(int index); + void onAssetListActivated(int index); }; #endif // RAVEN_QT_CREATEASSETDIALOG_H diff --git a/src/qt/forms/createassetdialog.ui b/src/qt/forms/createassetdialog.ui index 7332617c83..2f7f9c7403 100644 --- a/src/qt/forms/createassetdialog.ui +++ b/src/qt/forms/createassetdialog.ui @@ -7,13 +7,43 @@ 0 0 1001 - 436 + 516 Transaction details + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -28,11 +58,24 @@ A-Z 0-9 and . or _ as the second character + + 30 + The name of the asset you would like to create + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + diff --git a/src/qt/reissueassetdialog.cpp b/src/qt/reissueassetdialog.cpp index 120043fa16..5eab53e04a 100644 --- a/src/qt/reissueassetdialog.cpp +++ b/src/qt/reissueassetdialog.cpp @@ -71,7 +71,7 @@ void ReissueAssetDialog::setUpValues() LOCK(cs_main); std::vector assets; - GetAllOwnedAssets(assets); + GetAllOwnedAssets(model->getWallet(), assets); ui->comboBox->addItem("Select an asset"); diff --git a/src/qt/sendassetsentry.cpp b/src/qt/sendassetsentry.cpp index 927a6f587f..ce7c5beb63 100644 --- a/src/qt/sendassetsentry.cpp +++ b/src/qt/sendassetsentry.cpp @@ -309,7 +309,7 @@ void SendAssetsEntry::onSendOwnershipChanged() if (ui->ownerCheckBox->isChecked()) { LOCK(cs_main); std::vector names; - GetAllOwnedAssets(names); + GetAllOwnedAssets(model->getWallet(), names); QStringList list; for (auto name: names)