Merge branch 'develop'
This commit is contained in:
commit
80ff09d42f
28 changed files with 924 additions and 1657 deletions
24
.gitignore
vendored
24
.gitignore
vendored
|
@ -7,6 +7,9 @@
|
|||
# Gradle
|
||||
# ------
|
||||
.gradle
|
||||
gradle
|
||||
gradlew
|
||||
gradlew.bat
|
||||
/build
|
||||
/buildSrc/build
|
||||
/subprojects/*/build
|
||||
|
@ -79,7 +82,24 @@ atlassian-ide-plugin.xml
|
|||
# ----
|
||||
/*.log
|
||||
|
||||
src/main/java/com/luminiasoft/bitshares/mycelium/*
|
||||
|
||||
# Ignore bin backups
|
||||
*.bin
|
||||
|
||||
# [Maven]
|
||||
# -------
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# Build dir
|
||||
graphenej/build
|
||||
|
||||
local.properties
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,3 +0,0 @@
|
|||
dependencies {
|
||||
compile project(':graphenej')
|
||||
}
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
public class Main {
|
||||
|
||||
// Brain key from Nelson's app referencing the bilthon-83 account
|
||||
public static final String BILTHON_83_BRAIN_KEY = System.getenv("BILTHON_83_BRAIN_KEY");
|
||||
|
||||
public static final String BILTHON_83_ORIGINAL_BRAIN_KEY = System.getenv("BILTHON_83_ORIGINAL_BRAIN_KEY");
|
||||
|
||||
public static final String BILTHON_1_BRAIN_KEY = System.getenv("BILTHON_1_BRAIN_KEY");
|
||||
|
||||
public static final String BILTHON_5_BRAIN_KEY = System.getenv("BILTHON_5_BRAIN_KEY");
|
||||
|
||||
public static final String BILTHON_7_BRAIN_KEY = System.getenv("BILTHON_7_BRAIN_KEY");
|
||||
|
||||
public static final String BIP39_KEY = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||
|
||||
public static final String WIF = "5KMzB2GqGhnh7ufhgddmz1eKPHS72uTLeL9hHjSvPb1UywWknF5";
|
||||
|
||||
public static final String BILTHON_83_PASSWORD = System.getenv("BILTHON_83_PASSWORD");
|
||||
|
||||
public static final String BILTHON_25_PASSWORD = System.getenv("BILTHON_25_PASSWORD");
|
||||
|
||||
public static final String BILTHON_11_BRAIN_KEY = System.getenv("BILTHON_11_BRAINKEY");
|
||||
|
||||
public static final String BILTHON_15_BRAIN_KEY = System.getenv("BILTHON_15_BRAINKEY");
|
||||
|
||||
public static final String BILTHON_16_BRAIN_KEY = System.getenv("BILTHON_16_BRAINKEY");
|
||||
|
||||
public static final String BILTHON_36_BRAIN_KEY = System.getenv("BILTHON_36_BRAINKEY");
|
||||
|
||||
public static final String GENERIC_PASSWORD = System.getenv("GENERIC_PASSWORD");
|
||||
|
||||
public static final String DISCLOSABLE_PASSWORD = System.getenv("DISCLOSABLE_PASSWORD");
|
||||
|
||||
// Static block information used for transaction serialization tests
|
||||
public static int REF_BLOCK_NUM = 56204;
|
||||
public static int REF_BLOCK_PREFIX = 1614747814;
|
||||
public static int RELATIVE_EXPIRATION = 1478385607;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Test test = new Test();
|
||||
|
||||
// test.testTransactionSerialization();
|
||||
// ECKey.ECDSASignature signature = test.testSigning();
|
||||
|
||||
// try {
|
||||
// test.testWebSocketTransfer();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// test.testCustomSerializer();
|
||||
// test.testUserAccountSerialization();
|
||||
// test.testTransactionSerialization();
|
||||
// test.testLoginSerialization();
|
||||
// test.testNetworkBroadcastSerialization();
|
||||
// test.testNetworkBroadcastDeserialization();
|
||||
// test.testGetDynamicParams();
|
||||
// test.testGetRequiredFeesSerialization();
|
||||
// test.testRequiredFeesResponse();
|
||||
// test.testTransactionBroadcastSequence();
|
||||
// test.testAccountLookupDeserialization();
|
||||
// test.testPrivateKeyManipulations();
|
||||
// test.testPublicKeyManipulations();
|
||||
// test.testGetAccountByName();
|
||||
// test.testGetRequiredFees();
|
||||
// test.testRandomNumberGeneration();
|
||||
// test.testBrainKeyOperations(false);
|
||||
// test.testBip39Opertion();
|
||||
// test.testAccountNamebyAddress();
|
||||
// test.testAccountNameById();
|
||||
// test.testRelativeAccountHistory();
|
||||
// test.testingInvoiceGeneration();
|
||||
// test.testCompression();
|
||||
// test.testAccountUpdateSerialization();
|
||||
// test.testAccountUpdateOperationBroadcast();
|
||||
// test.testCreateBinFile();
|
||||
// test.testImportBinFile();
|
||||
test.testExportBinFile();
|
||||
// test.testLzmaCompression();
|
||||
// test.testLzmaDecompression();
|
||||
// test.testSimpleDecompression();
|
||||
// test.testLookupAccounts();
|
||||
// test.testLookupAccounts();
|
||||
// test.testDecodeMemo();
|
||||
// test.testGetRelativeAccountHistory();
|
||||
// test.testLookupAssetSymbols();
|
||||
// test.testListAssets();
|
||||
// test.testGetObjects();
|
||||
// test.testGetBlockHeader();
|
||||
// test.testGetLimitOrders();
|
||||
// test.testGetTradeHistory();
|
||||
// test.testAssetSerialization();
|
||||
// test.testGetMarketHistory();
|
||||
// test.testGetAccountBalances();
|
||||
// test.testGetAssetHoldersCount();
|
||||
// test.testSubscription(null);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -3,8 +3,15 @@ allprojects {
|
|||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: "java"
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||
}
|
||||
}
|
33
gradle.properties
Normal file
33
gradle.properties
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
VERSION_NAME=0.4.1
|
||||
VERSION_CODE=3
|
||||
GROUP=com.github.kenCode-de
|
||||
|
||||
POM_DESCRIPTION=A Java library for mobile app Developers; Graphene/Bitshares blockchain.
|
||||
POM_URL=https://github.com/kenCode-de/graphenej
|
||||
POM_SCM_URL=https://github.com/kenCode-de/graphenej
|
||||
POM_SCM_CONNECTION=scm:git@github.com:kenCode-de/graphenej.git
|
||||
POM_SCM_DEV_CONNECTION=scm:git@github.com:kenCode-de/graphenej.git
|
||||
POM_LICENCE_NAME=MIT License
|
||||
POM_LICENCE_URL=https://github.com/kenCode-de/graphenej/blob/master/LICENSE
|
||||
POM_LICENCE_DIST=repo
|
||||
POM_DEVELOPER_ID=bilthon
|
||||
POM_DEVELOPER_NAME=bilthon
|
|
@ -1,17 +1,9 @@
|
|||
group 'de.bitsharesmunich'
|
||||
version '0.1-SNAPSHOT'
|
||||
version '0.4.0-SNAPSHOT'
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply from: 'maven-push.gradle'
|
||||
|
||||
//apply plugin: 'java'
|
||||
//
|
||||
//model {
|
||||
// components {
|
||||
// main(JvmLibrarySpec)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//repositories {
|
||||
// mavenCentral()
|
||||
//}
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
|
@ -20,3 +12,24 @@ dependencies {
|
|||
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
|
||||
compile group: "org.tukaani", name: "xz", version: "1.6"
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion 24
|
||||
buildToolsVersion "25.0.0"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 3
|
||||
targetSdkVersion 24
|
||||
versionCode 3
|
||||
versionName "0.4.1"
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
3
graphenej/gradle.properties
Normal file
3
graphenej/gradle.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
POM_NAME=Graphenej
|
||||
POM_ARTIFACT_ID=graphenej
|
||||
POM_PACKAGING=aar
|
112
graphenej/maven-push.gradle
Normal file
112
graphenej/maven-push.gradle
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2013 Chris Banes
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'signing'
|
||||
|
||||
def isReleaseBuild() {
|
||||
return VERSION_NAME.contains("SNAPSHOT") == false
|
||||
}
|
||||
|
||||
def getReleaseRepositoryUrl() {
|
||||
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
|
||||
: "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||
}
|
||||
|
||||
def getSnapshotRepositoryUrl() {
|
||||
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
|
||||
: "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
}
|
||||
|
||||
def getRepositoryUsername() {
|
||||
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
|
||||
}
|
||||
|
||||
def getRepositoryPassword() {
|
||||
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
|
||||
}
|
||||
|
||||
afterEvaluate { project ->
|
||||
uploadArchives {
|
||||
repositories {
|
||||
mavenDeployer {
|
||||
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
||||
|
||||
pom.groupId = GROUP
|
||||
pom.artifactId = POM_ARTIFACT_ID
|
||||
pom.version = VERSION_NAME
|
||||
|
||||
repository(url: getReleaseRepositoryUrl()) {
|
||||
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
|
||||
}
|
||||
snapshotRepository(url: getSnapshotRepositoryUrl()) {
|
||||
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
|
||||
}
|
||||
|
||||
pom.project {
|
||||
name POM_NAME
|
||||
packaging POM_PACKAGING
|
||||
description POM_DESCRIPTION
|
||||
url POM_URL
|
||||
|
||||
scm {
|
||||
url POM_SCM_URL
|
||||
connection POM_SCM_CONNECTION
|
||||
developerConnection POM_SCM_DEV_CONNECTION
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name POM_LICENCE_NAME
|
||||
url POM_LICENCE_URL
|
||||
distribution POM_LICENCE_DIST
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id POM_DEVELOPER_ID
|
||||
name POM_DEVELOPER_NAME
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
|
||||
sign configurations.archives
|
||||
}
|
||||
|
||||
//task androidJavadocs(type: Javadoc) {
|
||||
//source = android.sourceSets.main.allJava
|
||||
//}
|
||||
|
||||
//task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
|
||||
//classifier = 'javadoc'
|
||||
//from androidJavadocs.destinationDir
|
||||
//}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.sourceFiles
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives androidSourcesJar
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
rootProject.name = 'graphenej'
|
||||
include 'application'
|
||||
|
9
graphenej/src/main/AndroidManifest.xml
Normal file
9
graphenej/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="de.bitsharesmunich.graphenej"
|
||||
android:versionCode="1"
|
||||
android:versionName="0.4.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="1" />
|
||||
<application/>
|
||||
</manifest>
|
|
@ -1,67 +0,0 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import de.bitsharesmunich.graphenej.errors.MalformedTransactionException;
|
||||
import de.bitsharesmunich.graphenej.operations.AccountUpdateOperation;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class used to build a transaction containing an account update operation.
|
||||
*/
|
||||
public class AccountUpdateTransactionBuilder extends TransactionBuilder {
|
||||
private List<BaseOperation> operations;
|
||||
private AssetAmount fee;
|
||||
private UserAccount account;
|
||||
private Authority owner;
|
||||
private Authority active;
|
||||
private AccountOptions new_options;
|
||||
|
||||
public AccountUpdateTransactionBuilder(ECKey privKey) {
|
||||
super(privKey);
|
||||
}
|
||||
|
||||
|
||||
public AccountUpdateTransactionBuilder setAccont(UserAccount account){
|
||||
this.account = account;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccountUpdateTransactionBuilder setOwner(Authority owner){
|
||||
this.owner = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccountUpdateTransactionBuilder setActive(Authority active){
|
||||
this.active = active;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccountUpdateTransactionBuilder setOptions(AccountOptions options){
|
||||
this.new_options = options;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccountUpdateTransactionBuilder setFee(AssetAmount fee){
|
||||
this.fee = fee;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction build() throws MalformedTransactionException {
|
||||
if(account == null){
|
||||
throw new MalformedTransactionException("Missing required account information");
|
||||
}else{
|
||||
operations = new ArrayList<>();
|
||||
AccountUpdateOperation operation;
|
||||
if(fee == null){
|
||||
operation = new AccountUpdateOperation(account, owner, active, new_options);
|
||||
}else{
|
||||
operation = new AccountUpdateOperation(account, owner, active, new_options, fee);
|
||||
}
|
||||
operations.add(operation);
|
||||
}
|
||||
return new Transaction(privateKey, blockData, operations);
|
||||
}
|
||||
}
|
|
@ -129,6 +129,9 @@ public class AssetAmount implements ByteSerializable, JsonSerializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom deserializer used for this class
|
||||
*/
|
||||
public static class AssetAmountDeserializer implements JsonDeserializer<AssetAmount> {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
|
||||
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
|
||||
|
||||
|
@ -8,6 +10,9 @@ import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
|
|||
*/
|
||||
public abstract class BaseOperation implements ByteSerializable, JsonSerializable {
|
||||
|
||||
public static final String KEY_FEE = "fee";
|
||||
public static final String KEY_EXTENSIONS = "extensions";
|
||||
|
||||
protected OperationType type;
|
||||
protected Extensions extensions;
|
||||
|
||||
|
@ -22,5 +27,9 @@ public abstract class BaseOperation implements ByteSerializable, JsonSerializabl
|
|||
|
||||
public abstract void setFee(AssetAmount assetAmount);
|
||||
|
||||
public abstract byte[] toBytes();
|
||||
public JsonElement toJsonObject(){
|
||||
JsonArray array = new JsonArray();
|
||||
array.add(this.getId());
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,131 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import com.google.gson.*;
|
||||
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henry
|
||||
*/
|
||||
public class LimitOrder {
|
||||
public String id;
|
||||
public String expiration;
|
||||
public UserAccount seller;
|
||||
public long for_sale;
|
||||
public long deferred_fee;
|
||||
public Price sell_price;
|
||||
public class LimitOrder extends GrapheneObject implements ByteSerializable {
|
||||
|
||||
public static final String KEY_EXPIRATION = "expiration";
|
||||
public static final String KEY_SELLER = "seller";
|
||||
public static final String KEY_FOR_SALE = "for_sale";
|
||||
public static final String KEY_DEFERRED_FEE = "deferred_fee";
|
||||
public static final String KEY_PRICE = "key_price";
|
||||
|
||||
private String expiration;
|
||||
private UserAccount seller;
|
||||
private long forSale;
|
||||
private long deferredFee;
|
||||
private Price sellPrice;
|
||||
|
||||
public LimitOrder(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public String getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public void setExpiration(String expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
public UserAccount getSeller() {
|
||||
return seller;
|
||||
}
|
||||
|
||||
public void setSeller(UserAccount seller) {
|
||||
this.seller = seller;
|
||||
}
|
||||
|
||||
public long getForSale() {
|
||||
return forSale;
|
||||
}
|
||||
|
||||
public void setForSale(long forSale) {
|
||||
this.forSale = forSale;
|
||||
}
|
||||
|
||||
public long getDeferredFee() {
|
||||
return deferredFee;
|
||||
}
|
||||
|
||||
public void setDeferredFee(long deferredFee) {
|
||||
this.deferredFee = deferredFee;
|
||||
}
|
||||
|
||||
public Price getSellPrice() {
|
||||
return sellPrice;
|
||||
}
|
||||
|
||||
public void setSellPrice(Price sellPrice) {
|
||||
this.sellPrice = sellPrice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toBytes() {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
DataOutput out = new DataOutputStream(byteArrayOutputStream);
|
||||
byte[] serialized = null;
|
||||
try {
|
||||
Varint.writeUnsignedVarLong(this.instance, out);
|
||||
serialized = byteArrayOutputStream.toByteArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom deserializer for the LimitOrder class, used to deserialize a json-formatted string in
|
||||
* the following format:
|
||||
*
|
||||
* {
|
||||
* "id": "1.7.2389233",
|
||||
* "expiration": "2017-04-21T15:40:04",
|
||||
* "seller": "1.2.114363",
|
||||
* "forSale": "10564959415",
|
||||
* "sell_price": {
|
||||
* "base": {
|
||||
* "amount": "10565237932",
|
||||
* "asset_id": "1.3.0"
|
||||
* },
|
||||
* "quote": {
|
||||
* "amount": 5803878,
|
||||
* "asset_id": "1.3.121"
|
||||
* }
|
||||
* },
|
||||
* "deferredFee": 0
|
||||
* }
|
||||
*/
|
||||
public static class LimitOrderDeserializer implements JsonDeserializer<LimitOrder> {
|
||||
|
||||
@Override
|
||||
public LimitOrder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
String id = object.get(KEY_ID).getAsString();
|
||||
String expiration = object.get(KEY_EXPIRATION).getAsString();
|
||||
UserAccount seller = context.deserialize(object.get(KEY_SELLER), UserAccount.class);
|
||||
String forSale = object.get(KEY_FOR_SALE).getAsString();
|
||||
Price price = context.deserialize(object.get(KEY_PRICE), Price.class);
|
||||
long deferredFee = object.get(KEY_DEFERRED_FEE).getAsLong();
|
||||
|
||||
LimitOrder limitOrder = new LimitOrder(id);
|
||||
limitOrder.setExpiration(expiration);
|
||||
limitOrder.setSeller(seller);
|
||||
limitOrder.setForSale(Long.parseLong(forSale));
|
||||
limitOrder.setSellPrice(price);
|
||||
limitOrder.setDeferredFee(deferredFee);
|
||||
return limitOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import de.bitsharesmunich.graphenej.errors.MalformedTransactionException;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
|
||||
/**
|
||||
* Created by nelson on 11/14/16.
|
||||
*/
|
||||
public abstract class TransactionBuilder {
|
||||
protected ECKey privateKey;
|
||||
protected BlockData blockData;
|
||||
|
||||
public TransactionBuilder(){}
|
||||
|
||||
public TransactionBuilder(ECKey privKey){
|
||||
this.privateKey = privKey;
|
||||
}
|
||||
|
||||
public TransactionBuilder setBlockData(BlockData blockData){
|
||||
this.blockData = blockData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract Transaction build() throws MalformedTransactionException;
|
||||
}
|
|
@ -59,6 +59,7 @@ public class GetLimitOrders extends WebSocketAdapter {
|
|||
Type GetLimitOrdersResponse = new TypeToken<WitnessResponse<List<LimitOrder>>>() {}.getType();
|
||||
builder.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer());
|
||||
builder.registerTypeAdapter(UserAccount.class, new UserAccount.UserAccountSimpleDeserializer());
|
||||
builder.registerTypeAdapter(LimitOrder.class, new LimitOrder.LimitOrderDeserializer());
|
||||
WitnessResponse<List<LimitOrder>> witnessResponse = builder.create().fromJson(response, GetLimitOrdersResponse);
|
||||
if (witnessResponse.error != null) {
|
||||
this.mListener.onError(witnessResponse.error);
|
||||
|
|
|
@ -133,7 +133,7 @@ public class TransactionBroadcastSequence extends WebSocketAdapter {
|
|||
websocket.sendText(call.toJsonString());
|
||||
}else if(baseResponse.id >= BROADCAST_TRANSACTION){
|
||||
Type WitnessResponseType = new TypeToken<WitnessResponse<String>>(){}.getType();
|
||||
WitnessResponse<WitnessResponse<String>> witnessResponse = gson.fromJson(response, WitnessResponseType);
|
||||
WitnessResponse<String> witnessResponse = gson.fromJson(response, WitnessResponseType);
|
||||
mListener.onSuccess(witnessResponse);
|
||||
websocket.disconnect();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package de.bitsharesmunich.graphenej.operations;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.bitsharesmunich.graphenej.*;
|
||||
|
||||
/**
|
||||
* Created by nelson on 3/21/17.
|
||||
*/
|
||||
public class LimitOrderCancelOperation extends BaseOperation {
|
||||
|
||||
// Constants used in the JSON representation
|
||||
public static final String KEY_FEE_PAYING_ACCOUNT = "fee_paying_account";
|
||||
public static final String KEY_ORDER_ID = "order";
|
||||
|
||||
|
||||
public LimitOrderCancelOperation(LimitOrder order, UserAccount feePayingAccount) {
|
||||
super(OperationType.LIMIT_ORDER_CANCEL_OPERATION);
|
||||
this.order = order;
|
||||
this.feePayingAccount = feePayingAccount;
|
||||
}
|
||||
|
||||
// Inner fields of a limit order cancel operation
|
||||
private AssetAmount fee;
|
||||
private UserAccount feePayingAccount;
|
||||
private LimitOrder order;
|
||||
|
||||
@Override
|
||||
public String toJsonString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJsonObject() {
|
||||
JsonArray array = (JsonArray) super.toJsonObject();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
if(fee != null)
|
||||
jsonObject.add(KEY_FEE, fee.toJsonObject());
|
||||
jsonObject.addProperty(KEY_FEE_PAYING_ACCOUNT, feePayingAccount.getObjectId());
|
||||
jsonObject.addProperty(KEY_ORDER_ID, order.getObjectId());
|
||||
jsonObject.add(KEY_EXTENSIONS, new JsonArray());
|
||||
array.add(jsonObject);
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFee(AssetAmount assetAmount) {
|
||||
this.fee = assetAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toBytes() {
|
||||
byte[] feeBytes = this.fee.toBytes();
|
||||
byte[] feePayingAccountBytes = this.feePayingAccount.toBytes();
|
||||
byte[] orderIdBytes = this.order.toBytes();
|
||||
byte[] extensions = this.extensions.toBytes();
|
||||
return Bytes.concat(feeBytes, feePayingAccountBytes, orderIdBytes, extensions);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package de.bitsharesmunich.graphenej.operations;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.bitsharesmunich.graphenej.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Operation used to denote the creation of a limit order on the blockchain.
|
||||
*
|
||||
* The blockchain will atempt to sell amount_to_sell.asset_id for as much min_to_receive.asset_id as possible.
|
||||
* The fee will be paid by the seller's account. Market fees will apply as specified by the issuer of both the
|
||||
* selling asset and the receiving asset as a percentage of the amount exchanged.
|
||||
*
|
||||
* If either the selling asset or the receiving asset is white list restricted, the order will only be created
|
||||
* if the seller is on the white list of the restricted asset type.
|
||||
*
|
||||
* Market orders are matched in the order they are included in the block chain.
|
||||
*/
|
||||
public class LimitOrderCreateOperation extends BaseOperation {
|
||||
// Number of bytes used for the expiration field.
|
||||
private final int EXPIRATION_BYTE_LENGTH = 4;
|
||||
|
||||
// Constants used in the JSON representation
|
||||
public static final String KEY_SELLER = "seller";
|
||||
public static final String KEY_AMOUNT_TO_SELL = "amount_to_sell";
|
||||
public static final String KEY_MIN_TO_RECEIVE = "min_to_receive";
|
||||
public static final String KEY_EXPIRATION = "expiration";
|
||||
public static final String KEY_FILL_OR_KILL = "fill_or_kill";
|
||||
|
||||
// Inner fields of a limit order
|
||||
private AssetAmount fee;
|
||||
private UserAccount seller;
|
||||
private AssetAmount amountToSell;
|
||||
private AssetAmount minToReceive;
|
||||
private int expiration;
|
||||
private boolean fillOrKill;
|
||||
|
||||
/**
|
||||
* @param seller: Id of the seller
|
||||
* @param toSell: Id of the asset to sell
|
||||
* @param minToReceive: The minimum amount of the asset to receive
|
||||
* @param expiration: Expiration in seconds
|
||||
* @param fillOrKill: If this flag is set the entire order must be filled or the operation is rejected.
|
||||
*/
|
||||
public LimitOrderCreateOperation(UserAccount seller, AssetAmount toSell, AssetAmount minToReceive, int expiration, boolean fillOrKill){
|
||||
super(OperationType.LIMIT_ORDER_CREATE_OPERATION);
|
||||
this.seller = seller;
|
||||
this.amountToSell = toSell;
|
||||
this.minToReceive = minToReceive;
|
||||
this.expiration = expiration;
|
||||
this.fillOrKill = fillOrKill;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJsonString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJsonObject() {
|
||||
JsonArray array = (JsonArray) super.toJsonObject();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
if(fee != null)
|
||||
jsonObject.add(KEY_FEE, fee.toJsonObject());
|
||||
jsonObject.addProperty(KEY_SELLER, seller.toJsonString());
|
||||
jsonObject.add(KEY_AMOUNT_TO_SELL, amountToSell.toJsonObject());
|
||||
jsonObject.add(KEY_MIN_TO_RECEIVE, minToReceive.toJsonObject());
|
||||
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
|
||||
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
jsonObject.addProperty(KEY_EXPIRATION, simpleDateFormat.format(new Date(((long) expiration) * 1000)));
|
||||
jsonObject.addProperty(KEY_FILL_OR_KILL, this.fillOrKill ? "true" : "false");
|
||||
jsonObject.add(KEY_EXTENSIONS, new JsonArray());
|
||||
array.add(jsonObject);
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFee(AssetAmount assetAmount) {
|
||||
this.fee = assetAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] toBytes() {
|
||||
byte[] feeBytes = this.fee.toBytes();
|
||||
byte[] sellerBytes = this.seller.toBytes();
|
||||
byte[] amountBytes = this.amountToSell.toBytes();
|
||||
byte[] minAmountBytes = this.minToReceive.toBytes();
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(EXPIRATION_BYTE_LENGTH);
|
||||
buffer.putInt(this.expiration);
|
||||
byte[] expirationBytes = Util.revertBytes(buffer.array());
|
||||
|
||||
byte[] fillOrKill = this.fillOrKill ? new byte[]{ 0x1 } : new byte[]{ 0x0 };
|
||||
byte[] extensions = this.extensions.toBytes();
|
||||
|
||||
return Bytes.concat(feeBytes, sellerBytes, amountBytes, minAmountBytes, expirationBytes, fillOrKill, extensions);
|
||||
}
|
||||
}
|
|
@ -14,9 +14,7 @@ import java.lang.reflect.Type;
|
|||
* Class used to encapsulate the TransferOperation operation related functionalities.
|
||||
*/
|
||||
public class TransferOperation extends BaseOperation {
|
||||
public static final String KEY_FEE = "fee";
|
||||
public static final String KEY_AMOUNT = "amount";
|
||||
public static final String KEY_EXTENSIONS = "extensions";
|
||||
public static final String KEY_FROM = "from";
|
||||
public static final String KEY_TO = "to";
|
||||
public static final String KEY_MEMO = "memo";
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import com.google.common.primitives.UnsignedLong;
|
||||
import com.neovisionaries.ws.client.WebSocket;
|
||||
import com.neovisionaries.ws.client.WebSocketException;
|
||||
import com.neovisionaries.ws.client.WebSocketFactory;
|
||||
import de.bitsharesmunich.graphenej.api.GetLimitOrders;
|
||||
import de.bitsharesmunich.graphenej.api.TransactionBroadcastSequence;
|
||||
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
|
||||
import de.bitsharesmunich.graphenej.models.BaseResponse;
|
||||
import de.bitsharesmunich.graphenej.models.WitnessResponse;
|
||||
import de.bitsharesmunich.graphenej.objects.Memo;
|
||||
import de.bitsharesmunich.graphenej.operations.*;
|
||||
import de.bitsharesmunich.graphenej.test.NaiveSSLContext;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by nelson on 3/6/17.
|
||||
*/
|
||||
public class TransactionTest {
|
||||
private final String BILTHON_15_BRAIN_KEY = System.getenv("BILTHON_15_BRAINKEY");
|
||||
private final String BILTHON_5_BRAIN_KEY = System.getenv("BILTHON_5_BRAINKEY");
|
||||
private final String BILTHON_16_BRAIN_KEY = System.getenv("BILTHON_16_BRAINKEY");
|
||||
|
||||
private final String BLOCK_PAY_DE = System.getenv("BLOCKPAY_DE");
|
||||
private final String BLOCK_PAY_FR = System.getenv("BLOCKPAY_FR");
|
||||
|
||||
// Transfer operation transaction
|
||||
private final Asset CORE_ASSET = new Asset("1.3.0");
|
||||
private final UserAccount bilthon_15 = new UserAccount("1.2.143563");
|
||||
private final UserAccount bilthon_5 = new UserAccount("1.2.139313");
|
||||
private final UserAccount bilthon_16 = new UserAccount("1.2.143569");
|
||||
|
||||
// Limit order create transaction
|
||||
private final Asset BIT_USD = new Asset("1.3.121");
|
||||
private UserAccount seller = bilthon_15;
|
||||
private AssetAmount amountToSell = new AssetAmount(UnsignedLong.valueOf(100000), CORE_ASSET);
|
||||
private AssetAmount minToReceive = new AssetAmount(UnsignedLong.valueOf(520), BIT_USD);
|
||||
private long expiration;
|
||||
|
||||
// Lock object
|
||||
private static final class Lock { }
|
||||
private final Object lockObject = new Lock();
|
||||
|
||||
// Response
|
||||
private BaseResponse baseResponse;
|
||||
|
||||
/**
|
||||
* Generic witness response listener that will just release the lock created in
|
||||
* main thread.
|
||||
*/
|
||||
WitnessResponseListener listener = new WitnessResponseListener() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(WitnessResponse response) {
|
||||
System.out.println("onSuccess");
|
||||
baseResponse = response;
|
||||
synchronized (this){
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(BaseResponse.Error error) {
|
||||
System.out.println("onError. Msg: "+error.data.message);
|
||||
synchronized (this){
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives the elements required for building a transaction, puts them together and broadcasts it.
|
||||
* @param privateKey: The private key used to sign the transaction.
|
||||
* @param operationList: The list of operations to include
|
||||
* @param responseListener: The response listener.
|
||||
* @param lockObject: Optional object to use as a lock
|
||||
*/
|
||||
private void broadcastTransaction(ECKey privateKey, List<BaseOperation> operationList, WitnessResponseListener responseListener, Object lockObject) {
|
||||
try{
|
||||
Transaction transaction = new Transaction(privateKey, null, operationList);
|
||||
|
||||
SSLContext context = null;
|
||||
context = NaiveSSLContext.getInstance("TLS");
|
||||
WebSocketFactory factory = new WebSocketFactory();
|
||||
|
||||
// Set the custom SSL context.
|
||||
factory.setSSLContext(context);
|
||||
|
||||
WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_DE);
|
||||
|
||||
mWebSocket.addListener(new TransactionBroadcastSequence(transaction, CORE_ASSET, responseListener));
|
||||
mWebSocket.connect();
|
||||
|
||||
// If a lock object is specified, we use it
|
||||
if(lockObject != null){
|
||||
synchronized (lockObject){
|
||||
lockObject.wait();
|
||||
}
|
||||
}else{
|
||||
// Otherwise we just use this listener as the lock
|
||||
synchronized (responseListener){
|
||||
responseListener.wait();
|
||||
}
|
||||
}
|
||||
Assert.assertNotNull(baseResponse);
|
||||
Assert.assertNull(baseResponse.error);
|
||||
}catch(NoSuchAlgorithmException e){
|
||||
System.out.println("NoSuchAlgoritmException. Msg: " + e.getMessage());
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("InterruptedException. Msg: "+e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.out.println("IOException. Msg: " + e.getMessage());
|
||||
} catch (WebSocketException e) {
|
||||
System.out.println("WebSocketException. Msg: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransferTransaction(){
|
||||
ECKey sourcePrivateKey = new BrainKey(BILTHON_15_BRAIN_KEY, 0).getPrivateKey();
|
||||
PublicKey to1 = new PublicKey(ECKey.fromPublicOnly(new BrainKey(BILTHON_5_BRAIN_KEY, 0).getPublicKey()));
|
||||
PublicKey to2 = new PublicKey(ECKey.fromPublicOnly(new BrainKey(BILTHON_16_BRAIN_KEY, 0).getPublicKey()));
|
||||
|
||||
// Creating memo
|
||||
long nonce = 1;
|
||||
byte[] encryptedMessage = Memo.encryptMessage(sourcePrivateKey, to1, nonce, "another message");
|
||||
Memo memo = new Memo(new Address(ECKey.fromPublicOnly(sourcePrivateKey.getPubKey())), new Address(to1.getKey()), nonce, encryptedMessage);
|
||||
|
||||
// Creating operation 1
|
||||
TransferOperation transferOperation1 = new TransferOperationBuilder()
|
||||
.setTransferAmount(new AssetAmount(UnsignedLong.valueOf(1), CORE_ASSET))
|
||||
.setSource(bilthon_15)
|
||||
.setDestination(bilthon_5) // bilthon-5
|
||||
.setFee(new AssetAmount(UnsignedLong.valueOf(264174), CORE_ASSET))
|
||||
.build();
|
||||
|
||||
// Creating operation 2
|
||||
TransferOperation transferOperation2 = new TransferOperationBuilder()
|
||||
.setTransferAmount(new AssetAmount(UnsignedLong.valueOf(1), CORE_ASSET))
|
||||
.setSource(bilthon_15) // bilthon-15
|
||||
.setDestination(bilthon_16) // bilthon-16
|
||||
.setFee(new AssetAmount(UnsignedLong.valueOf(264174), CORE_ASSET))
|
||||
.build();
|
||||
|
||||
|
||||
// Adding operations to the operation list
|
||||
ArrayList<BaseOperation> operationList = new ArrayList<>();
|
||||
operationList.add(transferOperation1);
|
||||
operationList.add(transferOperation2);
|
||||
|
||||
// Broadcasting transaction
|
||||
broadcastTransaction(sourcePrivateKey, operationList, listener, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimitOrderCreateTransaction(){
|
||||
ECKey privateKey = new BrainKey(BILTHON_15_BRAIN_KEY, 0).getPrivateKey();
|
||||
expiration = (System.currentTimeMillis() / 1000) + 60 * 60;
|
||||
|
||||
// Creating limit order creation operation
|
||||
LimitOrderCreateOperation operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, (int) expiration, false);
|
||||
operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET));
|
||||
|
||||
ArrayList<BaseOperation> operationList = new ArrayList<>();
|
||||
operationList.add(operation);
|
||||
|
||||
// Broadcasting transaction
|
||||
broadcastTransaction(privateKey, operationList, listener, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since tests should be independent of each other, in order to be able to test the cancellation of an
|
||||
* existing order we must first proceed to create one. And after creating one, we must also retrieve
|
||||
* its id in a separate call.
|
||||
*
|
||||
* All of this just makes this test a bit more complex, since we have 3 clearly defined tasks that require
|
||||
* network communication
|
||||
*
|
||||
* 1- Create order
|
||||
* 2- Retrieve order id
|
||||
* 3- Send order cancellation tx
|
||||
*
|
||||
* Only the last one is what we actually want to test
|
||||
*
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws IOException
|
||||
* @throws WebSocketException
|
||||
*/
|
||||
@Test
|
||||
public void testLimitOrderCancelTransaction() throws NoSuchAlgorithmException, IOException, WebSocketException {
|
||||
|
||||
// We first must create a limit order for this test
|
||||
ECKey privateKey = new BrainKey(BILTHON_15_BRAIN_KEY, 0).getPrivateKey();
|
||||
expiration = (System.currentTimeMillis() / 1000) + 60 * 5;
|
||||
|
||||
// Creating limit order creation operation
|
||||
LimitOrderCreateOperation operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, (int) expiration, false);
|
||||
operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET));
|
||||
|
||||
ArrayList<BaseOperation> operationList = new ArrayList<>();
|
||||
operationList.add(operation);
|
||||
|
||||
// Broadcasting transaction (Task 1)
|
||||
broadcastTransaction(privateKey, operationList, new WitnessResponseListener() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(WitnessResponse response) {
|
||||
|
||||
System.out.println("onSuccess.0");
|
||||
try{
|
||||
// Setting up the assets
|
||||
Asset base = amountToSell.getAsset();
|
||||
Asset quote = minToReceive.getAsset();
|
||||
|
||||
SSLContext context = NaiveSSLContext.getInstance("TLS");
|
||||
WebSocketFactory factory = new WebSocketFactory();
|
||||
|
||||
// Set the custom SSL context.
|
||||
factory.setSSLContext(context);
|
||||
WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_DE);
|
||||
|
||||
// Requesting limit order to cancel (Task 2)
|
||||
mWebSocket.addListener(new GetLimitOrders(base.getObjectId(), quote.getObjectId(), 100, new WitnessResponseListener() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(WitnessResponse response) {
|
||||
System.out.println("onSuccess.1");
|
||||
List<LimitOrder> orders = (List<LimitOrder>) response.result;
|
||||
for(LimitOrder order : orders){
|
||||
if(order.getSeller().getObjectId().equals(bilthon_15.getObjectId())){
|
||||
|
||||
// Instantiating a private key for bilthon-15
|
||||
ECKey privateKey = new BrainKey(BILTHON_15_BRAIN_KEY, 0).getPrivateKey();
|
||||
|
||||
// Creating limit order cancellation operation
|
||||
LimitOrderCancelOperation operation = new LimitOrderCancelOperation(order, bilthon_15);
|
||||
ArrayList<BaseOperation> operationList = new ArrayList<>();
|
||||
operationList.add(operation);
|
||||
|
||||
// Broadcasting order cancellation tx (Task 3)
|
||||
broadcastTransaction(privateKey, operationList, new WitnessResponseListener() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(WitnessResponse response) {
|
||||
System.out.println("onSuccess.2");
|
||||
baseResponse = response;
|
||||
synchronized (this){
|
||||
notifyAll();
|
||||
}
|
||||
synchronized (lockObject){
|
||||
lockObject.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(BaseResponse.Error error) {
|
||||
System.out.println("onError.2");
|
||||
synchronized (this){
|
||||
notifyAll();
|
||||
}
|
||||
synchronized (lockObject){
|
||||
lockObject.notifyAll();
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(BaseResponse.Error error) {
|
||||
System.out.println("onError.1");
|
||||
System.out.println(error.data.message);
|
||||
Assert.assertNull(error);
|
||||
synchronized (lockObject){
|
||||
lockObject.notifyAll();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
mWebSocket.connect();
|
||||
|
||||
}catch(NoSuchAlgorithmException e){
|
||||
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
|
||||
} catch (WebSocketException e) {
|
||||
System.out.println("WebSocketException. Msg: "+e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.out.println("IOException. Msg: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(BaseResponse.Error error) {
|
||||
System.out.println("OnError. Msg: "+error.message);
|
||||
synchronized (this){
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}, lockObject);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package de.bitsharesmunich.graphenej.operations;
|
||||
|
||||
import com.google.common.primitives.UnsignedLong;
|
||||
import de.bitsharesmunich.graphenej.*;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
/**
|
||||
* Created by nelson on 3/21/17.
|
||||
*/
|
||||
public class LimitOrderCancelOperationTest {
|
||||
private static final Asset CORE_ASSET = new Asset("1.3.0");
|
||||
private UserAccount feePayingAccount;
|
||||
private LimitOrder limitOrder;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
feePayingAccount = new UserAccount("1.2.143563");
|
||||
limitOrder = new LimitOrder("1.7.2360289");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBytes() throws Exception {
|
||||
LimitOrderCancelOperation operation = new LimitOrderCancelOperation(limitOrder, feePayingAccount);
|
||||
operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET));
|
||||
byte[] serialized = operation.toBytes();
|
||||
assertArrayEquals("Correct serialization", Util.hexToBytes("020000000000000000cbe108e187900100"), serialized);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package de.bitsharesmunich.graphenej.operations;
|
||||
|
||||
import com.google.common.primitives.UnsignedLong;
|
||||
import de.bitsharesmunich.graphenej.Asset;
|
||||
import de.bitsharesmunich.graphenej.AssetAmount;
|
||||
import de.bitsharesmunich.graphenej.UserAccount;
|
||||
import de.bitsharesmunich.graphenej.Util;
|
||||
import org.hamcrest.core.IsEqual;
|
||||
import org.hamcrest.core.IsNot;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Created by nelson on 3/6/17.
|
||||
*/
|
||||
public class LimitOrderCreateOperationTest {
|
||||
private static final int AMOUNT_TO_SELL = 25000000;
|
||||
private static final int MIN_TO_RECEIVE = 1;
|
||||
private static final Asset CORE_ASSET = new Asset("1.3.0");
|
||||
private static final Asset BIT_USD = new Asset("1.3.121");
|
||||
private static final int DEFAULT_EXPIRATION = 1488831620; // 2017-03-06T20:20:20
|
||||
|
||||
private UserAccount seller;
|
||||
private AssetAmount amountToSell;
|
||||
private AssetAmount minToReceive;
|
||||
private int expiration;
|
||||
private boolean fillOrKill;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
seller = new UserAccount("1.2.143563");
|
||||
amountToSell = new AssetAmount(UnsignedLong.valueOf(AMOUNT_TO_SELL), CORE_ASSET);
|
||||
minToReceive = new AssetAmount(UnsignedLong.valueOf(MIN_TO_RECEIVE), BIT_USD);
|
||||
expiration = DEFAULT_EXPIRATION;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBytes() throws Exception {
|
||||
// Testing serialization of operation with fillOrKill parameter == true
|
||||
LimitOrderCreateOperation operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, expiration, true);
|
||||
operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET));
|
||||
byte[] serialized = operation.toBytes();
|
||||
Assert.assertArrayEquals("Correct serialization", serialized, Util.hexToBytes("020000000000000000cbe10840787d01000000000001000000000000007984c4bd580100"));
|
||||
Assert.assertThat("Incorrect serialization", serialized, IsNot.not(IsEqual.equalTo("020000000000000000cbe10840787d01000000000001000000000000007984c4bd580000")));
|
||||
|
||||
// Testing serialization of operation with fillOrKill parameter == false
|
||||
operation = new LimitOrderCreateOperation(seller, amountToSell, minToReceive, expiration, false);
|
||||
operation.setFee(new AssetAmount(UnsignedLong.valueOf(2), CORE_ASSET));
|
||||
serialized = operation.toBytes();
|
||||
Assert.assertArrayEquals("Correct serialization", serialized, Util.hexToBytes("020000000000000000cbe10840787d01000000000001000000000000007984c4bd580000"));
|
||||
Assert.assertThat("Incorrect serialization", serialized, IsNot.not(IsEqual.equalTo("020000000000000000cbe10840787d01000000000001000000000000007984c4bd580100")));
|
||||
}
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
rootProject.name = "Graphenej"
|
||||
|
||||
include ":graphenej", ":app"
|
||||
include ":graphenej"
|
||||
|
|
Loading…
Reference in a new issue