From 171bc186663e3c7a573a6240f28f430e8d6b7d50 Mon Sep 17 00:00:00 2001 From: Reuben Yap Date: Fri, 3 Jul 2026 19:22:21 +0800 Subject: [PATCH 1/5] Update vendored Spark Name registration format --- src/deps/sparkmobile/src/sparkname.h | 8 +++++++- src/deps/sparkmobile/tests/spark_name_test.cpp | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/deps/sparkmobile/src/sparkname.h b/src/deps/sparkmobile/src/sparkname.h index 0d2805f8..d80c9e66 100644 --- a/src/deps/sparkmobile/src/sparkname.h +++ b/src/deps/sparkmobile/src/sparkname.h @@ -9,7 +9,7 @@ namespace spark { struct CSparkNameTxData { public: - static const uint16_t CURRENT_VERSION = 1; + static const uint16_t CURRENT_VERSION = 2; public: uint16_t nVersion{CURRENT_VERSION}; // version @@ -27,6 +27,8 @@ struct CSparkNameTxData std::string additionalInfo; // failsafe if the hash of the transaction data is can't be converted to a scalar for proof creation/verification uint32_t hashFailsafe{0}; + // Registration-only; add transfer fields if mobile starts creating Spark Name transfers. + uint8_t operationType{0}; ADD_SERIALIZE_METHODS; @@ -41,6 +43,10 @@ struct CSparkNameTxData READWRITE(sparkNameValidityBlocks); READWRITE(additionalInfo); READWRITE(hashFailsafe); + if (nVersion >= 2) + { + READWRITE(operationType); + } } }; diff --git a/src/deps/sparkmobile/tests/spark_name_test.cpp b/src/deps/sparkmobile/tests/spark_name_test.cpp index 018e70c0..7628c9e4 100644 --- a/src/deps/sparkmobile/tests/spark_name_test.cpp +++ b/src/deps/sparkmobile/tests/spark_name_test.cpp @@ -42,6 +42,8 @@ BOOST_AUTO_TEST_CASE(spark_names) BOOST_CHECK_EQUAL(decodedData.sparkAddress, sparkNameData.sparkAddress); BOOST_CHECK_EQUAL(decodedData.sparkNameValidityBlocks, sparkNameData.sparkNameValidityBlocks); BOOST_CHECK_EQUAL(decodedData.additionalInfo, sparkNameData.additionalInfo); + BOOST_CHECK_EQUAL(decodedData.nVersion, spark::CSparkNameTxData::CURRENT_VERSION); + BOOST_CHECK_EQUAL((int)decodedData.operationType, 0); BOOST_CHECK(!decodedData.addressOwnershipProof.empty()); spark::OwnershipProof deserializedOwnershipProof; From 76b35781f25d71f168411b865030a36a85b5af83 Mon Sep 17 00:00:00 2001 From: Reuben Yap Date: Thu, 16 Jul 2026 19:06:54 +0800 Subject: [PATCH 2/5] Fix Spark Name version assertion --- src/deps/sparkmobile/tests/spark_name_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deps/sparkmobile/tests/spark_name_test.cpp b/src/deps/sparkmobile/tests/spark_name_test.cpp index 7628c9e4..08e70a01 100644 --- a/src/deps/sparkmobile/tests/spark_name_test.cpp +++ b/src/deps/sparkmobile/tests/spark_name_test.cpp @@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE(spark_names) BOOST_CHECK_EQUAL(decodedData.sparkAddress, sparkNameData.sparkAddress); BOOST_CHECK_EQUAL(decodedData.sparkNameValidityBlocks, sparkNameData.sparkNameValidityBlocks); BOOST_CHECK_EQUAL(decodedData.additionalInfo, sparkNameData.additionalInfo); - BOOST_CHECK_EQUAL(decodedData.nVersion, spark::CSparkNameTxData::CURRENT_VERSION); + BOOST_CHECK_EQUAL(decodedData.nVersion, uint16_t{2}); BOOST_CHECK_EQUAL((int)decodedData.operationType, 0); BOOST_CHECK(!decodedData.addressOwnershipProof.empty()); From 35e4a082b2206cc574c917052c999ecd8cb9ba1f Mon Sep 17 00:00:00 2001 From: Reuben Yap Date: Thu, 16 Jul 2026 19:18:04 +0800 Subject: [PATCH 3/5] Reject unsupported Spark Name versions --- src/deps/sparkmobile/src/sparkname.h | 4 +++- src/deps/sparkmobile/tests/spark_name_test.cpp | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/deps/sparkmobile/src/sparkname.h b/src/deps/sparkmobile/src/sparkname.h index d80c9e66..a9a77716 100644 --- a/src/deps/sparkmobile/src/sparkname.h +++ b/src/deps/sparkmobile/src/sparkname.h @@ -36,6 +36,8 @@ struct CSparkNameTxData void SerializationOp(Stream &s, Operation ser_action) { READWRITE(nVersion); + if (nVersion != 1 && nVersion != 2) + throw std::ios_base::failure("Unsupported Spark Name transaction data version"); READWRITE(inputsHash); READWRITE(name); READWRITE(sparkAddress); @@ -43,7 +45,7 @@ struct CSparkNameTxData READWRITE(sparkNameValidityBlocks); READWRITE(additionalInfo); READWRITE(hashFailsafe); - if (nVersion >= 2) + if (nVersion == 2) { READWRITE(operationType); } diff --git a/src/deps/sparkmobile/tests/spark_name_test.cpp b/src/deps/sparkmobile/tests/spark_name_test.cpp index 08e70a01..93097d0a 100644 --- a/src/deps/sparkmobile/tests/spark_name_test.cpp +++ b/src/deps/sparkmobile/tests/spark_name_test.cpp @@ -56,4 +56,17 @@ BOOST_AUTO_TEST_CASE(spark_names) BOOST_CHECK(address.verify_own(m, deserializedOwnershipProof)); } +BOOST_AUTO_TEST_CASE(rejects_unsupported_spark_name_versions) +{ + spark::CSparkNameTxData data; + data.nVersion = 3; + CDataStream serialized(SER_NETWORK, PROTOCOL_VERSION); + BOOST_CHECK_THROW(serialized << data, std::ios_base::failure); + + uint16_t unsupportedVersion = 3; + CDataStream encodedVersion(SER_NETWORK, PROTOCOL_VERSION); + encodedVersion << unsupportedVersion; + BOOST_CHECK_THROW(encodedVersion >> data, std::ios_base::failure); +} + BOOST_AUTO_TEST_SUITE_END() From 7ca805ccea2b499d19b49a75c37b06125ab349c4 Mon Sep 17 00:00:00 2001 From: Reuben Yap Date: Thu, 16 Jul 2026 19:22:03 +0800 Subject: [PATCH 4/5] Strengthen unsupported-version decode test --- src/deps/sparkmobile/tests/spark_name_test.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/deps/sparkmobile/tests/spark_name_test.cpp b/src/deps/sparkmobile/tests/spark_name_test.cpp index 93097d0a..302b909e 100644 --- a/src/deps/sparkmobile/tests/spark_name_test.cpp +++ b/src/deps/sparkmobile/tests/spark_name_test.cpp @@ -63,10 +63,12 @@ BOOST_AUTO_TEST_CASE(rejects_unsupported_spark_name_versions) CDataStream serialized(SER_NETWORK, PROTOCOL_VERSION); BOOST_CHECK_THROW(serialized << data, std::ios_base::failure); - uint16_t unsupportedVersion = 3; - CDataStream encodedVersion(SER_NETWORK, PROTOCOL_VERSION); - encodedVersion << unsupportedVersion; - BOOST_CHECK_THROW(encodedVersion >> data, std::ios_base::failure); + data.nVersion = 2; + CDataStream encodedData(SER_NETWORK, PROTOCOL_VERSION); + encodedData << data; + encodedData[0] = 3; + encodedData[1] = 0; + BOOST_CHECK_THROW(encodedData >> data, std::ios_base::failure); } BOOST_AUTO_TEST_SUITE_END() From 53db5a06a7b7f3df68fe6263f1453f77513bec06 Mon Sep 17 00:00:00 2001 From: Reuben Yap Date: Thu, 16 Jul 2026 20:37:45 +0800 Subject: [PATCH 5/5] Reject invalid Spark Name underscores --- lib/flutter_libsparkmobile.dart | 4 ++-- test/flutter_libsparkmobile_test.dart | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/flutter_libsparkmobile.dart b/lib/flutter_libsparkmobile.dart index 304bee6e..2f20bb36 100644 --- a/lib/flutter_libsparkmobile.dart +++ b/lib/flutter_libsparkmobile.dart @@ -20,8 +20,8 @@ const kSparkBaseDerivationPath = "m/44'/136'/0'/$kSparkChain/"; const kSparkBaseDerivationPathTestnet = "m/44'/1'/0'/$kSparkChain/"; const kMaxNameLength = - 20; // max 20 symbols, alphanumerical or "-_.", case-insensitive -const kNameRegexString = r'^[a-zA-Z0-9\-_\.]+$'; + 20; // max 20 symbols, alphanumerical or "-.", case-insensitive +const kNameRegexString = r'^[a-zA-Z0-9.-]+$'; const kMaxAdditionalInfoLengthBytes = 1024; const kMaxNameRegistrationLengthYears = 10; const kStage3CommunityFundAddressMainNet = "aFA2TbqG9cnhhzX5Yny2pBJRK5EaEqLCH7"; diff --git a/test/flutter_libsparkmobile_test.dart b/test/flutter_libsparkmobile_test.dart index 66dc9255..c3938118 100644 --- a/test/flutter_libsparkmobile_test.dart +++ b/test/flutter_libsparkmobile_test.dart @@ -3,6 +3,12 @@ import 'package:flutter_libsparkmobile/src/extensions.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { + test('Spark Names reject underscores', () { + final pattern = RegExp(kNameRegexString); + expect(pattern.hasMatch('NAME-FOR.TESTING'), isTrue); + expect(pattern.hasMatch('NAME_FOR_TESTING'), isFalse); + }); + test('mnemonic to address test', () async { // Generate key data from the mnemonic. //