Borg/docs/ipfs-distribution.md
snider 8486242fd8 docs: add IPFS and payment
integration guides + artist mode polish

   - Add docs/ipfs-distribution.md: complete guide for IPFS hosting
     - Installation, pinning services, gateways, best practices
     - Full album release workflow example

   - Add docs/payment-integration.md: Stripe, Gumroad, PayPal examples
     - Webhook handlers for automated license delivery
     - Serverless options (Vercel/Netlify)
     - Manual workflow for non-technical artists

   - Demo artist mode improvements:
     - WASM loads on-demand (fixes 6s delay on 4G)
     - Generate button enabled by password only
     - Vi demo preloads when WASM ready

   - Update RFC-001 section 8.3: mark completed items
2026-01-13 15:17:22 +00:00

6.8 KiB

IPFS Distribution Guide

This guide explains how to distribute your encrypted .smsg content via IPFS (InterPlanetary File System) for permanent, decentralized hosting.

Why IPFS?

IPFS is ideal for dapp.fm content because:

  • Permanent links - Content-addressed (CID) means the URL never changes
  • No hosting costs - Pin with free services or self-host
  • Censorship resistant - No single point of failure
  • Global CDN - Content served from nearest peer
  • Perfect for archival - Your content survives even if you disappear

Combined with password-as-license, IPFS creates truly permanent media distribution:

Artist uploads to IPFS → Fan downloads from anywhere → Password unlocks forever

Quick Start

1. Install IPFS

macOS:

brew install ipfs

Linux:

wget https://dist.ipfs.tech/kubo/v0.24.0/kubo_v0.24.0_linux-amd64.tar.gz
tar xvfz kubo_v0.24.0_linux-amd64.tar.gz
sudo mv kubo/ipfs /usr/local/bin/

Windows: Download from https://dist.ipfs.tech/#kubo

2. Initialize and Start

ipfs init
ipfs daemon

3. Add Your Content

# Create your encrypted content first
go run ./cmd/mkdemo my-album.mp4 my-album.smsg

# Add to IPFS
ipfs add my-album.smsg
# Output: added QmX...abc my-album.smsg

# Your content is now available at:
# - Local: http://localhost:8080/ipfs/QmX...abc
# - Gateway: https://ipfs.io/ipfs/QmX...abc

Distribution Workflow

For Artists

# 1. Package your media
go run ./cmd/mkdemo album.mp4 album.smsg
# Save the password: PMVXogAJNVe_DDABfTmLYztaJAzsD0R7

# 2. Add to IPFS
ipfs add album.smsg
# added QmYourContentCID album.smsg

# 3. Pin for persistence (choose one):

# Option A: Pin locally (requires running node)
ipfs pin add QmYourContentCID

# Option B: Use Pinata (free tier: 1GB)
curl -X POST "https://api.pinata.cloud/pinning/pinByHash" \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{"hashToPin": "QmYourContentCID"}'

# Option C: Use web3.storage (free tier: 5GB)
# Upload at https://web3.storage

# 4. Share with fans
# CID: QmYourContentCID
# Password: PMVXogAJNVe_DDABfTmLYztaJAzsD0R7
# Gateway URL: https://ipfs.io/ipfs/QmYourContentCID

For Fans

# Download via any gateway
curl -o album.smsg https://ipfs.io/ipfs/QmYourContentCID

# Or via local node (faster if running)
ipfs get QmYourContentCID -o album.smsg

# Play with password in browser demo or native app

IPFS Gateways

Public gateways for sharing (no IPFS node required):

Gateway URL Pattern Notes
ipfs.io https://ipfs.io/ipfs/{CID} Official, reliable
dweb.link https://{CID}.ipfs.dweb.link Subdomain style
cloudflare https://cloudflare-ipfs.com/ipfs/{CID} Fast, cached
w3s.link https://{CID}.ipfs.w3s.link web3.storage
nftstorage.link https://{CID}.ipfs.nftstorage.link NFT.storage

