feat: labels functionality

This commit is contained in:
Pravdyvy 2026-07-03 16:57:02 +03:00
parent 92dd9e25bc
commit 24e09df2af
9 changed files with 13085 additions and 671 deletions

View File

@ -220,7 +220,7 @@ sections:
run: "./logos/bin/logoscore call lez_core version"
code_block: "logoscore call lez_core version"
expect_contains:
- '"result":"0.2.0"'
- '"result":"0.3.0"'
- title: "Encode an account id to base58"
text: |

13528
flake.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
inputs = {
logos-module-builder.url = "github:logos-co/logos-module-builder";
nix-bundle-lgx.url = "github:logos-co/nix-bundle-lgx";
logos-execution-zone.url = "github:logos-blockchain/logos-execution-zone?rev=a58fbce2ff48c58b7bb5001b1a27e64b9596ee3a"; # v0.2.0
logos-execution-zone.url = "github:logos-blockchain/logos-execution-zone?rev=571f35b3849c889f893109fd2b9dad040f0a3b57"; # latest `dev`
};
outputs = inputs@{ logos-module-builder, ... }:

View File

@ -1,7 +1,7 @@
{
"name": "lez_core",
"display_name": "LEZ Core Module",
"version": "0.2.0",
"version": "0.3.0",
"description": "Logos Execution Zone Core Module for Logos Core",
"author": "Logos Blockchain Team",
"type": "core",

View File

@ -277,7 +277,7 @@ std::string LEZCoreModule::name() const {
}
std::string LEZCoreModule::version() const {
return "0.2.0";
return "0.3.0";
}
// === Account Management ===
@ -1212,4 +1212,101 @@ std::string LEZCoreModule::get_sequencer_addr() {
std::string value(addr);
wallet_ffi_free_string(addr);
return value;
}
// === Labels ===
bool LEZCoreModule::check_label_available(const std::string& label) {
const char* label_c = label.c_str();
LabelAvailability label_check = wallet_ffi_check_label_available(
walletHandle,
label_c
);
if (label_check.error != SUCCESS) {
fprintf(stderr, "check_label_available: wallet FFI error %d\n", label_check.error);
return false;
}
return label_check.is_available;
}
int64_t LEZCoreModule::add_label(const std::string& label, const std::string& account_id_hex, bool is_private) {
const char* label_c = label.c_str();
FfiAccountIdWithPrivacy acc_id_with_privacy;
FfiBytes32 id{};
if (!hexToBytes32(account_id_hex, &id)) {
fprintf(stderr, "wallet_ffi_add_label: invalid account_id_hex");
return WalletFfiError::INVALID_ACCOUNT_ID;
}
acc_id_with_privacy.account_id = id;
acc_id_with_privacy.is_private = is_private;
WalletFfiError error = wallet_ffi_add_label(walletHandle, label_c, acc_id_with_privacy);
if (error != SUCCESS) {
fprintf(stderr, "wallet_ffi_add_label failed : wallet FFI error %d\n", error);
}
return SUCCESS;
}
std::string LEZCoreModule::resolve_label(const std::string& label) {
const char* label_c = label.c_str();
AccountIdResolvedFromLabel acc_id_res = wallet_ffi_resolve_label(
walletHandle,
label_c
);
if (acc_id_res.error != SUCCESS) {
fprintf(stderr, "wallet_ffi_resolve_label failed : wallet FFI error %d\n", acc_id_res.error);
return {};
}
std::string hexed_account_id = bytes32ToHex(acc_id_res.account_id.account_id);
if (acc_id_res.account_id.is_private) {
return "Private/" + hexed_account_id;
} else {
return "Public/" + hexed_account_id;
}
}
std::vector<std::string> LEZCoreModule::get_all_labels_for_account(const std::string& account_id_hex, bool is_private) {
FfiAccountIdWithPrivacy acc_id_with_privacy;
FfiBytes32 id{};
if (!hexToBytes32(account_id_hex, &id)) {
fprintf(stderr, "get_all_labels_for_account: invalid account_id_hex");
return {};
}
acc_id_with_privacy.account_id = id;
acc_id_with_privacy.is_private = is_private;
LabelList label_list = wallet_ffi_get_all_labels_for_account(walletHandle, acc_id_with_privacy);
if (label_list.error != SUCCESS) {
fprintf(stderr, "wallet_ffi_get_all_labels_for_account failed : wallet FFI error %d\n", label_list.error);
return {};
}
std::vector<std::string> result;
result.reserve(label_list.labels_size);
for (uintptr_t i = 0; i < label_list.labels_size; ++i) {
result.emplace_back(label_list.labels_data[i]);
}
WalletFfiError err = wallet_ffi_free_label_list(&label_list);
if (err != SUCCESS) {
fprintf(stderr, "wallet_ffi_free_label_list failed : wallet FFI error %d\n", err);
}
return result;
}

View File

@ -92,6 +92,12 @@ public:
// === Configuration ===
std::string get_sequencer_addr();
// === Labels ===
bool check_label_available(const std::string& label);
int64_t add_label(const std::string& label, const std::string& account_id_hex, bool is_private);
std::string resolve_label(const std::string& label);
std::vector<std::string> get_all_labels_for_account(const std::string& account_id_hex, bool is_private);
private:
WalletHandle* walletHandle = nullptr;
};

View File

