aioz-storage

Deploy static websites to AIOZ Storage with built-in templates or custom sites.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "aioz-storage" with this command: npx skills add vinhbui3004/aioz-storage-skill

AIOZ Static Website Deploy

Deploy a static website to AIOZ decentralized storage. Supports 4 built-in templates or user's own static site.

FLOW OVERVIEW

1. Login (email + password) → Bearer token + accountId
2. Choose template or custom site
3. Clone template & customize CONFIG
4. Get bucket info (name + 12-word passphrase)
5. Get rootZKey from API
6. Generate grant via grant-cli.ts
7. Register S3 credentials from grant
8. Upload files to S3
9. Create static website via API
10. Site live at https://<bucket>.sites.aiozstorage.app

STEP 1: LOGIN

Ask user for AIOZ Storage email and password.

curl -s 'https://api.aiozstorage.network/api/v1/login' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'origin: https://aiozstorage.network' \
  -H 'referer: https://aiozstorage.network/' \
  --data-raw '{"email":"<EMAIL>","password":"<PASSWORD>"}'

Response: data.access_token (Bearer token), data.account.id (accountId). Store BEARER_TOKEN and ACCOUNT_ID.

STEP 2: CHOOSE TEMPLATE

Ask user which template or if they have their own static site.

Templates from https://github.com/AIOZStorage/aioz-storage-docs/tree/main/examples:

  1. landing — OLED dark theme, X/Twitter style landing page. CONFIG in assets/main.js.
  2. landing-alt — Purple gradient landing page. CONFIG in assets/main.js. Supports *italic* gradient text in headlines.
  3. portfolio — Clean minimal portfolio for devs/designers. CONFIG in assets/main.js. Image carousel for projects.
  4. documents — Full documentation site with Markdown content. CONFIG in assets/js/config.js. Search, TOC, syntax highlighting.
  5. Custom — User provides their own static files.

STEP 3: CLONE TEMPLATE & CUSTOMIZE

Clone the chosen template:

git clone --depth 1 https://github.com/AIOZStorage/aioz-storage-docs.git /tmp/aioz-storage-docs
cp -r /tmp/aioz-storage-docs/examples/<template_name> ./<project_folder>

Then customize the CONFIG object based on template type:

Template: landing

Config: assets/main.jsCONFIG object. Theme: "dark" (OLED black) or "light".

Key fields to customize:

  • brand.name — brand/product name
  • meta.title, meta.description — SEO
  • hero.eyebrow — pill badge (or null to hide), hero.title, hero.sub
  • hero.primaryCta{ label, href }, hero.secondaryCta
  • sections.* — toggle: highlights, logos, features, useCases, testimonials, pricingTop, pricingBot, faq
  • highlights[]{ number, label } stats (numbers animate on scroll)
  • logos.items[] — company name strings
  • features{ label, title, sub, items: [{ title, desc }] }
  • useCases{ label, title, sub, items: [{ tag, title, desc }] }
  • testimonials[]{ quote, name, role, company, avatar: { initials, bg } }
  • pricing.plans[]{ name, price, period, desc, isPopular, cta: { label, href }, features[] }
  • faq.items[]{ q, a }
  • cta.form.mode"redirect" | "mailto" | "webhook"
  • footer.brandDesc, footer.columns[], footer.socials[]
  • Colors in assets/style.css :root--color-primary: #1d9bf0

Template: landing-alt

Config: assets/main.jsCONFIG object. Theme: "light" | "dark" | "system".

Key fields to customize:

  • brand.name, brand.tagline
  • hero.badge — pill badge (or null), hero.headline (wrap words in *asterisks* for gradient italic text), hero.subheadline
  • hero.primaryCta, hero.secondaryCta, hero.ctaNote
  • sections.* — toggle: stats, problemSolution, features, useCases, logos, testimonials, pricing, faq
  • stats[]{ number, label } (numbers animate on scroll)
  • problemSolution{ problem: { label, title, items[] }, solution: { label, title, items[] } }
  • features.items[]{ size, gradient, kicker, title, desc, tag, visual } (bento grid, size: "wide"|"narrow"|"half"|"third"|"full")
  • pricing.plans[]{ name, price, period, desc, isPopular, cta, features[] }
  • cta.form.mode"redirect" | "mailto" | "webhook"
  • Colors in assets/style.css--color-primary: #635bff, --color-gradient-start, --color-gradient-end

Template: portfolio

Config: assets/main.jsCONFIG object. Theme: "light" | "dark" | "auto".

