BsafeDecentralized storage

Documentation

Bsafe docs

Everything about the Bsafe network: storing files on it, adding your own node to it, and how data, keys and money move through it.

Start

Introduction

Bsafe Protocol is a decentralized storage network. Instead of one company's data centre, your files live on storage nodes run by independent operators: people and teams offering spare disk to the network.

Your browser encrypts each file before it leaves your device, and the sealed copy is stored on three different nodes. The network watches every node and rebuilds any copy that goes missing. You pay once, on-chain, and that payment funds a reward pool that only node operators can be paid from.

01Distributed

Three copies on three independent operators' nodes.

02Encrypted

Files and names sealed in your browser. Nodes only see ciphertext.

03Self-healing

Lost copies are rebuilt from healthy ones within seconds.

04Open

Anyone can run a node. A public contract pays them.

Start

Store your first file

About two minutes, start to finish.

  1. Get a wallet. Any browser wallet such as MetaMask, on Ethereum Mainnet (chain ID 1) with a little ETH.
  2. Open the vault. Go to the vault, press Connect wallet and sign the message. Signing is free.
  3. Unlock storage. Press Unlock storage and confirm. The price is read from the contract, so you always send the exact amount.
  4. Upload. Drag files anywhere onto the vault or press Upload. Each one is encrypted on your device, then copied to three nodes.
  5. Come back from anywhere. Sign in from any browser with the same wallet and your files decrypt locally.

Browser forgot your payment? Sign in again. The backend reads hasPurchased for your wallet from the contract and restores access. You are never charged twice.

Start

Run a node

Nodes are the network. A node is a small Node.js server that keeps encrypted copies on disk and earns ETH for the space it holds, the data it serves and the hours it stays online. One machine can run several nodes, each in its own folder.

1. Mint a join token

Open Nodes and connect the wallet that should own the node and receive its rewards. Name the node, choose how much space to offer, and press Mint join token. A token works once and expires after 24 hours.

2. Start the node

You need Node.js 18 or newer and Git. The node software is open source: github.com/YOUR-ORG/bsafe-node. The console gives you this command with your token filled in.

$ git clone https://github.com/YOUR-ORG/bsafe-node.git
$ cd usernode
$ npm install
$ node server.js --token bsj_… --port 4001 --capacity 5 --home ./nodes/home-server --tunnel

On its first start the node:

  • creates its own identity key in <home>/wallet.json;
  • signs a join request carrying your token;
  • passes a contact check: the coordinator calls the node's /health and confirms the same identity answers;
  • saves its assigned ID in <home>/node.json.

Later starts need no token. From the usernode folder, run the restart command shown on the node's card in the console. To update, run git pull there and restart.

FlagEnv varDefaultWhat it does
--tokenJOIN_TOKEN–One-time join token (first start only)
--portPORT4001Port the node listens on
--homeNODE_HOMEthe usernode folderWhere identity, config and data live
--capacityCAPACITY_GB1Space you offer, in GB
--tunnelTUNNEL=1offOpen a Cloudflare quick tunnel and use it as --url
--urlPUBLIC_URLhttp://localhost:<port>Address the coordinator uses to reach the node
--coordinatorCOORDINATORhttp://localhost:5000Where the coordinator lives

Behind a home router

The coordinator pushes data to nodes, so a node needs an address it can reach. --tunnel handles it: npm install also fetches Cloudflare's cloudflared, and the node opens a free quick tunnel (no account, no port forwarding) and joins through it. The address changes on each restart; the coordinator picks up the new one when the node signs in, so identity and earnings carry over. Own a public address? Pass --url https://your-address instead.

3. Retire a node

Press Retire node in the console. The node stops taking new data, its copies move to other nodes, and it shuts down once empty. If the network has no spare room, retirement pauses and you can retry.

The network

How the network works

Five parts cooperate. Independent operators run the storage, Ethereum runs the money, your browser holds the keys, and two network services tie them together.

PartRun byJobCan see
Your browserYouDerives your key; encrypts and decrypts files and namesEverything, for you alone
Storage nodesIndependent operatorsHold and serve copies; answer only the coordinatorRandom-looking bytes
StorageIncentiveEthereumTakes payments, holds the reward pool, pays operatorsPublic on-chain state
CoordinatorNetwork serviceAdmits nodes, places copies, checks health, repairs, meters and settles rewardsOpaque blobs and sizes
BackendNetwork serviceWallet sign-in, payment checks, the encrypted file indexCiphertext, encrypted names, which nodes hold which file

