signArbitrary (ADR-036). Follow Build a browser app first if you are starting fresh. The Research Archive uses this exact pattern for encrypted drafts with secure collaboration.
How it works
The scheme uses two keys. The wallet key is re-derived from a wallet signature whenever needed. A random document key encrypts the file itself.Implement the pattern
1
Install libsodium
vite.config.ts
2
Derive a key from the wallet
Instead of asking users to manage separate encryption passwords, derive a deterministic key from a wallet signature.
src/crypto.ts
Why ADR-036? Signing a fixed message means the same wallet always produces the same signature, which derives the same encryption key. The key is never stored. It is re-derived on demand, so users only need their wallet to decrypt.
3
Add encrypt and decrypt helpers
The helpers wrap libsodium’s
crypto_secretbox authenticated encryption.src/crypto.ts
4
Upload encrypted files
Each file gets its own random document key. The document key encrypts the file. The wallet key encrypts the document key so the owner can recover it later. Everything travels inside one JSON manifest.
src/encrypted-cascade.ts
5
Download and decrypt
Download the manifest, recover the document key with the wallet key, then decrypt the file.
src/encrypted-cascade.ts
6
Share with collaborators
To share an encrypted file, re-encrypt the document key under the collaborator’s wallet-derived key.The collaborator downloads the invitation, decrypts the document key with their wallet, and uses it to decrypt the file.For a complete implementation of this pattern, see the Research Archive example.
Next steps
Research Archive example
See this encryption pattern inside a full application.
Upload lifecycle
Follow an upload from registration to completion.
JavaScript SDK reference
Look up the uploadFile and download options.