-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
842 use bufbuild type to storetransmit fvk instead of bech32 string #846
842 use bufbuild type to storetransmit fvk instead of bech32 string #846
Conversation
@@ -19,6 +19,7 @@ describe('Connected Sites Slice', () => { | |||
|
|||
beforeEach(() => { | |||
localStorage = mockLocalExtStorage(); | |||
// | |||
useStore = create<AllSlices>()(initializeStore(mockSessionExtStorage(), localStorage)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and in a number of other tests I get an error
TS2322: Type 'UseBoundStore<WithImmer<StoreApi<AllSlices>>>' is not assignable to type 'UseBoundStore<StoreApi<AllSlices>>'.
As I understand it, this is due to the addition of bufbuild types to WalletsSlice
, but I'm not sure if we should rewrite the tests or if we shouldn't use bufbuild types in the slice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is a downside of zustand+immer 😞 . It's not allowed to store bufbuild classes directly. It seems to be a limitation because immer cannot properly do a safe copy of it. So we likely need to be using WalletJson
here. But does this invalidate this whole task? Maybe not, we still should be storing FullViewingKey.toJson() in storage instead of a string.
@@ -19,6 +19,7 @@ describe('Connected Sites Slice', () => { | |||
|
|||
beforeEach(() => { | |||
localStorage = mockLocalExtStorage(); | |||
// | |||
useStore = create<AllSlices>()(initializeStore(mockSessionExtStorage(), localStorage)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is a downside of zustand+immer 😞 . It's not allowed to store bufbuild classes directly. It seems to be a limitation because immer cannot properly do a safe copy of it. So we likely need to be using WalletJson
here. But does this invalidate this whole task? Maybe not, we still should be storing FullViewingKey.toJson() in storage instead of a string.
packages/wasm/crate/src/build.rs
Outdated
/// witness_data: `WitnessData`` | ||
/// Returns: `Action` | ||
#[wasm_bindgen] | ||
pub fn build_action( | ||
transaction_plan: JsValue, | ||
action_plan: JsValue, | ||
full_viewing_key: &str, | ||
full_viewing_key: JsValue, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somewhat related to #844, but we can do something like this so we get types:
pub fn build_action(
transaction_plan: JsValue,
action_plan: JsValue,
full_viewing_key: &[u8],
witness_data: JsValue,
) -> WasmResult<JsValue> {
let full_viewing_key: FullViewingKey = FullViewingKey::decode(full_viewing_key)?;
and then in typescript we pass fullViewingKey.inner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it better? Do we want to get rid of toJson()
serialization and serde_wasm_bindgen
?
Should we do this in all cases when handling {inner: Uint8Array}
types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm working through these cases in #834. I go back and forth honestly. Perhaps it's not better than JsValue. We still pass an opaque type that needs deserializing on the other side. Maybe ignore this for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, here's the idea with this:
- wasm: https://github.com/penumbra-zone/web/pull/834/files#diff-8379276b019dd49da4c1b561332a55996d838efd25a8e02609f6ed40625e94d1R103-R108
- typescript: https://github.com/penumbra-zone/web/pull/834/files#diff-be70ea133ec02a72fd2fc4cd0b3c2782d9ce8d074a426f5490e9abf78e49c29bR14-R17
JsValue
can be anything. And it gets typed to an any
. However, in some cases, we can encode/decode through binary. If we pass an Uint8Array straight to wasm and receive one back, the typescript signature will be strongly enforced. It increases typesafety. It won't work in every case, but for pb types, it often can.
Wherever that bug is, sounds like a good candidate for testing 😅 |
packages/wasm/crate/src/keys.rs
Outdated
let fvk: FullViewingKey = FullViewingKey::decode(full_viewing_key)?; | ||
let result = serde_wasm_bindgen::to_value(&fvk.wallet_id())?; | ||
Ok(result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@grod220
WalletId
has no method .encode_to_vec()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like WalletId is missing a trait in the core repo. I'll open a PR to fix there. In the meantime, let's do:
pub fn get_wallet_id(full_viewing_key: JsValue) -> WasmResult<Vec<u8>> {
utils::set_panic_hook();
let fvk: FullViewingKey = serde_wasm_bindgen::from_value(full_viewing_key)?;
// Can do `fvk.wallet_id().encode_to_vec()` when Domain impl added to WalletId in core
let wallet_id_proto = WalletId::from(fvk.wallet_id());
Ok(wallet_id_proto.encode_to_vec())
}
828bb2f
to
108d4dc
Compare
ed06732
to
888283b
Compare
export enum LocalStorageVersion { | ||
V1 = 'V1', | ||
} | ||
|
||
export interface OriginRecord { | ||
origin: string; | ||
choice: UserChoice; | ||
date: number; | ||
} | ||
|
||
export interface LocalStorageState { | ||
wallets: WalletJson[]; | ||
grpcEndpoint: string; | ||
passwordKeyPrint?: KeyPrintJson; | ||
fullSyncHeight: number; | ||
knownSites: OriginRecord[]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the types that were defined @penumbra-zone/storage/src/chrome/local
to @penumbra-zone/types/src/local-storage
.
This was to avoid a cyclic import which created a bug with the error Cannot read properties of undefined (reading 'V1')
.
This also created a lot of import changes in this PR.
walletId: new WalletId({ | ||
inner: Uint8Array.from({ length: 8 }, () => Math.floor(Math.random() * 256)), | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is actually incorrect, if we want to test idb version update, we should not generate a random dbName, only increase the version.
But the thing is, if we fix this test, it causes all storage tests to hang and timeout error. I will open a separate PR for this fix (since this PR is big without it)
#[wasm_bindgen] | ||
pub fn get_short_address_by_index(full_viewing_key: &str, index: u32) -> WasmResult<JsValue> { | ||
utils::set_panic_hook(); | ||
|
||
let fvk = FullViewingKey::from_str(full_viewing_key)?; | ||
let (address, _dtk) = fvk.incoming().payment_address(index.into()); | ||
let short_address = address.display_short_form(); | ||
Ok(JsValue::from_str(&short_address)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really well done! This wasn't easy 😅 . Before you merge, please do some extensive testing with all user flows (migrating from v1/swapping/staking/send/etc) to ensure there aren't any bugs we missed.
Domain types implement the trait `DomainType` which adds proto encoding/decoding to the struct. This PR adds it for `WalletId`. This is helpful in the wasm crate when we pass over the wasm-javascript boundary: penumbra-zone/web#846 (comment)
I'll just point out I don't think users will have a case when a version is decreased, and developers should just consider that this can happen when switching between branches. |
Ah, good point. After you merge, please make a note in #browser-extension in discord. |
close #842