Skip to content

Commit

Permalink
Merge pull request #39 from bnogalm/protocol_13
Browse files Browse the repository at this point in the history
Protocol 13
  • Loading branch information
bnogalm authored Jun 2, 2020
2 parents 6671f8c + ad61c47 commit d49381a
Show file tree
Hide file tree
Showing 82 changed files with 2,745 additions and 749 deletions.
9 changes: 8 additions & 1 deletion StellarQtSDK.pri
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ DEFINES += STELLAR_QT_REPLY_TIMEOUT=30000
DEFINES *= ED25519_NO_SEED

DEFINES += STELLAR_QT_SDK_CLIENT_NAME=\"\\\"qtcpp-stellar-sdk\\\"\"
DEFINES += STELLAR_QT_SDK_CLIENT_VERSION=\"\\\"0.3.1\\\"\"
DEFINES += STELLAR_QT_SDK_CLIENT_VERSION=\"\\\"0.3.2\\\"\"

#DEFINES += STELLAR_QT_AUTOSET_BASE_FEE

QT *= core network
CONFIG *= c++11
Expand All @@ -18,9 +19,11 @@ INCLUDEPATH *= $$PWD/src/


SOURCES += \
$$PWD/src/abstracttransaction.cpp \
$$PWD/src/account.cpp \
$$PWD/src/accountmergeoperation.cpp \
$$PWD/src/createpassivesellofferoperation.cpp \
$$PWD/src/feebumptransaction.cpp \
$$PWD/src/managebuyofferoperation.cpp \
$$PWD/src/managesellofferoperation.cpp \
$$PWD/src/operation.cpp \
Expand All @@ -38,6 +41,7 @@ SOURCES += \
$$PWD/src/requests/feestatsrequestbuilder.cpp \
$$PWD/src/requests/strictreceivepathsrequestbuilder.cpp \
$$PWD/src/requests/strictsendpathsrequestbuilder.cpp \
$$PWD/src/responses/effects/trustlineauthorizedtomaintainliabilitieseffectresponse.cpp \
$$PWD/src/responses/feestatsresponse.cpp \
$$PWD/src/responses/operations/bumpsequenceoperationresponse.cpp \
$$PWD/src/responses/operations/managebuyofferoperationresponse.cpp \
Expand Down Expand Up @@ -161,14 +165,17 @@ DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

HEADERS += \
$$PWD/src/abstracttransaction.h \
$$PWD/src/createpassivesellofferoperation.h \
$$PWD/src/feebumptransaction.h \
$$PWD/src/managebuyofferoperation.h \
$$PWD/src/managesellofferoperation.h \
$$PWD/src/pathpaymentstrictreceiveoperation.h \
$$PWD/src/pathpaymentstrictsendoperation.h \
$$PWD/src/requests/feestatsrequestbuilder.h \
$$PWD/src/requests/strictreceivepathsrequestbuilder.h \
$$PWD/src/requests/strictsendpathsrequestbuilder.h \
$$PWD/src/responses/effects/trustlineauthorizedtomaintainliabilitieseffectresponse.h \
$$PWD/src/responses/feestatsresponse.h \
$$PWD/src/responses/operations/bumpsequenceoperationresponse.h \
$$PWD/src/responses/operations/managebuyofferoperationresponse.h \
Expand Down
3 changes: 3 additions & 0 deletions StellarQtSDKTest.pro
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ CONFIG += c++11 testcase
DEFINES += STELLAR_ALLOW_UNSECURE_RANDOM
DEFINES += STELLAR_SKIP_LIVE_TESTS

DEFINES += STELLAR_ENABLE_TEST_METHODS


TARGET = StellarQtSDKTest
CONFIG += console
Expand All @@ -19,6 +21,7 @@ include(StellarQtSDK.pri)

