Files
wownero-lws/CMakeLists.txt
jwinterm 97877eda27 Port monero-lws to wownero-lws
Adapts monero-lws for Wownero cryptocurrency:

- Rename all monero-lws-* binaries to wownero-lws-*
- Update submodule to point to official Wownero repo
- Use Wownero default ports (RPC: 34568, ZMQ: 34569)
- Update data directory to ~/.wownero/light_wallet_server
- Adapt next_difficulty() calls for Wownero API signature

Key technical changes for Wownero compatibility:

- BulletproofPlus (RCTTypeBulletproofPlus, type 8) commitment verification:
  Wownero stores BP+ commitments in 'divided by 8' form. Must call
  rct::scalarmult8() on outPk commitment before comparing with computed
  commitment (mask*G + amount*H). This is essential for amount decryption.

- Pass rct_type to decode_amount() for proper commitment handling

- Handle Wownero's ZMQ JSON format for ecdhTuple (32-byte mask/amount fields)

No fork of Wownero is required - uses official codeberg.org/wownero/wownero.
2026-01-04 20:04:42 -05:00

388 lines
12 KiB
CMake

# Copyright (c) 2020, The Monero Project
# Copyright (c) 2024-2025, The Wownero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cmake_minimum_required(VERSION 3.5.0)
project(wownero-lws)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_definitions(-DBOOST_UUID_DISABLE_ALIGNMENT) # This restores UUID's std::has_unique_object_representations property
option(BUILD_TESTS "Build Tests" OFF)
option(WITH_RMQ "Build with RMQ publish support" OFF)
if (WITH_RMQ)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMLWS_RMQ_ENABLED")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMLWS_RMQ_ENABLED")
endif()
# If `WOWNERO_BUILD_DIR` is not specified, wownero unit tests will be built with this hack
set (LWS_BUILD_TESTS "${BUILD_TESTS}")
set (BUILD_TESTS "Off")
option(SANITIZER "Use specific sanitizer" OFF)
if(NOT SANITIZER STREQUAL "OFF")
if (MSVC)
message(FATAL_ERROR "Cannot sanitize with MSVC")
else()
message(STATUS "Using sanitizer=${SANITIZER}")
add_compile_options("-fsanitize=${SANITIZER}")
add_link_options("-fsanitize=${SANITIZER}")
endif()
endif()
if(STATIC)
if(MSVC)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
endif()
set(WOWNERO_LIBRARIES
daemon_messages
serialization
net
cryptonote_core
cryptonote_basic
cryptonote_format_utils_basic
ringct
ringct_basic
multisig
hardforks
checkpoints
blockchain_db
common
lmdb
lmdb_lib
device
cncrypto
randomx
epee
easylogging
version
wallet-crypto
)
set(WOWNERO_OPTIONAL wallet-crypto)
if (WOWNERO_BUILD_DIR)
set(WOWNERO_SEARCH_PATHS
"/contrib/epee/src"
"/external/db_drivers/liblmdb"
"/external/easylogging++"
"/external/randomwow"
"/src"
"/src/crypto"
"/src/crypto/wallet"
"/src/cryptonote_basic"
"/src/lmdb"
"/src/ringct"
"/src/rpc"
"/src/common"
"/src/serialization"
"/src/net"
"/src/cryptonote_core"
"/src/multisig"
"/src/hardforks"
"/src/checkpoints"
"/src/blockchain_db"
"/src/device"
"/src/mnemonics"
)
#
# Pull some information from wownero build
#
# Needed due to "bug" in wownero CMake - the `project` function is used twice!
if (NOT WOWNERO_SOURCE_DIR)
message(FATAL_ERROR "The argument -DWOWNERO_SOURCE_DIR must specify a location of a wownero source tree")
endif()
get_filename_component(WOWNERO_SOURCE_DIR "${WOWNERO_SOURCE_DIR}" ABSOLUTE)
get_filename_component(WOWNERO_BUILD_DIR "${WOWNERO_BUILD_DIR}" ABSOLUTE)
message(STATUS "WOWNERO_SOURCE_DIR: ${WOWNERO_SOURCE_DIR}")
message(STATUS "WOWNERO_BUILD_DIR: ${WOWNERO_BUILD_DIR}")
if (NOT EXISTS "${WOWNERO_BUILD_DIR}/CMakeCache.txt")
message(FATAL_ERROR "Wownero cache not found at ${WOWNERO_BUILD_DIR}/CMakeCache.txt. Please ensure WOWNERO_BUILD_DIR is correct and Wownero has been configured.")
endif()
# wownero `master` and release branches use different LIBSODIUM
# find routines. So the upstream cmake names differ
load_cache(${WOWNERO_BUILD_DIR} READ_WITH_PREFIX wownero_
Boost_THREAD_LIBRARY_RELEASE
CMAKE_CXX_COMPILER
EXTRA_LIBRARIES
LIBUDEV_LIBRARY
usb_LIBRARY
HIDAPI_INCLUDE_DIR
HIDAPI_LIBRARY
LMDB_INCLUDE
wownero_SOURCE_DIR
OPENSSL_INCLUDE_DIR
OPENSSL_CRYPTO_LIBRARY
OPENSSL_SSL_LIBRARY
ZMQ_LIB
ZMQ_INCLUDE_PATH
sodium_LIBRARY_RELEASE
SODIUM_LIBRARY
UNBOUND_LIBRARIES
PGM_LIBRARY
NORM_LIBRARY
GSSAPI_LIBRARY
PROTOLIB_LIBRARY
)
if (wownero_wownero_SOURCE_DIR AND NOT (wownero_wownero_SOURCE_DIR MATCHES "${WOWNERO_SOURCE_DIR}"))
message(WARNING "Mismatch detected: wownero_wownero_SOURCE_DIR='${wownero_wownero_SOURCE_DIR}' vs WOWNERO_SOURCE_DIR='${WOWNERO_SOURCE_DIR}'. Proceeding anyway...")
endif()
if (wownero_CMAKE_CXX_COMPILER AND NOT (CMAKE_CXX_COMPILER STREQUAL wownero_CMAKE_CXX_COMPILER))
message(FATAL_ERROR "Compiler for wownero build (${wownero_CMAKE_CXX_COMPILER}) differs from this project (${CMAKE_CXX_COMPILER})")
endif()
if ("${wownero_UNBOUND_LIBRARIES}" STREQUAL "UNBOUND_LIBRARIES-NOTFOUND")
unset(wownero_UNBOUND_LIBRARIES)
endif()
if ("${wownero_HIDAPI_LIBRARY}" STREQUAL "HIDAPI_LIBRARY-NOTFOUND")
unset(wownero_HIDAPI_INCLUDE_DIR)
unset(wownero_HIDAPI_LIBRARY)
endif()
set(WOWNERO_LIBRARY_PATHS "")
foreach (PATH ${WOWNERO_SEARCH_PATHS})
list(APPEND WOWNERO_LIBRARY_PATHS "${WOWNERO_BUILD_DIR}${PATH}")
endforeach()
foreach (LIB ${WOWNERO_LIBRARIES})
find_library(LIB_PATH NAMES "${LIB}" PATHS ${WOWNERO_BUILD_DIR} ${WOWNERO_LIBRARY_PATHS} PATH_SUFFIXES "/src/${LIB}" "external/${LIB}" NO_DEFAULT_PATH)
list(FIND WOWNERO_OPTIONAL "${LIB}" LIB_OPTIONAL)
if (NOT LIB_PATH)
if (LIB_OPTIONAL EQUAL -1)
message(FATAL_ERROR "Unable to find required Wownero library ${LIB}")
endif()
else ()
set(LIB_NAME "wownero::${LIB}")
add_library(${LIB_NAME} STATIC IMPORTED)
set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LOCATION ${LIB_PATH})
list(APPEND IMPORTED_WOWNERO_LIBRARIES "${LIB_NAME}")
endif()
unset(LIB_PATH CACHE)
endforeach()
set(LMDB_INCLUDE "${wownero_LMDB_INCLUDE}")
set(LMDB_LIB_PATH "wownero::lmdb")
else () # NOT WOWNERO_BUILD_DIR
if (NOT WOWNERO_SOURCE_DIR)
set (WOWNERO_SOURCE_DIR "${wownero-lws_SOURCE_DIR}/external/monero")
endif ()
include(FetchContent)
FetchContent_Declare(wownero SOURCE_DIR "${WOWNERO_SOURCE_DIR}" EXCLUDE_FROM_ALL)
if (NOT wownero_POPULATED)
FetchContent_MakeAvailable(wownero)
endif ()
set(WOWNERO_BUILD_DIR "${wownero_BINARY_DIR}")
set(IMPORTED_WOWNERO_LIBRARIES "${WOWNERO_LIBRARIES}")
set(LMDB_LIB_PATH "lmdb")
set(wownero_Boost_THREAD_LIBRARY_RELEASE "${Boost_THREAD_LIBRARY_RELEASE}")
# Wownero uses ZMQ_LIB directly (via find_library), not pkg-config
set(wownero_ZMQ_LIB "${ZMQ_LIB}")
set(wownero_ZMQ_INCLUDE_PATH "${ZMQ_INCLUDE_PATH}")
if (SODIUM_LIBRARY)
set(wownero_SODIUM_LIBRARY "${SODIUM_LIBRARY}")
else()
set(wownero_SODIUM_LIBRARY "${wownero_sodium_LIBRARY_RELEASE}")
endif()
endif()
#
# Dependencies specific to wownero-lws
#
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
# boost
set(Boost_NO_BOOST_CMAKE ON)
# If Wownero was built statically, we should probably do the same
if (WOWNERO_BUILD_DIR AND NOT STATIC)
if (wownero_Boost_THREAD_LIBRARY_RELEASE MATCHES ".*\\.a$")
message(STATUS "Wownero build was static, enabling STATIC for this project")
set(STATIC ON)
endif()
endif()
if(STATIC)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
endif()
find_package(Boost 1.70 QUIET REQUIRED COMPONENTS chrono context coroutine filesystem program_options regex serialization thread)
get_filename_component(REAL_Boost_THREAD_LIBRARY "${Boost_THREAD_LIBRARY}" REALPATH)
get_filename_component(REAL_wownero_Boost_THREAD_LIBRARY "${wownero_Boost_THREAD_LIBRARY_RELEASE}" REALPATH)
if (NOT (REAL_Boost_THREAD_LIBRARY STREQUAL REAL_wownero_Boost_THREAD_LIBRARY))
message(STATUS "Found Boost_THREAD_LIBRARY: ${Boost_THREAD_LIBRARY} (real: ${REAL_Boost_THREAD_LIBRARY})")
message(STATUS "Found wownero_Boost_THREAD_LIBRARY_RELEASE: ${wownero_Boost_THREAD_LIBRARY_RELEASE} (real: ${REAL_wownero_Boost_THREAD_LIBRARY})")
message(FATAL_ERROR "Boost libraries for wownero build differs from this project")
endif()
if (WITH_RMQ)
find_path(RMQ_INCLUDE_DIR "amqp.h")
find_library(RMQ_LIBRARY rabbitmq REQUIRED)
else()
set(RMQ_INCLUDE_DIR "")
set(RMQ_LIBRARY "")
endif()
# Use ZMQ from Wownero build
if (wownero_ZMQ_INCLUDE_PATH)
set(ZMQ_INCLUDE_PATH "${wownero_ZMQ_INCLUDE_PATH}")
endif()
if (wownero_ZMQ_LIB)
set(ZMQ_LIB "${wownero_ZMQ_LIB}")
endif()
if (wownero_SODIUM_LIBRARY)
set(SODIUM_LIBRARY "${wownero_SODIUM_LIBRARY}")
else ()
set(SODIUM_LIBRARY "${wownero_sodium_LIBRARY_RELEASE}")
endif ()
if(NOT ZMQ_LIB)
message(FATAL_ERROR "Could not find required libzmq")
endif()
if(wownero_PGM_LIBRARY AND NOT "${wownero_PGM_LIBRARY}" STREQUAL "PGM_LIBRARY-NOTFOUND")
set(ZMQ_LIB "${ZMQ_LIB};${wownero_PGM_LIBRARY}")
endif()
if(wownero_NORM_LIBRARY AND NOT "${wownero_NORM_LIBRARY}" STREQUAL "NORM_LIBRARY-NOTFOUND")
set(ZMQ_LIB "${ZMQ_LIB};${wownero_NORM_LIBRARY}")
if(NOT wownero_PROTOLIB_LIBRARY OR "${wownero_PROTOLIB_LIBRARY}" STREQUAL "PROTOLIB_LIBRARY-NOTFOUND")
find_library(PROTOLIB_LIBRARY NAMES protokit protolib)
if(PROTOLIB_LIBRARY)
set(wownero_PROTOLIB_LIBRARY "${PROTOLIB_LIBRARY}")
endif()
endif()
endif()
if(wownero_GSSAPI_LIBRARY AND NOT "${wownero_GSSAPI_LIBRARY}" STREQUAL "GSSAPI_LIBRARY-NOTFOUND")
set(ZMQ_LIB "${ZMQ_LIB};${wownero_GSSAPI_LIBRARY}")
endif()
if(wownero_PROTOLIB_LIBRARY AND NOT "${wownero_PROTOLIB_LIBRARY}" STREQUAL "PROTOLIB_LIBRARY-NOTFOUND")
set(ZMQ_LIB "${ZMQ_LIB};${wownero_PROTOLIB_LIBRARY}")
endif()
if(wownero_sodium_LIBRARY_RELEASE AND NOT "${wownero_sodium_LIBRARY_RELEASE}" STREQUAL "sodium_LIBRARY_RELEASE-NOTFOUND")
set(ZMQ_LIB "${ZMQ_LIB};${wownero_sodium_LIBRARY_RELEASE}")
endif()
if(STATIC AND NOT IOS)
if(UNIX)
find_package(ZLIB)
if(ZLIB_FOUND)
set(wownero_OPENSSL_CRYPTO_LIBRARY "${wownero_OPENSSL_CRYPTO_LIBRARY};${ZLIB_LIBRARIES}")
endif()
find_library(ZSTD_LIBRARY NAMES zstd)
if(ZSTD_LIBRARY)
set(wownero_OPENSSL_CRYPTO_LIBRARY "${wownero_OPENSSL_CRYPTO_LIBRARY};${ZSTD_LIBRARY}")
else()
set(wownero_OPENSSL_CRYPTO_LIBRARY "${wownero_OPENSSL_CRYPTO_LIBRARY};zstd")
endif()
find_library(EVENT_LIBRARY NAMES event libevent)
if(EVENT_LIBRARY)
set(wownero_UNBOUND_LIBRARIES "${wownero_UNBOUND_LIBRARIES};${EVENT_LIBRARY}")
else()
set(wownero_UNBOUND_LIBRARIES "${wownero_UNBOUND_LIBRARIES};event")
endif()
set(wownero_OPENSSL_LIBRARIES "${wownero_OPENSSL_LIBRARIES};${CMAKE_DL_LIBS};${CMAKE_THREAD_LIBS_INIT};rt")
endif()
endif()
if(APPLE)
find_library(IOKIT_LIBRARY IOKit)
list(APPEND IMPORTED_WOWNERO_LIBRARIES ${IOKIT_LIBRARY})
endif()
add_library(wownero::libraries INTERFACE IMPORTED)
set_property(TARGET wownero::libraries PROPERTY
INTERFACE_INCLUDE_DIRECTORIES
${Boost_INCLUDE_DIR}
${wownero_HIDAPI_INCLUDE_DIRS}
${wownero_OPENSSL_INCLUDE_DIR}
"${WOWNERO_BUILD_DIR}/generated_include"
"${WOWNERO_SOURCE_DIR}/contrib/epee/include"
"${WOWNERO_SOURCE_DIR}/external/easylogging++"
"${WOWNERO_SOURCE_DIR}/external/rapidjson/include"
"${WOWNERO_SOURCE_DIR}/external/supercop/include"
"${WOWNERO_SOURCE_DIR}/src"
)
set_property(TARGET wownero::libraries PROPERTY
INTERFACE_LINK_LIBRARIES
${IMPORTED_WOWNERO_LIBRARIES}
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_REGEX_LIBRARY}
${Boost_SERIALIZATION_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${wownero_HIDAPI_LIBRARY}
${wownero_usb_LIBRARY}
${wownero_LIBUDEV_LIBRARY}
${wownero_OPENSSL_SSL_LIBRARY}
${wownero_OPENSSL_CRYPTO_LIBRARY}
${SODIUM_LIBRARY}
${wownero_UNBOUND_LIBRARIES}
${ZMQ_LIB}
${CMAKE_DL_LIBS}
Threads::Threads
rt
)
#
# Build wownero-lws code
#
add_subdirectory(src)
if (LWS_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()