nsyte
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesensyte — Decentralized Static Site Deployment
nsyte — 去中心化静态站点部署
nsyte is a Deno-based CLI that publishes static websites to the Nostr network using Blossom servers for file storage. Sites are content-addressed (SHA-256), censorship-resistant, and discoverable via Nostr relays.
Key concepts: For Nostr/Blossom domain knowledge (relays, pubkeys, nsec, NIP-46, events), see references/nostr-concepts.md.
nsyte是一款基于Deno的CLI工具,可将静态网站发布到Nostr网络,使用Blossom服务器进行文件存储。站点采用内容寻址(SHA-256)、具备抗审查特性,可通过Nostr中继节点搜索访问。
核心概念: 如需了解Nostr/Blossom领域知识(relays、pubkeys、nsec、NIP-46、events),请查看references/nostr-concepts.md。
Installation
安装
Check if installed
检查是否已安装
bash
nsyte --versionIf this prints a version string, skip to Project Setup.
bash
nsyte --version如果输出版本号,可直接跳转到项目设置。
Linux / macOS (recommended — no Deno required)
Linux / macOS(推荐方案 — 无需安装Deno)
bash
curl -fsSL https://nsyte.run/get/install.sh | bashInstalls to . Use if that directory is not writable.
/usr/local/bin/nsytesudobash
curl -fsSL https://nsyte.run/get/install.sh | bash默认安装到。如果该目录没有写入权限,可在命令前加。
/usr/local/bin/nsytesudoLinux / macOS (alternative — requires Deno 2.x)
Linux / macOS(备选方案 — 需要Deno 2.x)
bash
deno install -A -f -g -n nsyte jsr:@nsyte/clibash
deno install -A -f -g -n nsyte jsr:@nsyte/cliWindows
Windows
Download the latest binary from , place in , and add that directory to PATH.
https://github.com/sandwichfarm/nsyte/releases%USERPROFILE%\bin\从下载最新的二进制文件,放到目录下,并将该目录添加到系统PATH中。
https://github.com/sandwichfarm/nsyte/releases%USERPROFILE%\bin\Troubleshooting installation
安装故障排查
- Command not found: Add to PATH in
/usr/local/binor~/.bashrcand reload.~/.zshrc - Permission denied: Use for the curl install, or install to a user-writable location.
sudo - Deno version too old: Run or use the binary install instead.
deno upgrade
- 找不到命令: 将添加到
/usr/local/bin或~/.bashrc的PATH配置中,然后重载配置。~/.zshrc - 权限不足: curl安装命令前加,或者安装到用户可写的目录下。
sudo - Deno版本过低: 运行,或者改用二进制安装方案。
deno upgrade
Project Setup
项目设置
bash
cd /path/to/your/project
nsyte initInteractive prompts ask for:
- Auth method — generate new key, enter existing nsec/hex key, or connect NIP-46 bunker
- Relay URLs — one or more relay WebSocket URLs
wss:// - Blossom server URLs — one or more Blossom server URLs
https://
On success, creates . See Configuration for the schema.
.nsite/config.jsonbash
cd /path/to/your/project
nsyte init交互提示会要求你配置以下内容:
- 身份验证方式 — 生成新密钥、输入已有的nsec/十六进制密钥,或者连接NIP-46 bunker
- 中继节点URL — 一个或多个协议的中继WebSocket URL
wss:// - Blossom服务器URL — 一个或多个协议的Blossom服务器URL
https://
初始化成功后会生成文件。配置项说明请查看配置部分。
.nsite/config.jsonConfiguration
配置
Config file:
.nsite/config.jsonFor the full JSON Schema, see assets/config.schema.json.
配置文件路径:
.nsite/config.json完整的JSON Schema请查看assets/config.schema.json。
Required fields
必填字段
| Field | Type | Description |
|---|---|---|
| | Nostr relay URLs ( |
| | Blossom server URLs ( |
| 字段 | 类型 | 描述 |
|---|---|---|
| | Nostr中继节点URL( |
| | Blossom服务器URL( |
Authentication
身份验证相关
| Field | Type | Description |
|---|---|---|
| | 64-char hex pubkey for NIP-46 bunker. Pattern: |
| 字段 | 类型 | 描述 |
|---|---|---|
| | NIP-46 bunker的64位十六进制公钥,格式规则: |
Site identity
站点标识
| Field | Type | Default | Description |
|---|---|---|---|
| | | |
| | — | Site title for manifest event |
| | — | Site description for manifest event |
| | — | 404 fallback HTML path (e.g., |
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| | | |
| | — | 清单事件中的站点标题 |
| | — | 清单事件中的站点描述 |
| | — | 404 fallback HTML路径(例如SPA站点设置为 |
Publishing flags (root sites only — id
must be null/empty)
id发布标记(仅根站点可用 — id
必须为null/空)
id| Field | Type | Description |
|---|---|---|
| | Publish kind 0 profile metadata. Requires non-empty |
| | Publish kind 10002 relay list |
| | Publish kind 10063 Blossom server list |
| | Publish NIP-89 handler. Requires |
| 字段 | 类型 | 描述 |
|---|---|---|
| | 发布kind 0的个人资料元数据,要求 |
| | 发布kind 10002的中继节点列表 |
| | 发布kind 10063的Blossom服务器列表 |
| | 发布NIP-89 handler,要求 |
Optional objects
可选对象
| Field | Type | Description |
|---|---|---|
| | Nostr profile: |
| | NIP-89 config: |
| | Gateway hostnames (default: |
| 字段 | 类型 | 描述 |
|---|---|---|
| | Nostr个人资料: |
| | NIP-89配置:必填字段 |
| | 网关域名(默认: |
Example configs
配置示例
Minimal (root site):
json
{
"relays": ["wss://relay.damus.io", "wss://nos.lol"],
"servers": ["https://cdn.hzrd149.com"]
}Named site (blog):
json
{
"relays": ["wss://relay.damus.io"],
"servers": ["https://cdn.hzrd149.com"],
"id": "blog",
"title": "My Blog",
"description": "A blog about decentralized applications"
}With profile publishing:
json
{
"relays": ["wss://relay.damus.io", "wss://nos.lol"],
"servers": ["https://cdn.hzrd149.com"],
"publishProfile": true,
"publishRelayList": true,
"publishServerList": true,
"profile": {
"name": "Alice",
"display_name": "Alice",
"about": "Decentralization enthusiast",
"picture": "https://example.com/avatar.jpg",
"nip05": "alice@example.com",
"lud16": "alice@getalby.com"
}
}With NIP-89 app handler:
json
{
"relays": ["wss://relay.damus.io"],
"servers": ["https://cdn.hzrd149.com"],
"publishAppHandler": true,
"appHandler": {
"kinds": [1, 30023],
"name": "My Nostr Viewer",
"description": "A viewer for notes and articles",
"icon": "https://example.com/logo.png"
}
}最简配置(根站点):
json
{
"relays": ["wss://relay.damus.io", "wss://nos.lol"],
"servers": ["https://cdn.hzrd149.com"]
}命名站点(博客):
json
{
"relays": ["wss://relay.damus.io"],
"servers": ["https://cdn.hzrd149.com"],
"id": "blog",
"title": "我的博客",
"description": "一个关于去中心化应用的博客"
}配置个人资料发布:
json
{
"relays": ["wss://relay.damus.io", "wss://nos.lol"],
"servers": ["https://cdn.hzrd149.com"],
"publishProfile": true,
"publishRelayList": true,
"publishServerList": true,
"profile": {
"name": "Alice",
"display_name": "Alice",
"about": "去中心化爱好者",
"picture": "https://example.com/avatar.jpg",
"nip05": "alice@example.com",
"lud16": "alice@getalby.com"
}
}配置NIP-89 app handler:
json
{
"relays": ["wss://relay.damus.io"],
"servers": ["https://cdn.hzrd149.com"],
"publishAppHandler": true,
"appHandler": {
"kinds": [1, 30023],
"name": "我的Nostr查看器",
"description": "用于查看笔记和文章的查看器",
"icon": "https://example.com/logo.png"
}
}Interactive config editor
交互式配置编辑器
bash
nsyte configRequires an interactive terminal. Keys: / navigate, edit, save, reset, quit.
↑↓EntersrqFor non-interactive contexts, edit directly and validate:
.nsite/config.jsonbash
nsyte validatebash
nsyte config需要交互式终端支持。操作按键:/ 导航, 编辑, 保存, 重置, 退出。
↑↓Entersrq非交互式场景下可直接编辑,然后执行以下命令验证配置:
.nsite/config.jsonbash
nsyte validateAuthentication
身份验证
NIP-46 Bunker (recommended)
NIP-46 Bunker(推荐方案)
Connect via QR code
通过二维码连接
bash
nsyte bunker connectChoose "Scan QR Code", enter a relay URL, scan with signer app (Amber, nsec.app), approve.
bash
nsyte bunker connect选择「扫描二维码」,输入中继节点URL,使用签名应用(Amber、nsec.app)扫描并授权即可。
Connect via bunker URL
通过bunker URL连接
bash
nsyte bunker connect 'bunker://pubkey?relay=wss://relay.example.com&secret=xxx'CRITICAL: Always single-quote the URL — and are shell metacharacters.
?&bash
nsyte bunker connect 'bunker://pubkey?relay=wss://relay.example.com&secret=xxx'重要提示: URL必须用单引号包裹 — 和是Shell特殊字符,不包裹会被解析错误。
?&Link bunker to project
将bunker关联到项目
bash
nsyte bunker use [pubkey]Sets in config and stores nbunksec in OS keychain. Never manually edit .
bunkerPubkeybunkerPubkeybash
nsyte bunker use [pubkey]该命令会在配置中设置,并将nbunksec存储到系统钥匙串中。禁止手动编辑。
bunkerPubkeybunkerPubkeyBunker management commands
Bunker管理命令
| Command | Purpose |
|---|---|
| Connect interactively (QR or URL) |
| Connect via bunker URL |
| Import existing nbunksec |
| Export stored bunker as nbunksec |
| List stored bunkers |
| Set project to use a bunker |
| Remove a bunker from storage |
| Rebuild keychain index |
| 命令 | 用途 |
|---|---|
| 交互式连接(二维码或URL) |
| 通过bunker URL连接 |
| 导入已有的nbunksec |
| 导出已存储的bunker为nbunksec格式 |
| 列出所有已存储的bunker |
| 设置当前项目使用的bunker |
| 从存储中删除指定bunker |
| 重建钥匙串索引 |
Secrets storage
密钥存储
nsyte auto-selects the best backend:
- macOS: Keychain
- Linux: Secret Service (fallback: encrypted file)
- Windows: Credential Manager (fallback: encrypted file)
Override with .
NSYTE_FORCE_ENCRYPTED_STORAGE=truensyte会自动选择最优的存储后端:
- macOS: 钥匙串(Keychain)
- Linux: 秘密服务(Secret Service),降级方案:加密文件
- Windows: 凭据管理器(Credential Manager),降级方案:加密文件
可通过设置环境变量强制使用加密文件存储。
NSYTE_FORCE_ENCRYPTED_STORAGE=trueDeployment
部署
Basic deploy
基础部署
bash
nsyte deploy ./distbash
nsyte deploy ./distAuth resolution order
身份验证优先级顺序
-
flag (highest priority):
--secbashnsyte deploy ./dist --sec "nsec1..." nsyte deploy ./dist --sec "${NBUNK_SECRET}"Auto-detects format:,nsec1...,nbunksec1..., or 64-char hex.bunker://... -
Stored bunker from
.nsite/config.json+ OS keychain.bunkerPubkey -
If neither available, nsyte exits with an error.
-
参数(最高优先级):
--secbashnsyte deploy ./dist --sec "nsec1..." nsyte deploy ./dist --sec "${NBUNK_SECRET}"自动识别格式:、nsec1...、nbunksec1...或者64位十六进制密钥。bunker://... -
已存储的bunker:从的
.nsite/config.json+ 系统钥匙串中读取。bunkerPubkey -
如果以上两种方式都不可用,nsyte会报错退出。
Common flags
常用参数
| Flag | Purpose |
|---|---|
| Provide signing key/credential |
| Re-upload all files (skip diff) |
| SPA fallback for 404s |
| CI mode — no prompts, fail fast |
| 参数 | 用途 |
|---|---|
| 提供签名密钥/凭证 |
| 重新上传所有文件(跳过差异比对) |
| SPA站点404 fallback配置 |
| CI模式 — 无交互提示,出错直接退出 |
Interpreting output
输出结果说明
- Full success: — all files to all servers
{N} files uploaded successfully ({size}) - Partial success: — some servers failed
{uploaded}/{total} files uploaded - Total failure: — check relay/server/auth errors
Failed to upload any files
Gateway URL printed after deploy:
https://{npub}.nsite.lol/- 完全成功: — 所有文件已上传到所有服务器
{N} files uploaded successfully ({size}) - 部分成功: — 部分服务器上传失败
{uploaded}/{total} files uploaded - 完全失败: — 请检查中继节点/服务器/身份验证错误
Failed to upload any files
部署成功后会打印网关URL:
https://{npub}.nsite.lol/CI/CD
CI/CD
Step 1: Generate CI credential (one-time, on dev machine)
步骤1:生成CI凭证(在开发机上执行一次即可)
bash
nsyte cibash
nsyte cior with bunker URL:
或使用bunker URL:
nsyte ci 'bunker://pubkey?relay=wss://relay.example.com&secret=xxx'
The `nbunksec1...` string is printed once and never stored. Copy it immediately and save as a CI secret.nsyte ci 'bunker://pubkey?relay=wss://relay.example.com&secret=xxx'
生成的`nbunksec1...`字符串只会输出一次,不会存储,请立即复制保存为CI密钥。Step 2: Deploy in pipeline
步骤2:在流水线中部署
bash
nsyte deploy ./dist --non-interactive --sec "${NBUNK_SECRET}"CRITICAL: Use (not ).
--sec--nbunksecbash
nsyte deploy ./dist --non-interactive --sec "${NBUNK_SECRET}"重要提示: 使用参数(不是)。
--sec--nbunksecGitHub Actions example
GitHub Actions示例
yaml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: denoland/setup-deno@v1
- run: nsyte deploy ./dist --non-interactive --sec "${{ secrets.NBUNK_SECRET }}"yaml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: denoland/setup-deno@v1
- run: nsyte deploy ./dist --non-interactive --sec "${{ secrets.NBUNK_SECRET }}"CI checklist
CI检查清单
- committed or provided as artifact
.nsite/config.json - secret set to
NBUNK_SECRETstringnbunksec1... - flag present
--non-interactive - Optionally run before deploy
nsyte validate
- 已提交到仓库,或作为构建产物提供
.nsite/config.json - 密钥已设置为生成的
NBUNK_SECRET字符串nbunksec1... - 命令包含参数
--non-interactive - 可选择在部署前执行验证配置
nsyte validate
Other Commands
其他命令
| Command | Purpose |
|---|---|
| List published files |
| Interactive TUI file browser with relay/server propagation tracking |
| Download published files |
| Local dev server |
| Start resolver server with npub subdomains |
| Debug nsite setup (relays, servers, integrity) |
| Validate config (exit 0 = valid, 1 = invalid) |
| Remove published files from relays/servers |
| List available sites (root + named) |
| 命令 | 用途 |
|---|---|
| 列出已发布的文件 |
| 交互式TUI文件浏览器,可查看中继/服务器的传播状态 |
| 下载已发布的文件 |
| 本地开发服务器 |
| 启动带npub子域名的解析服务器 |
| 调试nsite配置(中继、服务器、完整性检查) |
| 验证配置(退出码0 = 有效,1 = 无效) |
| 从中继/服务器删除已发布的文件 |
| 列出所有可用站点(根站点+命名站点) |
Troubleshooting
故障排查
Auth errors
身份验证错误
- "No valid signing method": Provide or configure bunker via
--sec.nsyte bunker use - "No stored credential": set in config but keychain entry missing. Fix:
bunkerPubkey.nsyte bunker use [pubkey] - Bunker URL rejected: Shell ate metacharacters. Use single quotes: .
'bunker://...'
- "No valid signing method": 请提供参数,或通过
--sec配置bunker。nsyte bunker use - "No stored credential": 配置中设置了但钥匙串中缺少对应条目。修复方法:执行
bunkerPubkey。nsyte bunker use [pubkey] - Bunker URL被拒绝: Shell解析了特殊字符,请用单引号包裹URL:。
'bunker://...'
Deploy errors
部署错误
- Relay issues: Check array in config has valid
relaysURLs. Trywss://.--use-fallback-relays - Blossom server rejection: Check array. Try adding a different server via
servers.nsyte config - Config missing: Run first.
nsyte init
- 中继节点问题: 检查配置中的数组是否包含有效的
relaysURL,可尝试添加wss://参数。--use-fallback-relays - Blossom服务器拒绝请求: 检查数组,可通过
servers添加其他可用服务器。nsyte config - 缺少配置文件: 先执行初始化项目。
nsyte init
Config errors
配置错误
- "Config editor requires interactive terminal": Edit JSON directly + .
nsyte validate - Validation fails: Common causes: malformed URLs, without
publishAppHandler: true,appHandler.kindson named site.publish* - bunkerPubkey format: Must be 64 hex chars, not npub. Always use .
nsyte bunker use
- "Config editor requires interactive terminal": 直接编辑JSON配置文件,然后执行验证。
nsyte validate - 验证失败: 常见原因:URL格式错误、但缺少
publishAppHandler: true、命名站点使用了appHandler.kinds参数。publish* - bunkerPubkey格式错误: 必须是64位十六进制字符,不是npub,请始终通过设置。
nsyte bunker use