Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
satoshiotomakan authored Nov 22, 2024
2 parents 77538af + 9dae7e1 commit 7409aa9
Show file tree
Hide file tree
Showing 88 changed files with 3,753 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,6 @@ class CoinAddressDerivationTests {
TIA -> assertEquals("celestia142j9u5eaduzd7faumygud6ruhdwme98qpwmfv7", address)
NATIVEZETACHAIN -> assertEquals("zeta13u6g7vqgw074mgmf2ze2cadzvkz9snlwywj304", address)
DYDX -> assertEquals("dydx142j9u5eaduzd7faumygud6ruhdwme98qeayaky", address)
PACTUS -> assertEquals("pc1r7ys2g5a4xc2qtm0t4q987m4mvs57w5g0v4pvzg", address)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

package com.trustwallet.core.app.blockchains.pactus

import com.trustwallet.core.app.utils.toHex
import com.trustwallet.core.app.utils.toHexByteArray
import org.junit.Assert.assertEquals
import org.junit.Test
import wallet.core.jni.*

class TestPactusAddress {

init {
System.loadLibrary("TrustWalletCore")
}

@Test
fun testAddress() {
val key = PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6".toHexByteArray())
val pubkey = key.publicKeyEd25519
val address = AnyAddress(pubkey, CoinType.PACTUS)
val expected = AnyAddress("pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr", CoinType.PACTUS)

assertEquals(pubkey.data().toHex(), "0x95794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa")
assertEquals(address.description(), expected.description())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

package com.trustwallet.core.app.blockchains.pactus

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.java.AnySigner
import wallet.core.jni.CoinType
import wallet.core.jni.CoinType.PACTUS
import wallet.core.jni.proto.Pactus
import wallet.core.jni.proto.Pactus.SigningOutput
import com.trustwallet.core.app.utils.Numeric
import org.junit.Assert.assertArrayEquals

class TestPactusSigner {

init {
System.loadLibrary("TrustWalletCore")
}

@Test
fun testPactusTransferSigning() {
// Successfully broadcasted transaction:
// https://pacviewer.com/transaction/1b6b7226f7935a15f05371d1a1fefead585a89704ce464b7cc1d453d299d235f
//
val signingInput = Pactus.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(
PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6"
.toHexByteArray()).data()
)
transaction = Pactus.TransactionMessage.newBuilder().apply {
lockTime = 2335524
fee = 10000000
memo = "wallet-core"
transfer = Pactus.TransferPayload.newBuilder().apply {
sender = "pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr"
receiver = "pc1r0g22ufzn8qtw0742dmfglnw73e260hep0k3yra"
amount = 200000000
}.build()
}.build()
}

val output = AnySigner.sign(signingInput.build(), PACTUS, SigningOutput.parser())

assertEquals(
"0x1b6b7226f7935a15f05371d1a1fefead585a89704ce464b7cc1d453d299d235f",
Numeric.toHexString(output.transactionId.toByteArray())
)

assertEquals(
"0x4ed8fee3d8992e82660dd05bbe8608fc56ceabffdeeee61e3213b9b49d33a0fc8dea6d79ee7ec60f66433f189ed9b3c50b2ad6fa004e26790ee736693eda8506",
Numeric.toHexString(output.signature.toByteArray())
)

assertEquals(
"0x000124a3230080ade2040b77616c6c65742d636f726501037098338e0b6808119dfd4457ab806b9c2059b89b037a14ae24533816e7faaa6ed28fcdde8e55a7df218084af5f4ed8fee3d8992e82660dd05bbe8608fc56ceabffdeeee61e3213b9b49d33a0fc8dea6d79ee7ec60f66433f189ed9b3c50b2ad6fa004e26790ee736693eda850695794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
Numeric.toHexString(output.signedTransactionData.toByteArray())
)
}

@Test
fun testPactusBondWithPublicKeySigning() {
// Successfully broadcasted transaction:
// https://pacviewer.com/transaction/d194b445642a04ec78ced4448696e50b733f2f0b517a23871882c0eefaf1c28f
//
val signingInput = Pactus.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(
PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6"
.toHexByteArray()).data()
)
transaction = Pactus.TransactionMessage.newBuilder().apply {
lockTime = 2339009
fee = 10000000
memo = "wallet-core"
bond = Pactus.BondPayload.newBuilder().apply {
sender = "pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr"
receiver = "pc1p9y5gmu9l002tt60wak9extgvwm69rq3a9ackrl"
stake = 1000000000
publicKey = "public1pnz75msstqdrq5eguvcwanug0zauhqjw2cc4flmez3qethnp68y64ehc4k69amapj7x4na2uda0snqz4yxujgx3jsse4f64fgy7jkh0xauvhrc5ts09vfk48g85t0js66hvajm6xruemsvlxqv3xvkyur8v9v0mtn"
}.build()
}.build()
}

val output = AnySigner.sign(signingInput.build(), PACTUS, SigningOutput.parser())

assertEquals(
"0xd194b445642a04ec78ced4448696e50b733f2f0b517a23871882c0eefaf1c28f",
Numeric.toHexString(output.transactionId.toByteArray())
)

assertEquals(
"0x0d7bc6d94927534b89e2f53bcfc9fc849e0e2982438955eda55b4338328adac79d4ee3216d143f0e1629764ab650734f8ba188e716d71f9eff65e39ce7006300",
Numeric.toHexString(output.signature.toByteArray())
)

assertEquals(
"0x0001c1b0230080ade2040b77616c6c65742d636f726502037098338e0b6808119dfd4457ab806b9c2059b89b0129288df0bf7bd4b5e9eeed8b932d0c76f451823d6098bd4dc20b03460a651c661dd9f10f17797049cac62a9fef228832bbcc3a39355cdf15b68bddf432f1ab3eab8debe1300aa43724834650866a9d552827a56bbcdde32e3c517079589b54e83d16f9435abb3b2de8c3e677067cc0644ccb13833b8094ebdc030d7bc6d94927534b89e2f53bcfc9fc849e0e2982438955eda55b4338328adac79d4ee3216d143f0e1629764ab650734f8ba188e716d71f9eff65e39ce700630095794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
Numeric.toHexString(output.signedTransactionData.toByteArray())
)
}

