diff --git a/Cargo.lock b/Cargo.lock index 811d8376a..d31511154 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1225,6 +1225,15 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +[[package]] +name = "bip39" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc" +dependencies = [ + "bitcoin_hashes", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -3307,6 +3316,13 @@ dependencies = [ "tokio", ] +[[package]] +name = "gem_keystore" +version = "1.0.0" +dependencies = [ + "bip39", +] + [[package]] name = "gem_near" version = "1.0.0" @@ -3578,6 +3594,7 @@ dependencies = [ "gem_hash", "gem_hypercore", "gem_jsonrpc", + "gem_keystore", "gem_near", "gem_polkadot", "gem_solana", diff --git a/Cargo.toml b/Cargo.toml index 007cf9aac..f5c8c9eea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,6 +115,7 @@ sui-types = { package = "sui-sdk-types", version = "0.3.0", features = [ "serde", ] } k256 = { version = "0.13.4", features = ["ecdsa", "sha256"] } +bip39 = { version = "2.2.2", default-features = false } uniffi = { version = "0.31.1" } regex = { version = "1.12.3" } diff --git a/crates/gem_keystore/Cargo.toml b/crates/gem_keystore/Cargo.toml new file mode 100644 index 000000000..5d1025ad0 --- /dev/null +++ b/crates/gem_keystore/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gem_keystore" +version = { workspace = true } +edition = { workspace = true } + +[dependencies] +bip39 = { workspace = true } diff --git a/crates/gem_keystore/src/lib.rs b/crates/gem_keystore/src/lib.rs new file mode 100644 index 000000000..fbbe1bbd4 --- /dev/null +++ b/crates/gem_keystore/src/lib.rs @@ -0,0 +1,3 @@ +mod mnemonic; + +pub use mnemonic::Mnemonic; diff --git a/crates/gem_keystore/src/mnemonic.rs b/crates/gem_keystore/src/mnemonic.rs new file mode 100644 index 000000000..da45efdd6 --- /dev/null +++ b/crates/gem_keystore/src/mnemonic.rs @@ -0,0 +1,28 @@ +use bip39::Language; + +pub struct Mnemonic; + +impl Mnemonic { + pub fn suggest(prefix: &str) -> Vec { + let prefix = &prefix.trim().to_lowercase(); + if prefix.is_empty() { + return Vec::new(); + } + Language::English.words_by_prefix(prefix).iter().map(|word| word.to_string()).collect() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_suggest() { + assert_eq!(Mnemonic::suggest("woo"), vec!["wood", "wool"]); + assert_eq!(Mnemonic::suggest("abandon"), vec!["abandon"]); + assert_eq!(Mnemonic::suggest("woof"), Vec::::new()); + + let all_words = Mnemonic::suggest(" "); + assert_eq!(all_words.len(), 0); + } +} diff --git a/gemstone/Cargo.toml b/gemstone/Cargo.toml index 8830c12d7..623dbaeab 100644 --- a/gemstone/Cargo.toml +++ b/gemstone/Cargo.toml @@ -41,6 +41,7 @@ gem_xrp = { path = "../crates/gem_xrp", features = ["rpc", "signer"] } gem_near = { path = "../crates/gem_near", features = ["rpc", "signer"] } gem_polkadot = { path = "../crates/gem_polkadot", features = ["rpc", "signer"] } gem_wallet_connect = { path = "../crates/gem_wallet_connect" } +gem_keystore = { path = "../crates/gem_keystore" } chain_traits = { path = "../crates/chain_traits" } signer = { path = "../crates/signer" } number_formatter = { path = "../crates/number_formatter" } diff --git a/gemstone/src/keystore.rs b/gemstone/src/keystore.rs new file mode 100644 index 000000000..6d2c7c7b4 --- /dev/null +++ b/gemstone/src/keystore.rs @@ -0,0 +1,17 @@ +use gem_keystore::Mnemonic; + +#[uniffi::export] +pub fn suggest_recovery_phrase_words(prefix: &str) -> Vec { + Mnemonic::suggest(prefix) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_suggest_recovery_phrase_words() { + assert_eq!(suggest_recovery_phrase_words("woo"), vec!["wood", "wool"]); + assert_eq!(suggest_recovery_phrase_words("woof"), Vec::::new()); + } +} diff --git a/gemstone/src/lib.rs b/gemstone/src/lib.rs index d6209cd07..942f51776 100644 --- a/gemstone/src/lib.rs +++ b/gemstone/src/lib.rs @@ -9,6 +9,7 @@ pub mod deeplink; pub mod ethereum; pub mod gateway; pub mod gem_swapper; +pub mod keystore; pub mod message; pub mod models; pub mod network;