Key fields to customize:

  • personal.firstName, personal.lastName, personal.title, personal.email
  • personal.location{ city, country }
  • about.subtitle, about.bio (array of paragraphs), about.focusAreas (array of skill strings)
  • experience[]{ company, tagline, period, position, description, longDescription, location, industry, website: { label, url } }
  • projects[]{ title, tags[], year, images[], description, techNote, link: { label, url } } (multiple images = carousel)
  • social[]{ platform, url }
  • theme.defaultMode, theme.showToggle
  • sections — toggle: showAbout, showExperience, showProjects, showFocusAreas
  • footer.cta, footer.copyright (null = auto-generate)
  • meta.title, meta.description, meta.ogImage
  • Images in assets/images/ (1600×900 for projects, 1200×630 for OG)

Template: documents

Config: assets/js/config.jsCONFIG object. Theme: "light" | "dark" | "auto".

Key fields to customize:

  • site.title, site.description, site.version
  • site.logo.light, site.logo.dark
  • sidebar[]{ group, collapsed, items: [{ label, path }] } (path = filename without .md)
  • header.nav[]{ label, href }, header.links[]{ icon, href }
  • footer.copyright, footer.columns[]
  • features — toggle: search, tableOfContents, feedback, prevNext, copyCodeButton, scrollToTop
  • features.editLink{ enabled, baseUrl, text }
  • features.tocDepth — 2 or 3

Content: create .md files in /docs/ with YAML front matter:

---
title: Page Title
description: Brief description
order: 1
hidden: false
---

Callouts: > [!NOTE], > [!TIP], > [!WARNING], > [!DANGER] Code blocks with syntax highlighting (javascript, typescript, python, bash, json, html, css, yaml, sql, go, rust, java, etc.) Hash routing: index.html#/page-name → loads docs/page-name.md

STEP 4: GET BUCKET INFO

Ask user for:

  1. Bucket name — their bucket on aiozstorage.network
  2. 12-word seed phrase — BIP39 passphrase from bucket creation

IMPORTANT: AIOZ Storage does NOT store passphrases. If lost, bucket access is lost forever.

See: https://aiozstorage.network/docs/tutorials/manage-buckets

STEP 5: GET ROOT ZKEY

curl -s 'https://api.aiozstorage.network/api/v1/zkeys' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \
  -H 'origin: https://aiozstorage.network' \
  -H 'referer: https://aiozstorage.network/' \
  --data-raw '{"name":"deploy-key","force":true}'

Extract: ROOT_ZKEY = data.zkey

STEP 6: GENERATE GRANT

Prerequisites (one-time setup in {baseDir})

cd {baseDir} && npm install

This installs argon2-browser and ts-node. No build:sjcl needed — the CLI uses Node.js built-in crypto.

Run grant-cli.ts (RECOMMENDED: JSON output for bot)

Two grants are needed:

  1. Upload grant — permissions 1,2,3 (Read+Write+List) for S3 upload
  2. Website grant — permissions 1,3 (Read+List only) for website creation

Upload grant:

npx ts-node {baseDir}/grant-cli.ts \
  --mode per-bucket \
  --zkey "<ROOT_ZKEY>" \
  --account "<ACCOUNT_ID>" \
  --url w3s \
  --duration 0 \
  --bucket "<BUCKET_NAME>" \
  --passphrase "<12_WORD_SEED_PHRASE>" \
  --permissions 1,2,3 \
  --output json \
  --quiet

Website grant:

npx ts-node {baseDir}/grant-cli.ts \
  --mode per-bucket \
  --zkey "<ROOT_ZKEY>" \
  --account "<ACCOUNT_ID>" \
  --url w3s \
  --duration 0 \
  --bucket "<BUCKET_NAME>" \
  --passphrase "<12_WORD_SEED_PHRASE>" \
  --permissions 1,3 \
  --output json \
  --quiet

Output (single JSON line to stdout):

{"grant":"<GRANT_STRING>","zkey":"<ZKEY_STRING>"}

Parse JSON to extract UPLOAD_GRANT and WEBSITE_GRANT.

IMPORTANT: Website API rejects grants with Write (2) or Delete (4) permissions.

Alternative: config file

echo '{"mode":"per-bucket","rootZKey":"<ROOT_ZKEY>","accountId":"<ACCOUNT_ID>","url":"w3s","duration":0,"buckets":[{"name":"<BUCKET_NAME>","passphrase":"<PASSPHRASE>","permissions":["1","2","3"]}]}' > /tmp/upload-grant-config.json
npx ts-node {baseDir}/grant-cli.ts --config /tmp/upload-grant-config.json --output json --quiet

echo '{"mode":"per-bucket","rootZKey":"<ROOT_ZKEY>","accountId":"<ACCOUNT_ID>","url":"w3s","duration":0,"buckets":[{"name":"<BUCKET_NAME>","passphrase":"<PASSPHRASE>","permissions":["1","3"]}]}' > /tmp/website-grant-config.json
npx ts-node {baseDir}/grant-cli.ts --config /tmp/website-grant-config.json --output json --quiet

CLI flags