Example URLs for CID QmX...abc:

https://ipfs.io/ipfs/QmX...abc
https://QmX...abc.ipfs.dweb.link
https://cloudflare-ipfs.com/ipfs/QmX...abc

Pinning Services

Content on IPFS is only available while someone is hosting it. Use pinning services for persistence:

Free Options

Service Free Tier Link
Pinata 1 GB https://pinata.cloud
web3.storage 5 GB https://web3.storage
NFT.storage Unlimited* https://nft.storage
Filebase 5 GB https://filebase.com

*NFT.storage is designed for NFT data but works for any content.

Pin via CLI

# Pinata
export PINATA_JWT="your-jwt-token"
curl -X POST "https://api.pinata.cloud/pinning/pinByHash" \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d '{"hashToPin": "QmYourCID", "pinataMetadata": {"name": "my-album.smsg"}}'

# web3.storage (using w3 CLI)
npm install -g @web3-storage/w3cli
w3 login your@email.com
w3 up my-album.smsg

Integration with Demo Page

The demo page can load content directly from IPFS gateways:

// In the demo page, use gateway URL
const ipfsCID = 'QmYourContentCID';
const gatewayUrl = `https://ipfs.io/ipfs/${ipfsCID}`;

// Fetch and decrypt
const response = await fetch(gatewayUrl);
const bytes = new Uint8Array(await response.arrayBuffer());
const msg = await BorgSMSG.decryptBinary(bytes, password);

Or use the Fan tab with the IPFS gateway URL directly.

Best Practices

1. Always Pin Your Content

IPFS garbage-collects unpinned content. Always pin important files:

ipfs pin add QmYourCID
# Or use a pinning service

2. Use Multiple Pins

Pin with 2-3 services for redundancy:

# Pin locally
ipfs pin add QmYourCID

# Also pin with Pinata
curl -X POST "https://api.pinata.cloud/pinning/pinByHash" ...

# And web3.storage as backup
w3 up my-album.smsg

3. Share CID + Password Separately

Download: https://ipfs.io/ipfs/QmYourCID
License: [sent via email/DM after purchase]

4. Use IPNS for Updates (Optional)

IPNS lets you update content while keeping the same URL:

# Create IPNS name
ipfs name publish QmYourCID
# Published to k51...xyz

# Your content is now at:
# https://ipfs.io/ipns/k51...xyz

# Update to new version later:
ipfs name publish QmNewVersionCID

Example: Full Album Release

# 1. Create encrypted album
go run ./cmd/mkdemo my-album.mp4 my-album.smsg
# Password: PMVXogAJNVe_DDABfTmLYztaJAzsD0R7

# 2. Add to IPFS
ipfs add my-album.smsg
# added QmAlbumCID my-album.smsg

# 3. Pin with multiple services
ipfs pin add QmAlbumCID
w3 up my-album.smsg

# 4. Create release page
cat > release.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>My Album - Download</title></head>
<body>
  <h1>My Album</h1>
  <p>Download: <a href="https://ipfs.io/ipfs/QmAlbumCID">IPFS</a></p>
  <p>After purchase, you'll receive your license key via email.</p>
  <p><a href="https://demo.dapp.fm">Play with license key</a></p>
</body>
</html>
EOF

# 5. Host release page on IPFS too!
ipfs add release.html
# added QmReleaseCID release.html
# Share: https://ipfs.io/ipfs/QmReleaseCID

Troubleshooting

Content Not Loading

  1. Check if pinned: ipfs pin ls | grep QmYourCID
  2. Try different gateway: Some gateways cache slowly
  3. Check daemon running: ipfs swarm peers should show peers

Slow Downloads

  1. Use a faster gateway (cloudflare-ipfs.com is often fastest)
  2. Run your own IPFS node for direct access
  3. Pre-warm gateways by accessing content once

CID Changed After Re-adding

IPFS CIDs are content-addressed. If you modify the file, the CID changes. For the same content, the CID is always identical.

Resources