From a851f7f493ee963398c3ecdc4a50dbebbca95aea Mon Sep 17 00:00:00 2001 From: 10gic <2391796+10gic@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:11:28 +0800 Subject: [PATCH 1/5] Export bech32 and bech32m functions --- .../trustwallet/core/app/utils/TestBech32.kt | 23 ++++++++++ .../trustwallet/core/app/utils/TestBech32m.kt | 23 ++++++++++ codegen-v2/manifest/TWBech32.yaml | 42 +++++++++++++++++++ codegen-v2/manifest/TWBech32m.yaml | 42 +++++++++++++++++++ include/TrustWalletCore/TWBech32.h | 32 ++++++++++++++ include/TrustWalletCore/TWBech32m.h | 32 ++++++++++++++ src/interface/TWBech32.cpp | 34 +++++++++++++++ src/interface/TWBech32m.cpp | 34 +++++++++++++++ swift/Tests/Bech32Tests.swift | 22 ++++++++++ swift/Tests/Bech32mTests.swift | 22 ++++++++++ tests/interface/TWBech32Tests.cpp | 28 +++++++++++++ tests/interface/TWBech32mTests.cpp | 28 +++++++++++++ wasm/tests/Bech32.test.ts | 28 +++++++++++++ wasm/tests/Bech32m.test.ts | 28 +++++++++++++ 14 files changed, 418 insertions(+) create mode 100644 android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt create mode 100644 android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt create mode 100644 codegen-v2/manifest/TWBech32.yaml create mode 100644 codegen-v2/manifest/TWBech32m.yaml create mode 100644 include/TrustWalletCore/TWBech32.h create mode 100644 include/TrustWalletCore/TWBech32m.h create mode 100644 src/interface/TWBech32.cpp create mode 100644 src/interface/TWBech32m.cpp create mode 100644 swift/Tests/Bech32Tests.swift create mode 100644 swift/Tests/Bech32mTests.swift create mode 100644 tests/interface/TWBech32Tests.cpp create mode 100644 tests/interface/TWBech32mTests.cpp create mode 100644 wasm/tests/Bech32.test.ts create mode 100644 wasm/tests/Bech32m.test.ts diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt new file mode 100644 index 00000000000..57a19859a44 --- /dev/null +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt @@ -0,0 +1,23 @@ +package com.trustwallet.core.app.utils + +import org.junit.Assert.assertEquals +import org.junit.Test +import wallet.core.jni.Bech32 + +class TestBech32 { + init { + System.loadLibrary("TrustWalletCore"); + } + + @Test + fun testEncode() { + val data = Numeric.hexStringToByteArray("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + assertEquals(Bech32.encode("abcdef", data, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + } + + @Test + fun testDecode() { + val decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + assertEquals(Numeric.toHexString(decoded), "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + } +} diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt new file mode 100644 index 00000000000..dcf11ba826b --- /dev/null +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt @@ -0,0 +1,23 @@ +package com.trustwallet.core.app.utils + +import org.junit.Assert.assertEquals +import org.junit.Test +import wallet.core.jni.Bech32m + +class TestBech32m { + init { + System.loadLibrary("TrustWalletCore"); + } + + @Test + fun testEncode() { + val data = Numeric.hexStringToByteArray("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") + assertEquals(Bech32m.encode("abcdef", data, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + } + + @Test + fun testDecode() { + val decoded = Bech32m.decode("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + assertEquals(Numeric.toHexString(decoded), "0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") + } +} diff --git a/codegen-v2/manifest/TWBech32.yaml b/codegen-v2/manifest/TWBech32.yaml new file mode 100644 index 00000000000..713510aa06c --- /dev/null +++ b/codegen-v2/manifest/TWBech32.yaml @@ -0,0 +1,42 @@ +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 diff --git a/codegen-v2/manifest/TWBech32m.yaml b/codegen-v2/manifest/TWBech32m.yaml new file mode 100644 index 00000000000..ecac82ee20c --- /dev/null +++ b/codegen-v2/manifest/TWBech32m.yaml @@ -0,0 +1,42 @@ +name: TWBech32m +structs: +- name: TWBech32m + is_public: true + is_class: false +functions: +- name: TWBech32mEncode + 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: TWBech32mDecode + 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 diff --git a/include/TrustWalletCore/TWBech32.h b/include/TrustWalletCore/TWBech32.h new file mode 100644 index 00000000000..2f1437754bb --- /dev/null +++ b/include/TrustWalletCore/TWBech32.h @@ -0,0 +1,32 @@ +// 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, empty if the string is not a valid Bech32. Note that the human-readable part is not returned. +TW_EXPORT_STATIC_METHOD +TWData *_Nullable TWBech32Decode(TWString *_Nonnull string); + +TW_EXTERN_C_END diff --git a/include/TrustWalletCore/TWBech32m.h b/include/TrustWalletCore/TWBech32m.h new file mode 100644 index 00000000000..94789d9520a --- /dev/null +++ b/include/TrustWalletCore/TWBech32m.h @@ -0,0 +1,32 @@ +// 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 + +/// Bech32m encode / decode functions +TW_EXPORT_STRUCT +struct TWBech32m; + +/// 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 TWBech32mEncode(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, empty if the string is not a valid Bech32m. Note that the human-readable part is not returned. +TW_EXPORT_STATIC_METHOD +TWData *_Nullable TWBech32mDecode(TWString *_Nonnull string); + +TW_EXTERN_C_END diff --git a/src/interface/TWBech32.cpp b/src/interface/TWBech32.cpp new file mode 100644 index 00000000000..f61a338e390 --- /dev/null +++ b/src/interface/TWBech32.cpp @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#include + +#include "../Bech32.h" + +#include + +using namespace TW; + +TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data) { + auto cppHrp = *reinterpret_cast(hrp); + auto cppData = *reinterpret_cast(data); + auto result = Bech32::encode(cppHrp, cppData, Bech32::ChecksumVariant::Bech32); + return TWStringCreateWithUTF8Bytes(result.c_str()); +} + +TWData *_Nullable TWBech32Decode(TWString *_Nonnull string) { + auto cppString = *reinterpret_cast(string); + const auto decoded = Bech32::decode(cppString); + + auto data = std::get<1>(decoded); + if (data.empty()) { // Failed to decode + return nullptr; + } + + if (std::get<2>(decoded) != Bech32::ChecksumVariant::Bech32) { // Wrong ChecksumVariant + return nullptr; + } + + return TWDataCreateWithBytes(data.data(), data.size()); +} diff --git a/src/interface/TWBech32m.cpp b/src/interface/TWBech32m.cpp new file mode 100644 index 00000000000..4c05a7c8c6b --- /dev/null +++ b/src/interface/TWBech32m.cpp @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#include + +#include "../Bech32.h" + +#include + +using namespace TW; + +TWString *_Nonnull TWBech32mEncode(TWString* _Nonnull hrp, TWData *_Nonnull data) { + auto cppHrp = *reinterpret_cast(hrp); + auto cppData = *reinterpret_cast(data); + auto result = Bech32::encode(cppHrp, cppData, Bech32::ChecksumVariant::Bech32M); + return TWStringCreateWithUTF8Bytes(result.c_str()); +} + +TWData *_Nullable TWBech32mDecode(TWString *_Nonnull string) { + auto cppString = *reinterpret_cast(string); + const auto decoded = Bech32::decode(cppString); + + auto data = std::get<1>(decoded); + if (data.empty()) { // Failed to decode + return nullptr; + } + + if (std::get<2>(decoded) != Bech32::ChecksumVariant::Bech32M) { // Wrong ChecksumVariant + return nullptr; + } + + return TWDataCreateWithBytes(data.data(), data.size()); +} diff --git a/swift/Tests/Bech32Tests.swift b/swift/Tests/Bech32Tests.swift new file mode 100644 index 00000000000..5fed2f09916 --- /dev/null +++ b/swift/Tests/Bech32Tests.swift @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +import XCTest +import WalletCore + +class Bech32Tests: XCTestCase { + func testEncode() { + let data = Data(hexString: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")! + let encoded = Bech32.encode(hrp: "abcdef", data: data) + XCTAssertEqual(encoded, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + } + + func testDecode() { + guard let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") else { + return XCTFail() + } + + XCTAssertEqual(decoded.hexString, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + } +} diff --git a/swift/Tests/Bech32mTests.swift b/swift/Tests/Bech32mTests.swift new file mode 100644 index 00000000000..5707d4f6273 --- /dev/null +++ b/swift/Tests/Bech32mTests.swift @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +import XCTest +import WalletCore + +class Bech32mTests: XCTestCase { + func testEncode() { + let data = Data(hexString: "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")! + let encoded = Bech32m.encode(hrp: "abcdef", data: data) + XCTAssertEqual(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + } + + func testDecode() { + guard let decoded = Bech32m.decode(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") else { + return XCTFail() + } + + XCTAssertEqual(decoded.hexString, "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") + } +} diff --git a/tests/interface/TWBech32Tests.cpp b/tests/interface/TWBech32Tests.cpp new file mode 100644 index 00000000000..c3e0cf9595d --- /dev/null +++ b/tests/interface/TWBech32Tests.cpp @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#include "TestUtilities.h" + +#include + +#include + +TEST(TWBech32, Encode) { + const auto hrp = STRING("abcdef"); + const auto data = DATA("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + const auto result = WRAPS(TWBech32Encode(hrp.get(), data.get())); + assertStringsEqual(result, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); +} + +TEST(TWBech32, Decode) { + const auto input = STRING("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + const auto result = WRAPD(TWBech32Decode(input.get())); + assertHexEqual(result, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); +} + +TEST(TWBech32, Decode_WrongChecksumVariant) { + const auto input = STRING("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); // This is a Bech32m variant, not Bech32 variant. So it should fail. + const auto result = WRAPD(TWBech32Decode(input.get())); + ASSERT_EQ(result.get(), nullptr); +} diff --git a/tests/interface/TWBech32mTests.cpp b/tests/interface/TWBech32mTests.cpp new file mode 100644 index 00000000000..6d8780a3e0b --- /dev/null +++ b/tests/interface/TWBech32mTests.cpp @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#include "TestUtilities.h" + +#include + +#include + +TEST(TWBech32m, Encode) { + auto hrp = STRING("abcdef"); + const auto data = DATA("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); + auto result = WRAPS(TWBech32mEncode(hrp.get(), data.get())); + assertStringsEqual(result, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); +} + +TEST(TWBech32m, Decode) { + const auto input = STRING("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); + auto result = WRAPD(TWBech32mDecode(input.get())); + assertHexEqual(result, "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); +} + +TEST(TWBech32m, Decode_WrongChecksumVariant) { + const auto input = STRING("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); // This is a Bech32 variant, not Bech32m variant. So it should fail. + const auto result = WRAPD(TWBech32mDecode(input.get())); + ASSERT_EQ(result.get(), nullptr); +} \ No newline at end of file diff --git a/wasm/tests/Bech32.test.ts b/wasm/tests/Bech32.test.ts new file mode 100644 index 00000000000..5b363205914 --- /dev/null +++ b/wasm/tests/Bech32.test.ts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +import { assert } from "chai"; +import { Buffer } from "buffer"; + +describe("Bech32", () => { + + it("test decoding", () => { + const { Bech32, HexCoding } = globalThis.core; + + const decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + + assert.equal( + HexCoding.encode(decoded), + "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + ); + }); + + it("test encoding", () => { + const { Bech32 } = globalThis.core; + + const encoded = Bech32.encode("abcdef", Buffer.from("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "hex")); + + assert.equal(encoded, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + }); +}); diff --git a/wasm/tests/Bech32m.test.ts b/wasm/tests/Bech32m.test.ts new file mode 100644 index 00000000000..691d72f56c8 --- /dev/null +++ b/wasm/tests/Bech32m.test.ts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +import { assert } from "chai"; +import { Buffer } from "buffer"; + +describe("Bech32m", () => { + + it("test decoding", () => { + const { Bech32m, HexCoding } = globalThis.core; + + const decoded = Bech32m.decode("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); + + assert.equal( + HexCoding.encode(decoded), + "0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100" + ); + }); + + it("test encoding", () => { + const { Bech32m } = globalThis.core; + + const encoded = Bech32m.encode("abcdef", Buffer.from("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100", "hex")); + + assert.equal(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); + }); +}); From b707e823eae2360b2ff3b33f0248ab7dd6b5d2dc Mon Sep 17 00:00:00 2001 From: 10gic <2391796+10gic@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:15:43 +0800 Subject: [PATCH 2/5] Fix test cases --- .../java/com/trustwallet/core/app/utils/TestBech32.kt | 2 +- .../java/com/trustwallet/core/app/utils/TestBech32m.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt index 57a19859a44..97fd6637cd9 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt @@ -12,7 +12,7 @@ class TestBech32 { @Test fun testEncode() { val data = Numeric.hexStringToByteArray("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") - assertEquals(Bech32.encode("abcdef", data, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + assertEquals(Bech32.encode("abcdef", data), "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") } @Test diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt index dcf11ba826b..34808b8ad85 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt @@ -12,7 +12,7 @@ class TestBech32m { @Test fun testEncode() { val data = Numeric.hexStringToByteArray("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") - assertEquals(Bech32m.encode("abcdef", data, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + assertEquals(Bech32m.encode("abcdef", data), "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") } @Test From d134eff07136c5321417ae90fa61b94e63afdcf1 Mon Sep 17 00:00:00 2001 From: 10gic <2391796+10gic@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:07:51 +0800 Subject: [PATCH 3/5] Merge bech32m functions into TWBech32 struct --- .../trustwallet/core/app/utils/TestBech32.kt | 30 ++++++++++++- .../trustwallet/core/app/utils/TestBech32m.kt | 23 ---------- codegen-v2/manifest/TWBech32.yaml | 36 +++++++++++++++ codegen-v2/manifest/TWBech32m.yaml | 42 ------------------ include/TrustWalletCore/TWBase58.h | 4 +- include/TrustWalletCore/TWBech32.h | 17 ++++++- include/TrustWalletCore/TWBech32m.h | 32 -------------- src/Bech32.cpp | 4 +- src/interface/TWBech32.cpp | 44 +++++++++++++++---- src/interface/TWBech32m.cpp | 34 -------------- swift/Tests/Bech32Tests.swift | 30 ++++++++++--- swift/Tests/Bech32mTests.swift | 22 ---------- tests/interface/TWBech32Tests.cpp | 27 ++++++++++-- tests/interface/TWBech32mTests.cpp | 28 ------------ wasm/tests/Bech32.test.ts | 43 +++++++++++++++--- wasm/tests/Bech32m.test.ts | 28 ------------ 16 files changed, 206 insertions(+), 238 deletions(-) delete mode 100644 android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt delete mode 100644 codegen-v2/manifest/TWBech32m.yaml delete mode 100644 include/TrustWalletCore/TWBech32m.h delete mode 100644 src/interface/TWBech32m.cpp delete mode 100644 swift/Tests/Bech32mTests.swift delete mode 100644 tests/interface/TWBech32mTests.cpp delete mode 100644 wasm/tests/Bech32m.test.ts diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt index 97fd6637cd9..598823665db 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt @@ -11,13 +11,39 @@ class TestBech32 { @Test fun testEncode() { - val data = Numeric.hexStringToByteArray("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + val data = Numeric.hexStringToByteArray("00443214c74254b635cf84653a56d7c675be77df") assertEquals(Bech32.encode("abcdef", data), "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") } @Test fun testDecode() { val decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") - assertEquals(Numeric.toHexString(decoded), "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + 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) } } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt deleted file mode 100644 index 34808b8ad85..00000000000 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32m.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.trustwallet.core.app.utils - -import org.junit.Assert.assertEquals -import org.junit.Test -import wallet.core.jni.Bech32m - -class TestBech32m { - init { - System.loadLibrary("TrustWalletCore"); - } - - @Test - fun testEncode() { - val data = Numeric.hexStringToByteArray("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") - assertEquals(Bech32m.encode("abcdef", data), "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") - } - - @Test - fun testDecode() { - val decoded = Bech32m.decode("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") - assertEquals(Numeric.toHexString(decoded), "0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") - } -} diff --git a/codegen-v2/manifest/TWBech32.yaml b/codegen-v2/manifest/TWBech32.yaml index 713510aa06c..1d192712adb 100644 --- a/codegen-v2/manifest/TWBech32.yaml +++ b/codegen-v2/manifest/TWBech32.yaml @@ -40,3 +40,39 @@ functions: 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 diff --git a/codegen-v2/manifest/TWBech32m.yaml b/codegen-v2/manifest/TWBech32m.yaml deleted file mode 100644 index ecac82ee20c..00000000000 --- a/codegen-v2/manifest/TWBech32m.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: TWBech32m -structs: -- name: TWBech32m - is_public: true - is_class: false -functions: -- name: TWBech32mEncode - 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: TWBech32mDecode - 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 diff --git a/include/TrustWalletCore/TWBase58.h b/include/TrustWalletCore/TWBase58.h index c59ddd2a2a0..a35ae178865 100644 --- a/include/TrustWalletCore/TWBase58.h +++ b/include/TrustWalletCore/TWBase58.h @@ -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); diff --git a/include/TrustWalletCore/TWBech32.h b/include/TrustWalletCore/TWBech32.h index 2f1437754bb..53c0ab8973b 100644 --- a/include/TrustWalletCore/TWBech32.h +++ b/include/TrustWalletCore/TWBech32.h @@ -25,8 +25,23 @@ 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, empty if the string is not a valid Bech32. Note that the human-readable part is not returned. +/// \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 diff --git a/include/TrustWalletCore/TWBech32m.h b/include/TrustWalletCore/TWBech32m.h deleted file mode 100644 index 94789d9520a..00000000000 --- a/include/TrustWalletCore/TWBech32m.h +++ /dev/null @@ -1,32 +0,0 @@ -// 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 - -/// Bech32m encode / decode functions -TW_EXPORT_STRUCT -struct TWBech32m; - -/// 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 TWBech32mEncode(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, empty if the string is not a valid Bech32m. Note that the human-readable part is not returned. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWBech32mDecode(TWString *_Nonnull string); - -TW_EXTERN_C_END diff --git a/src/Bech32.cpp b/src/Bech32.cpp index d6bd309a1de..273c1f3f16c 100644 --- a/src/Bech32.cpp +++ b/src/Bech32.cpp @@ -103,7 +103,7 @@ Data create_checksum(const std::string& hrp, const Data& values, ChecksumVariant } // namespace -/** Encode a Bech32 string. */ +/** Encode a Bech32 string. Note that the values must each encode 5 bits, normally get from convertBits<8, 5, true> */ std::string encode(const std::string& hrp, const Data& values, ChecksumVariant variant) { Data checksum = create_checksum(hrp, values, variant); Data combined = values; @@ -116,7 +116,7 @@ std::string encode(const std::string& hrp, const Data& values, ChecksumVariant v return ret; } -/** Decode a Bech32 string. */ +/** Decode a Bech32 string. Note that the returned values are 5 bits each, you may want to use convertBits<5, 8, false> */ std::tuple decode(const std::string& str) { if (str.length() > 120 || str.length() < 2) { // too long or too short diff --git a/src/interface/TWBech32.cpp b/src/interface/TWBech32.cpp index f61a338e390..fe184ead846 100644 --- a/src/interface/TWBech32.cpp +++ b/src/interface/TWBech32.cpp @@ -10,25 +10,51 @@ using namespace TW; -TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data) { - auto cppHrp = *reinterpret_cast(hrp); - auto cppData = *reinterpret_cast(data); - auto result = Bech32::encode(cppHrp, cppData, Bech32::ChecksumVariant::Bech32); +static TWString *_Nonnull encodeGeneric(TWString* _Nonnull hrp, TWData *_Nonnull data, const Bech32::ChecksumVariant variant) { + const auto cppHrp = *static_cast(hrp); + const auto cppData = *static_cast(data); + Data enc; + if (!Bech32::convertBits<8, 5, true>(enc, cppData)) { + return TWStringCreateWithUTF8Bytes(""); + } + const auto result = Bech32::encode(cppHrp, enc, variant); return TWStringCreateWithUTF8Bytes(result.c_str()); } -TWData *_Nullable TWBech32Decode(TWString *_Nonnull string) { - auto cppString = *reinterpret_cast(string); +static TWData *_Nullable decodeGeneric(TWString *_Nonnull string, const Bech32::ChecksumVariant variant) { + const auto cppString = *static_cast(string); const auto decoded = Bech32::decode(cppString); - auto data = std::get<1>(decoded); + const auto data = std::get<1>(decoded); if (data.empty()) { // Failed to decode return nullptr; } - if (std::get<2>(decoded) != Bech32::ChecksumVariant::Bech32) { // Wrong ChecksumVariant + if (std::get<2>(decoded) != variant) { // Wrong ChecksumVariant + return nullptr; + } + + // Bech bits conversion + Data conv; + if (!Bech32::convertBits<5, 8, false>(conv, data)) { return nullptr; } - return TWDataCreateWithBytes(data.data(), data.size()); + return TWDataCreateWithBytes(conv.data(), conv.size()); +} + +TWString *_Nonnull TWBech32Encode(TWString* _Nonnull hrp, TWData *_Nonnull data) { + return encodeGeneric(hrp, data, Bech32::ChecksumVariant::Bech32); +} + +TWString *_Nonnull TWBech32EncodeM(TWString* _Nonnull hrp, TWData *_Nonnull data) { + return encodeGeneric(hrp, data, Bech32::ChecksumVariant::Bech32M); +} + +TWData *_Nullable TWBech32Decode(TWString *_Nonnull string) { + return decodeGeneric(string, Bech32::ChecksumVariant::Bech32); +} + +TWData *_Nullable TWBech32DecodeM(TWString *_Nonnull string) { + return decodeGeneric(string, Bech32::ChecksumVariant::Bech32M); } diff --git a/src/interface/TWBech32m.cpp b/src/interface/TWBech32m.cpp deleted file mode 100644 index 4c05a7c8c6b..00000000000 --- a/src/interface/TWBech32m.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include - -#include "../Bech32.h" - -#include - -using namespace TW; - -TWString *_Nonnull TWBech32mEncode(TWString* _Nonnull hrp, TWData *_Nonnull data) { - auto cppHrp = *reinterpret_cast(hrp); - auto cppData = *reinterpret_cast(data); - auto result = Bech32::encode(cppHrp, cppData, Bech32::ChecksumVariant::Bech32M); - return TWStringCreateWithUTF8Bytes(result.c_str()); -} - -TWData *_Nullable TWBech32mDecode(TWString *_Nonnull string) { - auto cppString = *reinterpret_cast(string); - const auto decoded = Bech32::decode(cppString); - - auto data = std::get<1>(decoded); - if (data.empty()) { // Failed to decode - return nullptr; - } - - if (std::get<2>(decoded) != Bech32::ChecksumVariant::Bech32M) { // Wrong ChecksumVariant - return nullptr; - } - - return TWDataCreateWithBytes(data.data(), data.size()); -} diff --git a/swift/Tests/Bech32Tests.swift b/swift/Tests/Bech32Tests.swift index 5fed2f09916..42f67aa1547 100644 --- a/swift/Tests/Bech32Tests.swift +++ b/swift/Tests/Bech32Tests.swift @@ -7,16 +7,36 @@ import WalletCore class Bech32Tests: XCTestCase { func testEncode() { - let data = Data(hexString: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")! + let data = Data(hexString: "00443214c74254b635cf84653a56d7c675be77df")! let encoded = Bech32.encode(hrp: "abcdef", data: data) XCTAssertEqual(encoded, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") } func testDecode() { - guard let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") else { - return XCTFail() - } + let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + XCTAssertEqual(decoded.hexString, "00443214c74254b635cf84653a56d7c675be77df") + } + + func testDecodeWrongChecksumVariant() { + // This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder. + let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + XCTAssertNil(decoded) + } + + func testEncodeM() { + let data = Data(hexString: "ffbbcdeb38bdab49ca307b9ac5a928398a418820")! + let encoded = Bech32.encodeM(hrp: "abcdef", data: data) + XCTAssertEqual(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + } + + func testDecodeM() { + let decoded = Bech32.decodeM(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + XCTAssertEqual(decoded.hexString, "ffbbcdeb38bdab49ca307b9ac5a928398a418820") + } - XCTAssertEqual(decoded.hexString, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + func testDecodeMWrongChecksumVariant() { + // This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder. + let decoded = Bech32.decodeM(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + XCTAssertNil(decoded) } } diff --git a/swift/Tests/Bech32mTests.swift b/swift/Tests/Bech32mTests.swift deleted file mode 100644 index 5707d4f6273..00000000000 --- a/swift/Tests/Bech32mTests.swift +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -import XCTest -import WalletCore - -class Bech32mTests: XCTestCase { - func testEncode() { - let data = Data(hexString: "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100")! - let encoded = Bech32m.encode(hrp: "abcdef", data: data) - XCTAssertEqual(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") - } - - func testDecode() { - guard let decoded = Bech32m.decode(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") else { - return XCTFail() - } - - XCTAssertEqual(decoded.hexString, "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100") - } -} diff --git a/tests/interface/TWBech32Tests.cpp b/tests/interface/TWBech32Tests.cpp index c3e0cf9595d..00c1b3b6d98 100644 --- a/tests/interface/TWBech32Tests.cpp +++ b/tests/interface/TWBech32Tests.cpp @@ -10,7 +10,7 @@ TEST(TWBech32, Encode) { const auto hrp = STRING("abcdef"); - const auto data = DATA("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + const auto data = DATA("00443214c74254b635cf84653a56d7c675be77df"); const auto result = WRAPS(TWBech32Encode(hrp.get(), data.get())); assertStringsEqual(result, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); } @@ -18,11 +18,32 @@ TEST(TWBech32, Encode) { TEST(TWBech32, Decode) { const auto input = STRING("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); const auto result = WRAPD(TWBech32Decode(input.get())); - assertHexEqual(result, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + assertHexEqual(result, "00443214c74254b635cf84653a56d7c675be77df"); } TEST(TWBech32, Decode_WrongChecksumVariant) { - const auto input = STRING("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); // This is a Bech32m variant, not Bech32 variant. So it should fail. + // This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder. + const auto input = STRING("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); const auto result = WRAPD(TWBech32Decode(input.get())); ASSERT_EQ(result.get(), nullptr); } + +TEST(TWBech32, EncodeM) { + const auto hrp = STRING("abcdef"); + const auto data = DATA("ffbbcdeb38bdab49ca307b9ac5a928398a418820"); + const auto result = WRAPS(TWBech32EncodeM(hrp.get(), data.get())); + assertStringsEqual(result, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); +} + +TEST(TWBech32, DecodeM) { + const auto input = STRING("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); + auto result = WRAPD(TWBech32DecodeM(input.get())); + assertHexEqual(result, "ffbbcdeb38bdab49ca307b9ac5a928398a418820"); +} + +TEST(TWBech32, DecodeM_WrongChecksumVariant) { + // This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder. + const auto input = STRING("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + const auto result = WRAPD(TWBech32DecodeM(input.get())); + ASSERT_EQ(result.get(), nullptr); +} diff --git a/tests/interface/TWBech32mTests.cpp b/tests/interface/TWBech32mTests.cpp deleted file mode 100644 index 6d8780a3e0b..00000000000 --- a/tests/interface/TWBech32mTests.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include "TestUtilities.h" - -#include - -#include - -TEST(TWBech32m, Encode) { - auto hrp = STRING("abcdef"); - const auto data = DATA("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); - auto result = WRAPS(TWBech32mEncode(hrp.get(), data.get())); - assertStringsEqual(result, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); -} - -TEST(TWBech32m, Decode) { - const auto input = STRING("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); - auto result = WRAPD(TWBech32mDecode(input.get())); - assertHexEqual(result, "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"); -} - -TEST(TWBech32m, Decode_WrongChecksumVariant) { - const auto input = STRING("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); // This is a Bech32 variant, not Bech32m variant. So it should fail. - const auto result = WRAPD(TWBech32mDecode(input.get())); - ASSERT_EQ(result.get(), nullptr); -} \ No newline at end of file diff --git a/wasm/tests/Bech32.test.ts b/wasm/tests/Bech32.test.ts index 5b363205914..a98194b4021 100644 --- a/wasm/tests/Bech32.test.ts +++ b/wasm/tests/Bech32.test.ts @@ -7,22 +7,55 @@ import { Buffer } from "buffer"; describe("Bech32", () => { - it("test decoding", () => { + it("test encode", () => { + const { Bech32 } = globalThis.core; + + const encoded = Bech32.encode("abcdef", Buffer.from("00443214c74254b635cf84653a56d7c675be77df", "hex")); + + assert.equal(encoded, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + }); + + it("test decode", () => { const { Bech32, HexCoding } = globalThis.core; const decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); assert.equal( HexCoding.encode(decoded), - "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "00443214c74254b635cf84653a56d7c675be77df" ); }); - it("test encoding", () => { + it("test decode wrongChecksumVariant", () => { const { Bech32 } = globalThis.core; + // This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder. + const decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + assert.isNull(decoded); + }); - const encoded = Bech32.encode("abcdef", Buffer.from("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "hex")); + it("test encodeM", () => { + const { Bech32 } = globalThis.core; - assert.equal(encoded, "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + const encoded = Bech32.encodeM("abcdef", Buffer.from("ffbbcdeb38bdab49ca307b9ac5a928398a418820", "hex")); + + assert.equal(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); + }); + + it("test decodeM", () => { + const { Bech32, HexCoding } = globalThis.core; + + const decoded = Bech32.decodeM("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); + + assert.equal( + HexCoding.encode(decoded), + "ffbbcdeb38bdab49ca307b9ac5a928398a418820" + ); + }); + + it("test decode wrongChecksumVariant", () => { + const { Bech32 } = globalThis.core; + // This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder. + const decoded = Bech32.decodeM("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); + assert.isNull(decoded); }); }); diff --git a/wasm/tests/Bech32m.test.ts b/wasm/tests/Bech32m.test.ts deleted file mode 100644 index 691d72f56c8..00000000000 --- a/wasm/tests/Bech32m.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -import { assert } from "chai"; -import { Buffer } from "buffer"; - -describe("Bech32m", () => { - - it("test decoding", () => { - const { Bech32m, HexCoding } = globalThis.core; - - const decoded = Bech32m.decode("abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); - - assert.equal( - HexCoding.encode(decoded), - "0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100" - ); - }); - - it("test encoding", () => { - const { Bech32m } = globalThis.core; - - const encoded = Bech32m.encode("abcdef", Buffer.from("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100", "hex")); - - assert.equal(encoded, "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx"); - }); -}); From fba64bf3a433c9a5f55b4e43d6cba4f8ae79b9d7 Mon Sep 17 00:00:00 2001 From: 10gic <2391796+10gic@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:47:07 +0800 Subject: [PATCH 4/5] Fix failed test cases --- .../trustwallet/core/app/utils/TestBech32.kt | 2 +- swift/Tests/Bech32Tests.swift | 4 ++-- wasm/tests/Bech32.test.ts | 18 ++---------------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt index 598823665db..64b32728c5c 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestBech32.kt @@ -1,6 +1,6 @@ package com.trustwallet.core.app.utils -import org.junit.Assert.assertEquals +import org.junit.Assert.* import org.junit.Test import wallet.core.jni.Bech32 diff --git a/swift/Tests/Bech32Tests.swift b/swift/Tests/Bech32Tests.swift index 42f67aa1547..e7f924113e9 100644 --- a/swift/Tests/Bech32Tests.swift +++ b/swift/Tests/Bech32Tests.swift @@ -13,7 +13,7 @@ class Bech32Tests: XCTestCase { } func testDecode() { - let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")! XCTAssertEqual(decoded.hexString, "00443214c74254b635cf84653a56d7c675be77df") } @@ -30,7 +30,7 @@ class Bech32Tests: XCTestCase { } func testDecodeM() { - let decoded = Bech32.decodeM(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") + let decoded = Bech32.decodeM(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx")! XCTAssertEqual(decoded.hexString, "ffbbcdeb38bdab49ca307b9ac5a928398a418820") } diff --git a/wasm/tests/Bech32.test.ts b/wasm/tests/Bech32.test.ts index a98194b4021..f9ac76a0c9f 100644 --- a/wasm/tests/Bech32.test.ts +++ b/wasm/tests/Bech32.test.ts @@ -22,17 +22,10 @@ describe("Bech32", () => { assert.equal( HexCoding.encode(decoded), - "00443214c74254b635cf84653a56d7c675be77df" + "0x00443214c74254b635cf84653a56d7c675be77df" ); }); - it("test decode wrongChecksumVariant", () => { - const { Bech32 } = globalThis.core; - // This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder. - const decoded = Bech32.decode("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); - assert.isNull(decoded); - }); - it("test encodeM", () => { const { Bech32 } = globalThis.core; @@ -48,14 +41,7 @@ describe("Bech32", () => { assert.equal( HexCoding.encode(decoded), - "ffbbcdeb38bdab49ca307b9ac5a928398a418820" + "0xffbbcdeb38bdab49ca307b9ac5a928398a418820" ); }); - - it("test decode wrongChecksumVariant", () => { - const { Bech32 } = globalThis.core; - // This is a Bech32 variant, not Bech32m variant. So it should fail using Bech32M decoder. - const decoded = Bech32.decodeM("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"); - assert.isNull(decoded); - }); }); From 67675e2aad0634f4ee97b56f333b6269efc6298e Mon Sep 17 00:00:00 2001 From: 10gic <2391796+10gic@users.noreply.github.com> Date: Sat, 9 Nov 2024 00:20:59 +0800 Subject: [PATCH 5/5] Fix failed swift test case --- swift/Tests/Bech32Tests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/Tests/Bech32Tests.swift b/swift/Tests/Bech32Tests.swift index e7f924113e9..f09bd9507fa 100644 --- a/swift/Tests/Bech32Tests.swift +++ b/swift/Tests/Bech32Tests.swift @@ -19,7 +19,7 @@ class Bech32Tests: XCTestCase { func testDecodeWrongChecksumVariant() { // This is a Bech32m variant, not Bech32 variant. So it should fail using Bech32 decoder. - let decoded = Bech32.decode(string: "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw") + let decoded = Bech32.decode(string: "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx") XCTAssertNil(decoded) }