Build

API

The endpoints the site itself uses. No key needed; reads are cached on the server.

GET /api/pool

The pool’s live rates, what it needs, how far it is covered, and what forever costs on Arweave today.

bash
curl -s https://deedstorage.com/api/pool
json
{
  "sleeves": [
    { "key": "usdc", "name": "USDC", "venue": "lent on Kamino", "share": 0.8, "rate": 0.0461, "size": 132371628 },
    { "key": "jitosol", "name": "JitoSOL", "venue": "SOL staked with Jito", "share": 0.2, "rate": 0.0476, "size": 1108892634 }
  ],
  "rate": 0.0464,
  "need": 0.03,
  "covered": 1.55,
  "sol": 105.79,
  "arweavePerGb": 51.38,
  "pricePerGb": 15.97,
  "at": 1792511984505
}

GET /api/coin?mint=…

Any Solana coin’s metadata and picture: where they live, their CIDs and the one-time price to keep them.

bash
curl -s "https://deedstorage.com/api/coin?mint=EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm"
json
{
  "mint": "EKpQGSJt…65zcjm", "program": "spl", "name": "dogwifhat", "symbol": "$WIF",
  "files": [
    { "role": "metadata", "status": 200, "bytes": 215, "cid": "bafkreihwqhou…dl5q",
      "via": "ipfs.filebase.io", "hostSaid": "answered 429" },
    { "role": "picture", "status": 200, "bytes": 105701, "cid": "bafkreibk3cov…zyum", "type": "image/jpeg" }
  ],
  "bytes": 105916,
  "quote": { "firstYear": 0.0034, "pool": 0.0966, "total": 0.1, "minimum": true }
}

Errors are 400 (not an address), 404 (not a token mint, or no metadata), 429 (lookup budget for this minute spent) and 502 (Solana did not answer).

Keeping, through the API

The site’s own keeping flow, open to any client. A wallet pays; the server only measures the content and signs the quote.

bash
# 1. pack the file into a CAR (unixfs-v1-2025) and upload it for your wallet
curl -s -X POST --data-binary @file.car -H 'content-type: application/vnd.ipld.car' \
  "https://deedstorage.com/api/upload?payer=<your wallet>"
# → { "cid": "bafy…", "bytes": 3158073, "quote": { "message": "…", "signature": "…", "expiry": 1792567200 } }

#    files over 96 MB go in parts: blocks as CAR sections, the header written by the server
curl -s -X POST "https://deedstorage.com/api/upload/start?payer=<your wallet>&bytes=<file size>"
# → { "session": "…", "partBytes": 8388608, "maxParts": 552 }
curl -s -X PUT --data-binary @part-0 "https://deedstorage.com/api/upload/part?session=<id>&n=0"   # … one per part
curl -s -X POST "https://deedstorage.com/api/upload/complete?session=<id>&root=<CID>&parts=<count>"
# → the same quote as above, up to 4 GB

# 2. send one transaction: the Ed25519 check of the quote, then keep (see The program)

# 3. record it at once (the keeper also finds it within a minute)
curl -s -X POST -H 'content-type: application/json' -d '{"signature":"<tx>"}' https://deedstorage.com/api/confirm
# → { "receipts": ["42"] }

GET /api/receipt/<n>

One deed in public: what was paid and how it split, each copy’s provider and state, the latest checks, renewals and repairs.

GET /api/files?owner=…

A wallet’s deeds, newest first, with how many of each one’s copies are verified.

GET /api/chain

The pool as the program holds it: vault balances, rent owed a year, deeds issued, copies by state and the last week of checkpoints.

POST /api/coin/keep

{ "mint": "…", "payer": "…" }: the coin’s metadata and picture fetched fresh, packed as one directory and quoted for that wallet.

Work out a CID yourself

The same profile the site uses, in Node or the browser:

ts
import { importByteStream } from 'ipfs-unixfs-importer';

const discard = { put: async (cid) => cid };
async function* bytes(buf) { yield buf; }

const { cid } = await importByteStream(bytes(fileBytes), discard, { profile: 'unixfs-v1-2025' });
console.log(cid.toString()); // bafy… or bafkrei…

GET /token.json

The $DEED metadata (name, symbol, description, image) that wallets and explorers read.

Connect a wallet

No Solana wallet in this browser. Get one, then come back: Phantom, Solflare, Backpack.