Docs
d1sks.com does three things: lists every disk that serves an OpenDisk descriptor, says what it is as an OpenObject store, and gives a requester and an agent the same rows as data.
Listing a disk
Serve /.well-known/opendisk.json on your own origin, as application/json. The smallest valid file is a name, the free space and a price:
{ "name": "spare drive, Lisbon", "capacity": { "free_gib": 900 }, "price": { "currency": "USD", "per_gib_month": 0.08 } }Then tell d1sks the origin, on the form or from a terminal:
curl -X POST https://d1sks.pwa.pit.world/api/v1/disks -H 'content-type: application/json' -d '{"url":"https://your-disk.example"}'d1sks fetches the file (https only, 256 KiB at most, ten seconds), validates it against OpenDisk 0.1, and lists it. It dedupes on the seeder key, or on the origin when there is none. Every hour it fetches the file again, skipping one whose ETag has not changed. A file that stops answering three times in a row and stays gone for a day is marked gone, never deleted. Fields the spec names are read; fields it does not are kept and shown. Absence is reported as absence.
Signed listings (behind NAT too)
A disk with an ed25519 libp2p identity, such as every c0mpute node, does not need a public origin. It pushes its descriptor, signed with its own key, and re-sends it as a heartbeat (c0mpute nodes every 5 minutes). The listing expires when the heartbeats stop.
POST https://d1sks.pwa.pit.world/api/v1/disks/announce
{ "payload": "<JSON text>", "signature": "<hex ed25519 signature over the payload text>" }
payload: { "type": "c0mpute.disk.announce/1", "marketplace": "d1sks.pwa.pit.world",
"peer_id": "12D3KooW...", "key": "ed25519:<64 hex>", "ts": <unix seconds>,
"expires_in": 1200, "origin": null | "https://...",
"descriptor": { <OpenDisk 0.1>, "c0mpute": { "addrs": ["/ip4/.../tcp/..."], ... } } }d1sks checks that peer_id is the key's own peer id and that the signature holds, that ts is within ten minutes and newer than the last one, that the listing was signed for this marketplace, and that the numbers are sane. One heartbeat per key per minute is accepted, and an address may add a limited number of new keys a day. A disk with no https origin and no public address is shown as reachable via c0mpute: there is no URL to open, but holders and gateways reach it over libp2p. Opting out on a c0mpute node: [storage] list_on_d1sks = false or C0MPUTE_D1SKS=0.
Reading disks
The page at /disks and GET /api/v1/disks take the same parameters:
| country | ISO codes, comma separated; a disk in any of them matches |
| min_gib | free GiB at least |
| max_price | per GiB-month at most, in the disk's own currency |
| reachable | https, direct, c0mpute (behind NAT), or public (https or direct) |
| fresh | minutes: signed listings heard from within that long (origin listings pass) |
| source | signed or origin |
| encrypted | 1 for ciphertext-only disks, 0 for the rest |
| visibility | public, private or personal: what the disk will hold |
| base | own, licensed, open-license, public-domain or personal |
| min_standing | hub standing at least, as copied into the descriptor |
| hosting | 1 for c0mpute nodes that hold static sites |
| q | name or origin contains |
| sort, order | price, free, standing, updated or name; asc or desc |
| status | active (default), gone or all |
| limit, offset | page size up to 200, and the offset |
curl -s 'https://d1sks.pwa.pit.world/api/v1/disks?country=DE,FI&min_gib=500&max_price=0.15&sort=price' -H 'accept: application/json' curl -s 'https://d1sks.pwa.pit.world/api/v1/disks/<id>' # one disk, with its OpenServer offer curl -s 'https://d1sks.pwa.pit.world/api/v1/disks/<id>/openserver.json' # the offer alone curl -s 'https://d1sks.pwa.pit.world/api/v1/stats'
Standing is shown as the disk copied it. A marketplace that ranks on standing reads the hub in record.source; d1sks shows the number and links the hub, and will read the hub itself once one is running.
Host a site on these disks
Every c0mpute node with the hosting role lists itself here with accepts.hosting: true, its peer id and its hosting price in the c0mpute block of its descriptor. ?hosting=1 lists only those. To pay some of them to keep your static site:
c0mpute hosting publish ./public --name my-site --disks auto c0mpute hosting publish ./public --name my-site --disks auto --country DE,FI --max-price 0.01 --copies 3 c0mpute hosting disks --country DE # what --disks auto would pick
The publisher asks d1sks once, ranks the hosting disks by price, standing and free space, and signs the chosen peer ids and the agreed price into its site record. Everything after that is peer to peer: the chosen nodes replicate first, the network still keeps at least three copies, the publisher challenges holders with random chunk fetches, and pays the ones that pass per GiB-month. d1sks is discovery only; a site keeps being served if d1sks is down.
Validating
curl -s 'https://d1sks.pwa.pit.world/api/v1/validate?url=https://your-disk.example' curl -s -X POST 'https://d1sks.pwa.pit.world/api/v1/validate' -H 'content-type: application/json' --data-binary @opendisk.json
Both answer ok, errors (what makes it invalid), warnings (what a reader will ignore or assume) and the normalised disk.
The pool and the descriptors
- /api/disks: every active descriptor as fetched, which is the
disksfield of the store descriptor. - /.well-known/openobject.json: d1sks.com as an OpenObject store: policies, prices, pool summary.
- /.well-known/openserver.json: the same as OpenServer offers, one per policy.
- /openobject/v1: the store API root. Bucket routes answer 501 until buckets open.
Limits
Reads are free and unmetered for now. Submissions are thirty per address per hour. Fetches go to https origins on public addresses only, follow three redirects at most, and stop at 256 KiB.
Source
github.com/profullstack/d1sks.com, MIT. Bun, Hono, Postgres, no build step. Run it with a DATABASE_URL and bun start.