Store key using `SubtleCrypto` API in browser
15% 😭. But we could future proof by checking support and conditionally using it while sticking to local storage for browsers that don't. Also we need to think about how we want to go about this, I believe WebCrypto can not return the private key, only sign data with it meaning @tomic/lib needs to use it directly. Right now storing the key is handled by browser because that is not really the concern of lib. WebCrypto might not be available in all contexts that lib should be able to run in. It is also not always appropriate for the key to be stored in general, for example on a server that has a store instance for each connected user.
I took a look at the api's and it works a bit different from what I thought. The API gives you a CryptoKey object that can be stored in IndexDB. This means you're not limited to just one stored key. Still I don't think actually storing the key should be the concern of @tomic/lib but we could export some helper functions to make it simple.
However
I ran into another issue when experimenting. I can't seem to make importKey() work with our private keys.
The following code gives me an error saying it can't create the key with the specified usages.
const toArrayBuf = (str: string) => {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
};
const key = await crypto.subtle.importKey(
'raw',
toArrayBuf(atob(agent.privateKey)),
{ name: 'Ed25519' },
false,
['sign'],
);
When generating an ed25519 keypair with crypto.subtle.generateKey() it works just fine so it's likely something to do with the format the private key is stored in.