identity.rs
identity.rs copied to clipboard
[Task] Wasm Bindings Improvements
Description
Remove exposure of Ed25519.sign, remove Storage
Send/Sync
ties to the wasm
feature, and make keyDel in typescript compatible with the Rust code. Refactor the Storage
trait to return better errors, and simplify its API.
Motivation
- Users should be able to sign data without relying on our code.
- We might need the Storage trait not to be Send/Sync for other bindings (e.g Python) as well, so we should not tie its bounds to the
wasm
feature. - Js implementation of
MemStore
keyDel
slightly differs from the Rust code regarding idempotency. -
identity_account::types::signature::Signature::pkey
is not used in the Rust code. -
Storage::set_password
is no longer needed. - Improve error feedback. See: https://github.com/iotaledger/identity.rs/pull/597#discussion_r812013066
To-do list
- [x] Assess the need to expose Ed25519.sign - @noble/ed25519 might provide the correct signature
- [ ] Remove Storage ties to
wasm
feature- [ ] Change the way the Account handles Storage
- [x] Use the
cfg_attr
on Storage and change the name of the feature that enables it
- [x] Decide whether
Storage::key_del
should be idempotent or not. #729 - [x] Refactor
Account
Signature
not to containPublicKey
https://github.com/iotaledger/identity.rs/issues/722 - [x] Remove
SetPassword
method fromStorage
https://github.com/iotaledger/identity.rs/issues/720 - [ ] Investigate simplification of state in the
Storage
interface, potentially reducing the number of state variables - [ ] Refactor
Error
forStorage
Interface- [ ] Introduce a reasonably abstract error type that can accommodate many
Storage
implementations, including any type of file- or network-I/O-related failures
- [ ] Introduce a reasonably abstract error type that can accommodate many
- [x] Prefer to use
UInt8Array
rather than Base58-BTC encoded strings for keys. https://github.com/iotaledger/identity.rs/issues/721 - [x] Write macro for
napi
related types and impl - #872 - [ ] Assess
NapiResult
error messages - [x] Avoid Serializing and Deserializing keys
Change checklist
Add an x
to the boxes that are relevant to your changes, and delete any items that are not.
- [ ] The feature or fix is implemented in Rust and across all bindings whereas possible.
- [ ] The feature or fix has sufficient testing coverage
- [ ] All tests and examples build and run locally as expected
- [ ] Every piece of code has been document according to the documentation guidelines.
- [ ] If conceptual documentation (mdbook) and examples highlighting the feature exist, they are properly updated.
- [ ] If the feature is not currently documented, a documentation task Issue has been opened to address this.
Users are already able to sign data without relying on our code.
E.g. using TweetNaCl
const key = new KeyPair(KeyType.Ed25519);
const seed = bs58.decode(key.private);
let naclKeyPair = nacl.sign.keyPair.fromSeed(seed);
let challengeBytes = Uint8Array.from([1,2,3,4]);
let signature = nacl.sign(challengeBytes, naclKeyPair.secretKey);
console.log(`Signature: ${bs58.encode(signature)}`);
I do think we should switch to using UInt8Array
to represent the private/public keys though, from Base58-BTC encoded strings. This is because it's the type existing libraries like TweetNaCl expect as input and to avoid requiring developers bring in Base58 dependencies to decode the strings we return. Alternative would be to expose the dencode_b58
, decode_multibase
functions too, which might be useful for Storage
implementers regardless.
Advantages of exposing Ed25519::sign
:
- It can be compatible with our exposed structs, like
KeyPair
,WasmPrivateKey
or generalised toUInt8Array
/String
. - It's shipped in the Wasm bytecode anyway, we may as well expose it along with other functions.
- It can avoid external dependencies for developers.
Disadvantages:
- API bloat: increasing the API surface also increases the maintenance cost.
- Slight code bloat.
We have had requests to include other features in identity.rs
such as BIP-39 mnemonics, so I think some developers might appreciate being able to use same the functions we do internally out of convenience.
See also this comment: https://github.com/iotaledger/identity.rs/pull/597/files#r811781156
We might need the Storage trait not to be Send/Sync for other bindings (e.g Python) as well, so we should not tie its bounds to the wasm feature.
I agree. Some conditional compilation required now just for wasm
might be beneficial for other use-cases too, so we can use other features (named more specifically like storage-sync
for example) on top of target-based compilation.
Edit: as long as enabling --all-features
does not break compilation.
Verify the need to return an error on KeyDel
~~I think all Storage
functions need to be async and fallible to account for unknowable remote implementations where every little network request could fail.~~ Not the point the issue raised, it's about idempotency and consistency between Rust and bindings behaviour.
This comment on #660 may have been missed regarding the Stronghold bindings package namespace: https://github.com/iotaledger/identity.rs/pull/660/files#r816770207
Edit: resolved.
As per internal discussions, the following tasks were marked as either important or easy to do prior to 0.5.0.
- Prefer to use
UInt8Array
rather than Base58-BTC encoded strings for keys in the Wasm bindings. https://github.com/iotaledger/identity.rs/issues/721 - Decide whether
Storage::key_del
should be idempotent or not. #729 - Refactor
Account
Signature
not to contain PublicKey. https://github.com/iotaledger/identity.rs/issues/722 - Remove
SetPassword
method from Storage. https://github.com/iotaledger/identity.rs/issues/720
Each needs its own issue or PR now.