diff --git a/flake.nix b/flake.nix index 2913bd9..f0c398f 100644 --- a/flake.nix +++ b/flake.nix @@ -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/lssa?rev=a999563a2d27325ecada318746f1a0dc083d187f"; # branch with the latest functionality + logos-execution-zone.url = "github:logos-blockchain/lssa?rev=76696a5d084236a234abc62c2b8c0d04acbf5e20"; # branch with the latest functionality }; outputs = inputs@{ logos-module-builder, ... }: diff --git a/src/i_logos_execution_zone_wallet_module.h b/src/i_logos_execution_zone_wallet_module.h index 4037277..4a05b77 100644 --- a/src/i_logos_execution_zone_wallet_module.h +++ b/src/i_logos_execution_zone_wallet_module.h @@ -90,6 +90,11 @@ public: virtual QList serialization_helper(const QList& input_data) = 0; + virtual QList authenticated_transfer_elf() = 0; + virtual QList token_elf() = 0; + virtual QList amm_elf() = 0; + virtual QList ata_elf() = 0; + virtual QString send_generic_public_transaction( const QList& account_ids, const QList& signing_requirements, @@ -103,6 +108,9 @@ public: const QList& program_elf, const QList>& program_dependencies, ) = 0; + virtual QString send_program_deployment_transaction( + const QList& program_elf, + ) = 0; // Wallet Lifecycle virtual int create_new( diff --git a/src/logos_execution_zone_wallet_module.cpp b/src/logos_execution_zone_wallet_module.cpp index 09e763a..26129fc 100644 --- a/src/logos_execution_zone_wallet_module.cpp +++ b/src/logos_execution_zone_wallet_module.cpp @@ -756,8 +756,61 @@ QList LogosExecutionZoneWalletModule::serialization_helper(const QList return result; } +QList LogosExecutionZoneWalletModule::token_elf() { + FfiProgram ffi_program {}; + WalletFfiError error = wallet_ffi_token_elf(&ffi_program); + if (error != SUCCESS) { + qWarning() << "authenticated_transfer_elf: wallet FFI error " << error; + return QList {}; + } + + QList result(ffi_program.elf_data, ffi_program.elf_data + raw_words.elf_size); + wallet_ffi_free_ffi_program(&ffi_program); + return result; +} + +QList LogosExecutionZoneWalletModule::amm_elf() { + FfiProgram ffi_program {}; + WalletFfiError error = wallet_ffi_amm_elf(&ffi_program); + if (error != SUCCESS) { + qWarning() << "authenticated_transfer_elf: wallet FFI error " << error; + return QList {}; + } + + QList result(ffi_program.elf_data, ffi_program.elf_data + raw_words.elf_size); + wallet_ffi_free_ffi_program(&ffi_program); + return result; +} + +QList LogosExecutionZoneWalletModule::ata_elf() { + FfiProgram ffi_program {}; + WalletFfiError error = wallet_ffi_ata_elf(&ffi_program); + if (error != SUCCESS) { + qWarning() << "authenticated_transfer_elf: wallet FFI error " << error; + return QList {}; + } + + QList result(ffi_program.elf_data, ffi_program.elf_data + raw_words.elf_size); + wallet_ffi_free_ffi_program(&ffi_program); + return result; +} + +QList LogosExecutionZoneWalletModule::authenticated_transfer_elf() { + FfiProgram ffi_program {}; + WalletFfiError error = wallet_ffi_transfer_elf(&ffi_program); + if (error != SUCCESS) { + qWarning() << "authenticated_transfer_elf: wallet FFI error " << error; + return QList {}; + } + + QList result(ffi_program.elf_data, ffi_program.elf_data + raw_words.elf_size); + wallet_ffi_free_ffi_program(&ffi_program); + return result; +} + + QString send_generic_public_transaction( - const QList& account_ids, + const QList& account_ids, const QList& signing_requirements, const QList& instruction, const QList& program_elf, @@ -768,7 +821,14 @@ QString send_generic_public_transaction( for (int i = 0; i < account_ids.size(); ++i) { FfiAccountIdentity acc_identity{}; - WalletFfiError error = wallet_ffi_resolve_public_account(account_ids[i], signing_requirements[i], &acc_identity); + + FfiBytes32 id{}; + if (!hexToBytes32(account_ids[i], &id)) { + qWarning() << "wallet_ffi_resolve_public_account: invalid account_id_hex"; + return transferResultToJson(nullptr, QStringLiteral("wallet_ffi_resolve_public_account: invalid account_id_hex")); + } + + WalletFfiError error = wallet_ffi_resolve_public_account(id, signing_requirements[i], &acc_identity); if (error != SUCCESS) { qWarning() << "wallet_ffi_resolve_public_account failed for index" << i << " : wallet FFI error" << error; return transferResultToJson(nullptr, QStringLiteral("wallet_ffi_resolve_public_account: wallet FFI error ") + QString::number(error)); @@ -843,6 +903,123 @@ QString send_generic_public_transaction( return resultJson; } +QString send_generic_private_transaction( + const QList& account_ids, + const QList& instruction, + const QList& program_elf, + const QList>& program_dependencies, +) { + QList identities_resolved; + identities_resolved.reserve(account_ids.size()); + + for (int i = 0; i < account_ids.size(); ++i) { + FfiAccountIdentity acc_identity{}; + + FfiBytes32 id{}; + if (!hexToBytes32(account_ids[i], &id)) { + qWarning() << "wallet_ffi_resolve_private_account: invalid account_id_hex"; + return transferResultToJson(nullptr, QStringLiteral("wallet_ffi_resolve_private_account: invalid account_id_hex")); + } + + WalletFfiError error = wallet_ffi_resolve_private_account(walletHandle, account_ids[i], &acc_identity); + if (error != SUCCESS) { + qWarning() << "wallet_ffi_resolve_private_account failed for index" << i << " : wallet FFI error" << error; + return transferResultToJson(nullptr, QStringLiteral("wallet_ffi_resolve_private_account: wallet FFI error ") + QString::number(error)); + } + resolved.append(acc_identity); + } + + const FfiAccountIdentity *account_identities = resolved.constData(); + uintptr_t account_identities_size = static_cast(resolved.size()); + + const uint8_t *input_instruction_data = instruction.constData(); + uintptr_t input_instruction_data_size = static_cast(instruction.size()); + FfiInstructionWords raw_words = wallet_ffi_serialization_helper(input_instruction_data, input_instruction_data_size); + if (raw_words.error != SUCCESS) { + qWarning() << "wallet_ffi_resolve_private_account failed at instruction serialization: wallet FFI error" << raw_words.error; + return transferResultToJson(nullptr, QStringLiteral("wallet_ffi_resolve_private_account: wallet FFI error ") + QString::number(error)); + } + + FfiProgram main_program {}; + + const uint8_t *program_elf_data = program_elf.constData(); + uintptr_t program_elf_size = static_cast(program_elf.size()); + + main_program.elf_data = program_elf_data; + main_program.elf_size = program_elf_size; + + QList ffi_program_dependencies; + + for (int i = 0; i < program_dependencies.size(); ++i) { + FfiProgram program{}; + + const uint8_t *program_elf_data = program_dependencies[i].constData(); + uintptr_t program_elf_size = static_cast(program_dependencies[i].size()); + + program.elf_data = program_elf_data; + program.elf_size = program_elf_size; + + ffi_program_dependencies.append(program); + } + + const FfiProgram *dependencies_data = ffi_program_dependencies.constData(); + uintptr_t dependencies_size = static_cast(ffi_program_dependencies.size()); + + FfiProgramWithDependencies program_with_dependencies {}; + + program_with_dependencies.program = main_program; + program_with_dependencies.deps = dependencies_data; + program_with_dependencies.deps_size = dependencies_size; + + FfiTransactionResult result {}; + + const WalletFfiError error = wallet_ffi_send_generic_private_transaction( + walletHandle, + account_identities, + account_identities_size, + raw_words.instruction_words, + raw_words.instruction_words_size, + &program_with_dependencies, + result, + ); + + for (FfiAccountIdentity& acc_identity : identities_resolved) { + wallet_ffi_free_account_identity(&acc_identity); + } + + if (error != SUCCESS) { + qWarning() << "send_generic_private_transaction: wallet FFI error" << error; + return transferResultToJson(nullptr, QStringLiteral("send_generic_private_transaction: wallet FFI error ") + QString::number(error)); + } + QString resultJson = genericTransactionResultToJson(&result, QString()); + wallet_ffi_free_transaction_result(&result); + return resultJson; +} + +QString send_program_deployment_transaction( + const QList& program_elf, +) { + FfiTransactionResult result {}; + + const uint8_t *program_elf_data = program_elf.constData(); + uintptr_t program_elf_size = static_cast(program_elf.size()); + + const WalletFfiError error = wallet_ffi_program_deployment( + walletHandle, + elf_data, + elf_size, + result, + ); + + if (error != SUCCESS) { + qWarning() << "send_program_deployment_transaction: wallet FFI error" << error; + return transferResultToJson(nullptr, QStringLiteral("send_program_deployment_transaction: wallet FFI error ") + QString::number(error)); + } + QString resultJson = genericTransactionResultToJson(&result, QString()); + wallet_ffi_free_transaction_result(&result); + return resultJson; +} + // === Wallet Lifecycle === int LogosExecutionZoneWalletModule::create_new( diff --git a/src/logos_execution_zone_wallet_module.h b/src/logos_execution_zone_wallet_module.h index 976e9e0..d999e9d 100644 --- a/src/logos_execution_zone_wallet_module.h +++ b/src/logos_execution_zone_wallet_module.h @@ -118,19 +118,27 @@ public: Q_INVOKABLE QList serialization_helper(const QList& input_data) override; + Q_INVOKABLE QList authenticated_transfer_elf() override; + Q_INVOKABLE QList token_elf() override; + Q_INVOKABLE QList amm_elf() override; + Q_INVOKABLE QList ata_elf() override; + Q_INVOKABLE QString send_generic_public_transaction( - const QList& account_ids, + const QList& account_ids, const QList& signing_requirements, const QList& instruction, const QList& program_elf, const QList>& program_dependencies, ) override; Q_INVOKABLE QString send_generic_private_transaction( - const QList& account_ids, + const QList& account_ids, const QList& instruction, const QList& program_elf, const QList>& program_dependencies, ) override; + Q_INVOKABLE QString send_program_deployment_transaction( + const QList& program_elf, + ) override; // Wallet Lifecycle Q_INVOKABLE int create_new(const QString& config_path, const QString& storage_path, const QString& password) override;