Skip to content

Commit

Permalink
Add Harmony (#626)
Browse files Browse the repository at this point in the history
* [project] Add Harmony blockchain definition

* [harmony-one] Add C Interface

* [harmony-one] Add swift integration tests

* [harmony-one] Add Kotlin code with init stubbed out code

* [harmony-one] Use RLP impl from ETH

* [harmony-one] Stub out Swift tests

* [harmony-one] Wrong package name kotlin

* [harmony-one] Add C++ tests

* [harmony-one] VC changes to coins.json

* [harmony-one] RLP encoding tested & works

* [harmony-one] Test signer & hash of transaction

* [harmony-one] Loose ends of successful signing

* [harmony-one] Have signer test passing in C++

* [harmony-one] Docs update

* [harmony-one] Swift test code signs transaction correctly

* [harmony-one] Test Kotlin signing

* [harmony-one] Remove unnecessary AddressChecksum code

* [harmony-one] Use bech32 format for address

* [harmony-one] Use bech32 address in android tests

* [harmony-one] Use bech32 address in ios tests

* [harmony-one] Remove duplicated string literal in Kotlin code

* [harmony-one] No tabs in coins.json

* [harmony-one] Factor out LOCAL_NET, add RLP encoded test in swift, remove explicit nonmainnet enumeration

* [harmony-one] Rename variable in tests, avoid lint issue in swift

* Update src/Harmony-One/Address.cpp

Co-Authored-By: hewig <360470+hewigovens@users.noreply.github.com>

* Update src/Harmony-One/Signer.cpp

Co-Authored-By: hewig <360470+hewigovens@users.noreply.github.com>

* [harmony-one] Remove Harmony-One name

* [harmony-one] Update Data used in Unit tests

* [harmony-one] Update Swift test

* [harmony-one] Update Kotlin code

* [harmony-one] Test output.encoded in android

* [harmony-one] Use load wrapper in Signer
  • Loading branch information
fxfactorial authored and hewigovens committed Sep 9, 2019
1 parent c98107a commit 50df64e
Show file tree
Hide file tree
Showing 28 changed files with 1,042 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class CoinAddressDerivationTests {
TERRA -> assertEquals("terra1rh402g98t7sly8trzqw5cyracntlep6qe3smug", address)
MONACOIN -> assertEquals("M9xFZzZdZhCDxpx42cM8bQHnLwaeX1aNja", address)
FIO -> assertEquals("FIO7MN1LuSfFgrbVHmrt9cVa2FYAs857Ppr9dzvEXoD1miKSxm3n3", address)
HARMONY -> assertEquals("one12fk20wmvgypdkn59n4hq8e3aa5899xfx4vsu09", address)
SOLANA -> assertEquals("2bUBiBNZyD29gP1oV6de7nxowMLoDBtopMMTGgMvjG5m", address)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.trustwallet.core.app.blockchains.harmony

import org.junit.Assert.assertEquals
import org.junit.Test
import wallet.core.jni.Base58
import wallet.core.jni.PrivateKey
import wallet.core.jni.PublicKey
import wallet.core.jni.PublicKeyType
import wallet.core.jni.HarmonyAddress

class TestHarmonyAddress {

init {
System.loadLibrary("TrustWalletCore")
}

val targetAddress = "one1a50tun737ulcvwy0yvve0pvu5skq0kjargvhwe"

@Test
fun testAddressFromPrivateKey() {
val key = PrivateKey(Base58.decodeNoCheck("GGzxJ4QmKCXH2juK89RVAmvFAfdUfUARCvxEsBM356vX"))
val pubkey = key.getPublicKeySecp256k1(false)
val address = HarmonyAddress(pubkey)
assertEquals(address.description(), targetAddress)
}

@Test
fun testAddressFromPublicKey() {
val pubkey = PublicKey(
Base58.decodeNoCheck("RKjfnr3wMojEruvXZuvNDmL7UfLUiyU3vsBGoZ4k2qY8YzoEJDHLmXDWid9K6YDuGJ2u1fZ8E8JXDjk3KUuDXtwz"),
PublicKeyType.SECP256K1EXTENDED
)
val address = HarmonyAddress(pubkey)
assertEquals(address.description(), targetAddress)
}

@Test
fun testAddressFromString() {
val address = HarmonyAddress(targetAddress)
assertEquals(address.description(), targetAddress)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.trustwallet.core.app.blockchains.harmony

import com.google.protobuf.ByteString
import com.trustwallet.core.app.utils.toHexByteArray
import org.junit.Assert.assertEquals
import org.junit.Test
import wallet.core.jni.PrivateKey
import wallet.core.jni.HarmonySigner
import wallet.core.jni.proto.Harmony
import com.trustwallet.core.app.utils.Numeric

class TestHarmonyTransactionSigner {

init {
System.loadLibrary("TrustWalletCore")
}

@Test
fun testHarmonyTransactionSigning() {
val signingInput = Harmony.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(PrivateKey("0xb578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e".toHexByteArray()).data())
toAddress = "one1d2rngmem4x2c6zxsjjz29dlah0jzkr0k2n88wc"
chainId = ByteString.copyFrom("0x02".toHexByteArray())
nonce = ByteString.copyFrom("0x9".toHexByteArray())
gasPrice = ByteString.copyFrom("0x0".toHexByteArray())
gasLimit = ByteString.copyFrom("0x5208".toHexByteArray())
fromShardId = ByteString.copyFrom("0x1".toHexByteArray())
toShardId = ByteString.copyFrom("0x0".toHexByteArray())
amount = ByteString.copyFrom("0x4c53ecdc18a60000".toHexByteArray())
}
val sign: Harmony.SigningOutput = HarmonySigner.sign(signingInput.build())
val e1 = "0xf86909808252080180946a87346f3ba9958d08d09484a2b7fdbbe42b0df6884c53ecdc18a600008028a0325aed6caa01a5235b"
val e2 = "7a508c8ab67f0c43946b05a1ea6a3e0628de4033fe372da06c19085d3376c30f6dc47cec795991cd37d6d0ebddfa633b0a8f494bc19cd01b"

assertEquals(Numeric.toHexString(sign.encoded.toByteArray()), e1 + e2)
assertEquals(Numeric.toHexString(sign.v.toByteArray()), "0x28")
assertEquals(Numeric.toHexString(sign.r.toByteArray()), "0x325aed6caa01a5235b7a508c8ab67f0c43946b05a1ea6a3e0628de4033fe372d")
assertEquals(Numeric.toHexString(sign.s.toByteArray()), "0x6c19085d3376c30f6dc47cec795991cd37d6d0ebddfa633b0a8f494bc19cd01b")
}
}
18 changes: 18 additions & 0 deletions coins.json
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,24 @@
"clientDocs": "https://fio.foundation"
}
},
{
"id": "harmony",
"name": "Harmony",
"symbol": "ONE",
"decimals": 18,
"blockchain": "Harmony",
"hrp": "one",
"derivationPath": "m/44'/1023'/0'/0/0",
"curve": "secp256k1",
"publicKeyType": "secp256k1Extended",
"explorer": "https://explorer.harmony.one/#/tx/",
"info": {
"url": "https://harmony.one",
"client": "https://github.com/harmony-one/go-sdk",
"clientPublic": "https://github.com/harmony-one/go-sdk",
"clientDocs": "https://app.gitbook.com/@harmony-one/s/sdk-wiki"
}
},
{
"id": "solana",
"name": "Solana",
Expand Down
1 change: 1 addition & 0 deletions docs/coins.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ This list is generated from [./coins.json](../coins.json)
| 888 | NEO | NEO | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/neo/info/logo.png" width="32" /> | <https://neo.org> |
| 889 | TomoChain | TOMO | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tomochain/info/logo.png" width="32" /> | <https://tomochain.com> |
| 1001 | Thunder Token | TT | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/thundertoken/info/logo.png" width="32" /> | <https://thundercore.com> |
| 1023 | Harmony | ONE | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/harmony/info/logo.png" width="32" /> | <https://harmony.one> |
| 1024 | Ontology | ONT | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ontology/info/logo.png" width="32" /> | <https://ont.io> |
| 1729 | Tezos | XTZ | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/tezos/info/logo.png" width="32" /> | <https://tezos.com> |
| 2017 | Kin | KIN | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/kin/info/logo.png" width="32" /> | <https://www.kin.org> |
Expand Down
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWBlockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum TWBlockchain {
TWBlockchainNebulas = 27,
TWBlockchainFIO = 28,
TWBlockchainSolana = 29,
TWBlockchainHarmony = 30,
};

TW_EXTERN_C_END
11 changes: 7 additions & 4 deletions include/TrustWalletCore/TWCoinType.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
#include "TWBase.h"
#include "TWBlockchain.h"
#include "TWCurve.h"
#include "TWHDVersion.h"
#include "TWHRP.h"
#include "TWPrivateKey.h"
#include "TWPurpose.h"
#include "TWString.h"
#include "TWHDVersion.h"
#include "TWHRP.h"

TW_EXTERN_C_BEGIN

Expand Down Expand Up @@ -79,6 +79,7 @@ enum TWCoinType {
TWCoinTypeRavencoin = 175,
TWCoinTypeWaves = 5741564,
TWCoinTypeTerra = 330,
TWCoinTypeHarmony = 1023,
};

/// Returns the blockchain for a coin type.
Expand Down Expand Up @@ -111,11 +112,13 @@ TWString *_Nonnull TWCoinTypeDerivationPath(enum TWCoinType coin);

/// Derives the address for a particular coin from the private key.
TW_EXPORT_METHOD
TWString *_Nonnull TWCoinTypeDeriveAddress(enum TWCoinType coin, struct TWPrivateKey *_Nonnull privateKey);
TWString *_Nonnull TWCoinTypeDeriveAddress(enum TWCoinType coin,
struct TWPrivateKey *_Nonnull privateKey);

/// Derives the address for a particular coin from the public key.
TW_EXPORT_METHOD
TWString *_Nonnull TWCoinTypeDeriveAddressFromPublicKey(enum TWCoinType coin, struct TWPublicKey *_Nonnull publicKey);
TWString *_Nonnull TWCoinTypeDeriveAddressFromPublicKey(enum TWCoinType coin,
struct TWPublicKey *_Nonnull publicKey);

/// HRP for this coin type
TW_EXPORT_PROPERTY
Expand Down
54 changes: 54 additions & 0 deletions include/TrustWalletCore/TWHarmonyAddress.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright © 2017-2019 Trust Wallet.
//
// This file is part of Trust. The full Trust copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

#pragma once

#include "TWBase.h"
#include "TWData.h"
#include "TWString.h"

TW_EXTERN_C_BEGIN

struct TWPublicKey;

/// Represents an Harmony address.
TW_EXPORT_CLASS
struct TWHarmonyAddress;

/// Compares two addresses for equality.
TW_EXPORT_STATIC_METHOD
bool TWHarmonyAddressEqual(struct TWHarmonyAddress *_Nonnull lhs,
struct TWHarmonyAddress *_Nonnull rhs);

/// Determines if the string is a valid address.
TW_EXPORT_STATIC_METHOD
bool TWHarmonyAddressIsValidString(TWString *_Nonnull string);

/// Creates an address from a string representaion.
TW_EXPORT_STATIC_METHOD
struct TWHarmonyAddress *_Nullable TWHarmonyAddressCreateWithString(TWString *_Nonnull string);

/// Creates an address from a key hash.
TW_EXPORT_STATIC_METHOD
struct TWHarmonyAddress *_Nullable TWHarmonyAddressCreateWithKeyHash(TWData *_Nonnull keyHash);

/// Creates an address from a public key.
TW_EXPORT_STATIC_METHOD
struct TWHarmonyAddress *_Nonnull TWHarmonyAddressCreateWithPublicKey(
struct TWPublicKey *_Nonnull publicKey);

TW_EXPORT_METHOD
void TWHarmonyAddressDelete(struct TWHarmonyAddress *_Nonnull address);

/// Returns the address string representation.
TW_EXPORT_PROPERTY
TWString *_Nonnull TWHarmonyAddressDescription(struct TWHarmonyAddress *_Nonnull address);

/// Returns the key hash.
TW_EXPORT_PROPERTY
TWData *_Nonnull TWHarmonyAddressKeyHash(struct TWHarmonyAddress *_Nonnull address);

TW_EXTERN_C_END
18 changes: 18 additions & 0 deletions include/TrustWalletCore/TWHarmonyChainID.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright © 2017-2019 Trust Wallet.
//
// This file is part of Trust. The full Trust copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

#pragma once
#include "TWBase.h"

TW_EXTERN_C_BEGIN

/// Chain identifier for Harmony blockchain.
TW_EXPORT_ENUM(uint32_t)
enum TWHarmonyChainID {
TWHarmonyChainIDMainNet = 0x1,
};

TW_EXTERN_C_END
12 changes: 12 additions & 0 deletions include/TrustWalletCore/TWHarmonyProto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright © 2017-2019 Trust Wallet.
//
// This file is part of Trust. The full Trust copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

#pragma once

#include "TWData.h"

typedef TWData *_Nonnull TW_Harmony_Proto_SigningInput;
typedef TWData *_Nonnull TW_Harmony_Proto_SigningOutput;
23 changes: 23 additions & 0 deletions include/TrustWalletCore/TWHarmonySigner.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright © 2017-2019 Trust Wallet.
//
// This file is part of Trust. The full Trust copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

#pragma once

#include "TWBase.h"
#include "TWData.h"
#include "TWHarmonyProto.h"

TW_EXTERN_C_BEGIN

/// Helper class to sign Harmony transactions.
TW_EXPORT_CLASS
struct TWHarmonySigner;

/// Signs a transaction.
TW_EXPORT_STATIC_METHOD
TW_Harmony_Proto_SigningOutput TWHarmonySignerSign(TW_Harmony_Proto_SigningInput input);

TW_EXTERN_C_END
Loading

0 comments on commit 50df64e

Please sign in to comment.