@Test
fun testPactusBondWithoutPublicKeySigning() {
// Successfully broadcasted transaction:
// https://pacviewer.com/transaction/f83f583a5c40adf93a90ea536a7e4b467d30ca4f308d5da52624d80c42adec80
//
val signingInput = Pactus.SigningInput.newBuilder()
signingInput.apply {
privateKey = ByteString.copyFrom(
PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6"
.toHexByteArray()).data()
)
transaction = Pactus.TransactionMessage.newBuilder().apply {
lockTime = 2335580
fee = 10000000
memo = "wallet-core"
bond = Pactus.BondPayload.newBuilder().apply {
sender = "pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr"
receiver = "pc1p6taz5l2kq5ppnxv4agnqj48svnvsy797xpe6wd"
stake = 1000000000
}.build()
}.build()
}

val output = AnySigner.sign(signingInput.build(), PACTUS, SigningOutput.parser())

assertEquals(
"0xf83f583a5c40adf93a90ea536a7e4b467d30ca4f308d5da52624d80c42adec80",
Numeric.toHexString(output.transactionId.toByteArray())
)

assertEquals(
"0x9e6279fb64067c7d7316ac74630bbb8589df268aa4548f1c7d85c087a8748ff0715b9149afbd94c5d8ee6b37c787ec63e963cbb38be513ebc436aa58f9a8f00d",
Numeric.toHexString(output.signature.toByteArray())
)

