basic commerce infrastructure

This commit is contained in:
howard-stearns 2017-08-09 11:50:52 -07:00
parent 9349e72eeb
commit 1cf81495ab
12 changed files with 134 additions and 2 deletions

View file

@ -131,6 +131,6 @@
{ "from": "Keyboard.Space", "to": "Actions.SHIFT" },
{ "from": "Keyboard.R", "to": "Actions.ACTION1" },
{ "from": "Keyboard.T", "to": "Actions.ACTION2" },
{ "from": "Keyboard.RightMouseClicked", "to": "Actions.ContextMenu" }
{ "from": "Keyboard.Tab", "to": "Actions.ContextMenu" }
]
}

View file

@ -27,6 +27,9 @@ Rectangle {
property string itemId;
// Style
color: hifi.colors.baseGray;
Hifi.QmlCommerce {
id: commerce;
}
//
// TITLE BAR START
@ -259,7 +262,7 @@ Rectangle {
width: parent.width/2 - anchors.rightMargin*2;
text: "Buy"
onClicked: {
sendToScript({method: 'checkout_buyClicked', params: itemId});
sendToScript({method: 'checkout_buyClicked', params: {success: commerce.buy(itemId, parseInt(itemPriceText.text))}});
}
}
}
@ -290,6 +293,7 @@ Rectangle {
itemNameText.text = message.params.itemName;
itemAuthorText.text = message.params.itemAuthor;
itemPriceText.text = message.params.itemPrice;
itemId = message.params.itemId;
break;
default:
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));

View file

@ -195,6 +195,7 @@
#include <ModelScriptingInterface.h>
#include "commerce/Ledger.h"
#include "commerce/Wallet.h"
#include "commerce/QmlCommerce.h"
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
// FIXME seems to be broken.
@ -2061,6 +2062,7 @@ void Application::initializeUi() {
LoginDialog::registerType();
Tooltip::registerType();
UpdateDialog::registerType();
QmlCommerce::registerType();
qmlRegisterType<ResourceImageItem>("Hifi", 1, 0, "ResourceImageItem");
qmlRegisterType<Preference>("Hifi", 1, 0, "Preference");

View file

@ -0,0 +1,14 @@
//
// CommerceLogging.cpp
// interface/interface/src/commerce
//
// Created by Howard Stearns on 8/9/17.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "CommerceLogging.h"
Q_LOGGING_CATEGORY(commerce, "hifi.commerce")

View file

@ -0,0 +1,19 @@
//
// CommerceLogging.h
// interface/src
//
// Created by Howard Stearns on 8/9/17.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_CommerceLogging_h
#define hifi_CommerceLogging_h
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(commerce)
#endif // hifi_CommerceLogging_h

View file

@ -9,4 +9,40 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QJsonObject>
#include <QJsonDocument>
#include "AccountManager.h"
#include "Wallet.h"
#include "Ledger.h"
#include "CommerceLogging.h"
bool Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const QString& buyerUsername) {
QJsonObject transaction;
transaction["hfc_key"] = hfc_key;
transaction["hfc"] = cost;
transaction["asset_id"] = asset_id;
transaction["inventory_key"] = inventory_key;
transaction["inventory_buyer_username"] = buyerUsername;
QJsonDocument transctionDoc{ transaction };
QString transactionString = transctionDoc.toJson(QJsonDocument::Compact);
auto wallet = DependencyManager::get<Wallet>();
QString signature = wallet->signWithKey(transactionString, hfc_key);
QJsonObject request;
request["transaction"] = transactionString;
request["signature"] = signature;
qCInfo(commerce) << "Transaction:" << QJsonDocument(request).toJson(QJsonDocument::Compact);
return true; // FIXME send to server.
}
bool receiveAt(const QString& hfc_key) {
auto accountManager = DependencyManager::get<AccountManager>();
if (!accountManager->isLoggedIn()) {
qCWarning(commerce) << "Cannot set receiveAt when not logged in.";
return false;
}
auto username = accountManager->getAccountInfo().getUsername();
qCInfo(commerce) << "Setting default receiving key for" << username;
return true; // FIXME send to server.
}

View file

@ -20,6 +20,9 @@ class Ledger : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
bool buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const QString& buyerUsername = "");
bool receiveAt(const QString& hfc_key);
};
#endif // hifi_Ledger_h

View file

@ -12,5 +12,19 @@
#include "QmlCommerce.h"
#include "Application.h"
#include "DependencyManager.h"
#include "Ledger.h"
#include "Wallet.h"
HIFI_QML_DEF(QmlCommerce)
bool QmlCommerce::buy(const QString& assetId, int cost, const QString& buyerUsername) {
auto ledger = DependencyManager::get<Ledger>();
auto wallet = DependencyManager::get<Wallet>();
QStringList keys = wallet->listPublicKeys();
if (keys.count == 0) {
return false;
}
QString key = keys[0];
// For now, we receive at the same key that pays for it.
return ledger->buy(key, cost, assetId, key, buyerUsername);
}

View file

@ -21,6 +21,8 @@ class QmlCommerce : public OffscreenQmlDialog {
Q_OBJECT
HIFI_QML_DECL
protected:
Q_INVOKABLE bool buy(const QString& assetId, int cost, const QString& buyerUsername = "");
};
#endif // hifi_QmlCommerce_h

View file

@ -9,4 +9,33 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <quuid.h>
#include "CommerceLogging.h"
#include "Ledger.h"
#include "Wallet.h"
bool Wallet::createIfNeeded() {
// FIXME: persist in file between sessions.
if (_publicKeys.count() > 0) return false;
qCInfo(commerce) << "Creating wallet.";
return generateKeyPair();
}
bool Wallet::generateKeyPair() {
// FIXME: need private key, too, and persist in file.
qCInfo(commerce) << "Generating keypair.";
QString key = QUuid::createUuid().toString();
_publicKeys.push_back(key);
auto ledger = DependencyManager::get<Ledger>();
return ledger->receiveAt(key);
}
QStringList Wallet::listPublicKeys() {
qCInfo(commerce) << "Enumerating public keys.";
createIfNeeded();
return _publicKeys;
}
QString Wallet::signWithKey(const QString& text, const QString& key) {
qCInfo(commerce) << "Signing text.";
return "fixme signed";
}

View file

@ -20,6 +20,14 @@ class Wallet : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
bool createIfNeeded();
bool generateKeyPair();
QStringList listPublicKeys();
QString signWithKey(const QString& text, const QString& key);
private:
QStringList _publicKeys{};
};
#endif // hifi_Wallet_h

View file

@ -197,6 +197,7 @@
//tablet.popFromStack();
break;
case 'checkout_buyClicked':
print("fromQml: " + JSON.stringify(message));
//tablet.popFromStack();
break;
default: