diff --git a/src/Simplex/Chat/Library/Commands.hs b/src/Simplex/Chat/Library/Commands.hs index 6f5845c1e7..ad21a337e0 100644 --- a/src/Simplex/Chat/Library/Commands.hs +++ b/src/Simplex/Chat/Library/Commands.hs @@ -5590,7 +5590,7 @@ chatCommandP = "/_service_response " *> (APISendServiceResponse <$> A.decimal <* A.space <*> strP <* A.space <*> jsonP), "/_wallet create" $> APIWalletCreate, "/_wallet import " *> (APIWalletImport <$> textP), - "/_wallet export " *> (APIWalletExportDerivedSecret <$> A.decimal <* A.space <*> A.decimal), + "/_wallet export " *> (APIWalletExportDerivedSecret <$> keyIndexP <* A.space <*> keyIndexP), "/_wallet export" $> APIWalletExportSeedMnemonic, "/_wallet delete" $> APIWalletDelete, "/_wallet" $> APIWallet, @@ -6134,6 +6134,10 @@ chatCommandP = quotedP = safeDecodeUtf8 <$> (A.char '"' *> A.takeTill (== '"') <* A.char '"') text1P = safeDecodeUtf8 <$> A.takeTill (== ' ') char_ = optional . A.char + -- BIP-32 hardens at 2^31, and Word32 would wrap + keyIndexP = do + i <- A.decimal :: Parser Integer + if i < 0x80000000 then pure (fromIntegral i) else fail "key index too large" displayNameP :: Parser Text displayNameP = safeDecodeUtf8 <$> displayNameP_ diff --git a/tests/WalletTests.hs b/tests/WalletTests.hs index e070732712..4039364726 100644 --- a/tests/WalletTests.hs +++ b/tests/WalletTests.hs @@ -126,6 +126,9 @@ testWalletExportDerivedSecret ps = withNewTestChat ps "alice" aliceProfile $ \al _ <- accountRows alice "alice, active" 0 alice ##> "/_wallet export 0 0" alice <## "m/44'/60'/0'/0/0 0x9858EfFD232B4033E47d90003D41EC34EcaEda94 0x1ab42cc412b618bdea3a599e3c9bae199ebf030895b039e9db1e30dafb12b727" + -- an index BIP-32 cannot harden is rejected, not wrapped into another account + alice ##> "/_wallet export 4294967296 0" + alice <## "bad chat command: Failed reading: empty" -- any path derives, whether or not a profile holds that account alice ##> "/_wallet export 3 7" l <- getTermLine alice