Upload path

Your browser seals the file. The backend checks your session and payment. The coordinator picks three online nodes with room, one per operator first and the least-loaded ones first, and writes the copies in parallel. The backend records which nodes hold the file.

Download path

The backend asks the coordinator for the file from any node holding a live copy. The ciphertext reaches your browser, which decrypts it. If one copy is missing or fails its integrity check, another one is used.

The network

Replication & repair

3copies of every file
5 sbetween node heartbeats
~15 suntil a silent node is marked offline

Each copy goes to a different operator whenever the network has enough of them, so one person switching off their machines can't take out every copy. When a node goes silent, the coordinator asks the backend to repair it: every copy that node held is re-created on another node from a healthy replica, and the index is updated.

A corrupted or tampered copy fails its integrity check on download and is served from another copy instead. How the network handles failures is on the Why page.

The network

Security model

  • Keys. A random 32-byte vault secret is created in your browser and encrypts every file with AES-256-GCM. The backend stores it only wrapped, under a key your browser derives with HKDF-SHA-256.
  • Metadata. Names, types, sizes and dates are encrypted too. The server sees opaque IDs.
  • Integrity. AES-GCM authenticates every file, so a node can't change a copy without the change being detected.
  • Node isolation. Nodes accept data requests only with the coordinator's session token and reject file IDs that could escape their data folder.
  • Node identity. Each node signs its join and login challenges with its own key, so it can't pose as another node.

Money

Payments

Storage is a one-time purchase: call purchaseStorage() with exactly storagePrice. The contract rejects any other amount and any second purchase from the same wallet. Most of the payment goes to the reward pool for node operators; a fixed protocol fee (capped at 20% by the contract) goes to the protocol.

How the backend checks a payment

  1. Its RPC and the transaction are both on chain 1.
  2. The transaction succeeded and has enough confirmations.
  3. It went to the StorageIncentive address, from the signed-in wallet.
  4. Its call data is exactly purchaseStorage().
  5. Its value equals the configured price.
  6. The contract emitted a matching StoragePurchased event.

A transaction hash can be used once. If it is missing or stale, the backend falls back to hasPurchased(wallet), read at a confirmed block. Live values are on the Contracts page.

Money

Node rewards

While a node is online, the coordinator meters three things:

SourceMeasured as
StorageBytes held × time
BandwidthBytes served on downloads
UptimeTime online and reporting in

Rates and the minimum claim are set in the coordinator's configuration (REWARD_*, MIN_PAYOUT), and the console always shows the live numbers.

Getting paid

  1. Register your operator wallet once with registerNode().
  2. Claim. The coordinator, as the contract's settler, calls rewardNode() to move your earnings from the pool to your balance. A claim never exceeds what the pool holds; the rest stays unclaimed.
  3. Withdraw your balance to your wallet with withdraw(), any time. Once credited, nobody can take it back.

Reference

HTTP API

Backend

MethodPathPurpose
POST/nonceGet a login nonce for a wallet
POST/loginTrade a signed nonce for a session
GET/payment-statusWhether the wallet has storage (restores on-chain purchases)
POST/paymentVerify a purchase; txHash is optional
POST/uploadUpload a sealed file and its metadata
GET/filesList your encrypted file index
GET/download/:idFetch a file from any live copy
DELETE/files/:idRemove a file from every node

Authenticated calls send the session in the x-session header.

Coordinator

MethodPathPurpose
GET/networkPublic network totals and reward rates
POST/operator/nonce, /operator/loginWallet sign-in for operators
GET/operator/overviewNodes, earnings, join tokens and payouts
POST/operator/join-tokensMint a one-time join token
POST/operator/nodes/:id/exitStart retiring a node
POST/operator/payoutsSettle unclaimed earnings on-chain

Operator calls send the session in the x-operator-session header.

Reference

Troubleshooting

“Switch your wallet to Ethereum Mainnet”

Approve the network switch your wallet offers. To add the network by hand: chain ID 1, RPC https://eth.drpc.org, currency ETH.

The payment isn't confirmed yet

Wait a few seconds and press Unlock storage again. The same transaction is re-checked and you won't be charged twice.

“No storage nodes with free capacity are online”

The network needs online nodes with free space. Check the live node count on the Nodes page, or add a node of your own.

A node fails its contact check

The coordinator couldn't reach the node at its --url. Check the port and address, or use --tunnel.

The Claim button is disabled

Register your payout wallet first, make sure your unclaimed earnings pass the minimum, and check that the coordinator has settlement configured.