diff --git a/chain/wallet/CellframeNodeConfig.cpp b/chain/wallet/CellframeNodeConfig.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1b72aaf6715d15a6fe0eb74cc8d2a790a3751bc --- /dev/null +++ b/chain/wallet/CellframeNodeConfig.cpp @@ -0,0 +1,40 @@ +#include "CellframeNodeConfig.h" + +CellframeNodeConfig::CellframeNodeConfig(QObject *parent) : QObject(parent) +{ + +} + + +CellframeNodeConfig *CellframeNodeConfig::instance(const QString &cfgPath) +{ + static CellframeNodeConfig _instance; + if (!cfgPath.isEmpty()) + _instance.parseConfig(cfgPath); + return &_instance; +} + + +QString CellframeNodeConfig::getDefaultCADir() +{ + //WARNING only Linux default + return "/opt/cellframe-node/var/lib/ca"; +} + +QString CellframeNodeConfig::getShareCADir() +{ + //WARNING only Linux default + return "/opt/cellframe-node/share/ca"; +} + +bool CellframeNodeConfig::parseConfig(const QString &cfgPath) +{ + Q_UNUSED(cfgPath); + //dap_config_open + return true; +} + + + + + diff --git a/chain/wallet/CellframeNodeConfig.h b/chain/wallet/CellframeNodeConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..0a2685ca0aba39723277e7e9626cc45edd5c1eb0 --- /dev/null +++ b/chain/wallet/CellframeNodeConfig.h @@ -0,0 +1,42 @@ +#ifndef CELLFRAMENODECONFIG_H +#define CELLFRAMENODECONFIG_H + + +#include <QObject> +#include <QString> + + +/* + part common module + + нужно вручную получать путь к файлу конфигураций на разных платформах и парÑить его + + ÑÐµÐ¹Ñ‡Ð°Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ заглушки Ð´Ð»Ñ Ð»Ð¸Ð½ÑƒÐºÑа + //TODO +*/ + + + +class CellframeNodeConfig : public QObject +{ + Q_OBJECT +public: + static CellframeNodeConfig* instance(const QString& cfgPath = ""); + + Q_INVOKABLE QString getDefaultCADir(); + Q_INVOKABLE QString getShareCADir(); + + Q_INVOKABLE bool parseConfig(const QString& cfgPath); + +signals: + + +private: + explicit CellframeNodeConfig(QObject *parent = nullptr); + +}; + + + + +#endif // CellframeNodeConfig_H diff --git a/chain/wallet/dapRPCProtocol/DapRpcSocket.cpp b/chain/wallet/dapRPCProtocol/DapRpcSocket.cpp index c3de0fcaea872994ad856381d17e2d0cdb60c2c1..0e1507fd2b82226b8efd540447fc9981ff490002 100644 --- a/chain/wallet/dapRPCProtocol/DapRpcSocket.cpp +++ b/chain/wallet/dapRPCProtocol/DapRpcSocket.cpp @@ -187,7 +187,7 @@ DapRpcServiceReply *DapRpcSocket::invokeRemoteMethod(const QString &asMethod, co { QVariantList params; if (param1.isValid()) params.append(param1); - if (param2.isValid()) params.append(param2); + if (param2.isValid()) params.append(param2); // if (param3.isValid()) params.append(param3); if (param4.isValid()) params.append(param4); if (param5.isValid()) params.append(param5); @@ -197,6 +197,12 @@ DapRpcServiceReply *DapRpcSocket::invokeRemoteMethod(const QString &asMethod, co if (param9.isValid()) params.append(param9); if (param10.isValid()) params.append(param10); + + //можно было бы передавать json объекты и маÑÑивы прÑмо из qml. Ð’ таком Ñлучае QVariant Ñодержит QJSValue который Ñам поÑебе пропадает при конверÑии в Ñтроку. + //только еÑли вручную проверÑÑ‚ÑŒ и конвертить параметры .value<QVariantMap>() + //qInfo() << "DapRpcSocket::invokeRemoteMethod:" << asMethod << params << param2.isValid() << param2.typeName(); + + DapRpcMessage request = DapRpcMessage::createRequest(asMethod, QJsonArray::fromVariantList(params)); return invokeRemoteMethod(request); diff --git a/chain/wallet/handlers/CertificateManager/DapCertificateCommands.cpp b/chain/wallet/handlers/CertificateManager/DapCertificateCommands.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4432b2dd1fbfa23f2ea05613bdd451d8a1da1d13 --- /dev/null +++ b/chain/wallet/handlers/CertificateManager/DapCertificateCommands.cpp @@ -0,0 +1,16 @@ +#include "DapCertificateCommands.h" +#include <QMetaEnum> + + +DapCertificateCommands *DapCertificateCommands::instance() +{ + static DapCertificateCommands s_instance; + return &s_instance; +} + + +QString DapCertificateCommands::commandToString(DapCertificateCommands::Commands command) +{ + static QMetaEnum CertificateCommands_MetaEnum = QMetaEnum::fromType<Commands>(); + return CertificateCommands_MetaEnum.valueToKey(int(command)); +} diff --git a/chain/wallet/handlers/CertificateManager/DapCertificateCommands.h b/chain/wallet/handlers/CertificateManager/DapCertificateCommands.h new file mode 100644 index 0000000000000000000000000000000000000000..fdf6676e8e1de4b1430caf2874bc39d03f95736e --- /dev/null +++ b/chain/wallet/handlers/CertificateManager/DapCertificateCommands.h @@ -0,0 +1,59 @@ +#ifndef DAPCERTIFICATECOMMANDS_H +#define DAPCERTIFICATECOMMANDS_H + +#include <QObject> + + +//one instance class in qml +//with enum commands and service name + + +class DapCertificateCommands : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString serviceName READ getServiceName CONSTANT) + Q_PROPERTY(QString statusOK READ getStatusOK CONSTANT) + Q_PROPERTY(QString statusFAIL READ getStatusFAIL CONSTANT) + +public: + static DapCertificateCommands* instance(); + + enum Commands{ //maybe need class + UnknownCommand = 0, //return by default and in error case + GetSertificateList, + CreateCertificate, + DumpCertifiacate, //получение информации о Ñертификате + ImportCertificate, + ExportPublicCertificateToFile, + ExportPublicCertificateToMempool, + AddSignatureToCertificate, //WARNING нереализовано + DeleteCertificate, + UpdateCertificateList //уведомление только еÑли изменÑетÑÑ Ð¿Ð°Ð¿ÐºÐ° Ñертификатов вручную + }; + Q_ENUM(Commands); + + //возвращает Ñтроковоe предÑтавление перечиÑÐ»ÐµÐ½Ð¸Ñ + Q_INVOKABLE QString commandToString(Commands command); + + //for access serviceName in qml + QString getServiceName() const { return serviceName(); }; + static QString serviceName() { return QString("DapCertificateManagerCommands"); }; + + //for access enum status result + QString getStatusOK() const { return statusOK(); }; + QString getStatusFAIL() const { return statusFAIL(); }; + + static QString statusOK() { return QString("OK"); }; + static QString statusFAIL() { return QString("FAIL"); }; + + + +protected: + explicit DapCertificateCommands() { } + +}; + + + + +#endif // DAPCERTIFICATECOMMANDS_H diff --git a/chain/wallet/handlers/CertificateManager/DapCertificateOperation.cpp b/chain/wallet/handlers/CertificateManager/DapCertificateOperation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ec36cca267ffe0079cb59a5534445804955e9ff --- /dev/null +++ b/chain/wallet/handlers/CertificateManager/DapCertificateOperation.cpp @@ -0,0 +1,439 @@ +#include "DapCertificateOperation.h" +#include <QString> + +#include "DapCertificateType.h" +#include "DapCertificateCommands.h" +#include "CellframeNodeConfig.h" +#include <QJsonArray> +#include <QJsonObject> +#include <QDir> +#include <QFile> +#include <QFileInfo> +#include <QDebug> +#include <QProcess> + + +#include "dap_cert_file.h" +#include "dap_binary_tree.h" +#include "dap_common.h" +#include "dap_config.h" +#include "dap_string.h" +#include "dap_strfuncs.h" + + + +bool DapCertificateOperation::addMetaDataToCert(const QString &certName, const QVariantMap& metaData, const QString &s_toolPath) +{ + Q_UNUSED(certName) + Q_UNUSED(s_toolPath) + + auto iterator = metaData.constBegin(); + while (iterator != metaData.constEnd()) { + QString value = iterator.value().toString(); + QProcess process; + + QString args; +// if (iterator.key() == "creation_date" || iterator.key() == "expiration_date") { //TODO add date custom +// args = QString("%1 cert add_metadata %2 %3") +// .arg(s_toolPath).arg(certName).arg(QString("%1:%2:%3:%4") // :%3:%4" key:type:length:value +// .arg(iterator.key()) +// .arg(dap_cert_metadata_type::DAP_CERT_META_DATETIME) +// .arg(value.size()) +// .arg(value) +// ); +// } else { + args = QString("%1 cert add_metadata %2 %3") + .arg(s_toolPath).arg(certName).arg(QString("%1:%2:%3:%4") // key:type:length:value + .arg(iterator.key()) + .arg(dap_cert_metadata_type::DAP_CERT_META_STRING) + .arg(value.size()) + .arg(value) + ); +// } + + args = args.toLatin1(); + + process.start(args); + process.waitForFinished(-1); + qDebug() << args << "\naddMetaDataToCert result:" << process.readAll(); + + ++iterator; + } // + + + return true; +} + + +//bool DapCertificateOperation::addMetaDataToCert(dap_cert_t *certFile, const QVariantMap &metaData) +//{ +// auto iterator = metaData.constBegin(); +// while (iterator != metaData.constEnd()) { +//// QString value = iterator.value().toString(); + +//// QString(":%1:%2:%3") // :%3:%4" key:type:length:value +//// .arg(dap_cert_metadata_type::DAP_CERT_META_STRING) +//// .arg(value.size()) +//// .arg(value) +//// ; + +// ++iterator; +// } // + +// return true; +//} + + +QJsonObject DapCertificateOperation::createCertificate(const QString &certName, const QString &signatureType, const QVariantMap &metaData + , QString &status, QString &errorMessage, const QString& s_toolPath) +{ + QFileInfo info(CellframeNodeConfig::instance()->getDefaultCADir() + QString("/%1.dcert").arg(certName) ); + + + if (info.exists()){ + status = DapCertificateCommands::statusFAIL(); + errorMessage = tr("Certificate is exists"); + + return QJsonObject({ + { "fileName", certName } + }); + } + + + static const QMap<QString, dap_enc_key_type_t> convertSignatureType = QMap<QString, dap_enc_key_type_t>({ + { "dilithium", DAP_ENC_KEY_TYPE_SIG_DILITHIUM } + , { "picnic", DAP_ENC_KEY_TYPE_SIG_PICNIC } + , { "bliss", DAP_ENC_KEY_TYPE_SIG_BLISS } + , { "tesla", DAP_ENC_KEY_TYPE_SIG_TESLA } + }); + + QProcess process; + auto args = QString("%1 cert create %2 %3").arg(s_toolPath).arg(certName).arg(signatureType); + process.start(args); + process.waitForFinished(-1); + process.close(); + //QString processResult = QString::fromLatin1(process.readAll()); + + info.refresh(); + + if (info.exists()) { //existsCertificate(certName, s_toolPath) + qDebug() << "add cert metaData" << metaData.size(); + addMetaDataToCert(certName, metaData, s_toolPath); + + //TODO check error add metadata + + return QJsonObject({ + { "fileName", info.fileName() } + , { "completeBaseName", info.completeBaseName() } + , { "filePath", info.filePath() } + , { "dirType", DapCertificateType::DefaultDir } + , { "accessKeyType", DapCertificateType::Both } //getAccessKeyType(newCert) + }); + } else { + status = DapCertificateCommands::statusFAIL(); + errorMessage = tr("Certificate not created"); + + return QJsonObject({ + { "fileName", certName } + }); + } + +} //createCertificate + + +QJsonObject DapCertificateOperation::deleteCertificate(const QString& filePath, QString& status, QString& errorMessage) +{ + Q_UNUSED(status) + Q_UNUSED(errorMessage) + + if (!QFile::remove(filePath)) { + status = DapCertificateCommands::statusFAIL(); + errorMessage = tr("File not deleted."); + } + + return QJsonObject({ + { "deletedFilePath", filePath } + }); +} + + +//QJsonObject DapCertificateOperation::dumpCertificate(const QString &certName, QString &status, QString &errorMessage +// , const QString &s_toolPath) +//{ +// QProcess process; +// auto args = QString("%1 cert dump %2 %3").arg(s_toolPath).arg(certName); +// process.start(args); +// process.waitForFinished(-1); +// QString processResult = QString::fromLatin1(process.readAll()); + +// //Ñчитаем что еÑли ответ пуÑтой то Ñертификата нет, но Ñто актуально только Ð´Ð»Ñ Ð´ÐµÑ„Ð¾Ð»Ñ‚Ð½Ð¾Ð¹ папки Ñертификатов +// if (processResult.isEmpty()) { +// status = DapCertificateCommands::statusFAIL(); +// errorMessage = tr("Certificate not find"); +// } + +// return QJsonObject({ +// { "certName", certName } +// }); +//} + + +QJsonObject DapCertificateOperation::dumpCertificateFile(const QString &certName, const QString &filePath, QString &status + , QString &errorMessage) +{ + Q_UNUSED(certName) + Q_UNUSED(filePath) + Q_UNUSED(status) + Q_UNUSED(errorMessage) + + + QJsonObject result; + result.insert("filePath", filePath); + + dap_cert_t* certFile = dap_cert_file_load(qPrintable(filePath)); + + if (certFile == nullptr) { + status = DapCertificateCommands::statusFAIL(); + errorMessage = tr("Certificate does not exist"); + result.insert("name", certName); + + return result; + } + + + auto parseCertFile{ + [&result](dap_cert_t * a_cert) { // -> bool + result.insert("name", QJsonValue::fromVariant(QString(a_cert->name))); + result.insert("signature", QJsonValue::fromVariant(QString(dap_sign_type_to_str( dap_sign_type_from_key_type(a_cert->enc_key->type) )))); + result.insert("privateKeySize", QJsonValue::fromVariant(QVariant::fromValue(a_cert->enc_key->priv_key_data_size))); + result.insert("publicKeySize", QJsonValue::fromVariant(QVariant::fromValue(a_cert->enc_key->pub_key_data_size))); + size_t l_meta_items_cnt = dap_binary_tree_count(a_cert->metadata); + result.insert("metaSectionCount", QJsonValue::fromVariant(QVariant::fromValue(l_meta_items_cnt))); + result.insert("signatureChainSize", QJsonValue::fromVariant(QVariant::fromValue(dap_cert_count_cert_sign (a_cert)))); + + QJsonArray metadata; + + if (l_meta_items_cnt) { + printf ("Metadata sections\n"); + dap_list_t *l_meta_list = dap_binary_tree_inorder_list(a_cert->metadata); + dap_list_t *l_meta_list_item = dap_list_first(l_meta_list); + while (l_meta_list_item) { + dap_cert_metadata_t *l_meta_item = (dap_cert_metadata_t *)l_meta_list_item->data; + char *l_str; + QString key, value; + int type = l_meta_item->type; + int length = 0; + + switch (l_meta_item->type) { + case DAP_CERT_META_STRING: + l_str = strndup((char *)l_meta_item->value, l_meta_item->length); + + key = l_meta_item->key; + length = l_meta_item->length; + value = l_str; + + free(l_str); + break; + case DAP_CERT_META_INT: + case DAP_CERT_META_BOOL: + key = l_meta_item->key; + length = l_meta_item->length; + value = l_str; + break; + default: + l_str = l_meta_item->length ? DAP_NEW_Z_SIZE(char, l_meta_item->length * 2 + 1) : NULL; + dap_bin2hex(l_str, l_meta_item->value, l_meta_item->length); + key = l_meta_item->key; + length = l_meta_item->length; + value = l_str; +// printf("%s\t%u\t%u\t%s\n", l_meta_item->key, l_meta_item->type, l_meta_item->length, l_str); + DAP_DELETE(l_str); + break; + } //switch + + metadata.append(QJsonObject({ + { "key", key } + , { "type", type } + , { "length", length } + , { "value", value } + })); + + l_meta_list_item = l_meta_list_item->next; + } + dap_list_free(l_meta_list); + } //if meta_item_cnt + + result.insert("metadata", metadata); + } + }; + + + parseCertFile(certFile); + + dap_cert_delete(certFile); + + return result; +} + + +bool DapCertificateOperation::existsCertificate(const QString &certName, const QString &s_toolPath) +{ + QProcess process; + process.start(QString("%1 cert dump %2").arg(s_toolPath).arg(certName)); + process.waitForFinished(-1); + QString result(QString::fromLatin1(process.readAll())); + //qDebug() << "DapCertificateOperation::existsCertificate" << certName << s_toolPath << result; + return !result.isEmpty(); +} + + +QJsonObject DapCertificateOperation::exportPublicCertificateToFile(const QString &certName, const QString &newCertName, QString &status + , QString &errorMessage, const QString& s_toolPath) +{ + //WARNING Ñертификат Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼ ключом ÑоздаетÑÑ Ð² папке обычных Ñертификатов + QString filePath = QString("%1/%2.dcert").arg(CellframeNodeConfig::instance()->getDefaultCADir()).arg(newCertName); + QFileInfo info(filePath); + + if (info.exists()) { + status = DapCertificateCommands::statusFAIL(); + errorMessage = tr("Certificate is exists"); + return QJsonObject({ + { "fileName", newCertName + ".dcert" } + , { "completeBaseName", newCertName } + , { "filePath", filePath } + , { "dirType", DapCertificateType::DefaultDir } + , { "accessKeyType", DapCertificateType::Public } //getAccessKeyType(newCert) + }); + } + + QProcess process; + QString args(QString("%1 cert create_cert_pkey %2 %3").arg(s_toolPath).arg(certName).arg(newCertName)); + process.start(args); + process.waitForFinished(-1); + + QString result(process.readAll()); + //WARNING в результате вÑегда пуÑто! + if (!result.isEmpty()) { + //TODO check process result + } + + //qDebug() << args << "\nexportPublicCertificateToFile" << filePath << ", result:" << result; + info.refresh(); + return getSimpleCertificateInfo(info, DapCertificateType::DefaultDir); +} + + +QJsonObject DapCertificateOperation::exportPublicCertificateToMempool(const QString &network, const QString &certName, QString &status + , QString &errorMessage, const QString& s_cliPath) +{ + QProcess process; + QString args(QString("%1 mempool_add_ca -net %2 -ca_name %3").arg(s_cliPath).arg(network).arg(certName)); // newCertName + process.start(args); + process.waitForFinished(-1); + + QString result(process.readAll()); //WARNING тут тоже ответ пуÑтой + if (result.isEmpty()) { + + } else { + + } + + //qDebug() << args << "\nexportPublicCertificateToMempool" << certName << network << ", result:" << result; + + return QJsonObject({ + { "certName", certName } + , { "network", network } + }); +} + + +DapCertificateType::AccessKeyType DapCertificateOperation::getAccessKeyType(const QString &certFilePath) +{ + dap_cert_t* certFile = dap_cert_file_load(qPrintable(certFilePath)); + if (certFile == nullptr){ + qCritical() << "file not open" << certFilePath; + return DapCertificateType::Public; + //WARNING нужна более Ð¿Ñ€Ð¾Ð´Ð²Ð¸Ð½ÑƒÑ‚Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ° ошибок, но по умолчанию вызов Ñтой функции проиходит Ñразу поÑле получение ÑпиÑка файлов + } + + auto result = getAccessKeyType(certFile); + dap_cert_delete(certFile); + return result; +} + + +DapCertificateType::AccessKeyType DapCertificateOperation::getAccessKeyType(dap_cert_t *certFile) +{ + int privateKeySize = certFile->enc_key->priv_key_data_size; + int publicKeySize = certFile->enc_key->pub_key_data_size; + + if (privateKeySize > 0 && publicKeySize > 0) { + return DapCertificateType::Both; + } else if (publicKeySize > 0){ + return DapCertificateType::Public; + } + + return DapCertificateType::Private; +} + + +QJsonArray DapCertificateOperation::getCertificateList(QString& status, QString& errorMessage) +{ + Q_UNUSED(status) + Q_UNUSED(errorMessage) + + QJsonArray result; + + auto parseDir = + [&result](const QString& dirPath, const DapCertificateType::DirType& dirType) -> bool + { + QDir dir(dirPath); + + if (!dir.exists()) { + qWarning() << "The directory does not exist:" << dirPath; + return false; + } + + dir.setFilter(QDir::Files); //only files in derictory + dir.setSorting(QDir::Name); //set sort by name + + QFileInfoList list = dir.entryInfoList(); // get all QFileInfo for files in dir + + foreach (const QFileInfo& info, list) { + if (info.suffix() == "dcert") { //выбираем только файлы Ñертификатов Ñ Ñ€Ð°Ñширением dcert + result.append(getSimpleCertificateInfo(info, dirType)); + } + + } + + return true; + }; + + + //предполагаем что в разных папках лежат, разные ключи. + parseDir(CellframeNodeConfig::instance()->getDefaultCADir(), DapCertificateType::DefaultDir ); + parseDir(CellframeNodeConfig::instance()->getShareCADir(), DapCertificateType::ShareDir ); + + + return result; +} + + +QJsonObject DapCertificateOperation::getSimpleCertificateInfo(const QFileInfo &info, const DapCertificateType::DirType& dirType) +{ + return QJsonObject({ + { "fileName", info.fileName() } + , { "completeBaseName", info.completeBaseName() } + , { "filePath", info.filePath() } + , { "dirType", dirType } + , { "accessKeyType", getAccessKeyType(info.filePath()) } + }); +} + + + + + + + + diff --git a/chain/wallet/handlers/CertificateManager/DapCertificateOperation.h b/chain/wallet/handlers/CertificateManager/DapCertificateOperation.h new file mode 100644 index 0000000000000000000000000000000000000000..d420447afbd8a3a50db8793803b43e3e036e322a --- /dev/null +++ b/chain/wallet/handlers/CertificateManager/DapCertificateOperation.h @@ -0,0 +1,67 @@ +#ifndef DAPCERTIFICATEOPERATION_H +#define DAPCERTIFICATEOPERATION_H + + +#include <QObject> +#include <QJsonDocument> +#include <QFileInfo> +#include "DapCertificateType.h" +#include "dap_cert.h" + + +class DapCertificateOperation : public QObject +{ + Q_OBJECT +public: + + + + static bool addMetaDataToCert(const QString& certName, const QVariantMap& metaData, const QString& s_toolPath); + + +// static bool addMetaDataToCert(dap_cert_t* certFile, const QVariantMap& metaData); + + //Ñоздание Ñертификата + static QJsonObject createCertificate(const QString& certName, const QString& signatureType, const QVariantMap &metaData + , QString& status, QString& errorMessage, const QString& s_toolPath); + + + static QJsonObject deleteCertificate(const QString& fileName, QString& status, QString& errorMessage); + +// //получение информации о Ñертификате через -tool, не работает Ð´Ð»Ñ Ð¿Ð°Ð¿ÐºÐ¸ публичных Ñертификатов +// static QJsonObject dumpCertificate(const QString& certName, QString& status, QString& errorMessage, const QString& s_toolPath); + + //получение информации о Ñертификате через файл + static QJsonObject dumpCertificateFile(const QString& certName, const QString& filePath + , QString& status, QString& errorMessage); + + //проверка того что Ñертификат Ñоздан, не работает Ð´Ð»Ñ Ð¿Ð°Ð¿ÐºÐ¸ публичных Ñертификатов + static bool existsCertificate(const QString& certName, const QString& s_toolPath); + + + static QJsonObject exportPublicCertificateToFile(const QString& certName, const QString& newCertName + , QString& status, QString& errorMessage, const QString& s_toolPath); + + static QJsonObject exportPublicCertificateToMempool(const QString& network, const QString& certName + , QString& status, QString& errorMessage, const QString &s_cliPath); + + + + //возвращает тип доÑтупа ключа из файла Ñертификата + static DapCertificateType::AccessKeyType getAccessKeyType(const QString& certFilePath); + + //возвращает тип доÑтупа ключа из объекта файла Ñертификата + static DapCertificateType::AccessKeyType getAccessKeyType(dap_cert_t* certFile); + + + static QJsonArray getCertificateList(QString& status, QString& errorMessage); + + static QJsonObject getSimpleCertificateInfo(const QFileInfo &info, const DapCertificateType::DirType& dirType); + + +}; + + + + +#endif // DAPCERTIFICATEOPERATION_H diff --git a/chain/wallet/handlers/CertificateManager/DapCertificateType.h b/chain/wallet/handlers/CertificateManager/DapCertificateType.h new file mode 100644 index 0000000000000000000000000000000000000000..589511659d3a5672546d3f1b519ce7a0eee22260 --- /dev/null +++ b/chain/wallet/handlers/CertificateManager/DapCertificateType.h @@ -0,0 +1,34 @@ +#ifndef DAPCERTIFICATETYPE_H +#define DAPCERTIFICATETYPE_H + + +#include <QObject> + + +class DapCertificateType +{ + Q_GADGET +public: + //certificate type access + enum AccessKeyType{ + Public = 0, + Private, + Both + }; + Q_ENUM(AccessKeyType); + + //certificate location dir + enum DirType{ + DefaultDir = 0, + ShareDir + }; + Q_ENUM(DirType); + + +protected: + explicit DapCertificateType() { } +}; + + + +#endif // DAPCERTIFICATETYPE_H diff --git a/chain/wallet/handlers/DapAbstractCommand.cpp b/chain/wallet/handlers/DapAbstractCommand.cpp index fa1ab2217feaf02a2a20bd636b82fc99528f3d02..bf3d599439903027bf59e109d43f89427de4dfe1 100644 --- a/chain/wallet/handlers/DapAbstractCommand.cpp +++ b/chain/wallet/handlers/DapAbstractCommand.cpp @@ -170,6 +170,9 @@ void DapAbstractCommand::notifedFromClient(const QVariant &arg1, const QVariant emit serviceNotifed(QVariant()); } + +Q_DECLARE_METATYPE(QVariantMap); + /// Send request to service. /// @details Performed on the client side. /// @param arg1...arg10 Parameters. @@ -179,7 +182,7 @@ void DapAbstractCommand::requestToService(const QVariant &arg1, const QVariant & const QVariant &arg8, const QVariant &arg9, const QVariant &arg10) { - QVariantList params; + QVariantList params; //а Ñто тут зачем? for delete if (arg1.isValid()) params.append(arg1); if (arg2.isValid()) params.append(arg2); if (arg3.isValid()) params.append(arg3); @@ -191,9 +194,14 @@ void DapAbstractCommand::requestToService(const QVariant &arg1, const QVariant & if (arg9.isValid()) params.append(arg9); if (arg10.isValid()) params.append(arg10); - DapRpcServiceReply *reply = dynamic_cast<DapRpcSocket *>(m_parent)->invokeRemoteMethod(QString("%1.%2").arg(this->getName()).arg("respondToClient"), - arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + + DapRpcServiceReply *reply = dynamic_cast<DapRpcSocket *>(m_parent)->invokeRemoteMethod( + QString("%1.%2").arg(this->getName()).arg("respondToClient"), + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + + //qDebug() << "DapAbstractCommand::requestToService" << reply; connect(reply, SIGNAL(finished()), this, SLOT(replyFromService())); + } /// Send a response to the client. @@ -226,7 +234,11 @@ QVariant DapAbstractCommand::replyFromService() { DapRpcServiceReply *reply = static_cast<DapRpcServiceReply *>(sender()); +// qDebug() << "DapAbstractCommand::replyFromService(), reply" << reply +// << "reply->response().toJsonValue():" << reply->response().toJsonValue(); + emit serviceResponded(reply->response().toJsonValue().toVariant()); + //тут не должно быть возвращаемого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡Ð°ÐµÐ¼Ð¾Ð³Ð¾ через sender() return reply->response().toJsonValue().toVariant(); } diff --git a/chain/wallet/handlers/DapAddWalletCommand.h b/chain/wallet/handlers/DapAddWalletCommand.h index f76cc0d6e6cbe0ef46b46b4655bebdbb109828d7..d3123867ed4587e34f13d7439a7c74817f3147e3 100644 --- a/chain/wallet/handlers/DapAddWalletCommand.h +++ b/chain/wallet/handlers/DapAddWalletCommand.h @@ -28,11 +28,15 @@ public slots: /// @details Performed on the service side. /// @param arg1...arg10 Parameters. /// @return Reply to client. - QVariant respondToClient(const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), - const QVariant &arg3 = QVariant(), const QVariant &arg4 = QVariant(), - const QVariant &arg5 = QVariant(), const QVariant &arg6 = QVariant(), - const QVariant &arg7 = QVariant(), const QVariant &arg8 = QVariant(), - const QVariant &arg9 = QVariant(), const QVariant &arg10 = QVariant()); + QVariant respondToClient(const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), //original + const QVariant &arg3 = QVariant(), const QVariant &arg4 = QVariant(), + const QVariant &arg5 = QVariant(), const QVariant &arg6 = QVariant(), + const QVariant &arg7 = QVariant(), const QVariant &arg8 = QVariant(), + const QVariant &arg9 = QVariant(), const QVariant &arg10 = QVariant()) override; + + + + }; #endif // DAPADDWALLETCOMMAND_H diff --git a/chain/wallet/handlers/DapCertificateManagerCommands.cpp b/chain/wallet/handlers/DapCertificateManagerCommands.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52228411ff3ea105666964180da87171feea5008 --- /dev/null +++ b/chain/wallet/handlers/DapCertificateManagerCommands.cpp @@ -0,0 +1,188 @@ +#include "DapCertificateManagerCommands.h" + +#include <QJsonDocument> +#include "CertificateManager/DapCertificateOperation.h" + + + +DapCertificateManagerCommands::DapCertificateManagerCommands(const QString &asServicename, QObject *parent + , const QString &asCliPath, const QString &asToolPath) + : DapAbstractCommand(asServicename, parent, asCliPath), m_sToolPath(asToolPath) +{ + +} + + +// result = { +// command: <enumcommand> +// status: "OK" | "FAIL", +// errorMessage: "", //optional when error +// data: ... //empty or object or array +// } +//arg1 DapCertificateCommands, arg2...arg10 - аргументы Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ð¹ команды +QVariant DapCertificateManagerCommands::respondToClient(const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4, const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8, const QVariant &arg9, const QVariant &arg10) +{ + Q_UNUSED(arg1) + Q_UNUSED(arg2) + Q_UNUSED(arg3) + Q_UNUSED(arg4) + Q_UNUSED(arg5) + Q_UNUSED(arg6) + Q_UNUSED(arg7) + Q_UNUSED(arg8) + Q_UNUSED(arg9) + Q_UNUSED(arg10) + + + qDebug() << "respondToClient, " << DapCertificateCommands::instance()->commandToString( + DapCertificateCommands::Commands(arg1.toInt())); + + bool arg1ConvertSuccess = true; + int command = arg1.toInt(&arg1ConvertSuccess); + + if (!arg1ConvertSuccess) { + qCritical() << "command not responsed"; + return QJsonObject({ + { "command", DapCertificateCommands::UnknownCommand } + , { "status", "FAIL" } + , { "errorMessage", "command not responsed" } + }); + } + + + QString status = DapCertificateCommands::statusOK(); + QString errorMessage; + QVariant result; + + + switch (command) { + case DapCertificateCommands::GetSertificateList: + result = DapCertificateOperation::getCertificateList(status, errorMessage); + break; + case DapCertificateCommands::CreateCertificate: { + QVariantMap metaData = QJsonDocument::fromJson(arg4.toString().toUtf8()).toVariant().value<QVariantMap>(); + result = DapCertificateOperation::createCertificate(arg2.toString(), arg3.toString(), metaData + , status, errorMessage, m_sToolPath); + } + break; + case DapCertificateCommands::DumpCertifiacate: + result = DapCertificateOperation::dumpCertificateFile(arg2.toString(), arg3.toString(), status, errorMessage); //this cliPath to tools_path + break; + case DapCertificateCommands::ImportCertificate: + //TODO + break; + case DapCertificateCommands::ExportPublicCertificateToFile: + result = DapCertificateOperation::exportPublicCertificateToFile(arg2.toString(), arg3.toString(), status, errorMessage, m_sToolPath); + break; + case DapCertificateCommands::ExportPublicCertificateToMempool: + result = DapCertificateOperation::exportPublicCertificateToMempool(arg2.toString(), arg3.toString(), status, errorMessage, m_sCliPath); + break; + case DapCertificateCommands::AddSignatureToCertificate: + //TODO + break; + case DapCertificateCommands::DeleteCertificate: + result = DapCertificateOperation::deleteCertificate(arg2.toString(), status, errorMessage); + break; + case DapCertificateCommands::UpdateCertificateList: + //вообще команда только Ð´Ð»Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, еÑли произошел Ð·Ð°Ð¿Ñ€Ð¾Ñ Ðº ÑервиÑÑ‹ то выполнÑем тоже что и при получении ÑпиÑка + result = DapCertificateOperation::getCertificateList(status, errorMessage); + break; + + default: + command = command < DapCertificateCommands::UnknownCommand && command > DapCertificateCommands::UpdateCertificateList + ? DapCertificateCommands::UnknownCommand : command; + break; + } + + +// QJsonValue value; + +// QJsonArray response; +// response.append(QJsonValue(arg1.toString())); +// response.append(QJsonValue("resultDataCert")); +// QJsonDocument doc; +// doc[] +// doc.toBinaryData() + + + return QJsonObject({ + { "command", command } + , { "status", status } + , { "errorMessage", errorMessage } + , { "data", QJsonValue::fromVariant(result) } + }); + +} //respondToClient + + + +void DapCertificateManagerCommands::notifedFromService(const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4 + , const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8 + , const QVariant &arg9, const QVariant &arg10) +{ + Q_UNUSED(arg1) + Q_UNUSED(arg2) + Q_UNUSED(arg3) + Q_UNUSED(arg4) + Q_UNUSED(arg5) + Q_UNUSED(arg6) + Q_UNUSED(arg7) + Q_UNUSED(arg8) + Q_UNUSED(arg9) + Q_UNUSED(arg10) + + qInfo() << "DapCertificateManagerCommands::notifedFromService" << arg1 << arg2 << arg3 << arg4; + + + bool arg1ConvertSuccess = true; + int command = arg1.toInt(&arg1ConvertSuccess); + + if (!arg1ConvertSuccess) { + qCritical() << "command not responsed"; + return ; + } + + + QString status = arg2.toString(); + if (!(status == DapCertificateCommands::statusOK() + || status == DapCertificateCommands::statusFAIL())) //правильней будет валидировать ÑÑ‚Ð°Ñ‚ÑƒÑ + { + status = DapCertificateCommands::statusFAIL(); + } + + QString errorMessage = arg3.toString(); + const QVariant& response = arg4; + QVariant result; + + switch (command) { + case DapCertificateCommands::UpdateCertificateList: + result = response; + break; + } + + + emit clientNotifed(QVariant(QJsonObject({ + { "command", command } + , { "status", status } + , { "errorMessage", errorMessage } + , { "data", QJsonValue::fromVariant(result) } + }) + )); +} //notifedFromService + + + + + + + + + + + + + + + + + diff --git a/chain/wallet/handlers/DapCertificateManagerCommands.h b/chain/wallet/handlers/DapCertificateManagerCommands.h new file mode 100644 index 0000000000000000000000000000000000000000..cc7f1890ceb990c55e3c0340f9446249a1b6bf79 --- /dev/null +++ b/chain/wallet/handlers/DapCertificateManagerCommands.h @@ -0,0 +1,67 @@ +#ifndef DAPCERTIFICATEMANAGERCOMMNADS_H +#define DAPCERTIFICATEMANAGERCOMMNADS_H + + +#include <QObject> +#include <QString> +#include "DapAbstractCommand.h" +#include "CertificateManager/DapCertificateCommands.h" +#include "CertificateManager/DapCertificateType.h" +#include "CellframeNodeConfig.h" + + +/* + как видно из Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñет команды Ð´Ð»Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ñертификатов, + но выполнÑет неÑколько команд, тип команды передаетÑÑ Ð¿ÐµÑ€Ð²Ñ‹Ð¼ параметром, вÑе допуÑтимые команды пропиÑаны в перечиÑлении + + cliPath должен Ñодержать путь до cellframe-node-tool +*/ + + + + + +class DapCertificateManagerCommands : public DapAbstractCommand +{ + Q_OBJECT //need +public: + /// Overloaded constructor. + /// @param asServiceName Service name. + /// @param parent Parent. + /// @details The parent must be either DapRPCSocket or DapRPCLocalServer. + /// @param asCliPath The path to cli nodes. + DapCertificateManagerCommands(const QString &asServicename, QObject *parent = nullptr + , const QString &asCliPath = QString(), const QString &asToolPat = QString()); + + +public slots: + /// Send a response to the client. + /// @details Performed on the service side. + /// @param arg1...arg10 Parameters. arg1 must be command from DapCertificateCommands + /// @return Reply to client. + QVariant respondToClient(const QVariant &arg1 = QVariant(), const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), const QVariant &arg4 = QVariant(), + const QVariant &arg5 = QVariant(), const QVariant &arg6 = QVariant(), + const QVariant &arg7 = QVariant(), const QVariant &arg8 = QVariant(), + const QVariant &arg9 = QVariant(), const QVariant &arg10 = QVariant()) override; + + + //перехватываем нотификации от ÑервиÑа, может быть избыточно + //неочевидно что иÑпуÑкаемые Ñигналы Ñтого клаÑÑа будут подключены к одному ÑвÑзаному Ñ Ñтой командой Ñигналу в DapServiceController + void notifedFromService(const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4 + , const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8 + , const QVariant &arg9, const QVariant &arg10) override; + + + + +private: + QString m_sToolPath; + + +}; + + + + +#endif // DapCertificateManagerCommands_H diff --git a/chain/wallet/handlers/DapGetListNetworksCommand.cpp b/chain/wallet/handlers/DapGetListNetworksCommand.cpp index 79adcecf8b2947390c21cf6774b0d0e87afa07fd..59abe8f0f7e5a2c3162bf8b749f186ff9d7baf89 100644 --- a/chain/wallet/handlers/DapGetListNetworksCommand.cpp +++ b/chain/wallet/handlers/DapGetListNetworksCommand.cpp @@ -28,11 +28,14 @@ QVariant DapGetListNetworksCommand::respondToClient(const QVariant &arg1, const Q_UNUSED(arg9) Q_UNUSED(arg10) + QStringList networkList; QProcess process; process.start(QString("%1 net list").arg(m_sCliPath)); process.waitForFinished(-1); QString result = QString::fromLatin1(process.readAll()); + + //qDebug() << "DapGetListNetworksCommand::respondToClient" << result << result.isEmpty(); if(!(result.isEmpty() || result.isNull() || result.contains('\''))) { QStringList str = result.remove(" ").remove("\n").remove("\r").split(":").at(1).split(","); diff --git a/chain/wallet/libdap-qt-chain-wallet.pri b/chain/wallet/libdap-qt-chain-wallet.pri index f1674f66df17f6fb9eef989de9b89eac16689b25..a05497154ee415e1bef6b55108afe6a9ed9c7f5b 100644 --- a/chain/wallet/libdap-qt-chain-wallet.pri +++ b/chain/wallet/libdap-qt-chain-wallet.pri @@ -12,6 +12,7 @@ win32{ DISTFILES += HEADERS += \ + $$PWD/CellframeNodeConfig.h \ $$PWD/DapChainConvertor.h \ $$PWD/DapHistoryType.h \ $$PWD/DapLogMessage.h \ @@ -19,9 +20,13 @@ HEADERS += \ $$PWD/DapWallet.h \ $$PWD/DapWalletHistoryEvent.h \ $$PWD/DapWalletToken.h \ + $$PWD/handlers/CertificateManager/DapCertificateCommands.h \ + $$PWD/handlers/CertificateManager/DapCertificateOperation.h \ + $$PWD/handlers/CertificateManager/DapCertificateType.h \ $$PWD/handlers/DapAbstractCommand.h \ $$PWD/handlers/DapActivateClientCommand.h \ $$PWD/handlers/DapAddWalletCommand.h \ + $$PWD/handlers/DapCertificateManagerCommands.h \ $$PWD/handlers/DapCreateTransactionCommand.h \ $$PWD/handlers/DapExportLogCommand.h \ $$PWD/handlers/DapGetHistoryExecutedCmdCommand.h \ @@ -45,15 +50,19 @@ HEADERS += \ $$PWD/serviceClient/DapServiceClientNativeWin.h SOURCES += \ + $$PWD/CellframeNodeConfig.cpp \ $$PWD/DapChainConvertor.cpp \ $$PWD/DapHistoryType.cpp \ $$PWD/DapLogMessage.cpp \ $$PWD/DapWallet.cpp \ $$PWD/DapWalletHistoryEvent.cpp \ $$PWD/DapWalletToken.cpp \ + $$PWD/handlers/CertificateManager/DapCertificateCommands.cpp \ + $$PWD/handlers/CertificateManager/DapCertificateOperation.cpp \ $$PWD/handlers/DapAbstractCommand.cpp \ $$PWD/handlers/DapActivateClientCommand.cpp \ $$PWD/handlers/DapAddWalletCommand.cpp \ + $$PWD/handlers/DapCertificateManagerCommands.cpp \ $$PWD/handlers/DapCreateTransactionCommand.cpp \ $$PWD/handlers/DapExportLogCommand.cpp \ $$PWD/handlers/DapGetHistoryExecutedCmdCommand.cpp \ diff --git a/stream/ch/chain/net/srv/vpn/DapStreamChChainNetSrvVpn.cpp b/stream/ch/chain/net/srv/vpn/DapStreamChChainNetSrvVpn.cpp index f635039c99592be6140e196a19437bbba7e00d5a..4f921d17bea5ead635249962d3517d5456f2dbc7 100644 --- a/stream/ch/chain/net/srv/vpn/DapStreamChChainNetSrvVpn.cpp +++ b/stream/ch/chain/net/srv/vpn/DapStreamChChainNetSrvVpn.cpp @@ -304,12 +304,12 @@ void ChChainNetSrvVpn::tunCreate() m_mainDapSession->upstreamPort(), streamer()->upstreamSocket()); #ifdef ANDROID - jint tunSocket = 0; - for (; tunSocket == 0;) { + jint tunSocket = -1; + for (; tunSocket <= 0;) { QThread::msleep(1000); tunSocket = QtAndroid::androidService().callMethod<jint>("getTunSocket"); + qInfo() << "Socket num: " << tunSocket; } - qInfo() << "Socket num: " << tunSocket; workerStart(tunSocket); #else tun->workerStart(); diff --git a/ui/chain/wallet/libdap-qt-ui-chain-wallet.qrc b/ui/chain/wallet/libdap-qt-ui-chain-wallet.qrc index b2b9c41577e45739344bda0d1c3bce150c789335..9eca0d56f2a63b598fc892c9b5544d340e96b45a 100644 --- a/ui/chain/wallet/libdap-qt-ui-chain-wallet.qrc +++ b/ui/chain/wallet/libdap-qt-ui-chain-wallet.qrc @@ -15,5 +15,14 @@ <file>resources/fonts/roboto_thin_italic.ttf</file> <file>resources/fonts/roboto_thin.ttf</file> <file>resources/JS/TimeFunctions.js</file> + <file>resources/fonts/Quicksand/OFL.txt</file> + <file>resources/fonts/Quicksand/Quicksand-Bold.ttf</file> + <file>resources/fonts/Quicksand/Quicksand-Light.ttf</file> + <file>resources/fonts/Quicksand/Quicksand-Medium.ttf</file> + <file>resources/fonts/Quicksand/Quicksand-Regular.ttf</file> + <file>resources/fonts/Quicksand/Quicksand-SemiBold.ttf</file> + <file>resources/fonts/Quicksand/Quicksand-VariableFont_wght.ttf</file> + <file>resources/fonts/Quicksand/README.txt</file> + <file>resources/QML/DapFontQuicksand.qml</file> </qresource> </RCC> diff --git a/ui/chain/wallet/resources/QML/DapFontQuicksand.qml b/ui/chain/wallet/resources/QML/DapFontQuicksand.qml new file mode 100644 index 0000000000000000000000000000000000000000..7844e2f78026f2ebd3528725b0295f4ed53e4962 --- /dev/null +++ b/ui/chain/wallet/resources/QML/DapFontQuicksand.qml @@ -0,0 +1,95 @@ +import QtQuick 2.0 +import "qrc:/" + + +Item +{ + + ///@details dapFactor Scaling factor. + property int dapFactor: 1 + + //Add Font Loader + DapFont + { + id: dapFonts + dapFontPath: "qrc:/resources/fonts/Quicksand/" + dapFontNames: ["Quicksand-Bold.ttf", + "Quicksand-Light.ttf", + "Quicksand-Medium.ttf", + "Quicksand-Regular.ttf", //3 + "Quicksand-SemiBold.ttf", + "Quicksand-VariableFont_wght.ttf"] + } + + + + property font bold14: Qt.font({ + family: dapFonts.dapProjectFonts[0].name, + bold: true, + italic: false, + pixelSize: 14 * dapFactor + }) + + + property font medium11: Qt.font({ + family: dapFonts.dapProjectFonts[2].name, + bold: false, + italic: false, + pixelSize: 11 * dapFactor + }) + + property font medium12: Qt.font({ + family: dapFonts.dapProjectFonts[2].name, + bold: false, + italic: false, + pixelSize: 12 * dapFactor + }) + + property font medium27: Qt.font({ + family: dapFonts.dapProjectFonts[2].name, + bold: false, + italic: false, + pixelSize: 27 * dapFactor + }) + + property font mediumBold16: Qt.font({ + family: dapFonts.dapProjectFonts[2].name, + bold: true, + italic: false, + pixelSize: 16 * dapFactor + }) + + property font regular12: Qt.font({ + family: dapFonts.dapProjectFonts[3].name, + bold: false, + italic: false, + pixelSize: 14 * dapFactor + }) + + + property font regular14: Qt.font({ + family: dapFonts.dapProjectFonts[3].name, + bold: false, + italic: false, + pixelSize: 14 * dapFactor + }) + + property font regular16: Qt.font({ + family: dapFonts.dapProjectFonts[3].name, + bold: false, + italic: false, + pixelSize: 16 * dapFactor + }) + + property font regularCustom: Qt.font({ family: dapFonts.dapProjectFonts[3].name }) + + + + + + +} //root + + + + diff --git a/ui/chain/wallet/resources/fonts/Quicksand/OFL.txt b/ui/chain/wallet/resources/fonts/Quicksand/OFL.txt new file mode 100755 index 0000000000000000000000000000000000000000..3ee9cb53c5f086edfef8a6723e218a5e631cdb89 --- /dev/null +++ b/ui/chain/wallet/resources/fonts/Quicksand/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2011 The Quicksand Project Authors (https://github.com/andrew-paglinawan/QuicksandFamily), with Reserved Font Name “Quicksandâ€. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Bold.ttf b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Bold.ttf new file mode 100755 index 0000000000000000000000000000000000000000..49326cda826cb32881eec6be046d007f235ab10a Binary files /dev/null and b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Bold.ttf differ diff --git a/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Light.ttf b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Light.ttf new file mode 100755 index 0000000000000000000000000000000000000000..42ef072667312bdca2bf348d5ff6b17d20a68e0b Binary files /dev/null and b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Light.ttf differ diff --git a/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Medium.ttf b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Medium.ttf new file mode 100755 index 0000000000000000000000000000000000000000..7dc8c2745ddc4da094e7137ec53d9f919e960f6a Binary files /dev/null and b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Medium.ttf differ diff --git a/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Regular.ttf b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..9fdce17db502a5a03759481e93c8d70bdc4f5d16 Binary files /dev/null and b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-Regular.ttf differ diff --git a/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-SemiBold.ttf b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-SemiBold.ttf new file mode 100755 index 0000000000000000000000000000000000000000..bc9a8abe83e322e27e78792f7dcf2d86573580cf Binary files /dev/null and b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-SemiBold.ttf differ diff --git a/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-VariableFont_wght.ttf b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-VariableFont_wght.ttf new file mode 100755 index 0000000000000000000000000000000000000000..887908a9c98acb3bf8636719ba5522f9377ebc36 Binary files /dev/null and b/ui/chain/wallet/resources/fonts/Quicksand/Quicksand-VariableFont_wght.ttf differ diff --git a/ui/chain/wallet/resources/fonts/Quicksand/README.txt b/ui/chain/wallet/resources/fonts/Quicksand/README.txt new file mode 100755 index 0000000000000000000000000000000000000000..2da54c8266ebdf254219e8ee2f51859bc0a102a9 --- /dev/null +++ b/ui/chain/wallet/resources/fonts/Quicksand/README.txt @@ -0,0 +1,67 @@ +Quicksand Variable Font +======================= + +This download contains Quicksand as both a variable font and static fonts. + +Quicksand is a variable font with this axis: + wght + +This means all the styles are contained in a single file: + Quicksand-VariableFont_wght.ttf + +If your app fully supports variable fonts, you can now pick intermediate styles +that aren’t available as static fonts. Not all apps support variable fonts, and +in those cases you can use the static font files for Quicksand: + static/Quicksand-Light.ttf + static/Quicksand-Regular.ttf + static/Quicksand-Medium.ttf + static/Quicksand-SemiBold.ttf + static/Quicksand-Bold.ttf + +Get started +----------- + +1. Install the font files you want to use + +2. Use your app's font picker to view the font family and all the +available styles + +Learn more about variable fonts +------------------------------- + + https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts + https://variablefonts.typenetwork.com + https://medium.com/variable-fonts + +In desktop apps + + https://theblog.adobe.com/can-variable-fonts-illustrator-cc + https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts + +Online + + https://developers.google.com/fonts/docs/getting_started + https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide + https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts + +Installing fonts + + MacOS: https://support.apple.com/en-us/HT201749 + Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux + Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows + +Android Apps + + https://developers.google.com/fonts/docs/android + https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts + +License +------- +Please read the full license text (OFL.txt) to understand the permissions, +restrictions and requirements for usage, redistribution, and modification. + +You can use them freely in your products & projects - print or digital, +commercial or otherwise. However, you can't sell the fonts on their own. + +This isn't legal advice, please consider consulting a lawyer and see the full +license for all details.