#include "WalletIdlDecoder.h" #include #include #include #include #include #include WalletDecodeResult WalletIdlDecoder::decode( const QByteArray& idlJson, const QVector& accounts) { WalletDecodeResult result; QJsonParseError idlError; const QJsonDocument idl = QJsonDocument::fromJson(idlJson, &idlError); if (idlError.error != QJsonParseError::NoError || !idl.isObject()) { result.status = QStringLiteral("error"); result.error = QStringLiteral("invalid_idl"); return result; } QJsonArray inputs; for (const WalletAccountRead& account : accounts) { inputs.append(QJsonObject { { QStringLiteral("id"), account.accountId }, { QStringLiteral("dataHex"), account.dataHex }, }); } const QByteArray request = QJsonDocument(QJsonObject { { QStringLiteral("idl"), idl.object() }, { QStringLiteral("accounts"), inputs }, }).toJson(QJsonDocument::Compact); char* responsePointer = wallet_idl_decode_accounts(request.constData()); if (!responsePointer) { result.status = QStringLiteral("error"); result.error = QStringLiteral("decoder_unavailable"); return result; } const QByteArray response(responsePointer); wallet_idl_decoder_free(responsePointer); QJsonParseError responseError; const QJsonDocument document = QJsonDocument::fromJson(response, &responseError); if (responseError.error != QJsonParseError::NoError || !document.isObject()) { result.status = QStringLiteral("error"); result.error = QStringLiteral("invalid_decoder_response"); return result; } const QJsonObject root = document.object(); result.status = root.value(QStringLiteral("status")).toString(); result.error = root.value(QStringLiteral("error")).toString(); for (const QJsonValue& value : root.value(QStringLiteral("accounts")).toArray()) { const QJsonObject decoded = value.toObject(); WalletDecodedAccount account; account.id = decoded.value(QStringLiteral("id")).toString(); account.status = decoded.value(QStringLiteral("status")).toString(); account.typeName = decoded.value(QStringLiteral("typeName")).toString(); account.value = decoded.value(QStringLiteral("value")); const QJsonObject ids = decoded.value(QStringLiteral("accountIds")).toObject(); for (auto iterator = ids.begin(); iterator != ids.end(); ++iterator) account.accountIds.insert(iterator.key(), iterator.value().toString()); result.accounts.append(std::move(account)); } return result; } void WalletIdlRegistry::registerProgram(const QString& programId, const QString& programName, const QByteArray& idlJson) { if (!programId.isEmpty() && !programName.isEmpty() && !idlJson.isEmpty()) m_programs.insert(programId, { programName, idlJson }); } QVector WalletIdlRegistry::decode( const QVector& accounts) const { QHash> grouped; for (const WalletAccountRead& account : accounts) { if (m_programs.contains(account.programOwner)) grouped[account.programOwner].append(account); } QVector decoded; decoded.reserve(grouped.size()); for (auto iterator = grouped.cbegin(); iterator != grouped.cend(); ++iterator) { const Program program = m_programs.value(iterator.key()); decoded.append({ iterator.key(), program.name, WalletIdlDecoder::decode(program.idl, iterator.value()), }); } return decoded; }