Atlas Shelter

A Shelter is a specialized registry that acts as a user's persistent inbox and outbox. Other registries crawl Shelter envelopes to accumulate max totalBurn. Shelters ensure data availability even when the user is offline.

Shelters are the decentralized equivalent of a personal mailbox. You rent storage from independent operators, your data stays available around the clock, and no single provider can lock you out.

Discovery

Users find available shelters through their configured Guide registry. The guide indexes DataCatalog envelopes from all connected registries and filters for those with rentingPolicy.enabled = true. The result is a list of shelter operators with their pricing and capacity.

Discover Available Shelters
import { getAvailableShelters } from "@app_/registry-client";

// Query a guide registry for shelters with renting enabled
const shelters = await getAvailableShelters(guideRegistryUrl);

// Each result contains the registry's DataCatalog and pricing
for (const shelter of shelters) {
  const { gbPrice, weekPrice, maxPeers } =
    shelter.catalog.storage.rentingPolicy;
  console.log(shelter.catalog.url, { gbPrice, weekPrice, maxPeers });
}

Pricing Model

Each shelter publishes its pricing in the DataCatalog envelope under storage.rentingPolicy. Prices are denominated in FairShares — the protocol's built-in currency.

Shelter Renting Policy
{
  "storage": {
    "rentingPolicy": {
      "enabled": true,
      "gbPrice": 5,
      "weekPrice": 2,
      "maxPeers": 50
    },
    "shelterPolicy": {
      "allowedRequesterPublicKeys": []
    }
  }
}
Field Type Description
enabled boolean Whether this registry accepts shelter lease rentals.
gbPrice integer Cost in FAIRS per gigabyte of storage.
weekPrice integer Cost in FAIRS per week of rental duration.
maxPeers integer Maximum number of users this shelter can serve.

Total lease cost: gbPrice × gb + weekPrice × weeks. For example, 10 GB for 4 weeks at the policy above costs 5×10 + 2×4 = 58 FAIRS.

Rental Flow

To rent shelter storage, a user submits a signed RentAction envelope with additionalType: "atlas:shelterLease" to the shelter registry. The object field carries an Offer specifying the requested gb and weeks.

RentAction — Shelter Lease
{
  "@context": "https://schema.org",
  "@type": "RentAction",
  "additionalType": "atlas:shelterLease",
  "landlord": {
    "@type": "Person",
    "identifier": "<shelter-registry-hash>"
  },
  "object": {
    "@type": "Offer",
    "additionalType": "atlas:shelterLease",
    "gb": 10,
    "weeks": 4
  },
  "price": 58,
  "priceCurrency": "FAIRS"
}

The shelter validates the request:

  • The landlord identifier must match the shelter's own registry identity.
  • The price must be at least gbPrice × gb + weekPrice × weeks. Underpayment is rejected.
  • The renter must not already have an active lease (no duplicate entries in the allowlist).

Access Control

On successful rental, the shelter adds the renter's identity hash to shelterPolicy.allowedRequesterPublicKeys. Only keys on this allowlist can push envelopes to the shelter.

Shelter Access Policy
{
  "storage": {
    "shelterPolicy": {
      "allowedRequesterPublicKeys": [
        "b3a1f8...",
        "e4c9d2..."
      ]
    }
  }
}

User Preferences

After renting a shelter lease, the user stores the shelter URL in their Person envelope as a ContactPoint with contactType: "atlas:shelter". This is how other users and apps discover where to deliver data.

Person Envelope — Shelter Contact Points
{
  "@context": "https://schema.org",
  "@type": "Person",
  "contactPoint": [
    {
      "@type": "ContactPoint",
      "contactType": "atlas:shelter",
      "url": "https://shelter-a.example"
    },
    {
      "@type": "ContactPoint",
      "contactType": "atlas:shelter",
      "url": "https://shelter-b.example"
    }
  ]
}

To send data to another user, resolve their shelter URLs from their Person envelope via a guide registry:

Resolve Author Shelter URLs
import { resolveAuthorShelterUrls } from "@app_/registry-client";

// Look up another user's shelter URLs via their Person envelope
const shelterUrls = await resolveAuthorShelterUrls(
  guideRegistryUrl,
  "b3a1f8..."  // target author's identity hash
);

// Push envelopes to the user's shelters for delivery
for (const url of shelterUrls) {
  await pushEnvelopes(url, envelopes);
}

Redundancy

Users can rent from multiple independent shelter operators. The contactPoint array requires at least one entry but has no upper bound. Multiple shelters provide geographic and operator diversity — if one goes offline, others still serve data. Apps write to all configured shelters for maximum availability.

Protocol Methods

Method Package Description
getAvailableShelters registry-client Query a guide registry for registries with rentingPolicy.enabled.
resolveAuthorShelterUrls registry-client Look up shelter URLs from a user's Person envelope via a guide.