clone

nostr relays on demand at <name>.bind.ws: claim one with your key, pay in zaps past the free allowance

dependabot/github_actions/actions-9b61906d8b
bindws / src / console / console.html
console.html 40.7K
1<main>2 <header class="mast">3 <div class="banner hidden" id="banner"><img id="bannerimg" alt=""></div>4 <div class="wordmark"><img id="iconimg" class="icon hidden" alt=""><h1 id="title"></h1></div>5 <div class="left"><div class="care" id="care"></div></div>6 <div class="right">7 <span class="urlrow"><code class="pill" id="url"></code><button class="ib" id="copy" title="Copy relay URL" aria-label="Copy relay URL"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></button></span>8 <span class="owner"><i class="av hidden" id="owner-av"></i><span id="ownerline"></span><em id="who"></em>9 <button id="signin" class="btn hidden">Sign in with extension</button>10 <button id="signin46" class="btn hidden">Remote signer</button>11 <button id="signout" class="ib hidden" title="Sign out" aria-label="Sign out"><svg viewBox="0 0 24 24"><path d="M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M15 8l5 4-5 4M20 12H9"/></svg></button>12 </span>13 </div>14 </header>1516 <section id="unclaimed" class="hidden">17 <h2>Nobody owns this relay yet.</h2>18 <p class="lead">Claim it and it's yours: you decide who can post, who can read, and what stays. One signature with a nostr browser extension; no account, no email, no card.</p>19 <div class="row"><button id="claim" class="btn pri">Claim this relay</button><button class="btn remote" data-note="claimnote">Use a remote signer</button><span class="note" id="claimnote"></span></div>20 <div class="block">21 <h3>Restore a backup</h3>22 <p class="note">Choose a private bind.ws archive to inspect it before restoring. Preview does not claim this relay. Restore accepts only an empty relay and the archive owner's signature.</p>23 <div class="form">24 <label class="wide"><span>Archive <small>up to 8 MB</small></span><input class="txt" type="file" id="backupfile" accept="application/json"></label>25 </div>26 <div class="actions"><button type="button" id="backupremote" class="btn">Use a remote signer</button><button type="button" id="backuppreview" class="btn">Preview restore</button><button type="button" id="backuprestore" class="btn pri" disabled>Restore</button></div>27 <div id="backup-preview" class="note"></div>28 </div>29 </section>3031 <section id="leased" class="hidden">32 <h2>A temporary relay, for now.</h2>33 <p class="lead">Anyone can read and write here until <b id="lease-until"></b>. Then everything on it is deleted and the name is freed. Claim it and it stays, events and files included: one signature with a nostr browser extension. Or claim a new name and pull this one into it from its Storage tab.</p>34 <div class="row"><button id="claimlease" class="btn pri">Claim this relay</button><button class="btn remote" data-note="leasenote">Use a remote signer</button><span class="note" id="leasenote"></span></div>35 </section>3637 <section id="remotesec" class="hidden">38 <h2>Connect a remote signer.</h2>39 <p class="lead">Your key stays in a signer app such as Amber or nsec.app; this page asks it to sign. On a phone, open the link and approve there. On a computer, paste the <span class="mono">bunker://</span> URL the app gives you.</p>40 <div class="row"><a id="nclink" class="btn pri" href="#">Open in your signer app</a><button id="nccopy" class="btn">Copy link</button><span class="note" id="ncnote"></span></div>41 <form id="bunkerform" class="addrow"><input class="txt mono" name="url" placeholder="bunker://…" required><button class="btn">Connect</button></form>42 <img id="ncqr" class="hidden" alt="QR code of the signer link" width="180" height="180">43 <p class="note" id="remotenote"></p>44 </section>4546 <section id="foldsec" class="folds">47 <div id="frontsec" class="hidden">48 <p class="lead hidden" id="desc"></p>49 <p class="metarow hidden" id="metarow"></p>50 </div>51 <details class="disclosure" id="aboutsec" name="page"><summary>About, for clients</summary><div id="about" class="about"></div></details>52 <details class="disclosure" id="connectsec" name="page"><summary>Connect</summary>53 <div class="door relay"><small>nostr relay</small><div class="v"><span id="d-ws"></span><button class="ib" data-copy="ws" title="Copy relay URL" aria-label="Copy relay URL"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></button></div></div>54 <p class="note">Each shortcut hands this relay to an app, with a QR code for a phone. Whichever app, add the relay URL above under its relay settings to post here.</p>55 <div class="appgrid" id="apps"></div>56 <p class="note" id="apps-note"></p>57 <details class="sub" id="conn-details"><summary>Connection details</summary>58 <div class="doors">59 <div class="door"><small>Blossom media</small><div class="v"><span id="d-blossom"></span><button class="ib" data-copy="blossom" title="Copy" aria-label="Copy"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></button></div></div>60 <div class="door"><small>names</small><div class="v"><span id="d-nip05"></span></div></div>61 <div class="door"><small>HTTP bridge, NIP-98</small><div class="v"><span>POST /events, /query, /count</span></div></div>62 </div>63 <div class="block hidden" id="git-connect">64 <h3>Git repositories, ntig</h3>65 <div>66 <p class="note">Use ordinary Git to clone a repository hosted here.</p>67 <div class="door"><small>Clone a repository</small><div class="v"><span id="git-clone"></span><button class="ib" id="git-copy" title="Copy clone example" aria-label="Copy clone example"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></button></div></div>68 <p class="note">Replace <span class="mono">&lt;npub&gt;</span> with the repository owner's npub, yours for your own repository, and <span class="mono">&lt;repo&gt;</span> with its repository name, such as <span class="mono">my-project</span>.</p>69 <p class="note">To host your own, use a Nostr Git client to publish your repository and signed branch state to this relay before pushing to the same remote. <a href="https://github.com/FelineStateMachine/bindws/blob/main/docs/22-grasp-01-git-hosting.md">Git hosting guide</a>.</p>70 </div>71 </div>72 </details>73 </details>74 </section>7576 <section id="peoplesec" class="hidden">77 <h2>People <span class="count" id="people-count"></span></h2>78 <p class="note hidden" id="people-note">Hidden from visitors. Only you see this list.</p>79 <div class="dir" id="dir"></div>80 </section>8182 <section id="fuelsec" class="hidden">83 <h2>Fuel</h2>84 <p class="lead">Free allowance first; past it, usage burns sats. Anyone can zap a top-up.</p>85 <div class="gauges">86 <div class="gauge"><small>Events stored</small><div class="bar"><i id="g-events"></i><b id="p-events"></b></div><span id="t-events"></span></div>87 <div class="gauge"><small>Files stored</small><div class="bar"><i id="g-media"></i><b id="p-media"></b></div><span id="t-media"></span></div>88 <div class="gauge"><small>Awake this month</small><div class="bar"><i id="g-active"></i><b id="p-active"></b></div><span id="t-active"></span></div>89 <div class="gauge"><small>Rows written this month</small><div class="bar"><i id="g-rows"></i><b id="p-rows"></b></div><span id="t-rows"></span></div>90 </div>91 <p class="balance" id="fuel-balance"></p>92 <form id="topup" class="topup hidden"><span class="sats"><input type="number" name="sats" min="1" value="1000"><span>sats</span></span><button class="btn pri">&#9889; Zap to top up</button><span class="note" id="topup-note"></span></form>93 <div id="invoice" class="invoice hidden">94 <p>Pay from any lightning wallet. The receipt lands on this relay and credits it automatically.</p>95 <div class="row"><a id="inv-link" class="btn" href="#">Open in wallet</a><button id="inv-copy" class="ib" title="Copy invoice" aria-label="Copy invoice"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></button><span class="state" id="inv-state"></span></div>96 <textarea id="inv-text" readonly></textarea>97 </div>98 </section>99100 <section id="myinvites" class="hidden">101 <h2>Your invites</h2>102 <p class="lead">The owner lets members bring people in. Each link admits one person and lasts three days.</p>103 <div class="row"><button id="mintmine" class="btn pri">New invite link</button><span class="note" id="minenote"></span></div>104 <ul id="mine" class="plain"></ul>105 </section>106107108 <div class="console hidden" id="console">109 <nav class="tabs" id="tabs">110 <a href="#people" data-tab="people">People<span class="count" id="tc-people"></span></a>111 <a href="#moderation" data-tab="moderation">Moderation<span class="count" id="tc-reports"></span></a>112 <a href="#rules" data-tab="rules">Rules</a>113 <a href="#identity" data-tab="identity">Identity</a>114 <a href="#connect" data-tab="connect">Connect</a>115 <a href="#data" data-tab="data">Data</a>116 <a href="#sync" data-tab="sync">Sync</a>117 <a href="#views" data-tab="views">Views</a>118 <a href="#health" data-tab="health">Health</a>119 <a href="#owner" data-tab="owner">Owner</a>120 </nav>121122 <section class="panel" data-panel="people">123 <h2>People</h2>124 <p class="lead">The member list is published as a signed roster; a name makes someone <span class="mono" id="nip05-example"></span>.</p>125 <div class="block">126 <form id="addmember" class="addrow"><input class="txt mono" name="pubkey" placeholder="hex pubkey or npub" required><input class="txt" name="name" placeholder="name (optional)" pattern="[a-z0-9._-]{1,64}" style="max-width:9rem"><input class="txt" name="note" placeholder="note" style="max-width:9rem"><button class="ib pri" title="Add member" aria-label="Add member"><svg viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></svg></button></form>127 <div class="scroll"><table id="members" class="people-table"><thead><tr><th>Who</th><th>Name</th><th>Note</th><th>Limits</th><th>Joined</th><th></th></tr></thead><tbody></tbody></table></div>128 </div>129 <div class="block">130 <div class="two">131 <div>132 <h3>Invites</h3>133 <form id="mintinvite" class="addrow"><select class="txt" name="ttl" style="max-width:8rem"><option value="3600">1 hour</option><option value="86400">1 day</option><option value="259200" selected>3 days</option><option value="2592000">30 days</option></select><input class="txt num" type="number" name="max" min="0" value="0" title="uses, 0 = unlimited" style="width:5rem;flex:0 0 auto"><input class="txt" name="note" placeholder="note"><button class="ib pri" title="New invite" aria-label="New invite"><svg viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></svg></button></form>134 <ul id="invites" class="plain"></ul>135 <form id="treeform" class="addrow hidden" title="Members invite members: how many hops from you the tree reaches, and how many live invites each member may hold"><span class="dim">members invite</span><input class="txt num" type="number" name="depth" min="0" max="10" value="0" style="width:4rem;flex:0 0 auto"><span class="dim">hops deep,</span><input class="txt num" type="number" name="quota" min="0" max="100" value="0" style="width:4rem;flex:0 0 auto"><span class="dim">each</span><button class="btn">Save</button></form>136 </div>137 <div>138 <h3>Joining</h3>139 <form id="joinform">140 <div class="form">141 <label class="wide"><span>Shown before someone accepts an invite</span><textarea name="joinTerms" placeholder="House rules, expectations, anything a newcomer should agree to." maxlength="20000"></textarea></label>142 <label class="wide switch"><input type="checkbox" name="directoryPublic"> Show the people directory to visitors</label>143 </div>144 <div class="actions"><button class="btn pri">Save</button></div>145 </form>146 </div>147 </div>148 </div>149 </section>150151 <section class="panel" data-panel="moderation">152 <h2>Moderation</h2>153 <p class="lead">Reports never show in the feed. Banning also deletes the reported thing.</p>154 <div class="block">155 <h3>Reports <span class="count" id="reports-count"></span></h3>156 <form id="thresholdform" class="addrow"><span class="dim">hide an event once</span><input class="txt num" type="number" name="reportThreshold" min="0" max="100" style="width:4.5rem;flex:0 0 auto"><span class="dim">different people report it; 0 never</span><button class="btn">Save</button></form>157 <div class="scroll"><table id="reports" class="events"><thead><tr><th>Time</th><th>Type</th><th>About</th><th>Reason</th><th></th></tr></thead><tbody></tbody></table></div>158 </div>159 <div class="block">160 <h3>Log</h3>161 <p class="dim">Every change made here or by a moderation event, newest first, the last 5,000.</p>162 <div class="scroll"><table id="audit" class="events"><thead><tr><th>Time</th><th>Who</th><th>Action</th><th>Target</th><th>Detail</th></tr></thead><tbody></tbody></table></div>163 <button class="btn" id="audit-more" type="button">Older</button>164 </div>165 <div class="block two">166 <div>167 <h3>Bans</h3>168 <form id="addban" class="addrow"><input class="txt mono" name="pubkey" placeholder="hex pubkey or npub" required><input class="txt" name="reason" placeholder="reason" style="max-width:8rem"><label class="note" title="Also delete everything they wrote and uploaded"><input type="checkbox" name="erase"> erase</label><button class="ib danger" title="Ban" aria-label="Ban"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M6 6l12 12"/></svg></button></form>169 <ul id="bans" class="plain"></ul>170 <ul id="banned-events" class="plain"></ul>171 </div>172 <div>173 <h3>Blocked addresses</h3>174 <form id="addblock" class="addrow"><input class="txt mono" name="ip" placeholder="IP address" required><input class="txt" name="reason" placeholder="reason" style="max-width:8rem"><button class="ib danger" title="Block" aria-label="Block"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M6 6l12 12"/></svg></button></form>175 <ul id="blocks" class="plain"></ul>176 </div>177 </div>178 <div class="block">179 <h3>Recent events</h3>180 <p class="note">Delete removes one thing. Ban also refuses it forever. Search covers notes, articles and profiles.</p>181 <form id="searchform" class="addrow"><input class="txt" name="q" placeholder="search" maxlength="200"><button class="btn">Search</button><button type="button" id="searchclear" class="btn hidden">Clear</button></form>182 <div class="scroll"><table id="events" class="events"><thead><tr><th>Time</th><th>Kind</th><th>Author</th><th>Content</th><th></th></tr></thead><tbody></tbody></table></div>183 <div class="actions left"><button id="more" class="btn">Load more</button></div>184 </div>185 <div class="block">186 <h3>Pinned <span class="count" id="pins-count"></span></h3>187 <p class="note">Group clients show these at the top. Up to 20, in this order.</p>188 <form id="pinform" class="addrow"><input class="txt mono" name="id" placeholder="event id or address kind:pubkey:d" required><button class="btn">Pin</button></form>189 <ul id="pins" class="plain"></ul>190 </div>191 </section>192193 <section class="panel" data-panel="rules">194 <h2>Rules</h2>195 <p class="lead">Bans apply regardless of these.</p>196 <div class="block">197 <h3>Presets</h3>198 <p class="note">One click sets writes, reads, kinds and keep-for together. Limits, identity and people stay.</p>199 <div id="presets"></div>200 <div class="row hidden" id="presetsourcerow"><input class="txt mono" id="presetsource" placeholder="wss://source.relay to mirror" style="max-width:24rem"><span class="note">Replica presets keep a standing pull of their kinds from this relay.</span></div>201 <p class="note" id="presetnote"></p>202 </div>203 <form id="access">204 <div class="two">205 <div><h3>Writes</h3><div class="choices">206 <label><input type="radio" name="writes" value="open"><b>Anyone</b><small>Every valid event is accepted, unless banned.</small></label>207 <label><input type="radio" name="writes" value="allowlist"><b>Members</b><small>Only people on the member list, and you.</small></label>208 <label><input type="radio" name="writes" value="wot"><b>Members and their follows</b><small>Members, plus everyone in a member's contact list.</small></label>209 <label><input type="radio" name="writes" value="owner"><b>Only me</b><small>Nobody else can post.</small></label>210 </div></div>211 <div><h3>Reads</h3><div class="choices">212 <label><input type="radio" name="reads" value="open"><b>Anyone</b><small>DMs and gift wraps still go only to their parties.</small></label>213 <label><input type="radio" name="reads" value="auth"><b>Authenticated only</b><small>Every query needs a NIP-42 sign-in first.</small></label>214 <label><input type="radio" name="reads" value="members"><b>Members only</b><small>Removing a member ends their subscriptions.</small></label>215 </div></div>216 </div>217 <div class="form" style="margin-top:1rem">218 <label><span>Open to anyone <small>kinds anyone may write, whatever the rule above says</small></span><input class="txt mono" name="openKinds" placeholder="7, 9735"></label>219 <label class="switch"><input type="checkbox" name="guestReplies"> Anyone may reply to a member's note</label>220 </div>221 <div class="limits">222 <label><span>Minimum proof of work <small>bits</small></span><input class="txt num" type="number" name="minPow" min="0" max="64"></label>223 <label><span>Reject events dated in the future by more than <small>seconds</small></span><input class="txt num" type="number" name="maxFuture" min="0"></label>224 <label><span>Max events per query</span><input class="txt num" type="number" name="maxLimit" min="1" max="5000"></label>225 <label><span>Max subscriptions per connection</span><input class="txt num" type="number" name="maxSubs" min="1" max="200"></label>226 <label><span>Max message size <small>KB</small></span><input class="txt num" type="number" name="maxMessageKB" min="16" max="1024"></label>227 <label><span>Events per minute <small>per connection</small></span><input class="txt num" type="number" name="eventsPerMinute" min="1"></label>228 <label><span>Queries per minute <small>per connection</small></span><input class="txt num" type="number" name="reqsPerMinute" min="1"></label>229 <label><span>Max upload size <small>MB</small></span><input class="txt num" type="number" name="maxBlobMB" min="1" max="95"></label>230 </div>231 <div class="actions"><button class="btn pri">Save rules</button></div>232 </form>233 <form id="git-capacity" class="block">234 <h3>Git capacity</h3>235 <p class="note">GRASP Git has its own retained-storage and request limits. Storage and compute still use the relay’s normal fuel and billing. Git transfer limits are independent from event and file limits.</p>236 <div class="limits">237 <label><span>Repositories <small>maximum on this relay</small></span><input class="txt num" type="number" name="maxRepositories" min="1" max="4096" required></label>238 <label><span>Relay Git storage <small>GiB, including metadata</small></span><input class="txt num" type="number" name="maxRelayGiB" min="0.001" max="6" step="0.001" required></label>239 <label><span>Compressed repository data <small>GiB, per repository</small></span><input class="txt num" type="number" name="maxCompressedGiB" min="0.001" max="6" step="0.001" required></label>240 <label><span>Pack size <small>MiB</small></span><input class="txt num" type="number" name="maxPackMiB" min="0.001" max="95" step="0.001" required></label>241 <label><span>Object size <small>MiB</small></span><input class="txt num" type="number" name="maxObjectMiB" min="0.001" max="64" step="0.001" required></label>242 </div>243 <details class="advanced"><summary>Advanced Git admission and fetch limits</summary><div class="limits">244 <label><span>Objects <small>per repository</small></span><input class="txt num" type="number" name="maxObjects" min="1" max="500000" required></label>245 <label><span>Raw bytes <small>per repository, GiB</small></span><input class="txt num" type="number" name="maxRawGiB" min="0.001" max="64" step="0.001" required></label>246 <label><span>Transaction bytes <small>MiB</small></span><input class="txt num" type="number" name="maxTransactionRawMiB" min="0.001" max="64" step="0.001" required></label>247 <label><span>Transaction objects</span><input class="txt num" type="number" name="maxTransactionObjects" min="1" max="100000" required></label>248 <label><span>Metadata <small>MiB per repository</small></span><input class="txt num" type="number" name="maxMetadataMiB" min="0.001" max="1024" step="0.001" required></label>249 <label><span>Refs <small>per repository</small></span><input class="txt num" type="number" name="maxRefs" min="1" max="16384" required></label>250 <label><span>Graph edges <small>per repository</small></span><input class="txt num" type="number" name="maxGraphEdges" min="1" max="4000000" required></label>251 <label><span>Fetch response <small>GiB</small></span><input class="txt num" type="number" name="maxFetchGiB" min="0.001" max="6" step="0.001" required></label>252 </div></details>253 <div class="actions"><button class="btn pri">Save Git capacity</button></div>254 </form>255 <div class="block">256 <h3>Kinds</h3>257 <p class="note">An empty allow list means every kind. Blocks always win.</p>258 <form id="kindform" class="addrow"><input class="txt num" type="number" name="kind" min="0" max="65535" placeholder="kind" required style="width:7rem;flex:0 0 auto"><button class="ib" name="rule" value="allow" title="Allow kind" aria-label="Allow kind"><svg viewBox="0 0 24 24"><path d="M5 12l5 5L20 7"/></svg></button><button class="ib danger" name="rule" value="block" title="Block kind" aria-label="Block kind"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M6 6l12 12"/></svg></button></form>259 <p class="kindline">Allowed: <span id="kinds-allow"></span></p>260 <p class="kindline">Blocked: <span id="kinds-block"></span></p>261 </div>262 <div class="block">263 <h3>Features</h3>264 <p class="note">Each is a door or a cost. Off leaves the NIP-11 list, answers 404 at its door and is refused at the socket.</p>265 <div id="features" class="limits"></div>266 <form id="push-policy-form" class="limits">267 <label><span>Push callback origins <small>One HTTPS origin per line, also approved by your host operator. Relay push costs fuel.</small></span><textarea class="txt" name="origins" rows="3" placeholder="https://push.example.com"></textarea></label>268 <label><span>Lettered NIP advertisements <small>Some older clients reject mixed NIP identifiers. Relay push requires them.</small></span><input type="checkbox" name="lettered"></label>269 <label><span>Automatic NIP-65 delivery <small>Send your public events to your write relays and tagged people's read relays. Each event is bounded to a few targets.</small></span><input type="checkbox" name="delivery"></label>270 <label><span>Maximum delivery targets <small>Per event</small></span><input class="txt num" type="number" name="deliveryMax" min="1" max="16" value="8" style="width:5rem"></label>271 <div class="actions"><button class="btn">Save delivery policy</button></div>272 </form>273 </div>274 <div class="block">275 <h3>Blocked words</h3>276 <p class="note">Content containing one is refused. You and your moderators are exempt. An entry written /like this/ is a regular expression.</p>277 <form id="wordsform"><textarea class="txt" name="words" rows="4" placeholder="one word, phrase or /pattern/ per line"></textarea><label class="switch"><input type="checkbox" name="inTags"> Also search tags</label><div class="actions"><button class="btn">Save words</button></div></form>278 </div>279 </section>280281 <section class="panel" data-panel="identity">282 <h2>Identity</h2>283 <form id="identity">284 <h3>Profile</h3>285 <div class="form">286 <label><span>Name</span><input class="txt" name="name" maxlength="200"></label>287 <label><span>Contact</span><input class="txt" name="contact" placeholder="mailto:you@example.com" maxlength="500"></label>288 <label class="wide"><span>Description</span><textarea name="description" maxlength="2000"></textarea></label>289 <label class="wide"><span>Icon URL</span><input class="txt" name="icon" placeholder="https://…/icon.png" maxlength="2000"></label>290 <label class="wide"><span>Banner URL</span><input class="txt" name="banner" placeholder="https://…/banner.png" maxlength="2000"></label>291 </div>292 <h3 class="gap">For directories</h3>293 <div class="form">294 <label><span>Posting policy URL</span><input class="txt" name="postingPolicy" placeholder="https://…/posting" maxlength="2000"></label>295 <label><span>Privacy policy URL</span><input class="txt" name="privacyPolicy" placeholder="https://…/privacy" maxlength="2000"></label>296 <label><span>Tags</span><input class="txt" name="tags" placeholder="bitcoin, cats"></label>297 <label><span>Languages</span><input class="txt" name="languageTags" placeholder="en, pt-BR"></label>298 <label><span>Countries</span><input class="txt" name="relayCountries" placeholder="US, DE"></label>299 </div>300 <div class="actions"><button class="btn pri">Save identity</button></div>301 </form>302 <div class="block">303 <h3>Your own domain</h3>304 <p class="note">Your hostname serves this relay or one of its sites once its CNAME resolves and its certificate is issued.</p>305 <form id="adddomain"><div class="form"><label><span>Hostname</span><input class="txt mono" name="host" placeholder="relay.example.com" required></label><label><span>Destination</span><select class="txt" name="site"><option value="">This relay</option></select></label></div><div class="actions"><button class="btn">Add domain</button></div></form>306 <div id="domains"></div>307 <p class="note" id="domainnote"></p>308 </div>309 <div class="block">310 <h3>Your relay lists</h3>311 <p class="note">Clients find your relays through these lists. Add this relay to each so they use it. What is already listed stays.</p>312 <div id="wire"></div>313 </div>314 <div class="block">315 <h3>Share</h3>316 <p class="note">A card for links and profiles, and the group address that group-aware clients open. Both are public and refresh every five minutes.</p>317 <div class="share">318 <a href="/card.svg" target="_blank" rel="noopener"><img id="cardimg" src="/card.svg" alt="relay card" width="600" height="315"></a>319 <div class="share-side">320 <img id="naddrqr" class="hidden" alt="QR code of the group address" width="150" height="150">321 <code class="mono naddr" id="naddr"></code>322 <div class="row"><button class="btn" id="copynaddr">Copy naddr</button><button class="btn" id="copyembed">Copy embed</button></div>323 </div>324 </div>325 </div>326 </section>327328 <section class="panel" data-panel="connect">329 <h2>Connect</h2>330 <p class="lead">The shortcuts on the Connect fold: which apps, in what order, and who sees each.</p>331 <div class="block">332 <div class="conn-bar"><h3>Shortcuts</h3><span class="note" id="connnote"></span><button type="button" id="connsave" class="btn pri" disabled>Save shortcuts</button></div>333 <p class="note">Top to bottom is the order visitors see. Edit sets a title of your own and the template's inputs; a shortcut whose feature is off waits until it is switched on.</p>334 <div id="conns" class="conns"></div>335 </div>336 <div class="block">337 <h3>Library</h3>338 <p class="note">One template per app, from the repository's connection-templates folder; the relay URL, the owner's profile and the viewer's own key fill in when the page opens.</p>339 <div id="connlib" class="appgrid"></div>340 </div>341 </section>342343 <section class="panel" data-panel="data">344 <h2>Data</h2>345 <p class="lead">Keep-for rules run once a day. Purges happen now and cannot be undone.</p>346 <div class="block" id="listhistoryblock">347 <h3>Recover your lists</h3>348 <p class="note">Older signed versions of your follows, relay lists and bookmarks stay private here. Restore a version to review it, then sign and publish it from this relay.</p>349 <div class="scroll"><table id="listhistory" class="events"><thead><tr><th>List</th><th>Created</th><th>Saved</th><th></th></tr></thead><tbody></tbody></table></div>350 </div>351 <div class="kbar" id="s-bar"></div><span class="legend slegend" id="s-legend"></span>352 <div class="usage" id="s-totals"></div>353 <div class="block">354 <h3>By kind</h3>355 <div class="scroll"><table id="kinds" class="events"><thead><tr><th>Kind</th><th class="r">Count</th><th class="r">Size</th><th>Oldest</th><th>Keep for</th><th></th></tr></thead><tbody></tbody></table></div>356 </div>357 <div class="block">358 <h3>Files <span class="count" id="blobs-count"></span></h3>359 <div class="scroll"><table id="blobs" class="events"><thead><tr><th>Time</th><th>File</th><th>Size</th><th>Uploader</th><th></th></tr></thead><tbody></tbody></table></div>360 </div>361 <div class="block">362 <h3>Sites <span class="count" id="sites-count"></span></h3>363 <p class="note">Published NIP-5A manifests and the hostnames where they are served.</p>364 <div class="scroll"><table id="sites" class="events"><thead><tr><th>Author</th><th>Name</th><th>URL</th><th class="r">Files</th><th class="r">Size</th><th>Expiry</th><th></th></tr></thead><tbody></tbody></table></div>365 </div>366 <div class="block">367 <h3>Dumps <span class="count" id="dumps-count"></span></h3>368 <p class="note">Every event as one JSONL file on a schedule, kept for a few runs and counted as files. Downloads need your signature.</p>369 <form id="dumpform" class="addrow"><select class="txt" name="dumps" style="max-width:8rem"><option value="off">off</option><option value="daily">daily</option><option value="weekly">weekly</option></select><input class="txt num" type="number" name="keep" min="1" max="60" value="7" title="how many to keep" style="width:5rem;flex:0 0 auto"><button class="btn">Save</button><button type="button" id="dumpnow" class="btn">Dump now</button></form>370 <ul id="dumps" class="plain"></ul>371 </div>372 <div class="block">373 <h3>Backups <span class="count" id="backups-count"></span></h3>374 <p class="note">Portable copies include configuration, events, site files and Git objects. They are private and bounded at 8 MB.</p>375 <div class="form"><label><span>Archive name</span><input class="txt mono" id="backupid" placeholder="backup" value="backup"></label></div>376 <div class="actions"><button type="button" id="backupnow" class="btn">Create and download</button></div>377 <ul id="backups" class="plain"></ul>378 </div>379 <div class="block">380 <h3>Import a file</h3>381 <p class="note">A JSONL of events, one per line, such as a dump or a strfry export, or a JSON array. Up to 64 MB. Signatures are checked; bans and kind rules apply; the write rule does not. Progress shows under Jobs.</p>382 <form id="importform" class="addrow"><input class="txt" type="file" name="file" accept=".jsonl,.json,.ndjson,application/json" required><button class="btn">Import</button></form>383 </div>384 </section>385386 <section class="panel" data-panel="sync">387 <h2>Sync</h2>388 <p class="lead">Events in and out, one round at a time, while the relay sleeps between rounds. Jobs spend awake time, which fuel counts.</p>389 <div class="block">390 <h3>Jobs</h3>391 <p class="note">Work the relay does on its own, one round at a time. A pull copies what another relay has and this one lacks. Fetch my history pulls your own events from the relays in your relay list. Rebroadcast sends what is here to other relays. Bans and kind rules apply to what arrives.</p>392 <div class="scroll"><table id="jobs" class="events"><thead><tr><th>Job</th><th>Relays</th><th>Filter</th><th>Schedule</th><th>Result</th><th></th></tr></thead><tbody></tbody></table></div>393394 <form id="pullform" class="addrow"><input class="txt mono" name="url" placeholder="wss://other.relay" required><select class="txt" name="every" style="max-width:9rem"><option value="0">once</option><option value="1">every hour</option><option value="6">every 6 hours</option><option value="24">every day</option></select><button class="btn">Pull</button></form>395 <form id="backfillform" class="addrow"><input class="txt mono" name="relays" placeholder="relays, comma separated; blank uses your relay list"><button class="btn">Fetch my history</button></form>396 <form id="pushform">397 <div class="form">398 <label class="wide"><span>Rebroadcast to</span><input class="txt mono" name="targets" placeholder="wss://a.relay, wss://b.relay" required></label>399 <label><span>Kinds <small>blank for all</small></span><input class="txt mono" name="kinds" placeholder="1, 30023"></label>400 <label><span>Newer than <small>days, blank for all</small></span><input class="txt num" type="number" name="days" min="0"></label>401 <label><span>Schedule</span><select class="txt" name="every"><option value="0">once</option><option value="1">every hour</option><option value="6">every 6 hours</option><option value="24">every day</option></select></label>402 </div>403 <div class="actions"><button class="btn">Rebroadcast</button></div>404 </form>405 </div>406 <div class="block">407 <h3>Automatic delivery</h3>408 <p class="note">Recent per-target results for automatic NIP-65 delivery.</p>409 <div class="scroll"><table id="deliveries"><thead><tr><th>Event</th><th>Target</th><th>Status</th><th>Attempts</th><th>Last error</th></tr></thead><tbody></tbody></table></div>410 </div>411 <div class="block">412 <h3>Fork this relay</h3>413 <p class="note">A new name, temporary until claimed, filled from this relay. Yours to split a name by job, or somebody else's to hand them a community with its history. One fork an hour.</p>414 <form id="forkform">415 <div class="form">416 <label><span>Name <small>optional</small></span><input class="txt mono" name="name" placeholder="a memorable one if blank" pattern="[a-z0-9-]{3,32}"></label>417 <label><span>Who claims it <small>npub or hex, you if blank</small></span><input class="txt mono" name="holder"></label>418 <label><span>What to copy</span><select class="txt" name="scope"><option value="all">everything</option><option value="mine">only my events</option><option value="kinds">these kinds</option></select></label>419 <label id="forkkinds" class="hidden"><span>Kinds <small>comma separated</small></span><input class="txt mono" name="kinds" placeholder="1, 30023"></label>420 <label class="wide switch"><input type="checkbox" name="people" checked> Copy the people</label>421 </div>422 <div class="actions"><button class="btn pri">Fork</button></div>423 </form>424 <p class="note" id="forknote"></p>425 <div class="row hidden" id="forkresult"><span class="mono" id="forkurl"></span><button class="ib" id="forkcopy" title="Copy" aria-label="Copy"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V6a2 2 0 0 1 2-2h9"/></svg></button></div>426 </div>427 </section>428429 <section class="panel" data-panel="views">430 <h2>Views</h2>431 <p class="lead">Records the relay computes and signs, for clients and for anyone. Each run costs the rows it writes.</p>432 <div class="block">433 <div id="views"></div>434 </div>435 </section>436437 <section class="panel" data-panel="health">438 <h2>Health</h2>439 <div class="counters">440 <div class="counter"><b class="big" id="h-last">–</b><small>since last event</small><span class="sub" id="h-last-sub"></span></div>441 <div class="counter"><b class="big" id="h-conns">–</b><small>connected now</small><span class="sub">websockets open</span></div>442 <div class="counter"><b class="big" id="h-fuel">–</b><small id="h-fuel-label">fuel</small><span class="sub" id="h-fuel-sub"></span></div>443 <div class="counter"><div class="kbar" id="h-kinds"></div><small>used for, last 30 days</small><span class="sub legend" id="h-kinds-legend"></span></div>444 </div>445 <div class="usage" id="usage"></div>446 <div class="block">447 <h3>Zaps received</h3>448 <div class="scroll"><table id="credits"><thead><tr><th>When</th><th>From</th><th class="r">Sats</th></tr></thead><tbody></tbody></table></div>449 </div>450 <div class="block">451 <h3>Notifications</h3>452 <p class="note">The relay writes you a private message (NIP-17) with its own key. It lands here, in your inbox on your own relay, and on your DM relays when this relay holds your kind 10050.</p>453 <form id="notify">454 <div class="form">455 <label class="wide switch"><input type="checkbox" name="reports"> A report arrives</label>456 <label class="wide switch"><input type="checkbox" name="fuel"> Fuel runs low</label>457 <label class="wide switch"><input type="checkbox" name="jobs"> A pull finishes</label>458 <label class="wide switch"><input type="checkbox" name="succession"> The handover clock is running</label>459 <label class="wide switch"><input type="checkbox" name="digest"> A note every week on how the relay is doing</label>460 </div>461 <div class="actions"><button class="btn pri">Save notifications</button><button type="button" id="notifytest" class="btn">Send a test message</button></div>462 </form>463 </div>464 </section>465466 <section class="panel" data-panel="owner">467 <h2>Owner</h2>468 <p class="lead">The relay's key, events, files and fuel stay put through everything here except delete.</p>469 <div class="block">470 <h3>Configuration</h3>471 <p class="note">Rules, identity, members, bans, address blocks and kind rules as a file. Importing replaces those lists; it never touches events, files, or the owner.</p>472 <div class="row"><button id="exportcfg" class="btn">Export configuration</button><button id="importcfg" class="btn">Import configuration</button><input type="file" id="cfgfile" accept="application/json,.json" class="hidden"></div>473 </div>474 <div class="block danger-zone">475 <h3>Transfer ownership</h3>476 <p class="note">Hands the relay to a member. You stay on as a moderator. The relay's key, events, files and fuel do not change. There is no undo.</p>477 <form id="transfer" class="addrow"><select class="txt mono" name="pubkey" required></select><button class="btn danger">Transfer</button></form>478 </div>479 <div class="block danger-zone">480 <h3>If I lose my key</h3>481 <p class="note">Name a member as your heir. If you do not sign in here for the time you pick, the relay writes to you once a week for a month, then hands itself to the heir and keeps you on as a moderator. Any signed action on the relay resets the clock.</p>482 <form id="succession">483 <div class="form">484 <label><span>Heir <small>a member</small></span><select class="txt mono" name="heir" required></select></label>485 <label><span>Hand over</span><select class="txt" name="afterDays"><option value="90">after 3 months away</option><option value="180" selected>after 6 months away</option><option value="365">after a year away</option></select></label>486 </div>487 <div class="actions"><button class="btn">Set heir</button><button type="button" id="clearsuccession" class="btn hidden">Clear</button></div>488 </form>489 <p class="note" id="successionnote"></p>490 </div>491 <div class="block danger-zone">492 <h3>Delete this relay</h3>493 <p class="note">Deletes every event, file, member, invite and setting, closes every connection, and returns the name to unclaimed for anyone to take. There is no undo.</p>494 <button id="deleterelay" class="btn danger">Delete this relay</button>495 </div>496 </section>497 </div>498499 <footer class="pg"><p>a bind.ws relay</p><a href="https://github.com/FelineStateMachine/bindws">source</a></footer>500</main>