assertEquals(
"0x00015ca3230080ade2040b77616c6c65742d636f726502037098338e0b6808119dfd4457ab806b9c2059b89b01d2fa2a7d560502199995ea260954f064d90278be008094ebdc039e6279fb64067c7d7316ac74630bbb8589df268aa4548f1c7d85c087a8748ff0715b9149afbd94c5d8ee6b37c787ec63e963cbb38be513ebc436aa58f9a8f00d95794161374b22c696dabb98e93f6ca9300b22f3b904921fbf560bb72145f4fa",
Numeric.toHexString(output.signedTransactionData.toByteArray())
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.trustwallet.core.app.utils

import org.junit.Assert.*
import org.junit.Test
import wallet.core.jni.Bech32

class TestBech32 {
init {
System.loadLibrary("TrustWalletCore");
}

@Test
fun testEncode() {
val data = Numeric.hexStringToByteArray("00443214c74254b635cf84653a56d7c675be77df")
assertEquals(Bech32.encode("abcdef", data), "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
}

@Test
fun testDecode() {
val decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
assertEquals(Numeric.toHexString(decoded), "0x00443214c74254b635cf84653a56d7c675be77df")
}

@Test
fun testDecodeWrongChecksumVariant() {
// This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder.
val decoded = Bech32.decode("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
assertNull(decoded)
}

@Test
fun testEncodeM() {
val data = Numeric.hexStringToByteArray("ffbbcdeb38bdab49ca307b9ac5a928398a418820")
assertEquals(Bech32.encodeM("abcdef", data), "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
}

@Test
fun testDecodeM() {
val decoded = Bech32.decodeM("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")
assertEquals(Numeric.toHexString(decoded), "0xffbbcdeb38bdab49ca307b9ac5a928398a418820")
}

@Test
fun testDecodeMWrongChecksumVariant() {
// This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder.
val decoded = Bech32.decodeM("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")
assertNull(decoded)
}
}
78 changes: 78 additions & 0 deletions codegen-v2/manifest/TWBech32.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: TWBech32
structs:
- name: TWBech32
is_public: true
is_class: false
functions:
- name: TWBech32Encode
is_public: true
is_static: true
params:
- name: hrp
type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
- name: data
type:
variant: data
is_constant: true
is_nullable: false
is_pointer: true
return_type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
- name: TWBech32Decode
is_public: true
is_static: true
params:
- name: string
type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
return_type:
variant: data
is_constant: true
is_nullable: true
is_pointer: true
- name: TWBech32EncodeM
is_public: true
is_static: true
params:
- name: hrp
type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
- name: data
type:
variant: data
is_constant: true
is_nullable: false
is_pointer: true
return_type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
- name: TWBech32DecodeM
is_public: true
is_static: true
params:
- name: string
type:
variant: string
is_constant: true
is_nullable: false
is_pointer: true
return_type:
variant: data
is_constant: true
is_nullable: true
is_pointer: true
1 change: 1 addition & 0 deletions docs/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ This list is generated from [./registry.json](../registry.json)
| 14001 | WAX | WAXP | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/wax/info/logo.png" width="32" /> | <http://wax.io> |
| 18000 | Meter | MTR | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/meter/info/logo.png" width="32" /> | <https://meter.io/> |
| 19167 | Flux | FLUX | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/zelcash/info/logo.png" width="32" /> | <https://runonflux.io> |
| 21888 | Pactus | PAC | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/pactus/info/logo.png" width="32" /> | <https://pactus.org> |
| 52752 | Celo | CELO | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/celo/info/logo.png" width="32" /> | <https://celo.org> |
| 59144 | Linea | ETH | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/linea/info/logo.png" width="32" /> | <https://linea.build> |
| 81457 | Blast | ETH | <img src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/blast/info/logo.png" width="32" /> | <https://blast.io> |
Expand Down
4 changes: 2 additions & 2 deletions include/TrustWalletCore/TWBase58.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ TWString *_Nonnull TWBase58EncodeNoCheck(TWData *_Nonnull data);
/// Decodes a Base58 string, checking the checksum. Returns null if the string is not a valid Base58 string.
///
/// \param string The Base58 string to decode.
/// \return the decoded data, empty if the string is not a valid Base58 string with checksum.
/// \return the decoded data, null if the string is not a valid Base58 string with checksum.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBase58Decode(TWString *_Nonnull string);

/// Decodes a Base58 string, w/o checking the checksum. Returns null if the string is not a valid Base58 string.
///
/// \param string The Base58 string to decode.
/// \return the decoded data, empty if the string is not a valid Base58 string without checksum.
/// \return the decoded data, null if the string is not a valid Base58 string without checksum.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBase58DecodeNoCheck(TWString *_Nonnull string);

Expand Down
47 changes: 47 additions & 0 deletions include/TrustWalletCore/TWBech32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.

#pragma once

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

TW_EXTERN_C_BEGIN

/// Bech32 encode / decode functions
TW_EXPORT_STRUCT
struct TWBech32;

/// Encodes data as a Bech32 string.
///
/// \param hrp The human-readable part.
/// \param data The data part.
/// \return the encoded Bech32 string.
TW_EXPORT_STATIC_METHOD
TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data);

/// Decodes a Bech32 string. Returns null if the string is not a valid Bech32 string.
///
/// \param string The Bech32 string to decode.
/// \return the decoded data, null if the string is not a valid Bech32 string. Note that the human-readable part is not returned.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBech32Decode(TWString *_Nonnull string);

/// Encodes data as a Bech32m string.
///
/// \param hrp The human-readable part.
/// \param data The data part.
/// \return the encoded Bech32m string.
TW_EXPORT_STATIC_METHOD
TWString *_Nonnull TWBech32EncodeM(TWString* _Nonnull hrp, TWData *_Nonnull data);

/// Decodes a Bech32m string. Returns null if the string is not a valid Bech32m string.
///
/// \param string The Bech32m string to decode.
/// \return the decoded data, null if the string is not a valid Bech32m string. Note that the human-readable part is not returned.
TW_EXPORT_STATIC_METHOD
TWData *_Nullable TWBech32DecodeM(TWString *_Nonnull string);

TW_EXTERN_C_END
1 change: 1 addition & 0 deletions include/TrustWalletCore/TWBlockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum TWBlockchain {
TWBlockchainNativeEvmos = 53, // Cosmos
TWBlockchainNativeInjective = 54, // Cosmos
TWBlockchainBitcoinCash = 55,
TWBlockchainPactus = 56,
};

TW_EXTERN_C_END
Loading

0 comments on commit 7409aa9

Please sign in to comment.