FlagRequiredDescription
--modeYesper-bucket or all-buckets
--zkeyYesRoot ZKey (base64url)
--accountYesAccount UUID
--urlNoService URL (default: w3s)
--durationNoms, 0 = no expiry (default: 0)
--bucketper-bucketBucket name
--passphraseYes12-word seed phrase
--permissionsper-bucket1,2,3,4 (1=Read 2=Write 3=List 4=Delete)
--configNoPath to JSON config file
--outputNojson for JSON output
--quietNoSuppress logs, stdout only

STEP 7: REGISTER S3 CREDENTIALS

Use the upload grant (permissions 1,2,3):

curl -s 'https://reg-api.aiozstorage.network/api/v1/access' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \
  -H 'origin: https://aiozstorage.network' \
  -H 'referer: https://aiozstorage.network/' \
  --data-raw '{"grant":"<GRANT>","public":false}'

Extract: ACCESS_KEY_ID = data.access_key_id, SECRET_KEY = data.secret_key

STEP 8: UPLOAD FILES TO S3

S3 endpoint: https://s3.aiozstorage.network | Region: us-east-1 | PathStyle: true

Using AWS CLI

AWS_ACCESS_KEY_ID="<ACCESS_KEY_ID>" \
AWS_SECRET_ACCESS_KEY="<SECRET_KEY>" \
aws s3 sync ./<project_folder>/ s3://<BUCKET_NAME>/ \
  --endpoint-url https://s3.aiozstorage.network \
  --region us-east-1

Using Node.js (@aws-sdk/client-s3)

Use S3Client with { region: "us-east-1", endpoint: "https://s3.aiozstorage.network", forcePathStyle: true, credentials: { accessKeyId, secretAccessKey } }. Upload each file with PutObjectCommand, setting correct Content-Type:

.htmltext/html .csstext/css .jsapplication/javascript .jsonapplication/json .svgimage/svg+xml .pngimage/png .jpg/.jpegimage/jpeg .webpimage/webp .icoimage/x-icon .mdtext/markdown .woff2font/woff2 default→application/octet-stream

STEP 9: CREATE STATIC WEBSITE

Use the website grant (permissions 1,3 — Read+List only):

curl -s 'https://api.aiozstorage.app/api/v1/websites' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \
  -H 'origin: https://aiozstorage.network' \
  -H 'referer: https://aiozstorage.network/' \
  --data-raw '{
    "bucket_name":"<BUCKET_NAME>",
    "enabled":true,
    "index_document":"index.html",
    "error_document":"404.html",
    "use_default_error":true,
    "error_pages":{},
    "grant":"<WEBSITE_GRANT>"
  }'

IMPORTANT: Website API rejects grants with Write (2) or Delete (4) permissions. Use --permissions 1,3 for this grant.

API domain is api.aiozstorage.app (not .network).

STEP 10: DONE

Site is live at: https://<BUCKET_NAME>.sites.aiozstorage.app

API DOMAINS

  • api.aiozstorage.network — login, zkeys
  • reg-api.aiozstorage.network — S3 credential registration
  • s3.aiozstorage.network — S3 upload endpoint
  • api.aiozstorage.app — static website creation
  • <bucket>.sites.aiozstorage.app — static website URL

ERROR HANDLING

  • Login fails → check email/password
  • ZKey creation fails → Bearer token expired, re-login
  • Grant generation fails → verify rootZKey, accountId, bucket name, passphrase
  • S3 upload fails → check credentials, endpoint, bucket name
  • Website creation fails → check grant, bucket name, Bearer token
  • Site 404 → ensure index.html at bucket root (not in subfolder)

IMPORTANT NOTES

  • grant encodes both authorization (Macaroon/ZKey) and encryption key (EKey from passphrase)
  • Two grants needed: upload grant (permissions 1,2,3) and website grant (permissions 1,3)
  • Website API rejects grants with Write (2) or Delete (4) permissions
  • AIOZ Storage is S3-compatible — any AWS SDK works
  • Bearer tokens expire — re-login on 401
  • grant-cli.ts requires Node.js >= 18
  • argon2-browser WASM loading is auto-patched in the CLI
  • All template asset paths are relative (./assets/...) — works from any base URL
  • For documents template, content is in /docs/*.md with YAML front matter
  • For landing/landing-alt/portfolio, all content is in CONFIG object in assets/main.js

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Leads

Leads - command-line tool for everyday use

Registry SourceRecently Updated
General

Bmi Calculator

BMI计算器。BMI计算、理想体重、健康计划、体重追踪、儿童BMI、结果解读。BMI calculator with ideal weight, health plan. BMI、体重、健康。

Registry SourceRecently Updated
General

Blood

Blood — a fast health & wellness tool. Log anything, find it later, export when needed.

Registry SourceRecently Updated
General

Better Genshin Impact

📦BetterGI · 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄地 | 一条龙 | 全连音游 - UI A better genshin impact, c#, auto-play-game, automatic, g...

Registry SourceRecently Updated