Skip to content

Commit

Permalink
R4R: support htlt transactions for binance chain (#627)
Browse files Browse the repository at this point in the history
* support htlt transactions for binance chain

* Add tests for htlt transactions

* clang format test file

* fix failed tests

* refactor naming and resolve comment

* change serialization methods to accommodate changes on chain

* refactor indent
  • Loading branch information
HaoyangLiu authored and hewigovens committed Sep 9, 2019
1 parent 50df64e commit 893e2f7
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 2 deletions.
4 changes: 4 additions & 0 deletions include/TrustWalletCore/TWBinanceProto.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ typedef TWData *_Nonnull TW_Binance_Proto_CancelTradeOrder;
typedef TWData *_Nonnull TW_Binance_Proto_SendOrder;
typedef TWData *_Nonnull TW_Binance_Proto_TokenFreezeOrder;
typedef TWData *_Nonnull TW_Binance_Proto_TokenUnfreezeOrder;
typedef TWData *_Nonnull TW_Binance_Proto_HTLTOrder;
typedef TWData *_Nonnull TW_Binance_Proto_DepositHTLTOrder;
typedef TWData *_Nonnull TW_Binance_Proto_ClaimHTLOrder;
typedef TWData *_Nonnull TW_Binance_Proto_RefundHTLTOrder;
typedef TWData *_Nonnull TW_Binance_Proto_SigningInput;
typedef TWData *_Nonnull TW_Binance_Proto_SigningOutput;
23 changes: 23 additions & 0 deletions src/Binance/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "../Cosmos/Address.h"
#include <TrustWalletCore/TWHRP.h>
#include "../HexCoding.h"

using namespace TW;

Expand Down Expand Up @@ -57,6 +58,28 @@ json Binance::orderJSON(const Binance::Proto::SigningInput& input) {
j["from"] = addressString(input.unfreeze_order().from());
j["symbol"] = input.unfreeze_order().symbol();
j["amount"] = input.unfreeze_order().amount();
} else if (input.has_htlt_order()) {
j["from"] = addressString(input.htlt_order().from());
j["to"] = addressString(input.htlt_order().to());
j["recipient_other_chain"] = input.htlt_order().recipient_other_chain();
j["sender_other_chain"] = input.htlt_order().sender_other_chain();
j["random_number_hash"] = hex(input.htlt_order().random_number_hash());
j["timestamp"] = input.htlt_order().timestamp();
j["amount"] = tokensJSON(input.htlt_order().amount());
j["expected_income"] = input.htlt_order().expected_income();
j["height_span"] = input.htlt_order().height_span();
j["cross_chain"] = input.htlt_order().cross_chain();
} else if (input.has_deposithtlt_order()) {
j["from"] = addressString(input.deposithtlt_order().from());
j["swap_id"] = hex(input.deposithtlt_order().swap_id());
j["amount"] = tokensJSON(input.deposithtlt_order().amount());
} else if (input.has_claimhtlt_order()) {
j["from"] = addressString(input.claimhtlt_order().from());
j["swap_id"] = hex(input.claimhtlt_order().swap_id());
j["random_number"] = hex(input.claimhtlt_order().random_number());
} else if (input.has_refundhtlt_order()) {
j["from"] = addressString(input.refundhtlt_order().from());
j["swap_id"] = hex(input.refundhtlt_order().swap_id());
}
return j;
}
Expand Down
16 changes: 16 additions & 0 deletions src/Binance/Signer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ static const auto tradeOrderPrefix = std::vector<uint8_t>{0xCE, 0x6D, 0xC0, 0x43
static const auto cancelTradeOrderPrefix = std::vector<uint8_t>{0x16, 0x6E, 0x68, 0x1B};
static const auto tokenFreezeOrderPrefix = std::vector<uint8_t>{0xE7, 0x74, 0xB3, 0x2D};
static const auto tokenUnfreezeOrderPrefix = std::vector<uint8_t>{0x65, 0x15, 0xFF, 0x0D};
static const auto HTLTOrderPrefix = std::vector<uint8_t>{0xB3, 0x3F, 0x9A, 0x24};
static const auto depositHTLTOrderPrefix = std::vector<uint8_t>{0x63, 0x98, 0x64, 0x96};
static const auto claimHTLTOrderPrefix = std::vector<uint8_t>{0xC1, 0x66, 0x53, 0x00};
static const auto refundHTLTOrderPrefix = std::vector<uint8_t>{0x34, 0x54, 0xA2, 0x7C};
static const auto pubKeyPrefix = std::vector<uint8_t>{0xEB, 0x5A, 0xE9, 0x87};
static const auto transactionPrefix = std::vector<uint8_t>{0xF0, 0x62, 0x5D, 0xEE};

Expand Down Expand Up @@ -73,6 +77,18 @@ std::vector<uint8_t> Signer::encodeOrder() const {
} else if (input.has_unfreeze_order()) {
data = input.unfreeze_order().SerializeAsString();
prefix = tokenUnfreezeOrderPrefix;
} else if (input.has_htlt_order()) {
data = input.htlt_order().SerializeAsString();
prefix = HTLTOrderPrefix;
} else if (input.has_deposithtlt_order()) {
data = input.deposithtlt_order().SerializeAsString();
prefix = depositHTLTOrderPrefix;
} else if (input.has_claimhtlt_order()) {
data = input.claimhtlt_order().SerializeAsString();
prefix = claimHTLTOrderPrefix;
} else if (input.has_refundhtlt_order()) {
data = input.refundhtlt_order().SerializeAsString();
prefix = refundHTLTOrderPrefix;
} else {
return {};
}
Expand Down
38 changes: 38 additions & 0 deletions src/proto/Binance.proto
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,40 @@ message TokenUnfreezeOrder {
int64 amount = 3; // amount of token to unfreeze
}

message HTLTOrder {
// 0xB33F9A24 // prefix
bytes from = 1; // signer address
bytes to = 2; // recipient address
string recipient_other_chain = 3;
string sender_other_chain = 4;
bytes random_number_hash = 5; //hash of a random number and timestamp, based on SHA256
int64 timestamp = 6;
repeated SendOrder.Token amount = 7;
string expected_income = 8; // expected gained token on the other chain
int64 height_span = 9;
bool cross_chain = 10;
}

message DepositHTLTOrder {
// 0xB33F9A24 // prefix
bytes from = 1; // signer address
repeated SendOrder.Token amount = 2;
bytes swap_id = 3;
}

message ClaimHTLOrder {
// 0xC1665300 // prefix
bytes from = 1; // signer address
bytes swap_id = 2;
bytes random_number = 3;
}

message RefundHTLTOrder {
// 0x3454A27C // prefix
bytes from = 1; // signer address
bytes swap_id = 2;
}

// Input data necessary to create a signed order.
message SigningInput {
string chain_id = 1;
Expand All @@ -90,6 +124,10 @@ message SigningInput {
SendOrder send_order = 10;
TokenFreezeOrder freeze_order = 11;
TokenUnfreezeOrder unfreeze_order = 12;
HTLTOrder htlt_order = 13;
DepositHTLTOrder depositHTLT_order = 14;
ClaimHTLOrder claimHTLT_order = 15;
RefundHTLTOrder refundHTLT_order = 16;
}
}

Expand Down
135 changes: 133 additions & 2 deletions tests/Binance/SignerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ TEST(BinanceSigner, Sign) {
order.set_price(136350000);
order.set_quantity(100000000);
order.set_timeinforce(1);

auto signer = Binance::Signer(std::move(input));
auto signature = signer.sign();

Expand All @@ -67,7 +67,7 @@ TEST(BinanceSigner, Build) {
order.set_price(100000000);
order.set_quantity(1200000000);
order.set_timeinforce(1);

auto signer = Binance::Signer(std::move(input));
auto result = signer.build();

Expand Down Expand Up @@ -202,4 +202,135 @@ TEST(BinanceSigner, BuildSend2) {
);
}

TEST(BinanceSigner, BuildHTLT) {
const auto fromPrivateKey = PrivateKey(parse_hex("eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d"));
const auto fromPublicKey = PublicKey(fromPrivateKey.getPublicKey(TWPublicKeyTypeSECP256k1));
auto fromAddr = Cosmos::Address(HRP_BINANCE, fromPublicKey).keyHash;

const auto toPrivateKey = PrivateKey(parse_hex("851fab89c14f4bbec0cc06f5e445ec065efc641068d78b308c67217d9bd5c88a"));
const auto toPublicKey = PublicKey(toPrivateKey.getPublicKey(TWPublicKeyTypeSECP256k1));
auto toAddr = Cosmos::Address(HRP_BINANCE, toPublicKey).keyHash;

auto signingInput = Proto::SigningInput();
signingInput.set_chain_id("test-chain");
signingInput.set_account_number(15);
signingInput.set_sequence(0);
signingInput.set_private_key(fromPrivateKey.bytes.data(), fromPrivateKey.bytes.size());

auto token = Proto::SendOrder::Token();
token.set_denom("BNB");
token.set_amount(100000000);

auto randomNumberHash =
parse_hex("e8eae926261ab77d018202434791a335249b470246a7b02e28c3b2fb6ffad8f3");

auto &htltOrder = *signingInput.mutable_htlt_order();
htltOrder.set_from(fromAddr.data(), fromAddr.size());
htltOrder.set_to(toAddr.data(), toAddr.size());
htltOrder.set_recipient_other_chain("");
htltOrder.set_sender_other_chain("");
*htltOrder.add_amount() = token;
htltOrder.set_height_span(400);
htltOrder.set_expected_income("100000000:BTC-1DC");
htltOrder.set_timestamp(1567746273);
htltOrder.set_random_number_hash(randomNumberHash.data(), randomNumberHash.size());
htltOrder.set_cross_chain(false);

const auto data = Binance::Signer(std::move(signingInput)).build();
ASSERT_EQ(hex(data.begin(), data.end()),
"ee01f0625dee0a7ab33f9a240a1408c7c918f6b72c3c0c21b7d08eb6fc66509998e112140153f11d6db7"
"e69c7d51e771c697378018fb6c242a20e8eae926261ab77d018202434791a335249b470246a7b02e28c3"
"b2fb6ffad8f330e1d1c7eb053a0a0a03424e421080c2d72f42113130303030303030303a4254432d3144"
"43489003126c0a26eb5ae9872103a9a55c040c8eb8120f3d1b32193250841c08af44ea561aac993dbe0f"
"6b6a8fc7124051439de2da19fe9fd22137c903cfc5dc87553bf05dca0bb202c0e07c47f9b51269efa272"
"43eb7b55888f5384a84ac1eac6d325c830d1be0ed042838e2dc0f6a9180f");
}

TEST(BinanceSigner, BuildDepositHTLT) {
const auto fromPrivateKey = PrivateKey(parse_hex("851fab89c14f4bbec0cc06f5e445ec065efc641068d78b308c67217d9bd5c88a"));
const auto fromPublicKey = PublicKey(fromPrivateKey.getPublicKey(TWPublicKeyTypeSECP256k1));
auto fromAddr = Cosmos::Address(HRP_BINANCE, fromPublicKey).keyHash;

auto signingInput = Proto::SigningInput();
signingInput.set_chain_id("test-chain");
signingInput.set_account_number(16);
signingInput.set_sequence(0);
signingInput.set_private_key(fromPrivateKey.bytes.data(), fromPrivateKey.bytes.size());

auto token = Proto::SendOrder::Token();
token.set_denom("BTC-1DC");
token.set_amount(100000000);

auto swapID = parse_hex("dd8fd4719741844d35eb35ddbeca9531d5493a8e4667689c55e73c77503dd9e5");

auto &depositHTLTOrder = *signingInput.mutable_deposithtlt_order();
depositHTLTOrder.set_from(fromAddr.data(), fromAddr.size());
depositHTLTOrder.set_swap_id(swapID.data(), swapID.size());
*depositHTLTOrder.add_amount() = token;

const auto data = Binance::Signer(std::move(signingInput)).build();
ASSERT_EQ(hex(data.begin(), data.end()),
"c001f0625dee0a4c639864960a140153f11d6db7e69c7d51e771c697378018fb6c24120e0a074254432d"
"3144431080c2d72f1a20dd8fd4719741844d35eb35ddbeca9531d5493a8e4667689c55e73c77503dd9e5"
"126c0a26eb5ae98721038df6960084e20b2d07d50e1422f94105c6241d9f1482a4eb79ce8bfd460f19e4"
"12400ca4144c6818e2836d09b4faf3161781d85f9adfc00badb2eaa0953174610a233b81413dafcf8471"
"6abad48a4ed3aeb9884d90eb8416eec5d5c0c6930ab60bd01810");
}

TEST(BinanceSigner, BuildClaimHTLT) {
const auto fromPrivateKey = PrivateKey(parse_hex("eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d"));
const auto fromPublicKey = PublicKey(fromPrivateKey.getPublicKey(TWPublicKeyTypeSECP256k1));
auto fromAddr = Cosmos::Address(HRP_BINANCE, fromPublicKey).keyHash;

auto signingInput = Proto::SigningInput();
signingInput.set_chain_id("test-chain");
signingInput.set_account_number(15);
signingInput.set_sequence(1);
signingInput.set_private_key(fromPrivateKey.bytes.data(), fromPrivateKey.bytes.size());

auto randomNumber =
parse_hex("bda6933c7757d0ca428aa01fb9d0935a231f87bf2deeb9b409cea3f2d580a2cc");
auto swapID = parse_hex("dd8fd4719741844d35eb35ddbeca9531d5493a8e4667689c55e73c77503dd9e5");

auto &claimHTLTOrder = *signingInput.mutable_claimhtlt_order();
claimHTLTOrder.set_from(fromAddr.data(), fromAddr.size());
claimHTLTOrder.set_swap_id(swapID.data(), swapID.size());
claimHTLTOrder.set_random_number(randomNumber.data(), randomNumber.size());

const auto data = Binance::Signer(std::move(signingInput)).build();
ASSERT_EQ(
hex(data.begin(), data.end()),
"d401f0625dee0a5ec16653000a1408c7c918f6b72c3c0c21b7d08eb6fc66509998e11220dd8fd4719741844d35"
"eb35ddbeca9531d5493a8e4667689c55e73c77503dd9e51a20bda6933c7757d0ca428aa01fb9d0935a231f87bf"
"2deeb9b409cea3f2d580a2cc126e0a26eb5ae9872103a9a55c040c8eb8120f3d1b32193250841c08af44ea561a"
"ac993dbe0f6b6a8fc71240fa30ba50111aa31d8329dacb6d044c1c7d54f1cb782bc9aa2a50c3fabce02a4579d7"
"5b76ca69a9fab11b676d9da66b5af7aa4c9ad3d18e24fffeb16433be39fb180f2001");
}

TEST(BinanceSigner, BuildRefundHTLT) {
const auto fromPrivateKey = PrivateKey(parse_hex("eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d"));
const auto fromPublicKey = PublicKey(fromPrivateKey.getPublicKey(TWPublicKeyTypeSECP256k1));
auto fromAddr = Cosmos::Address(HRP_BINANCE, fromPublicKey).keyHash;

auto signingInput = Proto::SigningInput();
signingInput.set_chain_id("test-chain");
signingInput.set_account_number(15);
signingInput.set_sequence(1);
signingInput.set_private_key(fromPrivateKey.bytes.data(), fromPrivateKey.bytes.size());

auto swapID = parse_hex("dd8fd4719741844d35eb35ddbeca9531d5493a8e4667689c55e73c77503dd9e5");

auto &refundHTLTOrder = *signingInput.mutable_refundhtlt_order();
refundHTLTOrder.set_from(fromAddr.data(), fromAddr.size());
refundHTLTOrder.set_swap_id(swapID.data(), swapID.size());

const auto data = Binance::Signer(std::move(signingInput)).build();
ASSERT_EQ(hex(data.begin(), data.end()),
"b201f0625dee0a3c3454a27c0a1408c7c918f6b72c3c0c21b7d08eb6fc66509998e11220dd8fd4719741"
"844d35eb35ddbeca9531d5493a8e4667689c55e73c77503dd9e5126e0a26eb5ae9872103a9a55c040c8e"
"b8120f3d1b32193250841c08af44ea561aac993dbe0f6b6a8fc71240c9f36142534d16ec8ce656f8eb73"
"70b32206a2d15198b7165acf1e2a18952c9e4570b0f862e1ab7bb868c30781a42c9e3ec0ae08982e8d6c"
"91c55b83c71b7b1e180f2001");
}

} // namespace TW::Binance

0 comments on commit 893e2f7

Please sign in to comment.