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 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" 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(); 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(