BlobSafe is a wallet-owned storage dApp for private team files on Shelby Protocol.
Live app: https://blobsafe.vercel.app
Repository: https://github.com/0xPevita/blobsafe
BlobSafe combines Shelby storage, Aptos wallet signatures, client-side encryption, and on-chain access control. Sensitive files are sealed in the browser before upload, while public files remain directly readable through Shelby and S3-compatible tooling.
Most team file tools require trust in a centralized provider. The provider can see file contents, change access policy, or remove access. BlobSafe is designed around a different model:
- the browser encrypts private files before they touch the network;
- the wallet owner controls decrypt access;
- access grants and revocations are committed on-chain;
- Shelby stores the blobs and provides high-throughput reads;
- recovery metadata can be saved as wallet-encrypted Shelby blobs for cross-device use.
BlobSafe is not a generic cloud drive clone. It is a Web3-native vault for teams, DAOs, and developers who need verifiable ownership, cryptographic privacy for sealed files, and practical file workflows.
flowchart LR
owner[Owner wallet] --> sign[Wallet signature]
sign --> seal[Browser seals file<br/>AES-256-GCM]
seal --> shelby[Shelby blob storage<br/>sealed bytes]
seal --> receipt[Local receipt<br/>hash and wrapped key]
receipt --> recovery[Encrypted recovery point<br/>optional Shelby backup]
owner --> contract[Aptos access contract]
contract --> register[Register file metadata]
contract --> grant[Grant, renew, expire, revoke]
grant --> package[Recipient grant JSON<br/>plus access code]
package --> recipient[Recipient wallet]
recipient --> verify[Verify active on-chain grant]
verify --> decrypt[Decrypt shared file in browser]
shelby --> decrypt
BlobSafe is running on ShelbyNet and Shelby Testnet configuration paths.
Implemented and tested:
- public file upload and preview;
- encrypted file seal, preview, download, and SHA-256 verification;
- wallet-scoped file and folder listing;
- on-chain file registration;
- on-chain access grant, timed grant, renewal, expiry, and revoke;
- group grant delivery with per-recipient grant JSON and access code;
- recipient import and shared-file download;
- recovery point save and restore across browsers/devices;
- audit log for storage, registry, grant, revoke, delete, and recovery events;
- network switch between ShelbyNet and Shelby Testnet;
- Shelby S3 Gateway validation tooling.
| Surface | Value |
|---|---|
| Production app | https://blobsafe.vercel.app |
| Primary network | ShelbyNet |
| Contract module | 0x852058e9eff548bc28eb315812d3c92f0baff51f4673ce14e1e1cfd2be956300::access_control |
| Contract version | module_version() == 6 |
| Frontend deploy | Vercel |
| Source branch | main |
The same dApp can switch to Shelby Testnet when the corresponding API key and contract address are configured.
| Vault overview | Seal files |
|---|---|
![]() |
![]() |
| Owned files | Shared access |
|---|---|
![]() |
![]() |
| Recipient groups | Vault settings |
|---|---|
![]() |
![]() |
| Audit activity |
|---|
![]() |
Encrypted files use browser Web Crypto AES-256-GCM. Each file gets a per-file key. The key is wrapped with a wallet-signature-derived key, so BlobSafe does not receive plaintext file keys.
Public uploads are intentionally plaintext. They are useful for media, public artifacts, or files that should be readable from another browser without restoring private receipt metadata.
The Move contract records file ownership metadata and recipient access grants. Owners can grant, renew, expire, or revoke access. Recipients must have an active grant before BlobSafe lets them decrypt a shared encrypted file.
Encrypted files need local receipt metadata to preview and decrypt. BlobSafe can save a wallet-encrypted recovery point back to Shelby. A new browser can detect that recovery point and restore the receipts after the same wallet signs.
BlobSafe uses predictable Shelby blob names:
blobsafe/encrypted/<folder>/<file>
blobsafe/public/<folder>/<file>
blobsafe/backups/receipt-backup-...
This keeps folders portable across the dApp and S3-compatible clients.
The repo includes a Shelby S3 Gateway config template and validator. Public files copied through S3 open directly. Encrypted files copied through S3 remain sealed bytes and must be decrypted through BlobSafe with the right wallet or active grant.
| Layer | Technology |
|---|---|
| App | Vite, React 18, TypeScript |
| Styling | Tailwind CSS |
| Motion | Framer Motion |
| Storage | Shelby Protocol SDK / React SDK |
| Chain | Aptos TypeScript SDK |
| Wallet | Aptos Wallet Adapter |
| Encryption | Web Crypto API |
| State | TanStack Query, Zustand |
| Contract | Aptos Move |
| Deploy | Vercel |
Copy the example file:
cp .env.example .env.localRequired frontend variables:
VITE_SHELBYNET_API_KEY=aptoslabs_your_key_here
VITE_SHELBY_TESTNET_API_KEY=aptoslabs_your_key_here
VITE_SHELBY_NETWORK=shelbynet
VITE_BLOBSAFE_CONTRACT_ADDRESS=0xyour_contract_address
VITE_BLOBSAFE_SHELBYNET_CONTRACT_ADDRESS=0xyour_shelbynet_contract_address
VITE_BLOBSAFE_TESTNET_CONTRACT_ADDRESS=0xyour_testnet_contract_addressOptional:
VITE_APTOS_API_KEY=aptoslabs_your_key_here
VITE_SHELBY_S3_GATEWAY_URL=http://localhost:9000Do not put Aptos private keys, S3 secret keys, or Shelby gateway signing secrets in VITE_* variables. Vite exposes those variables to the browser by design.
npm install
npm run devOpen:
http://127.0.0.1:3000
Production build:
npm run build
npm run previewSmoke tests:
npm run test:e2eManual end-to-end coverage is documented in TESTING.md.
The access-control contract lives in:
move/sources/access_control.move
Main responsibilities:
- register file metadata;
- store file owner, blob name, file hash, size, expiry, and deleted state;
- grant and revoke single-recipient access;
- write timed grants and grant expiry state;
- manage team recipient groups;
- expose view functions used by the dApp.
Compile and test:
$env:BLOBSAFE_ADDR="<publisher-address>"
npm run move:compile
npm run move:testPublish and initialize:
$env:BLOBSAFE_ADDR="<publisher-address>"
npm run move:publish
npm run move:init
aptos move run --function-id <publisher-address>::access_control::init_access_index
aptos move run --function-id <publisher-address>::access_control::init_team_registry
aptos move run --function-id <publisher-address>::access_control::init_grant_expiry_index
aptos move run --function-id <publisher-address>::access_control::init_grant_expiry_ledgerThen set the publisher address in .env.local and restart the app.
BlobSafe includes a local gateway template:
tools/s3/shelby.config.example.yaml
Start a local Shelby S3 Gateway:
Copy-Item tools/s3/shelby.config.example.yaml shelby.config.yaml
# Edit shelby.config.yaml with your Shelby API key, bucket owner account, and local S3 signing secret.
npx @shelby-protocol/s3-gateway --config shelby.config.yaml --port 9000Validate list and read:
$env:SHELBY_S3_GATEWAY_URL="http://localhost:9000"
$env:SHELBY_S3_BUCKET="0xyour_wallet_address"
$env:SHELBY_S3_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
$env:SHELBY_S3_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
npm run s3:validateValidate a specific object:
$env:BLOBSAFE_S3_OBJECT_KEY="blobsafe/public/<folder>/<file>"
npm run s3:validateOptional PUT validation:
$env:BLOBSAFE_S3_PUT_TEST="true"
npm run s3:validatePUT validation requires the gateway account to be the same account as the bucket owner and to have enough Shelby storage funds.
BlobSafe separates storage from decryption authority.
- Shelby stores blobs.
- Aptos records ownership and access metadata.
- The browser performs encryption and decryption.
- The wallet signs messages used to derive local wrapping keys.
- Grant payloads contain encrypted key material, not plaintext keys.
Important boundaries:
- public files are not encrypted;
- encrypted files require a receipt or recovery point to decrypt;
- recovery points are encrypted and wallet-scoped;
- S3 downloads of encrypted objects return sealed bytes;
VITE_*values are public browser config, not server secrets.
- This is a browser-first dApp. Large-file UX should still be tested under real community load.
- Aptos wallet adapter dependencies currently emit peer dependency warnings during install, but production builds complete successfully.
- S3 Gateway validation is local-tooling based. BlobSafe does not embed S3 signing secrets in the browser.
- Encrypted-file recovery depends on users saving or restoring wallet-encrypted receipt recovery points.
src/
pages/
LandingPage.tsx
DappPage.tsx
DappRoute.tsx
components/
FileUpload.tsx
FileList.tsx
SharedAccess.tsx
TeamAccess.tsx
ReceiptBackupPanel.tsx
lib/
accessControl.ts
encryption.ts
receiptBackups.ts
shareGrants.ts
shelby.ts
teams.ts
store/
useFileStore.ts
move/
sources/access_control.move
tools/
s3/
validate-s3.mjs
shelby.config.example.yaml
MIT. See LICENSE.







