From c90d1124d8678339b394b2041875f125608a05a5 Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini Date: Mon, 14 Mar 2022 01:00:51 -0300 Subject: [PATCH 1/4] git ignore node_modules and package_lock.json --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 07c0c97a..fb17c023 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ **/*.rs.bk **/__pycache__ bindings/wallet-uniffi/codegen +**/*node_modules +**/*package-lock.json From ca6b16dced6b6eae77b63b22dac4d3c5b5ccef25 Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini Date: Mon, 14 Mar 2022 01:01:26 -0300 Subject: [PATCH 2/4] cleanup plugin api from legacy conversion These functions are not really used anymore, and while the cost of maintaining them is not that high, it's still better to have less things to care about when updating, or when new users aks questions. This commit focuses mostly on the bindings, mostly because that's where most of the 'complexity' (duplication) is found, the underlying code is not really that problematic, but it may be good to remove it too. In any case, code can be retrieved from the history if necessary. - walletRestore - walletRetrieveFunds - walletConvert - conversionTransactionsSize - conversionTransactionsGet - conversionGetIgnored - walletPendingTransactions - pendingTransactionsSize - pendingTransactionsGet --- bindings/wallet-c/src/lib.rs | 257 +----------- bindings/wallet-c/wallet.h | 202 +--------- .../src/android/WalletPlugin.kt | 172 +------- .../wallet-cordova/src/ios/WalletPlugin.h | 8 - .../wallet-cordova/src/ios/WalletPlugin.m | 163 -------- bindings/wallet-cordova/tests/src/main.js | 190 ++------- bindings/wallet-cordova/www/wallet.js | 122 ------ bindings/wallet-core/src/c/mod.rs | 371 +----------------- bindings/wallet-core/src/lib.rs | 2 - bindings/wallet-core/src/wallet.rs | 177 +-------- bindings/wallet-js/src/lib.rs | 93 ----- bindings/wallet-uniffi/src/lib.rs | 57 --- bindings/wallet-uniffi/src/lib.udl | 14 - 13 files changed, 53 insertions(+), 1775 deletions(-) diff --git a/bindings/wallet-c/src/lib.rs b/bindings/wallet-c/src/lib.rs index 8eb3803d..8e387507 100644 --- a/bindings/wallet-c/src/lib.rs +++ b/bindings/wallet-c/src/lib.rs @@ -9,15 +9,12 @@ use wallet_core::c::{ fragment::{fragment_delete, fragment_from_raw, fragment_id}, symmetric_cipher_decrypt, time::BlockDate, - vote, wallet_convert, wallet_convert_ignored, wallet_convert_transactions_get, - wallet_convert_transactions_size, wallet_delete_conversion, wallet_delete_error, - wallet_delete_proposal, wallet_delete_settings, wallet_delete_wallet, wallet_id, - wallet_import_keys, wallet_recover, wallet_retrieve_funds, wallet_set_state, - wallet_spending_counter, wallet_total_value, wallet_vote_cast, + vote, wallet_delete_error, wallet_delete_proposal, wallet_delete_settings, + wallet_delete_wallet, wallet_id, wallet_import_keys, wallet_set_state, wallet_spending_counter, + wallet_total_value, wallet_vote_cast, }; use wallet_core::{ - Conversion as ConversionRust, Error as ErrorRust, Fragment as FragmentRust, - Proposal as ProposalRust, Wallet as WalletRust, + Error as ErrorRust, Fragment as FragmentRust, Proposal as ProposalRust, Wallet as WalletRust, }; #[repr(C)] @@ -25,8 +22,6 @@ pub struct Wallet {} #[repr(C)] pub struct Settings {} #[repr(C)] -pub struct Conversion {} -#[repr(C)] pub struct Proposal {} #[repr(C)] pub struct Fragment; @@ -38,68 +33,11 @@ pub struct EncryptingVoteKey {} pub type WalletPtr = *mut Wallet; pub type SettingsPtr = *mut Settings; -pub type ConversionPtr = *mut Conversion; pub type ProposalPtr = *mut Proposal; pub type FragmentPtr = *mut Fragment; pub type ErrorPtr = *mut Error; pub type EncryptingVoteKeyPtr = *mut EncryptingVoteKey; -/// retrieve a wallet from the given mnemonics, password and protocol magic -/// -/// this function will work for all yoroi, daedalus and other wallets -/// as it will try every kind of wallet anyway -/// -/// You can also use this function to recover a wallet even after you have -/// transferred all the funds to the new format (see the _convert_ function) -/// -/// The recovered wallet will be returned in `wallet_out`. -/// -/// # parameters -/// -/// * mnemonics: a null terminated utf8 string (already normalized NFKD) in english; -/// * password: pointer to the password (in bytes, can be UTF8 string or a bytes of anything); -/// this value is optional and passing a null pointer will result in no password; -/// * password_length: the length of the password; -/// * wallet_out: a pointer to a pointer. The recovered wallet will be allocated on this pointer; -/// -/// # errors -/// -/// The function may fail if: -/// -/// * the mnemonics are not valid (invalid length or checksum); -/// * the `wallet_out` is null pointer -/// -/// On error the function returns a `ErrorPtr`. On success `NULL` is returned. -/// The `ErrorPtr` can then be observed to gathered details of the error. -/// Don't forget to call `iohk_jormungandr_wallet_delete_error` to free -/// the `ErrorPtr` from memory and avoid memory leaks. -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub unsafe extern "C" fn iohk_jormungandr_wallet_recover( - mnemonics: *const c_char, - password: *const u8, - password_length: usize, - wallet_out: *mut WalletPtr, -) -> ErrorPtr { - let mnemonics = CStr::from_ptr(mnemonics); - - let mnemonics = mnemonics.to_string_lossy(); - let r = wallet_recover( - &mnemonics, - password, - password_length, - wallet_out as *mut *mut WalletRust, - ); - - r.into_c_api() as ErrorPtr -} - /// recover a wallet from an account and a list of utxo keys /// /// You can also use this function to recover a wallet even after you have @@ -182,180 +120,6 @@ pub unsafe extern "C" fn iohk_jormungandr_wallet_id( wallet_id(wallet as *mut WalletRust, id_out).into_c_api() as ErrorPtr } -/// retrieve funds from daedalus or yoroi wallet in the given block0 (or -/// any other blocks). -/// -/// Execute this function then you can check who much funds you have -/// retrieved from the given block. -/// -/// this function may take sometimes so it is better to only call this -/// function if needed. -/// -/// # Parameters -/// -/// * wallet: the recovered wallet (see recover function); -/// * block0: the pointer to the bytes of the block0; -/// * block0_length: the length of the block0 byte string; -/// * settings_out: the settings that will be parsed from the given -/// block0; -/// -/// # Errors -/// -/// * this function may fail if the wallet pointer is null; -/// * the block is not valid (cannot be decoded) -/// -/// On error the function returns a `ErrorPtr`. On success `NULL` is returned. -/// The `ErrorPtr` can then be observed to gathered details of the error. -/// Don't forget to call `iohk_jormungandr_wallet_delete_error` to free -/// the `ErrorPtr` from memory and avoid memory leaks. -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub unsafe extern "C" fn iohk_jormungandr_wallet_retrieve_funds( - wallet: WalletPtr, - block0: *const u8, - block0_length: usize, - settings_out: *mut SettingsPtr, -) -> ErrorPtr { - let r = wallet_retrieve_funds( - wallet as *mut WalletRust, - block0, - block0_length, - settings_out as *mut *mut SettingsRust, - ); - - r.into_c_api() as ErrorPtr -} - -/// once funds have been retrieved with `iohk_jormungandr_wallet_retrieve_funds` -/// it is possible to convert all existing funds to the new wallet. -/// -/// The returned arrays are transactions to send to the network in order to do the -/// funds conversion. -/// -/// Don't forget to call `iohk_jormungandr_wallet_delete_conversion` to -/// properly free the memory -/// -/// # Errors -/// -/// On error the function returns a `ErrorPtr`. On success `NULL` is returned. -/// The `ErrorPtr` can then be observed to gathered details of the error. -/// Don't forget to call `iohk_jormungandr_wallet_delete_error` to free -/// the `ErrorPtr` from memory and avoid memory leaks. -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub unsafe extern "C" fn iohk_jormungandr_wallet_convert( - wallet: WalletPtr, - settings: SettingsPtr, - valid_until: BlockDate, - conversion_out: *mut ConversionPtr, -) -> ErrorPtr { - let r = wallet_convert( - wallet as *mut WalletRust, - settings as *mut SettingsRust, - valid_until, - conversion_out as *mut *mut ConversionRust, - ); - - r.into_c_api() as ErrorPtr -} - -/// get the number of transactions built to convert the retrieved wallet -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub unsafe extern "C" fn iohk_jormungandr_wallet_convert_transactions_size( - conversion: ConversionPtr, -) -> usize { - wallet_convert_transactions_size(conversion as *mut ConversionRust) -} - -/// retrieve the index-nth transactions in the conversions starting from 0 -/// and finishing at `size-1` where size is retrieved from -/// `iohk_jormungandr_wallet_convert_transactions_size`. -/// -/// the memory allocated returned is not owned and should not be kept -/// for longer than potential call to `iohk_jormungandr_wallet_delete_conversion` -/// -/// # Errors -/// -/// On error the function returns a `ErrorPtr`. On success `NULL` is returned. -/// The `ErrorPtr` can then be observed to gathered details of the error. -/// Don't forget to call `iohk_jormungandr_wallet_delete_error` to free -/// the `ErrorPtr` from memory and avoid memory leaks. -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub unsafe extern "C" fn iohk_jormungandr_wallet_convert_transactions_get( - conversion: ConversionPtr, - index: usize, - transaction_out: *mut *const u8, - transaction_size: *mut usize, -) -> ErrorPtr { - let r = wallet_convert_transactions_get( - conversion as *mut ConversionRust, - index, - transaction_out, - transaction_size, - ); - - r.into_c_api() as ErrorPtr -} - -/// get the total value ignored in the conversion -/// -/// value_out: will returns the total value lost into dust inputs -/// ignored_out: will returns the number of dust utxos -/// -/// these returned values are informational only and this show that -/// there are UTxOs entries that are unusable because of the way they -/// are populated with dusts. -/// -/// # Errors -/// -/// On error the function returns a `ErrorPtr`. On success `NULL` is returned. -/// The `ErrorPtr` can then be observed to gathered details of the error. -/// Don't forget to call `iohk_jormungandr_wallet_delete_error` to free -/// the `ErrorPtr` from memory and avoid memory leaks. -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub unsafe extern "C" fn iohk_jormungandr_wallet_convert_ignored( - conversion: ConversionPtr, - value_out: *mut u64, - ignored_out: *mut usize, -) -> ErrorPtr { - let r = wallet_convert_ignored(conversion as *mut ConversionRust, value_out, ignored_out); - - r.into_c_api() as ErrorPtr -} - /// get the current spending counter for the (only) account in this wallet /// /// @@ -789,19 +553,6 @@ pub extern "C" fn iohk_jormungandr_wallet_delete_wallet(wallet: WalletPtr) { wallet_delete_wallet(wallet as *mut WalletRust) } -/// delete the pointer -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -#[no_mangle] -pub extern "C" fn iohk_jormungandr_wallet_delete_conversion(conversion: ConversionPtr) { - wallet_delete_conversion(conversion as *mut ConversionRust) -} - /// delete the pointer /// /// # Safety diff --git a/bindings/wallet-c/wallet.h b/bindings/wallet-c/wallet.h index ea09fe76..3bbf0cd9 100644 --- a/bindings/wallet-c/wallet.h +++ b/bindings/wallet-c/wallet.h @@ -57,6 +57,8 @@ typedef struct Proposal typedef struct Proposal *ProposalPtr; +typedef struct Settings *SettingsPtr; + typedef struct Wallet { @@ -64,15 +66,6 @@ typedef struct Wallet typedef struct Wallet *WalletPtr; -typedef struct Settings *SettingsPtr; - -typedef struct Conversion -{ - -} Conversion; - -typedef struct Conversion *ConversionPtr; - typedef struct PerCertificateFee { uint64_t certificate_pool_registration; @@ -308,102 +301,6 @@ ErrorPtr iohk_jormungandr_vote_proposal_new_public(const uint8_t *vote_plan_id, uint8_t num_choices, ProposalPtr *proposal_out); -/** - * once funds have been retrieved with `iohk_jormungandr_wallet_retrieve_funds` - * it is possible to convert all existing funds to the new wallet. - * - * The returned arrays are transactions to send to the network in order to do the - * funds conversion. - * - * Don't forget to call `iohk_jormungandr_wallet_delete_conversion` to - * properly free the memory - * - * # Errors - * - * On error the function returns a `ErrorPtr`. On success `NULL` is returned. - * The `ErrorPtr` can then be observed to gathered details of the error. - * Don't forget to call `iohk_jormungandr_wallet_delete_error` to free - * the `ErrorPtr` from memory and avoid memory leaks. - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -ErrorPtr iohk_jormungandr_wallet_convert(WalletPtr wallet, - SettingsPtr settings, - struct BlockDate valid_until, - ConversionPtr *conversion_out); - -/** - * get the total value ignored in the conversion - * - * value_out: will returns the total value lost into dust inputs - * ignored_out: will returns the number of dust utxos - * - * these returned values are informational only and this show that - * there are UTxOs entries that are unusable because of the way they - * are populated with dusts. - * - * # Errors - * - * On error the function returns a `ErrorPtr`. On success `NULL` is returned. - * The `ErrorPtr` can then be observed to gathered details of the error. - * Don't forget to call `iohk_jormungandr_wallet_delete_error` to free - * the `ErrorPtr` from memory and avoid memory leaks. - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -ErrorPtr iohk_jormungandr_wallet_convert_ignored(ConversionPtr conversion, - uint64_t *value_out, - uintptr_t *ignored_out); - -/** - * retrieve the index-nth transactions in the conversions starting from 0 - * and finishing at `size-1` where size is retrieved from - * `iohk_jormungandr_wallet_convert_transactions_size`. - * - * the memory allocated returned is not owned and should not be kept - * for longer than potential call to `iohk_jormungandr_wallet_delete_conversion` - * - * # Errors - * - * On error the function returns a `ErrorPtr`. On success `NULL` is returned. - * The `ErrorPtr` can then be observed to gathered details of the error. - * Don't forget to call `iohk_jormungandr_wallet_delete_error` to free - * the `ErrorPtr` from memory and avoid memory leaks. - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -ErrorPtr iohk_jormungandr_wallet_convert_transactions_get(ConversionPtr conversion, - uintptr_t index, - const uint8_t **transaction_out, - uintptr_t *transaction_size); - -/** - * get the number of transactions built to convert the retrieved wallet - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -uintptr_t iohk_jormungandr_wallet_convert_transactions_size(ConversionPtr conversion); - /** * Delete a binary buffer that was returned by this library alongside with its * length. @@ -416,18 +313,6 @@ uintptr_t iohk_jormungandr_wallet_convert_transactions_size(ConversionPtr conver */ void iohk_jormungandr_wallet_delete_buffer(uint8_t *ptr, uintptr_t length); -/** - * delete the pointer - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -void iohk_jormungandr_wallet_delete_conversion(ConversionPtr conversion); - /** * delete the pointer and free the allocated memory * @@ -599,89 +484,6 @@ ErrorPtr iohk_jormungandr_wallet_import_keys(const uint8_t *account_key, uintptr_t utxo_keys_len, WalletPtr *wallet_out); -/** - * retrieve a wallet from the given mnemonics, password and protocol magic - * - * this function will work for all yoroi, daedalus and other wallets - * as it will try every kind of wallet anyway - * - * You can also use this function to recover a wallet even after you have - * transferred all the funds to the new format (see the _convert_ function) - * - * The recovered wallet will be returned in `wallet_out`. - * - * # parameters - * - * * mnemonics: a null terminated utf8 string (already normalized NFKD) in english; - * * password: pointer to the password (in bytes, can be UTF8 string or a bytes of anything); - * this value is optional and passing a null pointer will result in no password; - * * password_length: the length of the password; - * * wallet_out: a pointer to a pointer. The recovered wallet will be allocated on this pointer; - * - * # errors - * - * The function may fail if: - * - * * the mnemonics are not valid (invalid length or checksum); - * * the `wallet_out` is null pointer - * - * On error the function returns a `ErrorPtr`. On success `NULL` is returned. - * The `ErrorPtr` can then be observed to gathered details of the error. - * Don't forget to call `iohk_jormungandr_wallet_delete_error` to free - * the `ErrorPtr` from memory and avoid memory leaks. - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -ErrorPtr iohk_jormungandr_wallet_recover(const char *mnemonics, - const uint8_t *password, - uintptr_t password_length, - WalletPtr *wallet_out); - -/** - * retrieve funds from daedalus or yoroi wallet in the given block0 (or - * any other blocks). - * - * Execute this function then you can check who much funds you have - * retrieved from the given block. - * - * this function may take sometimes so it is better to only call this - * function if needed. - * - * # Parameters - * - * * wallet: the recovered wallet (see recover function); - * * block0: the pointer to the bytes of the block0; - * * block0_length: the length of the block0 byte string; - * * settings_out: the settings that will be parsed from the given - * block0; - * - * # Errors - * - * * this function may fail if the wallet pointer is null; - * * the block is not valid (cannot be decoded) - * - * On error the function returns a `ErrorPtr`. On success `NULL` is returned. - * The `ErrorPtr` can then be observed to gathered details of the error. - * Don't forget to call `iohk_jormungandr_wallet_delete_error` to free - * the `ErrorPtr` from memory and avoid memory leaks. - * - * # Safety - * - * This function dereference raw pointers. Even though - * the function checks if the pointers are null. Mind not to put random values - * in or you may see unexpected behaviors - * - */ -ErrorPtr iohk_jormungandr_wallet_retrieve_funds(WalletPtr wallet, - const uint8_t *block0, - uintptr_t block0_length, - SettingsPtr *settings_out); - /** * update the wallet account state * diff --git a/bindings/wallet-cordova/src/android/WalletPlugin.kt b/bindings/wallet-cordova/src/android/WalletPlugin.kt index b8b61746..2547ad3d 100644 --- a/bindings/wallet-cordova/src/android/WalletPlugin.kt +++ b/bindings/wallet-cordova/src/android/WalletPlugin.kt @@ -30,10 +30,6 @@ class WalletPlugin private val proposalPool: MutableMap = mutableMapOf() private var nextProposalId = AtomicInteger() - @ExperimentalUnsignedTypes - private val conversionPool: MutableMap = mutableMapOf() - private var nextConversionId = AtomicInteger() - /** * Sets the context of the Command. This can then be used to do things like get * file paths associated with the Activity. @@ -65,22 +61,14 @@ class WalletPlugin Log.d(TAG, "action: $action") when (action) { "WALLET_IMPORT_KEYS" -> walletImportKeys(args, callbackContext) - "WALLET_RESTORE" -> walletRestore(args, callbackContext) "SYMMETRIC_CIPHER_DECRYPT" -> symmetricCipherDecrypt(args, callbackContext) "SETTINGS_NEW" -> settingsNew(args, callbackContext) "SETTINGS_GET" -> settingsGet(args, callbackContext) - "WALLET_RETRIEVE_FUNDS" -> walletRetrieveFunds(args, callbackContext) "WALLET_VOTE" -> walletVote(args, callbackContext) "WALLET_TOTAL_FUNDS" -> walletTotalFunds(args, callbackContext) "WALLET_SPENDING_COUNTER" -> walletSpendingCounter(args, callbackContext) "WALLET_ID" -> walletId(args, callbackContext) "WALLET_SET_STATE" -> walletSetState(args, callbackContext) - "WALLET_PENDING_TRANSACTIONS" -> walletPendingTransactions(args, callbackContext) - "WALLET_CONFIRM_TRANSACTION" -> walletConfirmTransaction(args, callbackContext) - "WALLET_CONVERT" -> walletConvert(args, callbackContext) - "CONVERSION_TRANSACTIONS_SIZE" -> conversionTransactionsSize(args, callbackContext) - "CONVERSION_TRANSACTIONS_GET" -> conversionTransactionsGet(args, callbackContext) - "CONVERSION_IGNORED" -> conversionIgnored(args, callbackContext) "PENDING_TRANSACTIONS_SIZE" -> pendingTransactionsSize(args, callbackContext) "PENDING_TRANSACTIONS_GET" -> pendingTransactionsGet(args, callbackContext) "BLOCK_DATE_FROM_SYSTEM_TIME" -> blockDateFromSystemTime(args, callbackContext) @@ -92,7 +80,6 @@ class WalletPlugin "SETTINGS_DELETE" -> settingsDelete(args, callbackContext) "PROPOSAL_DELETE" -> proposalDelete(args, callbackContext) "PENDING_TRANSACTIONS_DELETE" -> pendingTransactionsDelete(args, callbackContext) - "CONVERSION_DELETE" -> conversionDelete(args, callbackContext) else -> { Log.w(TAG, "not found: $action") return false @@ -118,25 +105,6 @@ class WalletPlugin } } - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun walletRestore(args: CordovaArgs, callbackContext: CallbackContext) { - val mnemonics = args.getString(0) - cordova.threadPool.execute { - try { - val normalized: String = Normalizer.normalize(mnemonics, Form.NFKD) - val wallet = Wallet.fromMnemonics(normalized, emptyList()) - - val walletId = nextWalletId.incrementAndGet() - wallets[walletId] = wallet - callbackContext.success(walletId) - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - } - - @ExperimentalUnsignedTypes @Throws(JSONException::class) private fun symmetricCipherDecrypt(args: CordovaArgs, callbackContext: CallbackContext) { @@ -259,27 +227,6 @@ class WalletPlugin } } - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun walletRetrieveFunds(args: CordovaArgs, callbackContext: CallbackContext) { - val walletPtr = args.getInt(0) - val block0 = args.getArrayBuffer(1).toUByteArray().toList() - - val wallet = wallets[walletPtr] - cordova.threadPool.execute { - try { - val settingsId = nextSettingsId.incrementAndGet() - val settings: Settings = wallet?.retrieveFunds(block0)!! - - settingsPool[settingsId] = settings - - callbackContext.success(settingsId.toString()) - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - } - @ExperimentalUnsignedTypes @Throws(JSONException::class) private fun walletVote(args: CordovaArgs, callbackContext: CallbackContext) { @@ -358,68 +305,6 @@ class WalletPlugin } } - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun walletPendingTransactions(args: CordovaArgs, callbackContext: CallbackContext) { - val walletId = args.getInt(0) - val wallet = wallets[walletId] - try { - val pendingTransactions = wallet?.pendingTransactions()!! - - val pid = nextPendingTransactionsId.incrementAndGet() - pendingTransactionsPool[pid] = pendingTransactions - - callbackContext.success(pid) - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun walletConfirmTransaction(args: CordovaArgs, callbackContext: CallbackContext) { - val walletId = args.getInt(0) - val fragmentId = args.getArrayBuffer(1).toUByteArray() - - val wallet = wallets[walletId] - - try { - wallet?.confirmTransaction(fragmentId.toList()) - callbackContext.success() - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun walletConvert(args: CordovaArgs, callbackContext: CallbackContext) { - val walletId = args.getInt(0) - val settingsId = args.getInt(1) - val expirationDate = args[2] as JSONObject - val epoch = expirationDate.getString("epoch").toULong() - val slot = expirationDate.getString("slot").toULong() - - val wallet = wallets[walletId] - val settings = settingsPool[settingsId] - - cordova.threadPool.execute { - try { - val conversion = wallet?.convert( - settings!!, BlockDate( - epoch.toUInt(), - slot.toUInt() - ) - ) - val conversionId = nextConversionId.incrementAndGet() - conversionPool[conversionId] = conversion!! - callbackContext.success(conversionId.toString()) - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - } - @ExperimentalUnsignedTypes @Throws(JSONException::class) private fun pendingTransactionsSize(args: CordovaArgs, callbackContext: CallbackContext) { @@ -538,50 +423,6 @@ class WalletPlugin } } - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun conversionTransactionsSize(args: CordovaArgs, callbackContext: CallbackContext) { - val conversionId = args.getInt(0) - val conversion = conversionPool[conversionId] - try { - callbackContext.success(conversion?.fragments?.size.toString()) - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun conversionTransactionsGet(args: CordovaArgs, callbackContext: CallbackContext) { - val conversionId = args.getInt(0) - val index = args.getInt(1) - val conversion = conversionPool[conversionId] - try { - val transaction: ByteArray? = conversion?.fragments?.get(index)?.serialize()?.toUByteArray()?.toByteArray() - callbackContext.success(transaction) - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun conversionIgnored(args: CordovaArgs, callbackContext: CallbackContext) { - val conversionId = args.getInt(0) - val conversion = conversionPool[conversionId] - - try { - val value = conversion?.ignoredValue - val count = conversion?.ignoredCount - - val json = JSONObject().put("value", value).put("ignored", count) - callbackContext.success(json) - - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - @ExperimentalUnsignedTypes @Throws(JSONException::class) private fun walletDelete(args: CordovaArgs, callbackContext: CallbackContext) { @@ -630,19 +471,8 @@ class WalletPlugin } } - @ExperimentalUnsignedTypes - @Throws(JSONException::class) - private fun conversionDelete(args: CordovaArgs, callbackContext: CallbackContext) { - val cid: Int = args.getInt(0) - try { - conversionPool.remove(cid) - callbackContext.success() - } catch (e: Exception) { - callbackContext.error(e.message) - } - } - companion object { const val TAG = "WALLET" } } + diff --git a/bindings/wallet-cordova/src/ios/WalletPlugin.h b/bindings/wallet-cordova/src/ios/WalletPlugin.h index ff610d2f..e9d8ba83 100644 --- a/bindings/wallet-cordova/src/ios/WalletPlugin.h +++ b/bindings/wallet-cordova/src/ios/WalletPlugin.h @@ -5,20 +5,13 @@ @interface WalletPlugin : CDVPlugin -- (void)WALLET_RESTORE:(CDVInvokedUrlCommand*)command; - (void)WALLET_IMPORT_KEYS:(CDVInvokedUrlCommand*)command; - (void)SYMMETRIC_CIPHER_DECRYPT:(CDVInvokedUrlCommand*)command; -- (void)WALLET_RETRIEVE_FUNDS:(CDVInvokedUrlCommand*)command; - (void)WALLET_SPENDING_COUNTER:(CDVInvokedUrlCommand*)command; - (void)WALLET_TOTAL_FUNDS:(CDVInvokedUrlCommand*)command; - (void)WALLET_ID:(CDVInvokedUrlCommand*)command; - (void)WALLET_SET_STATE:(CDVInvokedUrlCommand*)command; - (void)WALLET_VOTE:(CDVInvokedUrlCommand*)command; -- (void)WALLET_CONVERT:(CDVInvokedUrlCommand*)command; - -- (void)CONVERSION_TRANSACTIONS_SIZE:(CDVInvokedUrlCommand*)command; -- (void)CONVERSION_TRANSACTIONS_GET:(CDVInvokedUrlCommand*)command; -- (void)CONVERSION_IGNORED:(CDVInvokedUrlCommand*)command; - (void)PROPOSAL_NEW_PUBLIC:(CDVInvokedUrlCommand*)command; - (void)PROPOSAL_NEW_PRIVATE:(CDVInvokedUrlCommand*)command; @@ -33,7 +26,6 @@ - (void)WALLET_DELETE:(CDVInvokedUrlCommand*)command; - (void)SETTINGS_DELETE:(CDVInvokedUrlCommand*)command; -- (void)CONVERSION_DELETE:(CDVInvokedUrlCommand*)command; - (void)PROPOSAL_DELETE:(CDVInvokedUrlCommand*)command; @end diff --git a/bindings/wallet-cordova/src/ios/WalletPlugin.m b/bindings/wallet-cordova/src/ios/WalletPlugin.m index 4e0643aa..bb0cc9da 100644 --- a/bindings/wallet-cordova/src/ios/WalletPlugin.m +++ b/bindings/wallet-cordova/src/ios/WalletPlugin.m @@ -24,29 +24,6 @@ @implementation WalletPlugin -- (void)WALLET_RESTORE:(CDVInvokedUrlCommand*)command -{ - NSString* mnemonics = [command.arguments objectAtIndex:0]; - - [self.commandDelegate runInBackground:^{ - CDVPluginResult* pluginResult = nil; - - WalletPtr wallet_ptr; - ErrorPtr result = - iohk_jormungandr_wallet_recover([mnemonics UTF8String], nil, 0, &wallet_ptr); - - if (result != nil) { - pluginResult = jormungandr_error_to_plugin_result(result); - } else { - NSString* returnValue = [NSString stringWithFormat:@"%ld", (uintptr_t)wallet_ptr]; - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsString:returnValue]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; -} - - (void)WALLET_IMPORT_KEYS:(CDVInvokedUrlCommand*)command { NSData* account_key = [command.arguments objectAtIndex:0]; @@ -136,41 +113,6 @@ - (void)SYMMETRIC_CIPHER_DECRYPT:(CDVInvokedUrlCommand*)command [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -- (void)WALLET_RETRIEVE_FUNDS:(CDVInvokedUrlCommand*)command -{ - NSString* wallet_ptr_raw = [command.arguments objectAtIndex:0]; - NSData* block0 = [command.arguments objectAtIndex:1]; - - if ([block0 isEqual:[NSNull null]]) { - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR - messageAsString:@"missing argument"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; - } - - WalletPtr wallet_ptr = (WalletPtr)[wallet_ptr_raw longLongValue]; - - [self.commandDelegate runInBackground:^{ - CDVPluginResult* pluginResult = nil; - - SettingsPtr settings_ptr = nil; - ErrorPtr result = iohk_jormungandr_wallet_retrieve_funds(wallet_ptr, - block0.bytes, - block0.length, - &settings_ptr); - - if (result != nil) { - pluginResult = jormungandr_error_to_plugin_result(result); - } else { - NSString* returnValue = [NSString stringWithFormat:@"%ld", (uintptr_t)settings_ptr]; - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsString:returnValue]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; -} - - (void)WALLET_SPENDING_COUNTER:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; @@ -298,102 +240,6 @@ - (void)WALLET_VOTE:(CDVInvokedUrlCommand*)command [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -- (void)WALLET_CONVERT:(CDVInvokedUrlCommand*)command -{ - CDVPluginResult* pluginResult = nil; - NSString* wallet_ptr_raw = [command.arguments objectAtIndex:0]; - NSString* settings_ptr_raw = [command.arguments objectAtIndex:1]; - NSDictionary* expirationDate = [command.arguments objectAtIndex:2]; - - uint32_t epoch = (uint32_t)[expirationDate[@"epoch"] longLongValue]; - uint32_t slot = (uint32_t)[expirationDate[@"slot"] longLongValue]; - BlockDate date = { epoch, slot }; - - WalletPtr wallet_ptr = (WalletPtr)[wallet_ptr_raw longLongValue]; - SettingsPtr settings_ptr = (SettingsPtr)[settings_ptr_raw longLongValue]; - - ConversionPtr conversion_ptr = nil; - ErrorPtr result = - iohk_jormungandr_wallet_convert(wallet_ptr, settings_ptr, date, &conversion_ptr); - - if (result != nil) { - pluginResult = jormungandr_error_to_plugin_result(result); - } else { - NSString* returnValue = [NSString stringWithFormat:@"%ld", (uintptr_t)conversion_ptr]; - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsString:returnValue]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)CONVERSION_TRANSACTIONS_SIZE:(CDVInvokedUrlCommand*)command -{ - NSString* conversion_ptr_raw = [command.arguments objectAtIndex:0]; - ConversionPtr conversion_ptr = (ConversionPtr)[conversion_ptr_raw longLongValue]; - uintptr_t value = iohk_jormungandr_wallet_convert_transactions_size(conversion_ptr); - NSString* returnValue = [NSString stringWithFormat:@"%ld", (uintptr_t)value]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsString:returnValue]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)CONVERSION_TRANSACTIONS_GET:(CDVInvokedUrlCommand*)command -{ - CDVPluginResult* pluginResult = nil; - - NSString* conversion_ptr_raw = [command.arguments objectAtIndex:0]; - NSString* index_raw = [command.arguments objectAtIndex:1]; - - ConversionPtr conversion_ptr = (ConversionPtr)[conversion_ptr_raw longLongValue]; - uintptr_t index = (uintptr_t)[index_raw longLongValue]; - - uint8_t* transaction_out_ptr = nil; - uintptr_t transaction_size; - - ErrorPtr result = iohk_jormungandr_wallet_convert_transactions_get(conversion_ptr, - index, - &transaction_out_ptr, - &transaction_size); - - if (result != nil) { - pluginResult = jormungandr_error_to_plugin_result(result); - } else { - NSData* returnValue = [NSData dataWithBytes:transaction_out_ptr length:transaction_size]; - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsArrayBuffer:returnValue]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)CONVERSION_IGNORED:(CDVInvokedUrlCommand*)command -{ - CDVPluginResult* pluginResult = nil; - - NSString* conversion_ptr_raw = [command.arguments objectAtIndex:0]; - ConversionPtr conversion_ptr = (ConversionPtr)[conversion_ptr_raw longLongValue]; - - uint64_t value_out; - uintptr_t ignored_out; - - ErrorPtr result = - iohk_jormungandr_wallet_convert_ignored(conversion_ptr, &value_out, &ignored_out); - - if (result != nil) { - pluginResult = jormungandr_error_to_plugin_result(result); - } else { - NSDictionary* returnValue = @{ - @"value" : [NSNumber numberWithUnsignedLongLong:value_out], - @"ignored" : [NSNumber numberWithUnsignedLong:ignored_out] - }; - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDictionary:returnValue]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - - (void)PROPOSAL_NEW_PUBLIC:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; @@ -745,15 +591,6 @@ - (void)SETTINGS_DELETE:(CDVInvokedUrlCommand*)command [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -- (void)CONVERSION_DELETE:(CDVInvokedUrlCommand*)command -{ - NSString* conversion_ptr_raw = [command.arguments objectAtIndex:0]; - ConversionPtr conversion_ptr = (ConversionPtr)[conversion_ptr_raw longLongValue]; - iohk_jormungandr_wallet_delete_conversion(conversion_ptr); - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - - (void)PROPOSAL_DELETE:(CDVInvokedUrlCommand*)command { NSString* proposal_ptr_raw = [command.arguments objectAtIndex:0]; diff --git a/bindings/wallet-cordova/tests/src/main.js b/bindings/wallet-cordova/tests/src/main.js index e1bf442e..86a5d1cb 100644 --- a/bindings/wallet-cordova/tests/src/main.js +++ b/bindings/wallet-cordova/tests/src/main.js @@ -6,7 +6,6 @@ const primitives = require('wallet-cordova-plugin.wallet'); const { hexStringToBytes, promisify, uint8ArrayEquals } = require('./src/utils.js'); const keys = require('../../../test-vectors/free_keys/keys.json'); const genesis = require('../../../test-vectors/block0.json'); -const BLOCK0 = genesis.hex; const BLOCK0_ID = genesis.id; const ENCRYPTED_WALLET = keys.encrypted; const PASSWORD = new Uint8Array(4); @@ -18,30 +17,22 @@ const VOTE_ENCRYPTION_KEY = 'ristretto255_votepk1nc988wtjlrm5k0z43088p0rrvd5yhvc // TODO: write settings getter for this const BLOCK0_DATE = 1586637936; +const SLOT_DURATION = 10; +const SLOTS_PER_EPOCH = 100; let promisifyP = f => promisify(primitives, f) -const restoreWallet = promisifyP(primitives.walletRestore); const importKeys = promisifyP(primitives.walletImportKeys); -const retrieveFunds = promisifyP(primitives.walletRetrieveFunds); const spendingCounter = promisifyP(primitives.walletSpendingCounter); const walletId = promisifyP(primitives.walletId); const totalFunds = promisifyP(primitives.walletTotalFunds); -const convertWallet = promisifyP(primitives.walletConvert); const setState = promisifyP(primitives.walletSetState); const deleteWallet = promisifyP(primitives.walletDelete); const deleteSettings = promisifyP(primitives.settingsDelete); -const deleteConversion = promisifyP(primitives.conversionDelete); const deleteProposal = promisifyP(primitives.proposalDelete); -const deletePending = promisifyP(primitives.pendingTransactionsDelete); -const conversionGetTransactionAt = promisifyP(primitives.conversionTransactionsGet); -const conversionGetIgnored = promisifyP(primitives.conversionGetIgnored); const proposalNewPublic = promisifyP(primitives.proposalNewPublic); const proposalNewPrivate = promisifyP(primitives.proposalNewPrivate); const walletVote = promisifyP(primitives.walletVote); const walletSetState = promisifyP(primitives.walletSetState); -const walletConfirmTransaction = promisifyP(primitives.walletConfirmTransaction); -const walletPendingTransactions = promisifyP(primitives.walletPendingTransactions); -const pendingTransactionsGet = promisifyP(primitives.pendingTransactionsGet); const symmetricCipherDecrypt = promisifyP(primitives.symmetricCipherDecrypt); const settingsGet = promisifyP(primitives.settingsGet); const settingsNew = promisifyP(primitives.settingsNew); @@ -59,11 +50,11 @@ const tests = [ ['should recover wallet', async function () { const walletPtr = await walletFromFile(); expect(walletPtr !== 0).toBe(true); - const settingsPtr = await retrieveFunds(walletPtr, hexStringToBytes(BLOCK0)); + const settingsPtr = await defaultSettings(); expect(settingsPtr !== 0).toBe(true); const funds = await totalFunds(walletPtr); - expect(parseInt(funds)).toBe(21000); + expect(parseInt(funds)).toBe(0); const accountId = await walletId(walletPtr); @@ -79,51 +70,6 @@ const tests = [ const counter = 2; await setState(wallet, value, counter); }], - ['should fail with invalid mnemonics', async function () { - try { - await restoreWallet('invalidmnemonics'); - throw Error('Invalid mnemonics should fail'); - } catch (e) { - return; - } - }], - ['should fail with invalid block', async function () { - const accountKey = hexStringToBytes(keys.account.private_key); - const utxoKeys = Uint8Array.from([]); - - const wallet = await importKeys(accountKey, utxoKeys); - try { - await retrieveFunds(wallet, [0, 0, 0, 0]); - } - catch (e) { - return; - } - throw Error('Invalid block should fail'); - }], - ['get conversion transaction', async function () { - const wallet = await walletFromFile(); - - expect(wallet !== 0).toBe(true); - - const settings = await retrieveFunds(wallet, hexStringToBytes(BLOCK0)); - const conversion = await convertWallet(wallet, settings, await maxExpirationDate(settings, BLOCK0_DATE + 600)); - const transactions = await conversionGetTransactions(conversion); - expect(transactions.length).toBe(1); - - const ignoredValue = await conversionGetIgnored(conversion); - expect(ignoredValue.ignored).toBe('0'); - - const pendingBefore = await getPendingTransactions(wallet); - expect(pendingBefore.length).toBe(1); - await walletConfirmTransaction(wallet, new Uint8Array(pendingBefore[0])) - - const pendingAfter = await getPendingTransactions(wallet); - expect(pendingAfter.length).toBe(0); - - await deleteSettings(settings); - await deleteConversion(conversion); - await deleteWallet(wallet); - }], ['can cast vote', async function () { const array = new Array(32); for (let index = 0; index < array.length; index++) { @@ -137,7 +83,8 @@ const tests = [ const proposalPtr = await proposalNewPublic(votePlanId, index, numChoices); const walletPtr = await walletFromFile(); - const settingsPtr = await retrieveFunds(walletPtr, hexStringToBytes(BLOCK0)); + const settingsPtr = await defaultSettings(); + await walletSetState(walletPtr, 1000000, 0); expect(await spendingCounter(walletPtr)).toBe(0); @@ -146,9 +93,6 @@ const tests = [ expect(await spendingCounter(walletPtr)).toBe(1); - const pending = await getPendingTransactions(walletPtr); - expect(pending.length).toBe(1); - await deleteSettings(settingsPtr); await deleteWallet(walletPtr); await deleteProposal(proposalPtr); @@ -165,7 +109,7 @@ const tests = [ const proposalPtr = await proposalNewPrivate(votePlanId, index, numChoices, VOTE_ENCRYPTION_KEY); const walletPtr = await walletFromFile(); - const settingsPtr = await retrieveFunds(walletPtr, hexStringToBytes(BLOCK0)); + const settingsPtr = await defaultSettings(); await walletSetState(walletPtr, 1000000, 1); await walletVote(walletPtr, settingsPtr, proposalPtr, 0, await maxExpirationDate(settingsPtr, BLOCK0_DATE + 600)); @@ -203,33 +147,6 @@ const tests = [ throw Error('decryption failed'); } }], - ['extract settings', async function () { - const walletPtr = await walletFromFile(); - - expect(walletPtr !== 0).toBe(true); - const settingsPtr = await retrieveFunds(walletPtr, hexStringToBytes(BLOCK0)); - - expect(settingsPtr !== 0).toBe(true); - - const settings = await settingsGet(settingsPtr); - - expect(uint8ArrayEquals(settings.block0Hash, hexStringToBytes(BLOCK0_ID))).toBe(true); - expect(settings.discrimination).toBe(primitives.Discrimination.PRODUCTION); - - expect(settings.fees.constant).toBe("10"); - expect(settings.fees.coefficient).toBe("2"); - expect(settings.fees.certificate).toBe("100"); - - expect(settings.fees.certificatePoolRegistration).toBe("0"); - expect(settings.fees.certificateStakeDelegation).toBe("0"); - expect(settings.fees.certificateOwnerStakeDelegation).toBe("0"); - - expect(settings.fees.certificateVotePlan).toBe("0"); - expect(settings.fees.certificateVoteCast).toBe("0"); - - await deleteSettings(settingsPtr); - await deleteWallet(walletPtr); - }], ['new settings', async function () { const settingsExpected = { block0Hash: hexStringToBytes(BLOCK0_ID), @@ -289,41 +206,32 @@ const tests = [ const proposalPtr = await proposalNewPublic(votePlanId, index, numChoices); const walletPtr = await walletFromFile(); - const settingsPtr = await retrieveFunds(walletPtr, hexStringToBytes(BLOCK0)); + const settingsPtr = await defaultSettings(); await walletSetState(walletPtr, 1000000, 0); + // TODO: maybe walletVote should return an object with the both tx and the id const tx1 = await walletVote(walletPtr, settingsPtr, proposalPtr, 1, await maxExpirationDate(settingsPtr, BLOCK0_DATE + 600)); const tx2 = await walletVote(walletPtr, settingsPtr, proposalPtr, 2, await maxExpirationDate(settingsPtr, BLOCK0_DATE + 600)); - const id1 = await fragmentId(new Uint8Array(tx1)); - const id2 = await fragmentId(new Uint8Array(tx2)); - - const pendingTransactions = await getPendingTransactions(walletPtr); - - expect(uint8ArrayEquals(id1, pendingTransactions[0])).toBe(true); - expect(uint8ArrayEquals(id2, pendingTransactions[0])).toBe(true); + await fragmentId(new Uint8Array(tx1)); + await fragmentId(new Uint8Array(tx2)); await deleteSettings(settingsPtr); await deleteWallet(walletPtr); await deleteProposal(proposalPtr); }], ['systemtime to date', async function () { - const walletPtr = await walletFromFile(); - const settingsPtr = await retrieveFunds(walletPtr, hexStringToBytes(BLOCK0)); + const settingsPtr = await defaultSettings(); let first = await blockDateFromSystemTime(settingsPtr, BLOCK0_DATE); expect(first.epoch).toBe("0"); expect(first.slot).toBe("0"); - // TODO: implement getters for this. - let slots_per_epoch = 180; - let slot_duration = 20; - - let second = await blockDateFromSystemTime(settingsPtr, BLOCK0_DATE + slot_duration + 1); + let second = await blockDateFromSystemTime(settingsPtr, BLOCK0_DATE + SLOT_DURATION + 1); expect(second.epoch).toBe("0"); expect(second.slot).toBe("1"); - let third = await blockDateFromSystemTime(settingsPtr, BLOCK0_DATE + slot_duration * slots_per_epoch); + let third = await blockDateFromSystemTime(settingsPtr, BLOCK0_DATE + SLOT_DURATION * SLOTS_PER_EPOCH); expect(third.epoch).toBe("1"); expect(third.slot).toBe("0"); }], @@ -348,53 +256,31 @@ exports.defineAutoTests = function () { exports.defineManualTests = require('./src/manual_tests.js'); -function conversionGetTransactions(conversion) { - return new Promise(function (resolve, reject) { - primitives.conversionTransactionsSize(conversion, function (size) { - const transactions = []; - for (let i = 0; i < size; ++i) { - transactions.push(conversionGetTransactionAt(conversion, i)); - } - Promise.all(transactions).then( - function (array) { - resolve(array); - } - ).catch(function (err) { - reject(err); - }); - }, function (err) { - reject(err); - }); - } - ); -} +async function defaultSettings() { + const testSettings = { + block0Hash: hexStringToBytes(BLOCK0_ID), + discrimination: primitives.Discrimination.TEST, + fees: { + constant: "1", + coefficient: "2", + certificate: "3", + certificatePoolRegistration: "4", + certificateStakeDelegation: "5", + certificateOwnerStakeDelegation: "6", + certificateVotePlan: "7", + certificateVoteCast: "8", + } + }; -function pendingTransactionsGetAll(pendingTransactions) { - return new Promise(function (resolve, reject) { - primitives.pendingTransactionsSize(pendingTransactions, function (size) { - const transactions = []; - for (let i = 0; i < size; ++i) { - transactions.push(pendingTransactionsGet(pendingTransactions, i)); - } - Promise.all(transactions).then( - function (array) { - resolve(array); - } - ).catch(function (err) { - reject(err); - }); - }, function (err) { - reject(err); - }); - } + const block0Date = JSON.stringify(BLOCK0_DATE); + const slotDuration = JSON.stringify(SLOT_DURATION); + const era = {epochStart: "0", slotStart: "0", slotsPerEpoch: JSON.stringify(SLOTS_PER_EPOCH)}; + const transactionMaxExpiryEpochs = "2"; + + const settingsPtr = await settingsNew(testSettings.block0Hash, + testSettings.discrimination, testSettings.fees, block0Date, + slotDuration, era, transactionMaxExpiryEpochs ); -} -function getPendingTransactions(walletPtr) { - return walletPendingTransactions(walletPtr).then( - function (pendingPtr) { - return pendingTransactionsGetAll(pendingPtr).then(pending => { - return deletePending(pendingPtr).then(() => pending); - }); - }); + return settingsPtr; } diff --git a/bindings/wallet-cordova/www/wallet.js b/bindings/wallet-cordova/www/wallet.js index 960bf8b8..f091d0d4 100644 --- a/bindings/wallet-cordova/www/wallet.js +++ b/bindings/wallet-cordova/www/wallet.js @@ -4,29 +4,19 @@ var base64 = require('cordova/base64'); const NATIVE_CLASS_NAME = 'WalletPlugin'; -const WALLET_RESTORE_ACTION_TAG = 'WALLET_RESTORE'; const WALLET_IMPORT_KEYS_TAG = 'WALLET_IMPORT_KEYS'; -const WALLET_RETRIEVE_FUNDS_ACTION_TAG = 'WALLET_RETRIEVE_FUNDS'; const WALLET_TOTAL_FUNDS_ACTION_TAG = 'WALLET_TOTAL_FUNDS'; const WALLET_SPENDING_COUNTER_ACTION_TAG = 'WALLET_SPENDING_COUNTER'; const WALLET_ID_TAG = 'WALLET_ID'; -const WALLET_CONVERT_ACTION_TAG = 'WALLET_CONVERT'; const WALLET_SET_STATE_ACTION_TAG = 'WALLET_SET_STATE'; const WALLET_VOTE_ACTION_TAG = 'WALLET_VOTE'; const WALLET_CONFIRM_TRANSACTION = 'WALLET_CONFIRM_TRANSACTION'; -const CONVERSION_TRANSACTIONS_SIZE_ACTION_TAG = 'CONVERSION_TRANSACTIONS_SIZE'; -const CONVERSION_TRANSACTIONS_GET_ACTION_TAG = 'CONVERSION_TRANSACTIONS_GET'; -const CONVERSION_IGNORED_GET_ACTION_TAG = 'CONVERSION_IGNORED'; const PROPOSAL_NEW_PUBLIC_ACTION_TAG = 'PROPOSAL_NEW_PUBLIC'; const PROPOSAL_NEW_PRIVATE_ACTION_TAG = 'PROPOSAL_NEW_PRIVATE'; const WALLET_DELETE_ACTION_TAG = 'WALLET_DELETE'; const SETTINGS_DELETE_ACTION_TAG = 'SETTINGS_DELETE'; -const CONVERSION_DELETE_ACTION_TAG = 'CONVERSION_DELETE'; const PROPOSAL_DELETE_ACTION_TAG = 'PROPOSAL_DELETE'; const WALLET_PENDING_TRANSACTIONS = 'WALLET_PENDING_TRANSACTIONS'; -const PENDING_TRANSACTIONS_DELETE = 'PENDING_TRANSACTIONS_DELETE'; -const PENDING_TRANSACTIONS_GET = 'PENDING_TRANSACTIONS_GET'; -const PENDING_TRANSACTIONS_SIZE = 'PENDING_TRANSACTIONS_SIZE'; const SYMMETRIC_CIPHER_DECRYPT = 'SYMMETRIC_CIPHER_DECRYPT'; const SETTINGS_NEW = 'SETTINGS_NEW'; const SETTINGS_GET = 'SETTINGS_GET'; @@ -114,21 +104,6 @@ var plugin = { TEST: 1 }, - /** - * @callback TransactionIdCallback - * @param {Uint8Array} id - */ - - /** - * @param {string} mnemonics a string with the mnemonic phrase - * @param {pointerCallback} successCallback on success returns a pointer to a Wallet object - * @param {errorCallback} errorCallback this function can fail if the mnemonics are invalid - */ - walletRestore: function (mnemonics, successCallback, errorCallback) { - argscheck.checkArgs('sff', 'walletRestore', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_RESTORE_ACTION_TAG, [mnemonics]); - }, - /** * @param {Uint8Array} accountKeys a 64bytes array representing an Ed25519Extended private key * @param {Uint8Array} utxoKeys a contiguous array of Ed25519Extended private keys (64 bytes each) @@ -143,19 +118,6 @@ var plugin = { exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_IMPORT_KEYS_TAG, [accountKeys.buffer, utxoKeys.buffer]); }, - /** - * @param {string} ptr a pointer to a wallet obtained with walletRestore - * @param {Uint8Array} block0 a byte array representing the block - * @param {function} successCallback returns a pointer to the blockchain settings extracted from the block - * @param {errorCallback} errorCallback this can fail if the block or the pointer are invalid - */ - walletRetrieveFunds: function (ptr, block0, successCallback, errorCallback) { - argscheck.checkArgs('s*ff', 'walletRetrieveFunds', arguments); - checkUint8Array({ name: 'block0', testee: block0 }); - - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_RETRIEVE_FUNDS_ACTION_TAG, [ptr, block0.buffer]); - }, - /** * @param {string} ptr a pointer to a wallet obtained with walletRestore * @param {function} successCallback returns a number @@ -250,18 +212,6 @@ var plugin = { exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_VOTE_ACTION_TAG, [walletPtr, settingsPtr, proposalPtr, choice, validUntil]); }, - /** - * @param {string} walletPtr a pointer to a wallet obtained with walletRestore - * @param {string} settingsPtr a pointer to a settings object obtained with walletRetrieveFunds - * @param {BlockDate} validUntil maximum date in which this fragment can be applied to the ledger - * @param {pointerCallback} successCallback returns a Conversion object - * @param {errorCallback} errorCallback description (TODO) - */ - walletConvert: function (walletPtr, settingsPtr, validUntil, successCallback, errorCallback) { - argscheck.checkArgs('ss*ff', 'walletConvert', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_CONVERT_ACTION_TAG, [walletPtr, settingsPtr, validUntil]); - }, - /** * @param {string} walletPtr a pointer to a wallet obtained with walletRestore * @param {pointerCallback} successCallback @@ -272,27 +222,6 @@ var plugin = { exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_PENDING_TRANSACTIONS, [walletPtr]); }, - /** - * @param {string} ptr a pointer to a Conversion object obtained with walletConvert - * @param {function} successCallback returns a number representing the number of transactions produced by the conversion - * @param {errorCallback} errorCallback description (TODO) - */ - pendingTransactionsSize: function (ptr, successCallback, errorCallback) { - argscheck.checkArgs('*ff', 'pendingTransactionsSize', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, PENDING_TRANSACTIONS_SIZE, [ptr]); - }, - - /** - * @param {string} ptr a pointer to a PendingTransactions object obtained with walletPendingTransactions - * @param {number} index an index (starting from 0). Use pendingTransactionsSize to get the upper bound - * @param {TransactionIdCallback} successCallback callback that receives a transaction id in binary form - * @param {errorCallback} errorCallback this function can fail if the index is out of range - */ - pendingTransactionsGet: function (ptr, index, successCallback, errorCallback) { - argscheck.checkArgs('*nff', 'pendingTransactionsGet', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, PENDING_TRANSACTIONS_GET, [ptr, index]); - }, - /** * @param {string} walletPtr a pointer to a wallet obtained with walletRestore * @param {Uint8Array} transactionId the transaction id in bytes @@ -306,37 +235,6 @@ var plugin = { exec(successCallback, errorCallback, NATIVE_CLASS_NAME, WALLET_CONFIRM_TRANSACTION, [walletPtr, transactionId.buffer]); }, - /** - * @param {string} ptr a pointer to a Conversion object obtained with walletConvert - * @param {function} successCallback returns a number representing the number of transactions produced by the conversion - * @param {errorCallback} errorCallback description (TODO) - */ - conversionTransactionsSize: function (ptr, successCallback, errorCallback) { - argscheck.checkArgs('sff', 'conversionTransactionsSize', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, CONVERSION_TRANSACTIONS_SIZE_ACTION_TAG, [ptr]); - }, - - /** - * @param {string} ptr a pointer to a Conversion object obtained with walletConvert - * @param {number} index an index (starting from 0). Use conversionTransactionsSize to get the upper bound - * @param {function} successCallback callback that receives a transaction in binary form - * @param {errorCallback} errorCallback this function can fail if the index is out of range - */ - conversionTransactionsGet: function (ptr, index, successCallback, errorCallback) { - argscheck.checkArgs('snff', 'conversionTransactionsGet', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, CONVERSION_TRANSACTIONS_GET_ACTION_TAG, [ptr, index]); - }, - - /** - * @param {string} ptr a pointer to a Conversion object obtained with walletConvert - * @param {function} successCallback returns an object with ignored, and value properties - * @param {errorCallback} errorCallback - */ - conversionGetIgnored: function (ptr, successCallback, errorCallback) { - argscheck.checkArgs('sff', 'conversionGetIgnored', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, CONVERSION_IGNORED_GET_ACTION_TAG, [ptr]); - }, - /** * Get a proposal object, used to validate the vote on `walletVote` * @@ -494,16 +392,6 @@ var plugin = { exec(successCallback, errorCallback, NATIVE_CLASS_NAME, SETTINGS_DELETE_ACTION_TAG, [ptr]); }, - /** - * @param {string} ptr a pointer to a Conversion object obtained with walletConvert - * @param {function} successCallback indicates success. Does not return anything. - * @param {errorCallback} errorCallback - */ - conversionDelete: function (ptr, successCallback, errorCallback) { - argscheck.checkArgs('sff', 'conversionDelete', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, CONVERSION_DELETE_ACTION_TAG, [ptr]); - }, - /** * @param {string} ptr a pointer to a Proposal object obtained with proposalNew * @param {function} successCallback indicates success. Does not return anything. @@ -512,16 +400,6 @@ var plugin = { proposalDelete: function (ptr, successCallback, errorCallback) { argscheck.checkArgs('sff', 'proposalDelete', arguments); exec(successCallback, errorCallback, NATIVE_CLASS_NAME, PROPOSAL_DELETE_ACTION_TAG, [ptr]); - }, - - /** - * @param {string} ptr a pointer to a Proposal object obtained with proposalNew - * @param {function} successCallback indicates success. Does not return anything. - * @param {errorCallback} errorCallback - */ - pendingTransactionsDelete: function (ptr, successCallback, errorCallback) { - argscheck.checkArgs('*ff', 'pendingTransactionsDelete', arguments); - exec(successCallback, errorCallback, NATIVE_CLASS_NAME, PENDING_TRANSACTIONS_DELETE, [ptr]); } }; diff --git a/bindings/wallet-core/src/c/mod.rs b/bindings/wallet-core/src/c/mod.rs index 6c8d43ff..9e1c6c3a 100644 --- a/bindings/wallet-core/src/c/mod.rs +++ b/bindings/wallet-core/src/c/mod.rs @@ -7,8 +7,8 @@ pub mod settings; pub mod time; pub mod vote; -use crate::{Conversion, Error, Proposal, Result, Wallet}; -use chain_impl_mockchain::{fragment::Fragment, transaction::Input, value::Value, vote::Choice}; +use crate::{Error, Proposal, Result, Wallet}; +use chain_impl_mockchain::{fragment::Fragment, value::Value, vote::Choice}; use std::convert::TryInto; use thiserror::Error; @@ -18,10 +18,8 @@ use self::time::BlockDate; pub type WalletPtr = *mut Wallet; pub type SettingsPtr = *mut Settings; -pub type ConversionPtr = *mut Conversion; pub type ProposalPtr = *mut Proposal; pub type ErrorPtr = *mut Error; -pub type PendingTransactionsPtr = *mut PendingTransactions; pub type FragmentPtr = *mut Fragment; #[derive(Debug, Error)] @@ -32,71 +30,8 @@ struct NulPtr; #[error("access out of bound")] struct OutOfBound; -/// opaque handle over a list of pending transaction ids -pub struct PendingTransactions { - fragment_ids: Box<[chain_impl_mockchain::fragment::FragmentId]>, -} - pub const FRAGMENT_ID_LENGTH: usize = 32; -/// retrieve a wallet from the given mnemonics, password and protocol magic -/// -/// this function will work for all yoroi, daedalus and other wallets -/// as it will try every kind of wallet anyway -/// -/// You can also use this function to recover a wallet even after you have -/// transferred all the funds to the new format (see the _convert_ function) -/// -/// The recovered wallet will be returned in `wallet_out`. -/// -/// # parameters -/// -/// * mnemonics: a null terminated utf8 string (already normalized NFKD) in english; -/// * password: pointer to the password (in bytes, can be UTF8 string or a bytes of anything); -/// this value is optional and passing a null pointer will result in no password; -/// * password_length: the length of the password; -/// * wallet_out: a pointer to a pointer. The recovered wallet will be allocated on this pointer; -/// -/// # Safety -/// -/// This function dereference raw pointers (password and wallet_out). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -/// # errors -/// -/// The function may fail if: -/// -/// * the mnemonics are not valid (invalid length or checksum); -/// * the `wallet_out` is null pointer -/// -pub unsafe fn wallet_recover( - mnemonics: &str, - password: *const u8, - password_length: usize, - wallet_out: *mut WalletPtr, -) -> Result { - let wallet_out: &mut WalletPtr = if let Some(wallet_out) = wallet_out.as_mut() { - wallet_out - } else { - return Error::invalid_input("wallet_out").with(NulPtr).into(); - }; - - let result = if !password.is_null() && password_length > 0 { - todo!() - } else { - Wallet::recover(mnemonics, &[]) - }; - - match result { - Ok(wallet) => { - *wallet_out = Box::into_raw(Box::new(wallet)); - Result::success() - } - Err(err) => err.into(), - } -} - /// recover a wallet from an account and a list of utxo keys /// /// You can also use this function to recover a wallet even after you have @@ -194,154 +129,6 @@ pub unsafe fn wallet_id(wallet: WalletPtr, id_out: *mut u8) -> Result { Result::success() } -/// retrieve funds from daedalus or yoroi wallet in the given block0 (or -/// any other blocks). -/// -/// Execute this function then you can check who much funds you have -/// retrieved from the given block. -/// -/// this function may take sometimes so it is better to only call this -/// function if needed. -/// -/// # Safety -/// -/// This function dereference raw pointers (wallet, block0 and settings_out). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -/// # Parameters -/// -/// * wallet: the recovered wallet (see recover function); -/// * block0: the pointer to the bytes of the block0; -/// * block0_length: the length of the block0 byte string; -/// * settings_out: the settings that will be parsed from the given -/// block0; -/// -/// # Errors -/// -/// * this function may fail if the wallet pointer is null; -/// * the block is not valid (cannot be decoded) -/// -pub unsafe fn wallet_retrieve_funds( - wallet: WalletPtr, - block0: *const u8, - block0_length: usize, - settings_out: *mut SettingsPtr, -) -> Result { - let wallet: &mut Wallet = if let Some(wallet) = wallet.as_mut() { - wallet - } else { - return Error::invalid_input("wallet").with(NulPtr).into(); - }; - if block0.is_null() { - return Error::invalid_input("block0").with(NulPtr).into(); - } - let settings_out: &mut SettingsPtr = if let Some(settings_out) = settings_out.as_mut() { - settings_out - } else { - return Error::invalid_input("settings_out").with(NulPtr).into(); - }; - - let block0_bytes = std::slice::from_raw_parts(block0, block0_length); - - match wallet.retrieve_funds(block0_bytes) { - Ok(settings) => { - *settings_out = Box::into_raw(Box::new(settings)); - Result::success() - } - Err(err) => err.into(), - } -} - -/// -/// # Safety -/// -/// This function dereference raw pointers (wallet, fragment_id). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors. -/// -pub unsafe fn pending_transactions_len( - transactions: PendingTransactionsPtr, - len_out: *mut usize, -) -> Result { - let pending_transactions = non_null!(transactions); - - *len_out = pending_transactions.fragment_ids.len(); - - Result::success() -} - -/// -/// # Safety -/// -/// This function dereference raw pointers (wallet, fragment_id). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors. -/// -pub unsafe fn pending_transactions_get( - transactions: PendingTransactionsPtr, - index: usize, - id_out: *mut *const u8, -) -> Result { - let pending_transactions = non_null!(transactions); - - let fragment_id: &[u8] = pending_transactions.fragment_ids[index].as_ref(); - - *id_out = fragment_id.as_ptr(); - - Result::success() -} - -/// delete the pointer and free the allocated memory -/// -/// # Safety -/// -/// This function dereference raw pointers (wallet, fragment_id). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors. -/// -pub unsafe fn pending_transactions_delete(pending: PendingTransactionsPtr) { - if !pending.is_null() { - let boxed = Box::from_raw(pending); - - std::mem::drop(boxed); - } -} - -/// Get list of pending transaction id's -/// -/// # Parameters -/// -/// * wallet: the recovered wallet (see recover function); -/// * pending_transactions_out: an opaque type that works as an array -/// -/// # Errors -/// -/// * this function may fail if the wallet pointer is null; -/// * the block is not valid (cannot be decoded) -/// -/// # Safety -/// -/// This function dereference raw pointers (wallet). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors. -/// -pub unsafe fn wallet_pending_transactions( - wallet: WalletPtr, - pending_transactions_out: *mut PendingTransactionsPtr, -) -> Result { - let wallet = non_null!(wallet); - - let pending_transactions = PendingTransactions { - fragment_ids: wallet.pending_transactions().into_boxed_slice(), - }; - - *pending_transactions_out = - Box::into_raw(Box::new(pending_transactions)) as PendingTransactionsPtr; - - Result::success() -} - /// Confirm the previously generated transaction identified by fragment_id /// /// # Safety @@ -365,151 +152,6 @@ pub unsafe fn wallet_confirm_transaction(wallet: WalletPtr, fragment_id: *const Result::success() } -/// once funds have been retrieved with `iohk_jormungandr_wallet_retrieve_funds` -/// it is possible to convert all existing funds to the new wallet. -/// -/// The returned arrays are transactions to send to the network in order to do the -/// funds conversion. -/// -/// Don't forget to call `iohk_jormungandr_wallet_delete_conversion` to -/// properly free the memory -/// -/// # Safety -/// -/// This function dereference raw pointers (wallet, settings and conversion_out). Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -pub unsafe fn wallet_convert( - wallet: WalletPtr, - settings: SettingsPtr, - valid_until: BlockDate, - conversion_out: *mut ConversionPtr, -) -> Result { - let wallet: &mut Wallet = if let Some(wallet) = wallet.as_mut() { - wallet - } else { - return Error::invalid_input("wallet").with(NulPtr).into(); - }; - let settings = if let Some(settings) = settings.as_ref() { - settings.clone() - } else { - return Error::invalid_input("settings").with(NulPtr).into(); - }; - let conversion_out: &mut ConversionPtr = if let Some(conversion_out) = conversion_out.as_mut() { - conversion_out - } else { - return Error::invalid_input("conversion_out").with(NulPtr).into(); - }; - - let conversion = wallet.convert(settings, &valid_until.into()); - - *conversion_out = Box::into_raw(Box::new(conversion)); - - Result::success() -} - -/// get the number of transactions built to convert the retrieved wallet -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -pub unsafe fn wallet_convert_transactions_size(conversion: ConversionPtr) -> usize { - conversion - .as_ref() - .map(|c| c.transactions.len()) - .unwrap_or_default() -} - -/// retrieve the index-nth transactions in the conversions starting from 0 -/// and finishing at `size-1` where size is retrieved from -/// `iohk_jormungandr_wallet_convert_transactions_size`. -/// -/// the memory allocated returned is not owned and should not be kept -/// for longer than potential call to `iohk_jormungandr_wallet_delete_conversion` -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -pub unsafe fn wallet_convert_transactions_get( - conversion: ConversionPtr, - index: usize, - transaction_out: *mut *const u8, - transaction_size: *mut usize, -) -> Result { - let conversion = if let Some(conversion) = conversion.as_ref() { - conversion - } else { - return Error::invalid_input("conversion").with(NulPtr).into(); - }; - let transaction_out = if let Some(t) = transaction_out.as_mut() { - t - } else { - return Error::invalid_input("transaction_out").with(NulPtr).into(); - }; - let transaction_size = if let Some(t) = transaction_size.as_mut() { - t - } else { - return Error::invalid_input("transaction_size").with(NulPtr).into(); - }; - - if let Some(t) = conversion.transactions.get(index) { - *transaction_out = t.as_ptr(); - *transaction_size = t.len(); - Result::success() - } else { - Error::wallet_conversion().with(OutOfBound).into() - } -} - -/// get the total value ignored in the conversion -/// -/// value_out: will returns the total value lost into dust inputs -/// ignored_out: will returns the number of dust utxos -/// -/// these returned values are informational only and this show that -/// there are UTxOs entries that are unusable because of the way they -/// are populated with dusts. -/// -/// # Safety -/// -/// This function dereference raw pointers. Even though -/// the function checks if the pointers are null. Mind not to put random values -/// in or you may see unexpected behaviors -/// -pub unsafe fn wallet_convert_ignored( - conversion: ConversionPtr, - value_out: *mut u64, - ignored_out: *mut usize, -) -> Result { - if let Some(c) = conversion.as_ref() { - let v = *c - .ignored - .iter() - .map(|i: &Input| i.value()) - .sum::() - .as_ref(); - let l = c.ignored.len(); - - if let Some(value_out) = value_out.as_mut() { - *value_out = v - } - if let Some(ignored_out) = ignored_out.as_mut() { - *ignored_out = l - }; - - Result::success() - } else { - Error::invalid_input("conversion").with(NulPtr).into() - } -} - /// get the current spending counter for the (only) account in this wallet /// /// @@ -729,15 +371,6 @@ pub fn wallet_delete_wallet(wallet: WalletPtr) { } } -/// delete the pointer -pub fn wallet_delete_conversion(conversion: ConversionPtr) { - if !conversion.is_null() { - let boxed = unsafe { Box::from_raw(conversion) }; - - std::mem::drop(boxed); - } -} - /// delete the pointer pub fn wallet_delete_proposal(proposal: ProposalPtr) { if !proposal.is_null() { diff --git a/bindings/wallet-core/src/lib.rs b/bindings/wallet-core/src/lib.rs index 29b84aa4..91f6961a 100644 --- a/bindings/wallet-core/src/lib.rs +++ b/bindings/wallet-core/src/lib.rs @@ -1,11 +1,9 @@ pub mod c; -mod conversion; mod error; mod vote; mod wallet; pub use self::{ - conversion::Conversion, error::{Error, ErrorCode, ErrorKind, Result}, vote::Proposal, wallet::Wallet, diff --git a/bindings/wallet-core/src/wallet.rs b/bindings/wallet-core/src/wallet.rs index 7b276acc..b35fc59b 100644 --- a/bindings/wallet-core/src/wallet.rs +++ b/bindings/wallet-core/src/wallet.rs @@ -1,14 +1,12 @@ -use crate::{Conversion, Error, Proposal}; +use crate::{Error, Proposal}; use chain_core::property::Serialize as _; use chain_crypto::SecretKey; use chain_impl_mockchain::{ - block::{Block, BlockDate}, + block::BlockDate, fragment::{Fragment, FragmentId}, - transaction::Input, value::Value, vote::Choice, }; -use chain_ser::mempack::{ReadBuf, Readable as _}; use wallet::{AccountId, Settings}; /// the wallet @@ -19,7 +17,6 @@ use wallet::{AccountId, Settings}; /// pub struct Wallet { account: wallet::Wallet, - free_keys: wallet::scheme::freeutxo::Wallet, } impl Wallet { @@ -32,48 +29,6 @@ impl Wallet { self.account.account_id() } - /// Retrieve a wallet from the given BIP39 mnemonics and password. - /// - /// You can also use this function to recover a wallet even after you have transferred all the - /// funds to the account addressed by the public key (see the [convert] function). - /// - /// Returns the recovered wallet on success. - /// - /// Parameters - /// - /// * `mnemonics`: a UTF-8 string (already normalized NFKD) with space-separated words in English; - /// * `password`: the password (any string of bytes). - /// - /// # Errors - /// - /// The function may fail if: - /// - /// * the mnemonics are not valid (invalid length or checksum); - /// - pub fn recover(mnemonics: &str, password: &[u8]) -> Result { - let builder = wallet::RecoveryBuilder::new(); - - let builder = builder - .mnemonics(&bip39::dictionary::ENGLISH, mnemonics) - .map_err(|err| Error::invalid_input("mnemonics").with(err))?; - - let builder = if !password.is_empty() { - builder.password(password.to_vec().into()) - } else { - builder - }; - - let account = builder - .build_wallet() - .expect("build the account cannot fail as expected"); - - let free_keys = builder - .build_free_utxos() - .expect("build without free keys cannot fail"); - - Ok(Wallet { account, free_keys }) - } - /// Retrieve a wallet from a list of free keys used as utxo's /// /// You can also use this function to recover a wallet even after you have @@ -82,7 +37,7 @@ impl Wallet { /// Parameters /// /// * `account_key`: the private key used for voting - /// * `keys`: single keys used to retrieve UTxO inputs + /// * `keys`: unused /// /// # Errors /// @@ -92,143 +47,26 @@ impl Wallet { /// pub fn recover_free_keys<'a, U: Iterator>( account_key: &[u8], - keys: U, + _keys: U, ) -> Result { let builder = wallet::RecoveryBuilder::new(); let builder = builder.account_secret_key(SecretKey::from_binary(account_key).unwrap()); - let builder = keys.fold(builder, |builder, key| { - builder.add_key(SecretKey::from_binary(key.as_ref()).unwrap()) - }); - - let free_keys = builder.build_free_utxos().map_err(|err| { - Error::invalid_input("invalid secret keys for UTxO retrieval").with(err) - })?; - let account = builder .build_wallet() .expect("build the account cannot fail as expected"); - Ok(Wallet { account, free_keys }) - } - - /// retrieve funds from bip44 hd sequential wallet in the given block0 (or any other blocks). - /// - /// After this function is executed, the wallet user can check how much - /// funds have been retrieved from fragments of the given block. - /// - /// This function can take some time to run, so it is better to only - /// call it if needed. - /// - /// This function should not be called twice with the same block. - /// In a future revision of this library, this limitation may be lifted. - /// - /// # Errors - /// - /// * the block is not valid (cannot be decoded) - /// - pub fn retrieve_funds(&mut self, block0_bytes: &[u8]) -> Result { - let mut block0_bytes = ReadBuf::from(block0_bytes); - let block0 = - Block::read(&mut block0_bytes).map_err(|e| Error::invalid_input("block0").with(e))?; - - let settings = wallet::Settings::new(&block0).unwrap(); - for fragment in block0.contents().iter() { - self.free_keys.check_fragment(&fragment.hash(), fragment); - self.account.check_fragment(&fragment.hash(), fragment); - - self.confirm_transaction(fragment.hash()); - } - - Ok(settings) - } - - /// once funds have been retrieved with `iohk_jormungandr_wallet_retrieve_funds` - /// it is possible to convert all existing funds to the new wallet. - /// - /// The returned arrays are transactions to send to the network in order to do the - /// funds conversion. - /// - /// Don't forget to call `iohk_jormungandr_wallet_delete_conversion` to - /// properly free the memory - /// - /// # Safety - /// - /// This function dereference raw pointers (wallet, settings and conversion_out). Even though - /// the function checks if the pointers are null. Mind not to put random values - /// in or you may see unexpected behaviors - /// - pub fn convert(&mut self, settings: Settings, valid_until: &BlockDate) -> Conversion { - let address = self.account.account_id().address(settings.discrimination()); - - let mut raws = Vec::new(); - let mut ignored = Vec::new(); - - let account = &mut self.account; - let mut for_each = |fragment: Fragment, mut ignored_inputs: Vec| { - raws.push(fragment.serialize_as_vec().unwrap()); - ignored.append(&mut ignored_inputs); - account.check_fragment(&fragment.hash(), &fragment); - }; - - for (fragment, ignored) in wallet::transaction::dump_free_utxo( - &settings, - &address, - &mut self.free_keys, - *valid_until, - ) { - for_each(fragment, ignored) - } - - Conversion { - ignored, - transactions: raws, - } + Ok(Wallet { account }) } /// use this function to confirm a transaction has been properly received /// /// This function will automatically update the state of the wallet pub fn confirm_transaction(&mut self, id: FragmentId) { - self.free_keys.confirm(&id); self.account.confirm(&id); } - /// Get IDs of all pending transactions. Pending transactions - /// can be produced by `convert`, and remain in this list until confirmed - /// with the `confirm_transaction` method, or removed - /// with the `remove_pending_transaction` method. - /// - // TODO: this might need to be updated to have a more user friendly - // API. Currently do this for simplicity - pub fn pending_transactions(&self) -> Vec { - let mut check = std::collections::HashSet::new(); - let mut result = vec![]; - - for id in self.free_keys.pending_transactions() { - if check.insert(*id) { - result.push(*id); - } - } - - for id in self.account.pending_transactions() { - if check.insert(*id) { - result.push(*id); - } - } - - result - } - - /// remove a given pending transaction returning the associated Inputs - /// that were used for this transaction - pub fn remove_pending_transaction(&mut self, _id: &FragmentId) -> Option> { - // there are no cordova bindings for this, so this todo is not that important right now - // and I'm not that sure what's the best api here. - todo!("pending transactions"); - } - /// get the current spending counter /// pub fn spending_counter(&self) -> u32 { @@ -244,10 +82,7 @@ impl Wallet { /// how much the wallet started with or retrieved from the chain. /// pub fn total_value(&self) -> Value { - self.free_keys - .utxos() - .total_value() - .saturating_add(self.account.value()) + self.account.value() } /// Update the wallet's account state. diff --git a/bindings/wallet-js/src/lib.rs b/bindings/wallet-js/src/lib.rs index d75f2af3..69262723 100644 --- a/bindings/wallet-js/src/lib.rs +++ b/bindings/wallet-js/src/lib.rs @@ -1,12 +1,10 @@ //! JavaScript and TypeScript bindings for the Jormungandr wallet SDK. -use js_sys::Array; use rand_chacha::rand_core::SeedableRng; use rand_chacha::ChaCha20Rng; use std::convert::TryInto; use wasm_bindgen::prelude::*; -use wasm_bindgen::JsCast as _; mod utils; @@ -28,9 +26,6 @@ pub struct Wallet(wallet_core::Wallet); #[wasm_bindgen] pub struct Settings(wallet_core::Settings); -#[wasm_bindgen] -pub struct Conversion(wallet_core::Conversion); - /// Information about a proposal in a vote plan deployed onto the blockchain. #[wasm_bindgen] pub struct Proposal(wallet_core::Proposal); @@ -75,19 +70,6 @@ pub struct BlockDate(chain_impl_mockchain::block::BlockDate); #[wasm_bindgen] impl Wallet { - /// Recovers a wallet from the given BIP39 mnemonics and password. - /// - /// You can also use this function to recover a wallet even after you have - /// transferred all the funds to the new format (see the `convert` method). - /// - /// The mnemonics should be in the normalized Unicode form NFKD. - /// A string of plain English words satisfies this requirement. - pub fn recover(mnemonics: &str, password: &[u8]) -> Result { - wallet_core::Wallet::recover(mnemonics, password) - .map_err(|e| JsValue::from(e.to_string())) - .map(Wallet) - } - /// Imports private keys to create a wallet. /// /// The `account` parameter gives the Ed25519Extended private key @@ -110,10 +92,6 @@ impl Wallet { .map(Wallet) } - pub fn convert(&mut self, settings: &Settings, valid_until: &BlockDate) -> Conversion { - Conversion(self.0.convert(settings.0.clone(), &valid_until.0)) - } - /// get the account ID bytes /// /// This ID is also the account public key, it can be used to retrieve the @@ -122,24 +100,6 @@ impl Wallet { self.0.id().as_ref().to_vec() } - /// Retrieve funds belonging to the wallet in the given block0 (or - /// any other blocks). - /// - /// After this function is executed, the wallet user can check how much - /// funds have been retrieved from fragments of the given block. - /// - /// This function can take some time to run, so it is better to only - /// call it if needed. - /// - /// This function should not be called twice with the same block. - /// In a future revision of this library, this limitation may be lifted. - pub fn retrieve_funds(&mut self, block0: &[u8]) -> Result { - self.0 - .retrieve_funds(block0) - .map_err(|e| JsValue::from(e.to_string())) - .map(Settings) - } - /// Get the total value in the wallet. /// /// Make sure to call `retrieve_funds` prior to calling this function, @@ -202,59 +162,6 @@ impl Wallet { pub fn confirm_transaction(&mut self, fragment: &FragmentId) { self.0.confirm_transaction(fragment.0); } - - /// Returns the list of pending transaction IDs. - /// - /// This method can be used to query the fragment status with the node API - /// and then confirm the transactions for the - /// wallet state using `confirm_transaction`. - pub fn pending_transactions(&self) -> FragmentIds { - self.0 - .pending_transactions() - .iter() - .cloned() - .map(FragmentId) - .map(JsValue::from) - .collect::() - .unchecked_into::() - } -} - -#[wasm_bindgen] -impl Conversion { - /// retrieve the total number of ignored UTxOs in the conversion - /// transactions - /// - /// this is the number of utxos that are not included in the conversions - /// because it is more expensive to use them than to ignore them. This is - /// called dust. - pub fn num_ignored(&self) -> usize { - self.0.ignored().len() - } - - /// retrieve the total value lost in dust utxos - /// - /// this is the total value of all the ignored UTxOs because - /// they are too expensive to use in any transactions. - /// - /// I.e. their individual fee to add as an input is higher - /// than the value they individually holds - pub fn total_value_ignored(&self) -> u64 { - self.0 - .ignored() - .iter() - .map(|i| *i.value().as_ref()) - .sum::() - } - - /// the number of transactions built for the conversion - pub fn transactions_len(&self) -> usize { - self.0.transactions().len() - } - - pub fn transactions_get(&self, index: usize) -> Option> { - self.0.transactions().get(index).map(|t| t.to_owned()) - } } #[wasm_bindgen] diff --git a/bindings/wallet-uniffi/src/lib.rs b/bindings/wallet-uniffi/src/lib.rs index 0a5947e5..289eb329 100644 --- a/bindings/wallet-uniffi/src/lib.rs +++ b/bindings/wallet-uniffi/src/lib.rs @@ -105,12 +105,6 @@ pub struct BlockDate { pub struct SecretKeyEd25519Extended(SecretKey); -pub struct Conversion { - pub ignored_value: u64, - pub ignored_count: u32, - pub fragments: Vec>, -} - // kotlin codegen does not support wrapped types (rust newtypes) for now at least, // and writing custom type wrappers for this doesn't seem worth it. pub type FragmentId = Vec; @@ -170,39 +164,6 @@ impl Wallet { Ok(Self(Mutex::new(inner))) } - pub fn from_mnemonics(mnemonics: String, password: Vec) -> Result { - let wallet = InnerWallet::recover(&mnemonics, &password)?; - - Ok(Self(Mutex::new(wallet))) - } - - pub fn convert(&self, settings: Arc, valid_until: BlockDate) -> Conversion { - let mut wallet = self.0.lock().unwrap(); - let settings = settings.0.lock().unwrap(); - - // TODO: change the signature of convert to take a reference to the settings instead - let conversion = wallet.convert(settings.clone(), &valid_until.into()); - - Conversion { - ignored_value: conversion - .ignored() - .iter() - .map(|input| input.value().0) - .sum(), - ignored_count: conversion.ignored().len() as u32, - fragments: conversion - .transactions() - .iter() - // unwrapping here because fragments generated by the library should deserialize - // just fine. - // a refactor would be needed somehow to skip useless - // serialization/deserialization, but it can be done later. - .map(|raw| Fragment::new(raw.to_vec()).unwrap()) - .map(Arc::new) - .collect(), - } - } - pub fn set_state(&self, value: u64, counter: u32) { let mut guard = self.0.lock().unwrap(); @@ -218,16 +179,6 @@ impl Wallet { self.0.lock().unwrap().confirm_transaction(h.into()) } - pub fn pending_transactions(&self) -> Vec { - self.0 - .lock() - .unwrap() - .pending_transactions() - .iter() - .map(|f_id| f_id.as_ref().to_vec()) - .collect() - } - pub fn vote( &self, settings: Arc, @@ -258,14 +209,6 @@ impl Wallet { pub fn total_value(&self) -> Value { self.0.lock().unwrap().total_value().0 } - - pub fn retrieve_funds(&self, block0_raw: Vec) -> Result, WalletError> { - let mut wallet = self.0.lock().unwrap(); - - let settings = wallet.retrieve_funds(&block0_raw)?; - - Ok(Arc::new(Settings(Mutex::new(settings)))) - } } impl Settings { diff --git a/bindings/wallet-uniffi/src/lib.udl b/bindings/wallet-uniffi/src/lib.udl index fff18f5d..da7176d4 100644 --- a/bindings/wallet-uniffi/src/lib.udl +++ b/bindings/wallet-uniffi/src/lib.udl @@ -27,20 +27,12 @@ interface Wallet { sequence utxo_keys ); - [Name=from_mnemonics, Throws=WalletError] - constructor(string mnemonics, sequence password); - - Conversion convert(Settings settings, BlockDate valid_until); void set_state(u64 value, u32 counter); [Throws=WalletError] sequence vote(Settings settings, Proposal proposal, u8 choice, BlockDate valid_until); - void confirm_transaction(sequence fragment_id); - sequence> pending_transactions(); sequence account_id(); u32 spending_counter(); u64 total_value(); - [Throws=WalletError] - Settings retrieve_funds(sequence block0); }; interface SecretKeyEd25519Extended { @@ -113,12 +105,6 @@ dictionary BlockDate { u32 slot; }; -dictionary Conversion { - u64 ignored_value; - u32 ignored_count; - sequence fragments; -}; - [Enum] interface PayloadTypeConfig { Public(); From d72a6f9a612eaa0af72ee2ed007ec986f7323451 Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini Date: Mon, 14 Mar 2022 11:29:34 -0300 Subject: [PATCH 3/4] remove unused DumpIcarus type --- wallet/src/transaction/dump.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/wallet/src/transaction/dump.rs b/wallet/src/transaction/dump.rs index c04acbcd..1886e7e4 100644 --- a/wallet/src/transaction/dump.rs +++ b/wallet/src/transaction/dump.rs @@ -15,8 +15,6 @@ pub struct DumpIter<'a, W> { valid_until: BlockDate, } -pub type DumpIcarus<'a> = - DumpIter<'a, crate::scheme::bip44::Wallet>; pub type DumpFreeKeys<'a> = DumpIter<'a, crate::scheme::freeutxo::Wallet>; pub fn send_to_one_address( From 6cf261adf35d592f708ca7db4954589d00447ce2 Mon Sep 17 00:00:00 2001 From: Enzo Cioppettini Date: Mon, 14 Mar 2022 11:29:58 -0300 Subject: [PATCH 4/4] update Cargo.lock --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa8c9213..bc670953 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,7 +175,7 @@ dependencies = [ [[package]] name = "cardano-legacy-address" version = "0.1.1" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "cbor_event", "chain-ser", @@ -233,7 +233,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chain-addr" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "bech32 0.8.1", "chain-core", @@ -244,7 +244,7 @@ dependencies = [ [[package]] name = "chain-core" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "chain-ser", ] @@ -252,7 +252,7 @@ dependencies = [ [[package]] name = "chain-crypto" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "bech32 0.8.1", "cryptoxide", @@ -270,7 +270,7 @@ dependencies = [ [[package]] name = "chain-impl-mockchain" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "cardano-legacy-address", "chain-addr", @@ -304,12 +304,12 @@ dependencies = [ [[package]] name = "chain-ser" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" [[package]] name = "chain-time" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "chain-core", "chain-ser", @@ -318,9 +318,9 @@ dependencies = [ [[package]] name = "chain-vote" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "chain-core", "chain-crypto", "const_format", @@ -652,7 +652,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "imhamt" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" dependencies = [ "thiserror", ] @@ -1116,7 +1116,7 @@ checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" [[package]] name = "sparse-array" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" [[package]] name = "static_assertions" @@ -1251,7 +1251,7 @@ dependencies = [ [[package]] name = "typed-bytes" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#dd78f1699135ae850ec228dba50f5ff76dfd0ada" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#6c8b145feb6c68a7feb63e10e75bd14d3a2b3841" [[package]] name = "typenum"