From dfd83734422061e949788bf89cbb9ac99de31d18 Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Mon, 27 Oct 2025 15:10:54 +1100 Subject: [PATCH 1/5] feat: create pro backend wrapper for getting pro proofs --- include/pro/pro.hpp | 69 +++++++++++++++++++++++++++++++++++++++++++ include/utilities.hpp | 1 + 2 files changed, 70 insertions(+) diff --git a/include/pro/pro.hpp b/include/pro/pro.hpp index 71bfbee..5ab4e8e 100644 --- a/include/pro/pro.hpp +++ b/include/pro/pro.hpp @@ -9,6 +9,7 @@ #include "../meta/meta_base_wrapper.hpp" #include "../utilities.hpp" #include "meta/meta_base_wrapper.hpp" +#include "session/pro_backend.hpp" #include "session/session_protocol.hpp" namespace session::nodeapi { @@ -31,6 +32,10 @@ class ProWrapper : public Napi::ObjectWrap { "proFeaturesForMessage", static_cast( napi_writable | napi_configurable)), + StaticMethod<&ProWrapper::proProofRequestBody>( + "proProofRequestBody", + static_cast( + napi_writable | napi_configurable)), }); } @@ -89,6 +94,70 @@ class ProWrapper : public Napi::ObjectWrap { return obj; }); }; + + static Napi::Value proProofRequestBody(const Napi::CallbackInfo& info) { + return wrapResult(info, [&] { + // we expect arguments that match: + // first: { + // "version": string, + // "master_privkey": Uint8Array, + // "rotating_privkey": Uint8Array, + // "unix_ts": number, + // } + + assertInfoLength(info, 1); + assertIsObject(info[0]); + auto env = info.Env(); + + auto first = info[0].As(); + + if (first.IsEmpty()) + throw std::invalid_argument("proProofRequestBody first received empty"); + + assertIsNumber(first.Get("version"), "proProofRequestBody.version"); + assertIsNumber(first.Get("unix_ts"), "proProofRequestBody.unix_ts"); + auto version = first.Get("version").As(); + auto unix_ts = toCppSysMs(first.Get("unix_ts"), "proProofRequestBody.unix_ts"); + + assertIsUInt8Array(first.Get("master_privkey"), "proProofRequestBody.master_privkey"); + assertIsUInt8Array( + first.Get("rotating_privkey"), "proProofRequestBody.rotating_privkey"); + + // stack allocate to the buffer view so the ref doesnt get deleted + auto master_privkey_napi = first.Get("master_privkey"); + auto rotating_privkey_napi = first.Get("rotating_privkey"); + auto master_privkey = + toCppBufferView(master_privkey_napi, "proProofRequestBody.master_privkey"); + auto rotating_privkey = + toCppBuffer(rotating_privkey_napi, "proProofRequestBody.rotating_privkey"); + + assert(master_privkey.size() == 64); + assert(rotating_privkey.size() == 64); + + pro_backend::GetProProofRequest proProofRequest{ + .version = static_cast(version.Int32Value()), + .unix_ts = unix_ts, + }; + + auto [master_sig, rotating_sig] = proProofRequest.build_sigs( + proProofRequest.version, + master_privkey, + rotating_privkey, + proProofRequest.unix_ts); + + assert(master_sig.size() == 64); + assert(rotating_sig.size() == 64); + + proProofRequest.master_sig = master_sig; + proProofRequest.rotating_sig = rotating_sig; + memcpy(proProofRequest.master_pkey.data(), master_privkey.data(), 32); + memcpy(proProofRequest.rotating_pkey.data(), rotating_privkey.data(), 32); + + auto json = proProofRequest.to_json(); + auto json_str = Napi::String::New(env, json); + return json_str; + }); + }; }; }; // namespace session::nodeapi diff --git a/include/utilities.hpp b/include/utilities.hpp index 886935b..e98085f 100644 --- a/include/utilities.hpp +++ b/include/utilities.hpp @@ -60,6 +60,7 @@ auto getStringArgs(const Napi::CallbackInfo& info) { } std::string toCppString(Napi::Value x, const std::string& identifier); +std::span toCppBufferView(Napi::Value x, const std::string& identifier); std::vector toCppBuffer(Napi::Value x, const std::string& identifier); int64_t toCppInteger(Napi::Value x, const std::string& identifier, bool allowUndefined = false); From 0ac81653c5be1ac038342d6e4753ad525eae3f4e Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Mon, 27 Oct 2025 15:13:54 +1100 Subject: [PATCH 2/5] fix: use buffer view for rotating key --- include/pro/pro.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pro/pro.hpp b/include/pro/pro.hpp index 5ab4e8e..d7be9d7 100644 --- a/include/pro/pro.hpp +++ b/include/pro/pro.hpp @@ -129,7 +129,7 @@ class ProWrapper : public Napi::ObjectWrap { auto master_privkey = toCppBufferView(master_privkey_napi, "proProofRequestBody.master_privkey"); auto rotating_privkey = - toCppBuffer(rotating_privkey_napi, "proProofRequestBody.rotating_privkey"); + toCppBufferView(rotating_privkey_napi, "proProofRequestBody.rotating_privkey"); assert(master_privkey.size() == 64); assert(rotating_privkey.size() == 64); From 1ac97e8d190817e823fafbce522bb0596568e8f7 Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Wed, 29 Oct 2025 14:13:12 +1100 Subject: [PATCH 3/5] fix: use new build_to_json method to construct proof request wrapper --- include/pro/pro.hpp | 54 ++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/include/pro/pro.hpp b/include/pro/pro.hpp index d7be9d7..b2a6cf4 100644 --- a/include/pro/pro.hpp +++ b/include/pro/pro.hpp @@ -99,10 +99,10 @@ class ProWrapper : public Napi::ObjectWrap { return wrapResult(info, [&] { // we expect arguments that match: // first: { - // "version": string, - // "master_privkey": Uint8Array, - // "rotating_privkey": Uint8Array, - // "unix_ts": number, + // "requestVersion": string, + // "masterPrivkey": Uint8Array, + // "rotatingPrivkey": Uint8Array, + // "unixTsMs": number, // } assertInfoLength(info, 1); @@ -114,46 +114,30 @@ class ProWrapper : public Napi::ObjectWrap { if (first.IsEmpty()) throw std::invalid_argument("proProofRequestBody first received empty"); - assertIsNumber(first.Get("version"), "proProofRequestBody.version"); - assertIsNumber(first.Get("unix_ts"), "proProofRequestBody.unix_ts"); - auto version = first.Get("version").As(); - auto unix_ts = toCppSysMs(first.Get("unix_ts"), "proProofRequestBody.unix_ts"); + assertIsNumber(first.Get("requestVersion"), "proProofRequestBody.requestVersion"); + assertIsNumber(first.Get("unixTsMs"), "proProofRequestBody.unixTsMs"); + auto requestVersion = first.Get("requestVersion").As(); + auto unix_ts_ms = toCppSysMs(first.Get("unixTsMs"), "proProofRequestBody.unixTsMs"); - assertIsUInt8Array(first.Get("master_privkey"), "proProofRequestBody.master_privkey"); - assertIsUInt8Array( - first.Get("rotating_privkey"), "proProofRequestBody.rotating_privkey"); + assertIsUInt8Array(first.Get("masterPrivkey"), "proProofRequestBody.masterPrivkey"); + assertIsUInt8Array(first.Get("rotatingPrivkey"), "proProofRequestBody.rotatingPrivkey"); - // stack allocate to the buffer view so the ref doesnt get deleted - auto master_privkey_napi = first.Get("master_privkey"); - auto rotating_privkey_napi = first.Get("rotating_privkey"); + auto master_privkey_js = first.Get("masterPrivkey"); + auto rotating_privkey_js = first.Get("rotatingPrivkey"); auto master_privkey = - toCppBufferView(master_privkey_napi, "proProofRequestBody.master_privkey"); + toCppBuffer(master_privkey_js, "proProofRequestBody.masterPrivkey"); auto rotating_privkey = - toCppBufferView(rotating_privkey_napi, "proProofRequestBody.rotating_privkey"); + toCppBuffer(rotating_privkey_js, "proProofRequestBody.rotatingPrivkey"); - assert(master_privkey.size() == 64); - assert(rotating_privkey.size() == 64); + assert_length(master_privkey, 64, "master_privkey"); + assert_length(rotating_privkey, 64, "rotating_prevkey"); - pro_backend::GetProProofRequest proProofRequest{ - .version = static_cast(version.Int32Value()), - .unix_ts = unix_ts, - }; - - auto [master_sig, rotating_sig] = proProofRequest.build_sigs( - proProofRequest.version, + auto json = pro_backend::GetProProofRequest::build_to_json( + static_cast(requestVersion.Int32Value()), master_privkey, rotating_privkey, - proProofRequest.unix_ts); - - assert(master_sig.size() == 64); - assert(rotating_sig.size() == 64); - - proProofRequest.master_sig = master_sig; - proProofRequest.rotating_sig = rotating_sig; - memcpy(proProofRequest.master_pkey.data(), master_privkey.data(), 32); - memcpy(proProofRequest.rotating_pkey.data(), rotating_privkey.data(), 32); + unix_ts_ms); - auto json = proProofRequest.to_json(); auto json_str = Napi::String::New(env, json); return json_str; }); From ce4429a3bcdd1f33e5ff9d00bef9c65c4b8bb0de Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Wed, 29 Oct 2025 14:24:31 +1100 Subject: [PATCH 4/5] chore: add types for pro proof request --- types/pro/pro.d.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/types/pro/pro.d.ts b/types/pro/pro.d.ts index b9d7a6d..806c15c 100644 --- a/types/pro/pro.d.ts +++ b/types/pro/pro.d.ts @@ -74,9 +74,16 @@ declare module 'libsession_util_nodejs' { */ proFeatures: ProFeatures; }) => WithProFeatures & { success: boolean; error: string | null; codepointCount: number }; + proProofRequestBody: (args: { + requestVersion: string, + masterPrivkey: Uint8Array, + rotatingPrivkey: Uint8Array, + unixTsMs: number, + } + ) => string; }; - export type ProActionsCalls = MakeWrapperActionCalls; + export type ProActionsCalls = MakeWrapperActionCalls; /** From 195eda7f7ea2849db877f433a212b2e53394365f Mon Sep 17 00:00:00 2001 From: Ryan Miller Date: Wed, 29 Oct 2025 14:25:44 +1100 Subject: [PATCH 5/5] chore: return early with pro proof wrapper --- include/pro/pro.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/pro/pro.hpp b/include/pro/pro.hpp index b2a6cf4..4f7a62f 100644 --- a/include/pro/pro.hpp +++ b/include/pro/pro.hpp @@ -138,8 +138,7 @@ class ProWrapper : public Napi::ObjectWrap { rotating_privkey, unix_ts_ms); - auto json_str = Napi::String::New(env, json); - return json_str; + return json; }); }; };