HEADERS += \
test/fakeserver.h \
test/feebumptransactiontest.h \
test/keypairtest.h \
test/responses/feestatsdeserializertest.h \
test/strkeytest.h \
Expand Down
12 changes: 9 additions & 3 deletions examples/Example2/PaymentGUI.qml
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,17 @@ ColumnLayout{
text:qsTr("Pay");
visible: fundedTarget;
onClicked: {
sourceWallet.pay(destinationField.text,amountField.text,memoField.text);
paymentGui.enabled=false;
paymentGui.enabled=false;// pay and create if fails, it emit error and invokes onError synchronized, so we have to disable it before.
//signals and slots are invoked in the same moment if the objects live in the same thread and you don't defer the signal by using a timer.
sourceWallet.pay(destinationField.text,amountField.text,memoField.text);
}
}
Button{
text:qsTr("Create");
visible: validTarget && !fundedTarget;
onClicked: {
sourceWallet.create(destinationField.text,amountField.text,memoField.text);
paymentGui.enabled=false;
sourceWallet.create(destinationField.text,amountField.text,memoField.text);
}
}
//this is a way to connect signals to functions on the GUI
Expand All @@ -87,9 +88,14 @@ ColumnLayout{
onSuccess:{
targetWallet.update();
paymentGui.enabled=true;
errorText.text = qsTr("Success!");
}
onError:{
paymentGui.enabled=true;
errorText.text = lastError;
}
}
Text{
id:errorText;
}
}
14 changes: 9 additions & 5 deletions examples/Example2/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,16 @@ void Wallet::pay(QString destination, QString amount, QString memo)
{
try {
//verify the destination account is valid, building a keypair object, exception will be rised if there is a problem with it.
KeyPair* destKeypair = KeyPair::fromAccountId(destination);
//KeyPair* destKeypair = KeyPair::fromAccountId(destination);
//since protocol 13, this check is performed inside operator constructors, it will rise a runtime exception

Server *server= m_gateway->server();

Transaction *t = Transaction::Builder(m_account)
.addOperation(new PaymentOperation(destKeypair,new AssetTypeNative(),amount))
.addOperation(new PaymentOperation(destination,new AssetTypeNative(),amount))
.addMemo(new MemoText(memo))
.setTimeout(10000)// we have to set a timeout
.setTimeout(10000)// we have to set a timeout
.setBaseFee(100)
.build();
t->sign(m_account->getKeypair());
SubmitTransactionResponse* response = server->submitTransaction(t);
Expand All @@ -95,14 +97,16 @@ void Wallet::create(QString destination, QString amount, QString memo)
{
try {
//verify the destination account is valid, building a keypair object, exception will be rised if there is a problem with it.
KeyPair* destKeypair = KeyPair::fromAccountId(destination);
//KeyPair* destKeypair = KeyPair::fromAccountId(destination);
//since protocol 13, this check is performed inside operator constructors, it will rise a runtime exception

Server *server= m_gateway->server();

Transaction *t = Transaction::Builder(m_account)
.addOperation(new CreateAccountOperation(destKeypair,amount))
.addOperation(new CreateAccountOperation(destination,amount))
.addMemo(new MemoText(memo))
.setTimeout(10000)// we have to set a timeout
.setBaseFee(100)
.build();
t->sign(m_account->getKeypair());
SubmitTransactionResponse* response = server->submitTransaction(t);
Expand Down
95 changes: 95 additions & 0 deletions src/abstracttransaction.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "abstracttransaction.h"
#include "transaction.h"
#include "feebumptransaction.h"

AbstractTransaction::AbstractTransaction(Network *network) : m_network(network)
{
checkNotNull(network, "network cannot be null");
}
void AbstractTransaction::sign(KeyPair *signer) {
checkNotNull(signer, "signer cannot be null");
QByteArray txHash = this->hash();

m_signatures.append(signer->signDecorated(txHash));
}

void AbstractTransaction::sign(QByteArray preimage) {
checkNotNull(preimage, "preimage cannot be null");
stellar::DecoratedSignature decoratedSignature;
stellar::Signature &signature = decoratedSignature.signature;

signature.set(reinterpret_cast<uchar*>(preimage.data()),preimage.length());


QByteArray hash = Util::hash(preimage);
QByteArray signatureHintBytes =hash.right(4);

stellar::SignatureHint &signatureHint = decoratedSignature.hint;
memcpy(signatureHint.signatureHint,signatureHintBytes.data(),4);


decoratedSignature.hint = signatureHint;
decoratedSignature.signature = signature;


m_signatures.append(decoratedSignature);
}

QByteArray AbstractTransaction::hash() const
{
return Util::hash(this->signatureBase());
}

QString AbstractTransaction::hashHex() const
{
return QString::fromLatin1(hash().toHex());
}

Network *AbstractTransaction::getNetwork() const
{
return m_network;
}

QVector<stellar::DecoratedSignature> AbstractTransaction::getSignatures() const {
return m_signatures;
}

AbstractTransaction *AbstractTransaction::fromEnvelopeXdr(stellar::TransactionEnvelope &xdr, Network* network)
{
switch(xdr.type)
{
case stellar::EnvelopeType::ENVELOPE_TYPE_TX:
{
return Transaction::fromV1EnvelopeXdr(xdr.v1,network);
}
case stellar::EnvelopeType::ENVELOPE_TYPE_TX_V0:
{
return Transaction::fromV0EnvelopeXdr(xdr.v0,network);
}
case stellar::EnvelopeType::ENVELOPE_TYPE_TX_FEE_BUMP:
{
return FeeBumpTransaction::fromFeeBumpTransactionEnvelope(xdr.feeBump, network);
}
default: throw std::runtime_error("transaction type is not supported");
}


}

AbstractTransaction *AbstractTransaction::fromEnvelopeXdr(QString envelope, Network *network)
{
QByteArray data = QByteArray::fromBase64(envelope.toLatin1());
QDataStream stream(&data, QIODevice::ReadOnly);
stellar::TransactionEnvelope xdr;
stream >> xdr;
return fromEnvelopeXdr(xdr,network);
}

QString AbstractTransaction::toEnvelopeXdrBase64() {

stellar::TransactionEnvelope envelope =this->toEnvelopeXdr();
QByteArray outputStream;
QDataStream xdrOutputStream(&outputStream,QIODevice::WriteOnly);
xdrOutputStream<< envelope;
return outputStream.toBase64(XDR_BASE64ENCODING);
}
83 changes: 83 additions & 0 deletions src/abstracttransaction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#ifndef ABSTRACTTRANSACTION_H
#define ABSTRACTTRANSACTION_H

#include <QObject>
#include "xdr/stellartransaction.h"
#include "keypair.h"
#include "operation.h"
#include "memo.h"
#include "network.h"
class AbstractTransaction : public QObject
{
Q_OBJECT
protected:
Network* m_network;
QVector<stellar::DecoratedSignature> m_signatures;

explicit AbstractTransaction(Network* network);
public:
static const int MIN_BASE_FEE = 100;
/**
* Adds a new signature ed25519PublicKey to this transaction.
* @param signer {@link KeyPair} object representing a signer
*/
void sign(KeyPair* signer);

/**
* Adds a new sha256Hash signature to this transaction by revealing preimage.
* @param preimage the sha256 hash of preimage should be equal to signer hash
*/
void sign(QByteArray preimage);

/**
* Returns transaction hash.
*/
QByteArray hash() const;


/**
* Returns transaction hash encoded as a hexadecimal string.
*/
QString hashHex() const;


/**
* Returns signature base.
*/
virtual QByteArray signatureBase() const= 0;


Network* getNetwork() const;

QVector<stellar::DecoratedSignature> getSignatures() const;

/**
* Generates TransactionEnvelope XDR object.
*/
virtual stellar::TransactionEnvelope toEnvelopeXdr() = 0;

/**
* Returns base64-encoded TransactionEnvelope XDR object. Transaction need to have at least one signature.
*/
QString toEnvelopeXdrBase64();

/**
* Returns new AbstractTransaction object from Transaction XDR object.
* @param xdr XDR object
*/
static AbstractTransaction* fromEnvelopeXdr(stellar::TransactionEnvelope& xdr, Network * network = Network::current());

/**
* Creates a <code>Transaction</code> instance from previously build <code>TransactionEnvelope</code>
* @param envelope Base-64 encoded <code>TransactionEnvelope</code>
* @return
* @throws IOException
*/
static AbstractTransaction* fromEnvelopeXdr(QString envelope, Network* network= Network::current());


signals:

};

#endif // ABSTRACTTRANSACTION_H
40 changes: 12 additions & 28 deletions src/accountmergeoperation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,41 @@



AccountMergeOperation::AccountMergeOperation(KeyPair *destination)
:m_destination(nullptr)
AccountMergeOperation::AccountMergeOperation(QString destination)
{
checkNotNull(destination, "destination cannot be null");

m_op= destination->getXdrPublicKey();
}

AccountMergeOperation::AccountMergeOperation(stellar::AccountID &op)
:m_destination(nullptr),m_op(op)
{

m_destination = checkNotNull(destination, "destination cannot be null");
}

AccountMergeOperation::~AccountMergeOperation(){
if(m_destination)
{
delete m_destination;
}
}

KeyPair *AccountMergeOperation::getDestination() {
if(!m_destination){
m_destination = KeyPair::fromXdrPublicKey(m_op);
}
QString AccountMergeOperation::getDestination() const {
return m_destination;
}

void AccountMergeOperation::fillOperationBody(stellar::Operation &operation) {
operation.type = stellar::OperationType::ACCOUNT_MERGE;
operation.operationAccountMerge = m_op;
operation.operationAccountMerge = StrKey::encodeToXDRMuxedAccount(m_destination);
}

AccountMergeOperation *AccountMergeOperation::build(stellar::AccountID &operationAccountMerge)
AccountMergeOperation *AccountMergeOperation::build(stellar::MuxedAccount &operationAccountMerge)
{
return new AccountMergeOperation(operationAccountMerge);

return new AccountMergeOperation(StrKey::encodeStellarAccountId(StrKey::muxedAccountToAccountId(operationAccountMerge)));
}

AccountMergeOperation *AccountMergeOperation::create(KeyPair* destination)
{
return new AccountMergeOperation(destination);
return new AccountMergeOperation(destination->getAccountId());
}

AccountMergeOperation *AccountMergeOperation::setSourceAccount(KeyPair *sourceAccount)
AccountMergeOperation *AccountMergeOperation::create(QString destination)
{
Operation::setSourceAccount(sourceAccount);
return this;
return new AccountMergeOperation(destination);
}

AccountMergeOperation *AccountMergeOperation::setSourceAccount(KeyPair &sourceAccount)
AccountMergeOperation *AccountMergeOperation::setSourceAccount(QString sourceAccount)
{
Operation::setSourceAccount(new KeyPair(sourceAccount));
Operation::setSourceAccount(sourceAccount);
return this;
}
Loading

0 comments on commit d49381a

Please sign in to comment.