@ -533,4 +533,80 @@ char* wallet_ffi_get_sequencer_addr(WalletHandle*) {
return strdup((addr && *addr) ? addr : "127.0.0.1:3000");
}
// === Labels ===
LabelAvailability wallet_ffi_check_label_available(WalletHandle *handle, const char *label) {
LOGOS_CMOCK_RECORD("wallet_ffi_check_label_available");
const int err = LOGOS_CMOCK_RETURN(int, "wallet_ffi_check_label_available");
LabelAvailability label_availablility;
if (err == 0) {
label_availablility.is_available = true;
} else {
label_availablility.is_available = false;
}
label_availablility.error = static_cast<WalletFfiError>(err);
return label_availablility;
}
WalletFfiError wallet_ffi_add_label(WalletHandle *handle, const char *label, FfiAccountIdWithPrivacy account_id_with_privacy) {
LOGOS_CMOCK_RECORD("wallet_ffi_add_label");
const int err = LOGOS_CMOCK_RETURN(int, "wallet_ffi_add_label");
return static_cast<WalletFfiError>(err);
}
AccountIdResolvedFromLabel wallet_ffi_resolve_label(WalletHandle *handle, const char *label) {
LOGOS_CMOCK_RECORD("wallet_ffi_resolve_label");
const int err = LOGOS_CMOCK_RETURN(int, "wallet_ffi_resolve_label");
FfiAccountIdWithPrivacy acc_id_with_privacy;
AccountIdResolvedFromLabel acc_id_res;
if (err == 0) {
const uint8_t value = static_cast<uint8_t>(LOGOS_CMOCK_RETURN(int, "get_acc_id_associated_with_label"));
for (int i = 0; i < 32; ++i) {
acc_id_with_privacy.account_id.data[i] = value;
}
}
acc_id_with_privacy.is_private = false;
acc_id_res.account_id = acc_id_with_privacy;
acc_id_res.error = static_cast<WalletFfiError>(err);
return acc_id_res;
}
LabelList wallet_ffi_get_all_labels_for_account(WalletHandle *handle, FfiAccountIdWithPrivacy account_id_with_privacy) {
LOGOS_CMOCK_RECORD("wallet_ffi_get_all_labels_for_account");
const int err = LOGOS_CMOCK_RETURN(int, "wallet_ffi_get_all_labels_for_account");
LabelList label_list;
if (err == 0) {
static std::vector<const char*> labelsData = { "Label1", "Label2" };
label_list.labels_data = labelsData.data();
label_list.labels_size = labelsData.size();
} else {
label_list.labels_data = nullptr;
label_list.labels_size = 0;
}
label_list.error = static_cast<WalletFfiError>(err);
return label_list;
}
WalletFfiError wallet_ffi_free_label_list(LabelList *label_list) {
LOGOS_CMOCK_RECORD("wallet_ffi_free_label_list");
if (label_list && label_list->labels_data) {
free(const_cast<char**>(label_list->labels_data));
label_list->labels_data = nullptr;
label_list->labels_size = 0;
}
}
} // extern "C"

View File

@ -21,6 +21,7 @@ typedef enum WalletFfiError {
INTERNAL_ERROR = 1,
INVALID_INPUT = 2,
NOT_FOUND = 3,
INVALID_ACCOUNT_ID = 4
} WalletFfiError;
// Opaque wallet handle.
@ -167,6 +168,27 @@ typedef struct FfiCreateWalletOutput {
char *mnemonic;
} FfiCreateWalletOutput;
typedef struct LabelAvailability {
bool is_available;
enum WalletFfiError error;
} LabelAvailability;
typedef struct FfiAccountIdWithPrivacy {
struct FfiBytes32 account_id;
bool is_private;
} FfiAccountIdWithPrivacy;
typedef struct AccountIdResolvedFromLabel {
struct FfiAccountIdWithPrivacy account_id;
enum WalletFfiError error;
} AccountIdResolvedFromLabel;
typedef struct LabelList {
const char **labels_data;
uintptr_t labels_size;
enum WalletFfiError error;
} LabelList;
// === Lifecycle ===
FfiCreateWalletOutput wallet_ffi_create_new(const char* config_path, const char* storage_path, const char* password);
@ -317,6 +339,23 @@ WalletFfiError wallet_ffi_vault_claim_private(
char* wallet_ffi_get_sequencer_addr(WalletHandle* handle);
// === Labels ===
LabelAvailability wallet_ffi_check_label_available(WalletHandle *handle,
const char *label);
WalletFfiError wallet_ffi_add_label(WalletHandle *handle,
const char *label,
FfiAccountIdWithPrivacy account_id_with_privacy);
AccountIdResolvedFromLabel wallet_ffi_resolve_label(WalletHandle *handle,
const char *label);
LabelList wallet_ffi_get_all_labels_for_account(WalletHandle *handle,
FfiAccountIdWithPrivacy account_id_with_privacy);
WalletFfiError wallet_ffi_free_label_list(LabelList *label_list);
#ifdef __cplusplus
}
#endif

View File

@ -29,7 +29,7 @@ static nlohmann::json parseObject(const std::string& json) {
LOGOS_TEST(name_and_version) {
LEZCoreModule module;
LOGOS_ASSERT_EQ(module.name(), std::string("lez_core"));
LOGOS_ASSERT_EQ(module.version(), std::string("0.2.0"));
LOGOS_ASSERT_EQ(module.version(), std::string("0.3.0"));
}
// ============================================================================