forked from bitcoinafterlife/bal-welist-website
Compare commits
34 Commits
main
...
bitcoinaft
| Author | SHA1 | Date | |
|---|---|---|---|
| ecaf983dbb | |||
|
3dcd8227fa
|
|||
|
b50b9f5de9
|
|||
| 373580b356 | |||
| a6ea23ff5f | |||
| 40db9f36ab | |||
| 8a9b1b21d1 | |||
| e71051d869 | |||
| e4707b7fd7 | |||
|
|
c297fb30db | ||
|
|
7be9959241 | ||
|
57347e87e7
|
|||
|
a8d1c5b214
|
|||
|
0298ec737e
|
|||
| add0b2cddc | |||
| 74fe167137 | |||
| f9ffc383a0 | |||
| d223404a86 | |||
| b79ee2fdd8 | |||
| 131e5ffabf | |||
| ce66b0de3f | |||
| ff4e46858b | |||
| 6c942e58c6 | |||
| 616c0d1285 | |||
| 03d41dd25d | |||
| adcd4cde94 | |||
| 8bdef5d18f | |||
| 5536d8b14e | |||
| 6cfa521adc | |||
| 560a4d1cbe | |||
| 221bfec74e | |||
| c9749bfed1 | |||
| 756ab98c41 | |||
| 098ca48e9d |
153
README.md
153
README.md
@@ -1,2 +1,153 @@
|
|||||||
welist html
|
# Server Status: Complete Explanation and Reference Guide
|
||||||
|
|
||||||
|
This page explains all the **Will Executor server health statuses** used throughout the BAL Web Interface. Each status type provides critical information about server operation, health checks, and potential issues for administrators monitoring the Bitcoin After Life network.
|
||||||
|
|
||||||
|
## Status Code Overview
|
||||||
|
|
||||||
|
| Status | Description | When It Occurs |
|
||||||
|
|--------|-------------|----------------|
|
||||||
|
| `OK` | Health check passed | Server is online, functioning normally |
|
||||||
|
| `TIMEOUT: <message>` | Connection timeout | Server response took too long |
|
||||||
|
| `CONNECTION: <message>` | Connection error | Network connectivity issues |
|
||||||
|
| `STATUS: <code>` | HTTP error (from server) | Server returned non-200 status |
|
||||||
|
| `WRONG REPLY: <message>` | Invalid JSON response | Server response couldn't be parsed |
|
||||||
|
| `REQUEST: <message>` | Request error | Client-side request failed |
|
||||||
|
| `BODY: <message>` | Body read error | Failed to read response body |
|
||||||
|
| `DECODE: <message>` | Decode error | Failed to decode response content |
|
||||||
|
| `KO` | Generic error | Unknown or unspecified error |
|
||||||
|
|
||||||
|
## Status Types Explained
|
||||||
|
|
||||||
|
### 🟢 Good Statuses
|
||||||
|
**`OK`** - Everything is functioning correctly:
|
||||||
|
- Server is online and responding
|
||||||
|
- Health check completed successfully
|
||||||
|
- Ready for new registration/processing
|
||||||
|
|
||||||
|
### 🟡 Warning/Moderate Issues
|
||||||
|
**`TIMEOUT: <message>`** - Connection timed out:
|
||||||
|
- Server took too than expected to respond
|
||||||
|
- Could indicate server overload or network issues
|
||||||
|
- Requires attention but server may still be functional
|
||||||
|
|
||||||
|
**`CONNECTION: <message>`** - Connection error:
|
||||||
|
- Network connectivity problems
|
||||||
|
- Server might be reachable but cannot communicate
|
||||||
|
- Potential infrastructure or configuration issue
|
||||||
|
|
||||||
|
**`STATUS: <code>`** - HTTP error:
|
||||||
|
- Server responded with an error code (4xx or 5xx)
|
||||||
|
- Could indicate misconfiguration, maintenance, or issues |
|
||||||
|
- Different error codes mean different things
|
||||||
|
|
||||||
|
### 🔴 Critical Issues
|
||||||
|
**`WRONG REPLY`** - Invalid JSON response:
|
||||||
|
- Server response format is incorrect
|
||||||
|
- May indicate server software bug or corruption
|
||||||
|
- Prevents proper data processing
|
||||||
|
|
||||||
|
**`REQUEST`** - Request error:
|
||||||
|
- Client request failed
|
||||||
|
- Network or protocol issue
|
||||||
|
- Server may be unreachable
|
||||||
|
|
||||||
|
**`BODY`** - Body read error:
|
||||||
|
- Failed to read response body after successful connection
|
||||||
|
- Could indicate server processing issues
|
||||||
|
- Data corruption or transmission problems
|
||||||
|
|
||||||
|
**`DECODE`** - Decode error:
|
||||||
|
- Failed to decode response content
|
||||||
|
- Encoding mismatch or corrupted data
|
||||||
|
- Prevents proper data interpretation
|
||||||
|
|
||||||
|
**`KO`** - Generic error:
|
||||||
|
- Unknown or unspecified error
|
||||||
|
- Fallback for all other unidentified issues
|
||||||
|
- Indicates something went wrong but exact cause unknown
|
||||||
|
|
||||||
|
## Example Status Messages
|
||||||
|
|
||||||
|
### Normal Operations
|
||||||
|
```
|
||||||
|
Status: OK
|
||||||
|
Meaning: Health check passed
|
||||||
|
Display: Server is healthy and ready
|
||||||
|
```
|
||||||
|
|
||||||
|
### Network/Time Issues
|
||||||
|
```
|
||||||
|
Status: TIMEOUT: Connection timed out after 30 seconds
|
||||||
|
Meaning: Server took too long to respond
|
||||||
|
Display: "Connection timeout (Connection timed out after 30 seconds)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTTP Errors
|
||||||
|
```
|
||||||
|
Status: STATUS: 500
|
||||||
|
Meaning: Server returned HTTP 500 Internal Server Error
|
||||||
|
Display: "HTTP error (HTTP error)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Response Processing Issues
|
||||||
|
```
|
||||||
|
Status: WRONG REPLY: Invalid JSON
|
||||||
|
Meaning: Server response could not be parsed as JSON
|
||||||
|
Display: "Invalid JSON response (Invalid JSON)"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Practical Usage Guide
|
||||||
|
|
||||||
|
### For Server Administrators
|
||||||
|
- **OK**: Check server resources and logs if needed
|
||||||
|
- **TIMEOUT/CONNECTION**: Check server network connectivity
|
||||||
|
- **STATUS**: Review server logs and restart if needed
|
||||||
|
- **WRONG REPLY/DECODE/REQUEST**: Investigate server software issues
|
||||||
|
- **KO**: Review server errors and restart
|
||||||
|
|
||||||
|
### For Users
|
||||||
|
- **OK**: Server is working correctly
|
||||||
|
- **TIMEOUT/CONNECTION**: Temporary issue, try again later
|
||||||
|
- **STATUS**: Server may be down for maintenance
|
||||||
|
- **Other errors**: Server issue, contact support if persistent
|
||||||
|
|
||||||
|
## Monitoring Tips
|
||||||
|
|
||||||
|
1. **Continuous Monitoring**: Regular checks of status codes help detect issues early
|
||||||
|
2. **Alert Setup**: Configure alerts for non-OK statuses
|
||||||
|
3. **Log Analysis**: Correlate status codes with server logs
|
||||||
|
4. **Capacity Planning**: Address persistent timeouts/connections with infrastructure improvements
|
||||||
|
|
||||||
|
## Status Processing Logic
|
||||||
|
|
||||||
|
### Status Code Processing
|
||||||
|
```javascript
|
||||||
|
const statusMap = {
|
||||||
|
'OK': 'Health check passed',
|
||||||
|
'TIMEOUT': 'Connection timeout',
|
||||||
|
'CONNECTION': 'Connection error',
|
||||||
|
'STATUS': 'HTTP error',
|
||||||
|
'WRONG REPLY': 'Invalid JSON response',
|
||||||
|
'REQUEST': 'Request error',
|
||||||
|
'BODY': 'Body read error',
|
||||||
|
'DECODE': 'Decode error',
|
||||||
|
'KO': 'Generic error'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract base status from status message
|
||||||
|
const st = (data.status||'').split(':')[0];
|
||||||
|
|
||||||
|
// Display only the description (e.g., "Connection timeout" instead of "TIMEOUT: Connection timeout")
|
||||||
|
statusDisplay = statusMap[st] || '—';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
For more details on server setup, monitoring, and troubleshooting, refer to:
|
||||||
|
- [Server Administration Guide](./administration)
|
||||||
|
- [Status Monitoring Setup](./monitoring-setup)
|
||||||
|
- [Error Resolution Handbook](./error-resolve)
|
||||||
|
|
||||||
|
## Additional Information
|
||||||
|
|
||||||
|
This status system provides a clear, human-readable way to understand server health at a glance, making it easier for administrators to quickly identify and respond to issues.
|
||||||
323
index.html
323
index.html
@@ -40,6 +40,10 @@ body{
|
|||||||
font-family:var(--body);
|
font-family:var(--body);
|
||||||
line-height:1.5;
|
line-height:1.5;
|
||||||
-webkit-font-smoothing:antialiased;
|
-webkit-font-smoothing:antialiased;
|
||||||
|
/* WHY: iOS Safari inflates font sizes when a phone is rotated to landscape,
|
||||||
|
which breaks the header and the server cards. Locking the adjustment to
|
||||||
|
100% keeps the layout identical in both orientations. No effect on desktop. */
|
||||||
|
-webkit-text-size-adjust:100%;
|
||||||
}
|
}
|
||||||
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
|
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
|
||||||
|
|
||||||
@@ -117,7 +121,8 @@ tbody tr:hover{background:color-mix(in srgb,var(--accent-soft) 50%,transparent)}
|
|||||||
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
|
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
|
||||||
.score{font-family:var(--display);font-weight:600;font-size:15px}
|
.score{font-family:var(--display);font-weight:600;font-size:15px}
|
||||||
|
|
||||||
.add-grid{display:grid;grid-template-columns:1.3fr 1fr;gap:24px;margin:40px 0;align-items:start}
|
.add-grid{display:grid;grid-template-columns:1.3fr 1fr;gap:24px;margin:40px 0;align-items:stretch}
|
||||||
|
.add-grid>.panel{display:flex;flex-direction:column}
|
||||||
.panel{
|
.panel{
|
||||||
background:var(--panel);border:1px solid var(--line);
|
background:var(--panel);border:1px solid var(--line);
|
||||||
border-radius:var(--radius);padding:24px;box-shadow:var(--shadow);
|
border-radius:var(--radius);padding:24px;box-shadow:var(--shadow);
|
||||||
@@ -139,6 +144,17 @@ tbody tr:hover{background:color-mix(in srgb,var(--accent-soft) 50%,transparent)}
|
|||||||
.btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
|
.btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
|
||||||
.note{font-size:13px;color:var(--muted);margin-top:16px;line-height:1.55}
|
.note{font-size:13px;color:var(--muted);margin-top:16px;line-height:1.55}
|
||||||
.note strong{color:var(--ink)}
|
.note strong{color:var(--ink)}
|
||||||
|
.freshness-note{
|
||||||
|
font-size:12px;line-height:1.4;color:var(--muted);
|
||||||
|
background:var(--accent-soft);border:1px solid var(--line);border-radius:8px;
|
||||||
|
padding:7px 12px;margin:0 0 12px;
|
||||||
|
}
|
||||||
|
.freshness-note strong{color:var(--ink)}
|
||||||
|
.btn-share{
|
||||||
|
display:block;margin:0 auto 8px;font:inherit;font-size:13px;cursor:pointer;
|
||||||
|
padding:8px 16px;border-radius:8px;border:1px solid var(--line-strong);
|
||||||
|
background:var(--panel);color:var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
.invoice{display:none}
|
.invoice{display:none}
|
||||||
.invoice.show{display:block}
|
.invoice.show{display:block}
|
||||||
@@ -146,8 +162,18 @@ tbody tr:hover{background:color-mix(in srgb,var(--accent-soft) 50%,transparent)}
|
|||||||
.invoice .row:last-child{border-bottom:0}
|
.invoice .row:last-child{border-bottom:0}
|
||||||
.invoice .row span:first-child{color:var(--muted)}
|
.invoice .row span:first-child{color:var(--muted)}
|
||||||
.invoice .row span:last-child{font-family:var(--mono);text-align:right;word-break:break-all}
|
.invoice .row span:last-child{font-family:var(--mono);text-align:right;word-break:break-all}
|
||||||
#qrcode{margin:18px auto 4px;width:160px;height:160px}
|
.invoice .row a{color:var(--accent);text-decoration:none}
|
||||||
#qrcode img{width:160px;height:160px}
|
.invoice .row a:hover{text-decoration:underline}
|
||||||
|
#qrcode{margin:18px auto 4px;width:160px}
|
||||||
|
#qrcode canvas,#qrcode img{width:160px!important;height:160px!important;max-width:100%}
|
||||||
|
#qr-overlay{
|
||||||
|
display:none;position:fixed;inset:0;z-index:999;
|
||||||
|
background:rgba(0,0,0,.7);cursor:pointer;
|
||||||
|
align-items:center;justify-content:center;
|
||||||
|
}
|
||||||
|
#qr-overlay.show{display:flex}
|
||||||
|
#qr-big{padding:24px;background:#fff;border-radius:12px}
|
||||||
|
#qr-big canvas,#qr-big img{width:280px!important;height:280px!important;max-width:90vw}
|
||||||
.ok-line{color:var(--ok);font-weight:600;font-size:14px;margin-bottom:14px}
|
.ok-line{color:var(--ok);font-weight:600;font-size:14px;margin-bottom:14px}
|
||||||
.err-line{color:#d32f2f;font-weight:600;font-size:14px;margin-bottom:14px}
|
.err-line{color:#d32f2f;font-weight:600;font-size:14px;margin-bottom:14px}
|
||||||
.terms-box{display:none;margin:16px 0;padding:20px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius)}
|
.terms-box{display:none;margin:16px 0;padding:20px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius)}
|
||||||
@@ -166,6 +192,9 @@ tbody tr:hover{background:color-mix(in srgb,var(--accent-soft) 50%,transparent)}
|
|||||||
.intro-card h2{font-family:var(--display);font-size:24px;margin:0 0 10px;letter-spacing:-.01em}
|
.intro-card h2{font-family:var(--display);font-size:24px;margin:0 0 10px;letter-spacing:-.01em}
|
||||||
.intro-card p{margin:0;color:var(--muted);font-size:15px;line-height:1.65;max-width:820px}
|
.intro-card p{margin:0;color:var(--muted);font-size:15px;line-height:1.65;max-width:820px}
|
||||||
|
|
||||||
|
.fee-disclaimer{margin:12px 0 0;color:var(--muted);font-size:13px;line-height:1.5;font-style:italic}
|
||||||
|
.fee-disclaimer a{color:var(--accent)}
|
||||||
|
|
||||||
.info-section{margin:48px 0}
|
.info-section{margin:48px 0}
|
||||||
.info-section h2{font-family:var(--display);font-size:22px;margin:0 0 8px}
|
.info-section h2{font-family:var(--display);font-size:22px;margin:0 0 8px}
|
||||||
.info-section .sub{color:var(--muted);font-size:15px;line-height:1.6;margin:0 0 28px;max-width:760px}
|
.info-section .sub{color:var(--muted);font-size:15px;line-height:1.6;margin:0 0 28px;max-width:760px}
|
||||||
@@ -182,7 +211,11 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
.mobile-list{display:none}
|
.mobile-list{display:none}
|
||||||
@media (max-width:860px){
|
@media (max-width:860px){
|
||||||
.table-card{display:none}
|
.table-card{display:none}
|
||||||
.mobile-list{display:grid;gap:12px;max-height:350px;overflow:auto;padding-right:2px}
|
/* WHY: the previous "max-height:350px;overflow:auto" turned the server list
|
||||||
|
into a small scrollable window nested inside the page. On a touch screen
|
||||||
|
that inner scroll competes with the normal page scroll and makes the list
|
||||||
|
hard to read. On mobile the list now flows naturally with the page. */
|
||||||
|
.mobile-list{display:grid;gap:12px}
|
||||||
.add-grid{grid-template-columns:1fr}
|
.add-grid{grid-template-columns:1fr}
|
||||||
.info-grid{grid-template-columns:1fr}
|
.info-grid{grid-template-columns:1fr}
|
||||||
.hero-stats{gap:20px}
|
.hero-stats{gap:20px}
|
||||||
@@ -190,9 +223,82 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
.srv{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px;box-shadow:var(--shadow)}
|
.srv{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px;box-shadow:var(--shadow)}
|
||||||
.srv .top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:12px}
|
.srv .top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:12px}
|
||||||
.srv .rk{font-family:var(--display);font-weight:600;color:var(--rank);font-size:18px}
|
.srv .rk{font-family:var(--display);font-weight:600;color:var(--rank);font-size:18px}
|
||||||
.srv .grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;font-size:13px}
|
/* WHY: server URLs have no spaces, so a long URL cannot break by itself and
|
||||||
|
would overflow the card. "anywhere" lets it wrap at any character.
|
||||||
|
"min-width:0" is required because a flex child defaults to min-width:auto,
|
||||||
|
which prevents it from shrinking below its content width. */
|
||||||
|
.srv .top>div{min-width:0}
|
||||||
|
.srv .top a{display:inline-block;max-width:100%;overflow-wrap:anywhere}
|
||||||
|
/* WHY: with two fixed columns the fifth field (Height) was left alone on a
|
||||||
|
half-empty row. auto-fit fills the available width with as many columns as
|
||||||
|
fit, so the five fields always line up tidily. */
|
||||||
|
.srv .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(84px,1fr));gap:10px;font-size:13px}
|
||||||
.srv .grid div span{display:block;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px}
|
.srv .grid div span{display:block;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px}
|
||||||
.srv .grid div b{font-family:var(--mono);font-weight:600}
|
.srv .grid div b{font-family:var(--mono);font-weight:600;overflow-wrap:anywhere}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
Phone layout (<=600px).
|
||||||
|
Scope: header, filter bar and server list only. The "Add your Will Executor"
|
||||||
|
panel, the invoice and the QR code are intentionally left untouched, because
|
||||||
|
payments are expected to be made from a desktop browser.
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
@media (max-width:600px){
|
||||||
|
.controls{gap:10px}
|
||||||
|
|
||||||
|
/* WHY: the four chain buttons form a single non-wrapping row about 340px wide.
|
||||||
|
Inside a 360-390px phone screen (minus page padding) it overflowed the
|
||||||
|
viewport and produced horizontal scrolling. A 2x2 grid across the full
|
||||||
|
width removes the overflow. min-height:44px matches the recommended
|
||||||
|
minimum touch target size. */
|
||||||
|
.seg{display:grid;grid-template-columns:1fr 1fr;width:100%;border-radius:8px}
|
||||||
|
.seg button{font-size:14px;min-height:44px;padding:8px 10px;border-bottom:1px solid var(--line)}
|
||||||
|
.seg button:nth-child(2n){border-right:0} /* right column: no inner divider */
|
||||||
|
.seg button:nth-child(n+3){border-bottom:0} /* last row: no bottom divider */
|
||||||
|
|
||||||
|
/* Give the toggle and the JSON link a full-size touch area. */
|
||||||
|
.field{min-height:44px}
|
||||||
|
.btn-ghost{min-height:44px}
|
||||||
|
|
||||||
|
/* WHY: the search field takes the full width so it is comfortable to type in,
|
||||||
|
and the font is raised to 16px. Below 16px, iOS Safari automatically zooms
|
||||||
|
the whole page when the field receives focus, and the user then has to
|
||||||
|
pinch back out. 16px disables that behaviour. */
|
||||||
|
.search{flex:1 1 100%}
|
||||||
|
.search input{font-size:16px}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
Narrow phone layout (<=480px): tighter spacing to recover horizontal space.
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
@media (max-width:480px){
|
||||||
|
/* Recovers 12px of usable width on every row of the page. */
|
||||||
|
.wrap{padding:0 14px}
|
||||||
|
|
||||||
|
header.hero{padding:28px 0 20px}
|
||||||
|
.hero .wrap{gap:16px}
|
||||||
|
.brand{gap:12px}
|
||||||
|
.brand .mark{width:40px;height:40px;border-radius:10px}
|
||||||
|
.brand .mark .brand-logo{width:28px;height:28px}
|
||||||
|
.brand h1{font-size:20px}
|
||||||
|
.brand .sub{font-size:13px}
|
||||||
|
.stat .n{font-size:22px}
|
||||||
|
|
||||||
|
.controls{padding:16px 0 12px}
|
||||||
|
|
||||||
|
.srv{padding:14px}
|
||||||
|
|
||||||
|
.intro-card{padding:20px 18px;margin:22px 0 8px}
|
||||||
|
.intro-card h2{font-size:20px}
|
||||||
|
.intro-card p{font-size:14px}
|
||||||
|
|
||||||
|
.info-section{margin:32px 0}
|
||||||
|
.info-block{padding:18px 16px}
|
||||||
|
|
||||||
|
/* WHY: the four footer items were spread with space-between and wrapped into
|
||||||
|
an uneven, hard-to-read block. A single column reads cleanly on a phone. */
|
||||||
|
footer{margin-top:32px;padding:22px 0}
|
||||||
|
footer .wrap{flex-direction:column;gap:8px}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
|
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
|
||||||
@@ -207,13 +313,12 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<div class="mark"><svg class="brand-logo" viewBox="0 0 1036 1036" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Bitcoin After Life logo"><g transform="translate(0.000000,1036.000000) scale(0.100000,-0.100000)" fill="currentColor" stroke="none"><path d="M6130 10203 c-153 -318 -283 -665 -344 -916 -61 -250 -71 -335 -71 -602 1 -223 3 -249 28 -370 52 -244 140 -460 260 -633 72 -106 225 -257 320 -316 179 -111 335 -154 777 -211 232 -30 367 -61 442 -102 76 -41 195 -164 248 -257 170 -302 311 -774 362 -1211 19 -167 16 -591 -6 -745 -68 -484 -201 -871 -436 -1270 -541 -917 -1492 -1525 -2549 -1630 -132 -13 -453 -13 -596 0 -268 24 -530 77 -757 151 -1063 350 -1871 1192 -2187 2280 -63 217 -111 495 -127 742 -7 104 -7 107 -30 107 l-24 0 0 -167 c0 -286 27 -508 95 -773 148 -587 427 -1083 854 -1523 231 -237 423 -391 703 -563 685 -420 1543 -589 2343 -462 1346 213 2458 1211 2814 2524 89 329 116 543 115 919 0 349 -23 544 -100 847 -68 273 10 632 176 799 91 92 165 104 491 77 320 -26 499 36 699 242 171 175 285 422 320 690 15 116 12 401 -6 535 -13 100 -32 200 -91 478 -3 15 -8 27 -12 27 -3 0 -21 -30 -40 -66 -20 -39 -63 -96 -105 -139 -127 -130 -287 -216 -616 -330 -297 -104 -420 -161 -551 -256 -159 -117 -268 -285 -325 -504 -36 -135 -37 -312 -4 -500 12 -71 24 -132 26 -134 2 -2 41 33 87 78 115 115 199 177 369 270 267 146 442 260 590 384 38 32 72 57 74 54 7 -6 -107 -108 -193 -173 -88 -67 -259 -175 -402 -256 -58 -34 -146 -88 -196 -122 -107 -73 -276 -237 -332 -323 -50 -76 -100 -193 -116 -274 l-12 -60 -87 173 c-194 389 -411 680 -731 980 -375 353 -563 553 -677 723 -54 79 -170 297 -170 318 0 7 21 -22 46 -63 179 -288 481 -616 885 -962 265 -227 363 -338 496 -560 32 -54 60 -97 63 -98 9 0 100 229 141 352 99 302 114 589 44 869 -105 419 -325 659 -955 1039 -333 201 -500 322 -642 465 -148 150 -254 318 -297 475 -11 40 -22 75 -25 77 -2 2 -27 -44 -56 -104z"/><path d="M4436 9470 c-1069 -83 -2060 -527 -2825 -1265 -567 -548 -975 -1198 -1195 -1909 -248 -796 -290 -1575 -130 -2365 213 -1049 795 -2006 1636 -2688 727 -590 1604 -940 2558 -1023 189 -16 648 -14 825 5 601 63 1114 212 1645 481 834 421 1518 1083 1967 1904 296 540 464 1079 540 1725 23 203 23 683 -1 908 -39 374 -122 744 -237 1062 l-31 84 -151 -53 c-141 -49 -152 -54 -151 -77 1 -13 20 -94 42 -179 303 -1165 101 -2402 -553 -3395 -410 -622 -943 -1098 -1600 -1431 -469 -237 -913 -369 -1450 -430 -202 -24 -622 -24 -830 -1 -739 82 -1409 331 -1990 741 -293 206 -640 542 -869 840 -474 616 -756 1323 -843 2111 -20 185 -22 593 -4 785 112 1186 708 2250 1662 2965 619 465 1347 745 2139 826 127 13 546 18 745 9 l110 -5 21 160 c12 88 21 161 20 162 -4 4 -149 25 -275 39 -161 18 -620 26 -775 14z"/><path d="M3870 6492 c-52 -26 -73 -71 -78 -169 l-5 -83 -98 0 -99 0 0 -225 0 -225 100 0 100 0 0 -355 0 -355 -100 0 -100 0 0 -230 0 -230 100 0 100 0 0 -355 0 -355 -100 0 -100 0 0 -225 0 -225 100 0 100 0 0 -80 c0 -97 17 -142 62 -170 29 -17 50 -20 169 -20 125 0 139 2 170 23 43 29 58 71 58 170 l1 77 64 0 64 0 4 -111 c3 -107 4 -112 31 -135 27 -23 34 -24 182 -24 221 0 235 10 243 172 l5 98 261 0 c227 0 272 3 345 20 264 64 482 254 576 505 119 313 36 650 -216 878 l-72 64 33 47 c43 63 94 176 116 256 25 91 25 299 0 395 -59 230 -220 428 -431 530 -141 69 -182 77 -412 82 l-203 5 0 77 c0 104 -14 147 -53 171 -28 18 -51 20 -185 20 l-154 0 -34 -34 -34 -34 0 -101 0 -101 -65 0 -65 0 0 85 c0 162 -28 185 -222 185 -97 0 -130 -4 -158 -18z m1307 -732 c74 -45 103 -184 85 -416 -12 -151 -31 -208 -85 -248 -28 -21 -39 -21 -478 -24 l-449 -3 0 356 0 355 448 0 c426 0 448 -1 479 -20z m150 -1172 c46 -30 93 -97 125 -177 18 -45 22 -77 22 -161 1 -98 -1 -110 -30 -171 -35 -73 -92 -142 -135 -165 -23 -12 -115 -14 -544 -14 l-515 0 0 360 0 360 518 -3 518 -2 41 -27z"/></g></svg></div>
|
<div class="mark"><svg class="brand-logo" viewBox="0 0 1036 1036" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Bitcoin After Life logo"><g transform="translate(0.000000,1036.000000) scale(0.100000,-0.100000)" fill="currentColor" stroke="none"><path d="M6130 10203 c-153 -318 -283 -665 -344 -916 -61 -250 -71 -335 -71 -602 1 -223 3 -249 28 -370 52 -244 140 -460 260 -633 72 -106 225 -257 320 -316 179 -111 335 -154 777 -211 232 -30 367 -61 442 -102 76 -41 195 -164 248 -257 170 -302 311 -774 362 -1211 19 -167 16 -591 -6 -745 -68 -484 -201 -871 -436 -1270 -541 -917 -1492 -1525 -2549 -1630 -132 -13 -453 -13 -596 0 -268 24 -530 77 -757 151 -1063 350 -1871 1192 -2187 2280 -63 217 -111 495 -127 742 -7 104 -7 107 -30 107 l-24 0 0 -167 c0 -286 27 -508 95 -773 148 -587 427 -1083 854 -1523 231 -237 423 -391 703 -563 685 -420 1543 -589 2343 -462 1346 213 2458 1211 2814 2524 89 329 116 543 115 919 0 349 -23 544 -100 847 -68 273 10 632 176 799 91 92 165 104 491 77 320 -26 499 36 699 242 171 175 285 422 320 690 15 116 12 401 -6 535 -13 100 -32 200 -91 478 -3 15 -8 27 -12 27 -3 0 -21 -30 -40 -66 -20 -39 -63 -96 -105 -139 -127 -130 -287 -216 -616 -330 -297 -104 -420 -161 -551 -256 -159 -117 -268 -285 -325 -504 -36 -135 -37 -312 -4 -500 12 -71 24 -132 26 -134 2 -2 41 33 87 78 115 115 199 177 369 270 267 146 442 260 590 384 38 32 72 57 74 54 7 -6 -107 -108 -193 -173 -88 -67 -259 -175 -402 -256 -58 -34 -146 -88 -196 -122 -107 -73 -276 -237 -332 -323 -50 -76 -100 -193 -116 -274 l-12 -60 -87 173 c-194 389 -411 680 -731 980 -375 353 -563 553 -677 723 -54 79 -170 297 -170 318 0 7 21 -22 46 -63 179 -288 481 -616 885 -962 265 -227 363 -338 496 -560 32 -54 60 -97 63 -98 9 0 100 229 141 352 99 302 114 589 44 869 -105 419 -325 659 -955 1039 -333 201 -500 322 -642 465 -148 150 -254 318 -297 475 -11 40 -22 75 -25 77 -2 2 -27 -44 -56 -104z"/><path d="M4436 9470 c-1069 -83 -2060 -527 -2825 -1265 -567 -548 -975 -1198 -1195 -1909 -248 -796 -290 -1575 -130 -2365 213 -1049 795 -2006 1636 -2688 727 -590 1604 -940 2558 -1023 189 -16 648 -14 825 5 601 63 1114 212 1645 481 834 421 1518 1083 1967 1904 296 540 464 1079 540 1725 23 203 23 683 -1 908 -39 374 -122 744 -237 1062 l-31 84 -151 -53 c-141 -49 -152 -54 -151 -77 1 -13 20 -94 42 -179 303 -1165 101 -2402 -553 -3395 -410 -622 -943 -1098 -1600 -1431 -469 -237 -913 -369 -1450 -430 -202 -24 -622 -24 -830 -1 -739 82 -1409 331 -1990 741 -293 206 -640 542 -869 840 -474 616 -756 1323 -843 2111 -20 185 -22 593 -4 785 112 1186 708 2250 1662 2965 619 465 1347 745 2139 826 127 13 546 18 745 9 l110 -5 21 160 c12 88 21 161 20 162 -4 4 -149 25 -275 39 -161 18 -620 26 -775 14z"/><path d="M3870 6492 c-52 -26 -73 -71 -78 -169 l-5 -83 -98 0 -99 0 0 -225 0 -225 100 0 100 0 0 -355 0 -355 -100 0 -100 0 0 -230 0 -230 100 0 100 0 0 -355 0 -355 -100 0 -100 0 0 -225 0 -225 100 0 100 0 0 -80 c0 -97 17 -142 62 -170 29 -17 50 -20 169 -20 125 0 139 2 170 23 43 29 58 71 58 170 l1 77 64 0 64 0 4 -111 c3 -107 4 -112 31 -135 27 -23 34 -24 182 -24 221 0 235 10 243 172 l5 98 261 0 c227 0 272 3 345 20 264 64 482 254 576 505 119 313 36 650 -216 878 l-72 64 33 47 c43 63 94 176 116 256 25 91 25 299 0 395 -59 230 -220 428 -431 530 -141 69 -182 77 -412 82 l-203 5 0 77 c0 104 -14 147 -53 171 -28 18 -51 20 -185 20 l-154 0 -34 -34 -34 -34 0 -101 0 -101 -65 0 -65 0 0 85 c0 162 -28 185 -222 185 -97 0 -130 -4 -158 -18z m1307 -732 c74 -45 103 -184 85 -416 -12 -151 -31 -208 -85 -248 -28 -21 -39 -21 -478 -24 l-449 -3 0 356 0 355 448 0 c426 0 448 -1 479 -20z m150 -1172 c46 -30 93 -97 125 -177 18 -45 22 -77 22 -161 1 -98 -1 -110 -30 -171 -35 -73 -92 -142 -135 -165 -23 -12 -115 -14 -544 -14 l-515 0 0 360 0 360 518 -3 518 -2 41 -27z"/></g></svg></div>
|
||||||
<div>
|
<div>
|
||||||
<h1>Will Executor — Server List</h1>
|
<h1>Will Executor — Server List</h1>
|
||||||
<div class="sub">Bitcoin After Life · Will-executor node leaderboard</div>
|
<div class="sub"><a href="https://bitcoin-after.life" target="_blank" rel="noopener">Bitcoin After Life</a> · Will-executor node leaderboard</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hero-stats">
|
<div class="hero-stats">
|
||||||
<div class="stat"><div class="n" id="s-online">0</div><div class="l">Online</div></div>
|
<div class="stat"><div class="n" id="s-online">0</div><div class="l">Online</div></div>
|
||||||
<div class="stat"><div class="n" id="s-total">0</div><div class="l">Servers</div></div>
|
<div class="stat"><div class="n" id="s-total">0</div><div class="l">Servers</div></div>
|
||||||
<div class="stat"><div class="n" id="s-block">—</div><div class="l">Block</div></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@@ -243,16 +348,19 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<a class="btn-ghost" id="download" href="#" download="willexecutors.json">↓ JSON</a>
|
<a class="btn-ghost" id="download" href="#" download="willexecutors.json">↓ JSON</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p class="freshness-note">
|
||||||
|
<strong>Fee/description/version</strong> refresh about once a day (timing varies). <strong>Deposits</strong> are credited instantly after 3 confirmations (~30 min).
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="table-card">
|
<div class="table-card">
|
||||||
<table id="tbl">
|
<table id="tbl">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="num">#</th>
|
<th class="num">#</th>
|
||||||
<th>URL</th>
|
<th>URL</th>
|
||||||
<th>Info</th>
|
<th>Info*</th>
|
||||||
<th class="num">Fee</th>
|
<th class="num">Fee*</th>
|
||||||
<th>Version</th>
|
<th>Version*</th>
|
||||||
<th class="num">Balance</th>
|
|
||||||
<th class="num">Height</th>
|
<th class="num">Height</th>
|
||||||
<th class="num">Wins</th>
|
<th class="num">Wins</th>
|
||||||
<th class="num">Score</th>
|
<th class="num">Score</th>
|
||||||
@@ -264,6 +372,8 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
|
|
||||||
<div class="mobile-list" id="mlist"></div>
|
<div class="mobile-list" id="mlist"></div>
|
||||||
|
|
||||||
|
<p class="fee-disclaimer">* Info, Fee and Version data may not reflect actual values or may be outdated. Refer to the <a href="https://bitcoin-after.life" target="_blank" rel="noopener">Bitcoin After Life plugin</a> for up-to-date information.</p>
|
||||||
|
|
||||||
<section class="intro-card">
|
<section class="intro-card">
|
||||||
<h2>Will Executor Server List</h2>
|
<h2>Will Executor Server List</h2>
|
||||||
<p>This page displays all Will Executor servers that manage the inheritance processing for the Bitcoin After Life plugin on Electrum. Will Executors operate in a competitive environment, racing to broadcast inheritance transactions to network nodes and earn the associated transaction fees.</p>
|
<p>This page displays all Will Executor servers that manage the inheritance processing for the Bitcoin After Life plugin on Electrum. Will Executors operate in a competitive environment, racing to broadcast inheritance transactions to network nodes and earn the associated transaction fees.</p>
|
||||||
@@ -272,18 +382,21 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<div class="add-grid">
|
<div class="add-grid">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2>Add your Will Executor</h2>
|
<h2>Add your Will Executor</h2>
|
||||||
<p class="lead">Enter your server URL. It will be checked online before it appears in the list.</p>
|
<p class="lead">Enter your server URL. It will appear in the list once your deposit is confirmed (typically about 30 minutes).</p>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<input type="text" id="url" placeholder="https://bitcoin-after.life:9137">
|
<input type="text" id="url" placeholder="https://we.bitcoin-after.life">
|
||||||
<button class="btn" id="submit">Add server</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div style="margin-top:8px">
|
||||||
|
<input type="text" id="contact" placeholder="Email, npub or Telegram (optional)" style="width:100%;font:inherit;font-size:14px;padding:9px 12px;border:1px solid var(--line-strong);border-radius:8px;background:var(--panel);color:var(--ink)">
|
||||||
|
</div>
|
||||||
|
<button class="btn" id="submit" style="margin-top:8px">Add server</button>
|
||||||
|
|
||||||
<div class="ok-line" id="iv-status"></div>
|
<div class="ok-line" id="iv-status"></div>
|
||||||
|
|
||||||
<div class="terms-box" id="terms-box">
|
<div class="terms-box" id="terms-box">
|
||||||
<p class="lead">You are about to add this server:</p>
|
<p class="lead">You are about to add this server:</p>
|
||||||
<p><a id="terms-url" href="#" target="_blank" rel="noopener" class="mono"></a></p>
|
<p><a id="terms-url" href="#" target="_blank" rel="noopener" class="mono"></a></p>
|
||||||
<p style="font-size:13px;margin-top:4px"><strong>Make sure the link above works correctly before paying. No refunds or URL changes after payment.</strong></p>
|
<p style="font-size:13px;margin-top:4px"><strong>Make sure the link above works correctly before paying. No refunds after payment. URL changes require proof of ownership — see the <a href="/terms.html" target="_blank">Terms</a>.</strong></p>
|
||||||
<p style="font-size:14px">
|
<p style="font-size:14px">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="terms-check">
|
<input type="checkbox" id="terms-check">
|
||||||
@@ -294,26 +407,31 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="invoice" id="invoice">
|
<div class="invoice" id="invoice">
|
||||||
<div class="row"><span>Minimum amount</span><span id="iv-min">—</span></div>
|
<div class="row"><span>Annual fee</span><span id="iv-min">—</span></div>
|
||||||
<div class="row"><span>Chain</span><span id="iv-chain">—</span></div>
|
<div class="row"><span>Chain</span><span id="iv-chain">—</span></div>
|
||||||
<div class="row"><span>Address</span><span id="iv-addr">—</span></div>
|
<div class="row"><span>Address</span><span id="iv-addr">—</span></div>
|
||||||
<div class="row"><span>Balance</span><span id="iv-balance">—</span></div>
|
<div class="row"><span>Balance</span><span id="iv-balance">—</span></div>
|
||||||
<div class="row"><span>Status</span><span id="iv-status2">—</span></div>
|
<div class="row"><span>Donations</span><span id="iv-donations">—</span></div>
|
||||||
|
<div class="row"><span>Contact</span><span id="iv-contact">—</span></div>
|
||||||
<div class="row"><span>Server</span><span id="iv-url">—</span></div>
|
<div class="row"><span>Server</span><span id="iv-url">—</span></div>
|
||||||
|
<div class="row"><span>Will Executor</span><span><a id="iv-weinfo" href="#" target="_blank">—</a></span></div>
|
||||||
|
<div class="row" id="iv-nextdep-row" style="display:none"><span>Next renewal</span><span id="iv-nextdep">—</span></div>
|
||||||
<div id="qrcode"></div>
|
<div id="qrcode"></div>
|
||||||
</div>
|
<button class="btn-share" id="share-btn">Share invoice</button>
|
||||||
|
|
||||||
<p class="note">
|
<p class="note">
|
||||||
<strong>Please make sure your server is online before you attempt to add it.</strong>
|
<strong>Please make sure your server is online before you attempt to add it.</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2>How ranking works</h2>
|
<h2>How ranking works</h2>
|
||||||
<p class="lead">Bid-based ranking: higher contributions rank higher.</p>
|
<p class="lead">Ordered by excess donated, then total paid, then base fee (lower first), then WeTime points.</p>
|
||||||
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px"><span style="color:var(--muted)">Deposit threshold</span><b class="mono"><span id="thr-min">50,000</span> sats</b></div>
|
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px"><span style="color:var(--muted)">Yearly fee</span><b class="mono"><span id="thr-min">50,000</span> sats</b></div>
|
||||||
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px"><span style="color:var(--muted)">Plugin integration</span><b>automatic</b></div>
|
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px"><span style="color:var(--muted)">Listing period</span><b>365 days</b></div>
|
||||||
<div style="display:flex;justify-content:space-between;padding:8px 0;font-size:13px"><span style="color:var(--muted)">Early-adopter guarantee</span><b>12 months</b></div>
|
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px"><span style="color:var(--muted)">Renewal window</span><b>from 6 months before expiry</b></div>
|
||||||
|
<div style="display:flex;justify-content:space-between;padding:8px 0;font-size:13px"><span style="color:var(--muted)">Plugin integration</span><b>automatic</b></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -328,13 +446,13 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">02</span>
|
<span class="ic">02</span>
|
||||||
<h3>Ranking System</h3>
|
<h3>Ranking System</h3>
|
||||||
<p>This leaderboard operates on a bid-based ranking system where higher contributions result in better positioning.</p>
|
<p>This leaderboard is ordered by excess donated (over the yearly fee), then total amount paid, then lower base fee, then WeTime points.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">03</span>
|
<span class="ic">03</span>
|
||||||
<h3>Early Adopter Incentives</h3>
|
<h3>Listing & Renewal</h3>
|
||||||
<p>To support the project's initial launch phase, we plan to maintain the first Will Executor servers for a minimum of 12 months, rewarding early participants. Subsequently, premium positions will be available through an auction system based on protocol revenue generation.</p>
|
<p>A flat yearly fee buys 365 days of presence in the list, starting when your payment reaches 3 confirmations. You can renew for one additional year at any time from 6 months before expiry; listings that are not renewed are removed at expiry. See the <a href="/terms.html" target="_blank">Terms</a> for details.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
@@ -351,6 +469,7 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<span>Bitcoin After Life — Will Executor List</span>
|
<span>Bitcoin After Life — Will Executor List</span>
|
||||||
<a href="mailto:welist@bitcoin-after.life">welist@bitcoin-after.life</a>
|
<a href="mailto:welist@bitcoin-after.life">welist@bitcoin-after.life</a>
|
||||||
|
<a href="/terms.html">Terms</a>
|
||||||
<a class="mono" id="commit-link" href="https://bitcoin-after.life/gitea/bitcoinafterlife/bal-welist-website/commit/COMMIT_HASH_PLACEHOLDER">COMMIT_HASH_PLACEHOLDER</a>
|
<a class="mono" id="commit-link" href="https://bitcoin-after.life/gitea/bitcoinafterlife/bal-welist-website/commit/COMMIT_HASH_PLACEHOLDER">COMMIT_HASH_PLACEHOLDER</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -370,9 +489,7 @@ function getChain() {
|
|||||||
|
|
||||||
function getFiltered() {
|
function getFiltered() {
|
||||||
return allServers
|
return allServers
|
||||||
.filter(d => withTor ? true : !d.onion)
|
.filter(d => (d.url + " " + (d.info||"")).toLowerCase().includes(q.toLowerCase()));
|
||||||
.filter(d => (d.url + " " + (d.info||"")).toLowerCase().includes(q.toLowerCase()))
|
|
||||||
.sort((a, b) => (b.balance||0) - (a.balance||0) || (a.base_fee||0) - (b.base_fee||0) || (b.points||0) - (a.points||0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
@@ -382,7 +499,7 @@ function render() {
|
|||||||
tb.innerHTML = ""; ml.innerHTML = "";
|
tb.innerHTML = ""; ml.innerHTML = "";
|
||||||
|
|
||||||
if (!list.length) {
|
if (!list.length) {
|
||||||
tb.innerHTML = '<tr><td colspan="9" style="padding:28px;text-align:center;color:var(--muted)">No servers found.</td></tr>';
|
tb.innerHTML = '<tr><td colspan="8" style="padding:28px;text-align:center;color:var(--muted)">No servers found.</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
list.forEach((d, i) => {
|
list.forEach((d, i) => {
|
||||||
@@ -396,7 +513,6 @@ function render() {
|
|||||||
<td class="info">${DOMPurify.sanitize(d.info||'—')}</td>
|
<td class="info">${DOMPurify.sanitize(d.info||'—')}</td>
|
||||||
<td class="num">${fmt(d.base_fee)}</td>
|
<td class="num">${fmt(d.base_fee)}</td>
|
||||||
<td class="mono">${DOMPurify.sanitize(d.version||'—')}</td>
|
<td class="mono">${DOMPurify.sanitize(d.version||'—')}</td>
|
||||||
<td class="num">${fmt(d.balance)}</td>
|
|
||||||
<td class="num">${fmt(d.last_block)}</td>
|
<td class="num">${fmt(d.last_block)}</td>
|
||||||
<td class="num">${d.count_win != null ? d.count_win : '—'}</td>
|
<td class="num">${d.count_win != null ? d.count_win : '—'}</td>
|
||||||
<td class="num"><span class="score">${fmt(d.points)}</span></td>
|
<td class="num"><span class="score">${fmt(d.points)}</span></td>
|
||||||
@@ -411,18 +527,15 @@ function render() {
|
|||||||
<div><span>Score</span><b>${fmt(d.points)}</b></div>
|
<div><span>Score</span><b>${fmt(d.points)}</b></div>
|
||||||
<div><span>Wins</span><b>${d.count_win != null ? d.count_win : '—'}</b></div>
|
<div><span>Wins</span><b>${d.count_win != null ? d.count_win : '—'}</b></div>
|
||||||
<div><span>Fee</span><b>${fmt(d.base_fee)} sat</b></div>
|
<div><span>Fee</span><b>${fmt(d.base_fee)} sat</b></div>
|
||||||
<div><span>Balance</span><b>${fmt(d.balance)}</b></div>
|
|
||||||
<div><span>Version</span><b>${DOMPurify.sanitize(d.version||'—')}</b></div>
|
<div><span>Version</span><b>${DOMPurify.sanitize(d.version||'—')}</b></div>
|
||||||
<div><span>Height</span><b>${fmt(d.last_block)}</b></div>
|
<div><span>Height</span><b>${fmt(d.last_block)}</b></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`);
|
</div>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
const online = allServers.filter(d => d.status === "online" || d.status === "OK").length;
|
const online = allServers.filter(d => d.status === "OK").length;
|
||||||
document.getElementById('s-online').textContent = online;
|
document.getElementById('s-online').textContent = online;
|
||||||
document.getElementById('s-total').textContent = allServers.length;
|
document.getElementById('s-total').textContent = allServers.length;
|
||||||
const top = getFiltered()[0];
|
|
||||||
document.getElementById('s-block').textContent = top ? fmt(top.last_block) : '—';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
@@ -430,10 +543,14 @@ async function fetchData() {
|
|||||||
const params = new URLSearchParams({ page: 0, limit: 100 });
|
const params = new URLSearchParams({ page: 0, limit: 100 });
|
||||||
if (!withTor) params.append("onion", "no");
|
if (!withTor) params.append("onion", "no");
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/data/${chain}?${params}`);
|
// NOTE: /data/{chain} returns a HashMap, whose JSON key order is not
|
||||||
|
// guaranteed (it can change on every backend restart). /datalist/{chain}
|
||||||
|
// returns an ordered array (Vec) that preserves the server-side sort
|
||||||
|
// (donation DESC, balance DESC, base_fee ASC, wetime_points DESC) — see terms.html §3.
|
||||||
|
const response = await fetch(`/datalist/${chain}?${params}`);
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
const obj = await response.json();
|
const list = await response.json();
|
||||||
allServers = Object.entries(obj).map(([key, s]) => ({ id: key, ...s }));
|
allServers = list;
|
||||||
render();
|
render();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Fetch error:', err);
|
console.error('Fetch error:', err);
|
||||||
@@ -491,18 +608,50 @@ document.getElementById('submit').addEventListener('click', async () => {
|
|||||||
document.getElementById('iv-chain').textContent = '—';
|
document.getElementById('iv-chain').textContent = '—';
|
||||||
document.getElementById('iv-addr').textContent = '—';
|
document.getElementById('iv-addr').textContent = '—';
|
||||||
document.getElementById('iv-balance').textContent = '—';
|
document.getElementById('iv-balance').textContent = '—';
|
||||||
document.getElementById('iv-status2').textContent = '—';
|
document.getElementById('iv-donations').textContent = '—';
|
||||||
document.getElementById('iv-url').textContent = '—';
|
document.getElementById('iv-url').textContent = '—';
|
||||||
|
document.getElementById('iv-contact').textContent = '—';
|
||||||
|
document.getElementById('iv-weinfo').href = '#';
|
||||||
|
document.getElementById('iv-weinfo').textContent = '—';
|
||||||
|
document.getElementById('iv-nextdep-row').style.display = 'none';
|
||||||
|
document.getElementById('iv-nextdep').textContent = '—';
|
||||||
|
document.getElementById('iv-min').parentElement.style.display = '';
|
||||||
|
document.getElementById('iv-addr').parentElement.style.display = '';
|
||||||
|
document.getElementById('qrcode').style.display = '';
|
||||||
|
document.getElementById('share-btn').style.display = '';
|
||||||
document.getElementById('qrcode').innerHTML = '';
|
document.getElementById('qrcode').innerHTML = '';
|
||||||
|
document.getElementById('qrcode').style.cursor = '';
|
||||||
|
document.getElementById('qr-overlay').classList.remove('show');
|
||||||
|
document.getElementById('share-btn').textContent = 'Share invoice';
|
||||||
document.getElementById('terms-box').classList.remove('show');
|
document.getElementById('terms-box').classList.remove('show');
|
||||||
|
document.getElementById('terms-box').style.display = '';
|
||||||
document.getElementById('terms-check').checked = false;
|
document.getElementById('terms-check').checked = false;
|
||||||
document.getElementById('terms-accept').disabled = true;
|
document.getElementById('terms-accept').disabled = true;
|
||||||
const chain = getChain();
|
const chain = getChain();
|
||||||
|
const infoUrl = url + '/' + chain + '/info';
|
||||||
|
document.getElementById('terms-url').href = infoUrl;
|
||||||
|
document.getElementById('terms-url').textContent = url;
|
||||||
|
document.getElementById('terms-box').classList.add('show');
|
||||||
|
document.getElementById('terms-box').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('terms-check').addEventListener('change', function () {
|
||||||
|
document.getElementById('terms-accept').disabled = !this.checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('terms-accept').addEventListener('click', async function () {
|
||||||
|
document.getElementById('terms-box').classList.remove('show');
|
||||||
|
const urlInput = document.getElementById('url');
|
||||||
|
let url = urlInput.value.trim();
|
||||||
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||||
|
url = 'https://' + url;
|
||||||
|
}
|
||||||
|
const chain = getChain();
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/data', {
|
const response = await fetch('/data', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ url, chain })
|
body: JSON.stringify({ url, chain, contact: document.getElementById('contact').value.trim() || undefined })
|
||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -513,48 +662,86 @@ document.getElementById('submit').addEventListener('click', async () => {
|
|||||||
document.getElementById('iv-min').textContent = fmt(result.min_amount != null ? result.min_amount : minAmount) + ' sats';
|
document.getElementById('iv-min').textContent = fmt(result.min_amount != null ? result.min_amount : minAmount) + ' sats';
|
||||||
document.getElementById('iv-chain').textContent = result.chain || chain;
|
document.getElementById('iv-chain').textContent = result.chain || chain;
|
||||||
document.getElementById('iv-addr').textContent = result.address || '—';
|
document.getElementById('iv-addr').textContent = result.address || '—';
|
||||||
document.getElementById('iv-balance').textContent = result.balance != null ? fmt(result.balance) : '—';
|
const balStr = result.balance != null ? fmt(result.balance) : null;
|
||||||
document.getElementById('iv-status2').textContent = result.status || '—';
|
const uncStr = result.unconfirmed_balance != null ? fmt(result.unconfirmed_balance) : null;
|
||||||
const invoiceuri = `bitcoin:${result.address}?label=BAL&message=Order+For+url+%26+${encodeURIComponent(url)}`;
|
document.getElementById('iv-balance').textContent = balStr ? (uncStr ? balStr + ' (' + uncStr + ')' : balStr) : '—';
|
||||||
|
document.getElementById('iv-donations').textContent = result.donation != null ? fmt(result.donation) : '—';
|
||||||
|
document.getElementById('iv-contact').textContent = document.getElementById('contact').value.trim() || '—';
|
||||||
|
const weLink = result.id ? `/weinfo/${result.chain || chain}/${result.id}` : null;
|
||||||
|
const weinfoEl = document.getElementById('iv-weinfo');
|
||||||
|
if (weLink) {
|
||||||
|
weinfoEl.href = weLink;
|
||||||
|
weinfoEl.textContent = 'View page';
|
||||||
|
} else {
|
||||||
|
weinfoEl.href = '#';
|
||||||
|
weinfoEl.textContent = '—';
|
||||||
|
}
|
||||||
|
const serverUrl = result.url || url;
|
||||||
|
document.getElementById('iv-url').textContent = serverUrl;
|
||||||
|
if (result.payment_needed === false) {
|
||||||
|
document.getElementById('iv-min').parentElement.style.display = 'none';
|
||||||
|
document.getElementById('iv-addr').parentElement.style.display = 'none';
|
||||||
|
document.getElementById('qrcode').style.display = 'none';
|
||||||
|
document.getElementById('share-btn').style.display = 'none';
|
||||||
|
document.getElementById('iv-nextdep').textContent = result.next_deposit_date || '—';
|
||||||
|
document.getElementById('iv-nextdep-row').style.display = 'flex';
|
||||||
|
document.getElementById('iv-status').className = 'ok-line';
|
||||||
|
document.getElementById('iv-status').textContent = 'Server is already listed. Next renewal: ' + (result.next_deposit_date || '—');
|
||||||
|
const inv = document.getElementById('invoice');
|
||||||
|
inv.classList.add('show');
|
||||||
|
inv.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const amountSats = result.min_amount != null ? result.min_amount : minAmount;
|
||||||
|
const amountBtc = (amountSats / 1e8).toFixed(8).replace(/\.?0+$/, '');
|
||||||
|
const invoiceuri = `bitcoin:${result.address}?amount=${amountBtc}&label=BAL&message=Order+For+url+%26+${encodeURIComponent(url)}`;
|
||||||
const qrEl = document.getElementById('qrcode');
|
const qrEl = document.getElementById('qrcode');
|
||||||
qrEl.innerHTML = '';
|
qrEl.innerHTML = '';
|
||||||
new QRCode(qrEl, invoiceuri);
|
new QRCode(qrEl, { text: invoiceuri, width: 160, height: 160 });
|
||||||
const serverUrl = result.url || url;
|
qrEl.style.cursor = 'pointer';
|
||||||
const infoUrl = serverUrl + '/' + (result.chain || chain) + '/info';
|
qrEl.onclick = function () {
|
||||||
document.getElementById('iv-url').textContent = serverUrl;
|
const overlay = document.getElementById('qr-overlay');
|
||||||
document.getElementById('terms-url').href = infoUrl;
|
const big = document.getElementById('qr-big');
|
||||||
document.getElementById('terms-url').textContent = serverUrl;
|
big.innerHTML = '';
|
||||||
document.getElementById('terms-box').classList.add('show');
|
new QRCode(big, { text: invoiceuri, width: 280, height: 280 });
|
||||||
document.getElementById('terms-box').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
overlay.classList.add('show');
|
||||||
|
};
|
||||||
|
document.getElementById('qr-overlay').onclick = function () {
|
||||||
|
this.classList.remove('show');
|
||||||
|
};
|
||||||
|
const shareBtn = document.getElementById('share-btn');
|
||||||
|
shareBtn.textContent = 'Share invoice';
|
||||||
|
shareBtn.onclick = function () {
|
||||||
|
if (navigator.share) {
|
||||||
|
navigator.share({ title: 'BAL Invoice', text: invoiceuri });
|
||||||
|
} else {
|
||||||
|
navigator.clipboard.writeText(invoiceuri).then(() => {
|
||||||
|
this.textContent = 'Copied!';
|
||||||
|
setTimeout(() => this.textContent = 'Share invoice', 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.getElementById('iv-status').className = 'ok-line';
|
||||||
|
document.getElementById('iv-status').textContent = '✓ Server verified: ' + serverUrl + '. Pay the invoice — it will be listed after 3 confirmations.';
|
||||||
|
const inv = document.getElementById('invoice');
|
||||||
|
inv.classList.add('show');
|
||||||
|
inv.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
document.getElementById('iv-status').className = 'err-line';
|
document.getElementById('iv-status').className = 'err-line';
|
||||||
document.getElementById('iv-status').textContent = 'Network error. Please try again.';
|
document.getElementById('iv-status').textContent = 'Network error. Please try again.';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('terms-check').addEventListener('change', function () {
|
|
||||||
document.getElementById('terms-accept').disabled = !this.checked;
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('terms-accept').addEventListener('click', function () {
|
|
||||||
document.getElementById('terms-box').classList.remove('show');
|
|
||||||
const inv = document.getElementById('invoice');
|
|
||||||
document.getElementById('iv-status').className = 'ok-line';
|
|
||||||
document.getElementById('iv-status').textContent = '✓ Server added: ' + document.getElementById('iv-url').textContent + '. Pay the invoice to complete.';
|
|
||||||
inv.classList.add('show');
|
|
||||||
inv.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('url').addEventListener('keydown', e => {
|
document.getElementById('url').addEventListener('keydown', e => {
|
||||||
if (e.key === 'Enter') document.getElementById('submit').click();
|
if (e.key === 'Enter') document.getElementById('submit').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
(function init() {
|
(async function init() {
|
||||||
|
await Promise.all([fetchData(), fetchMinAmount()]);
|
||||||
const blob = new Blob([JSON.stringify(allServers, null, 2)], { type: 'application/json' });
|
const blob = new Blob([JSON.stringify(allServers, null, 2)], { type: 'application/json' });
|
||||||
document.getElementById('download').href = URL.createObjectURL(blob);
|
document.getElementById('download').href = URL.createObjectURL(blob);
|
||||||
fetchData();
|
|
||||||
fetchMinAmount();
|
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<div id="qr-overlay"><div id="qr-big"></div></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
220
terms.html
220
terms.html
@@ -3,8 +3,17 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>BAL Server List — Terms & Conditions</title>
|
<title>BAL Server List — Terms & Conditions</title>
|
||||||
<link rel="icon" href="Logo_nero.ico" type="image/x-icon">
|
<link rel="icon" href="Logo_nero.ico" type="image/x-icon">
|
||||||
|
<!--
|
||||||
|
Sections 2-4 rewritten on 2026-07 for the yearly-listing model
|
||||||
|
(flat yearly fee, renewal from 6 months before expiry). The list
|
||||||
|
is ordered by total excess donated, then total amount paid, then
|
||||||
|
base fee, then WeTime points as a tie-breaker (see Section 3),
|
||||||
|
matching the server-side get_list() ordering. Section 1, header,
|
||||||
|
footer and the dynamic min-deposit script are unchanged from the
|
||||||
|
previous version.
|
||||||
|
-->
|
||||||
<style>
|
<style>
|
||||||
:root{
|
:root{
|
||||||
--maxw:1120px;
|
--maxw:1120px;
|
||||||
@@ -67,6 +76,25 @@ header.hero{padding:48px 0 28px;border-bottom:1px solid var(--line)}
|
|||||||
.info-block .ic{font-family:var(--mono);font-size:12px;color:var(--accent);letter-spacing:.1em;display:block;margin-bottom:10px}
|
.info-block .ic{font-family:var(--mono);font-size:12px;color:var(--accent);letter-spacing:.1em;display:block;margin-bottom:10px}
|
||||||
.info-block h3{font-size:15px;margin:0 0 8px;letter-spacing:.01em}
|
.info-block h3{font-size:15px;margin:0 0 8px;letter-spacing:.01em}
|
||||||
.info-block p{font-size:14px;color:var(--muted);margin:0;line-height:1.6}
|
.info-block p{font-size:14px;color:var(--muted);margin:0;line-height:1.6}
|
||||||
|
/* Blocks with more than one paragraph need breathing room between them */
|
||||||
|
.info-block p + p{margin-top:8px}
|
||||||
|
|
||||||
|
/* --- Added for the yearly-listing model (2026-07) ---
|
||||||
|
Listing lifecycle: a small horizontal timeline that encodes the real
|
||||||
|
sequence pay -> listed -> renewal window -> expiry. Spans both grid
|
||||||
|
columns so the four steps read left to right. */
|
||||||
|
.lifecycle{grid-column:1 / -1;display:grid;grid-template-columns:repeat(4,1fr);gap:16px;
|
||||||
|
background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
|
||||||
|
padding:22px 24px;box-shadow:var(--shadow)}
|
||||||
|
.step{position:relative;padding-top:14px;border-top:3px solid var(--line-strong)}
|
||||||
|
.step:first-child{border-top-color:var(--accent)}
|
||||||
|
.step::before{
|
||||||
|
content:"";position:absolute;top:-7px;left:0;width:11px;height:11px;border-radius:50%;
|
||||||
|
background:var(--panel);border:3px solid var(--line-strong);
|
||||||
|
}
|
||||||
|
.step:first-child::before{border-color:var(--accent)}
|
||||||
|
.step h3{font-size:14px;margin:0 0 6px;letter-spacing:.01em}
|
||||||
|
.step p{font-size:13px;color:var(--muted);margin:0;line-height:1.55}
|
||||||
|
|
||||||
footer{border-top:1px solid var(--line);margin-top:48px;padding:28px 0;color:var(--muted);font-size:13px}
|
footer{border-top:1px solid var(--line);margin-top:48px;padding:28px 0;color:var(--muted);font-size:13px}
|
||||||
footer .wrap{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px}
|
footer .wrap{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px}
|
||||||
@@ -75,6 +103,11 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
@media (max-width:860px){
|
@media (max-width:860px){
|
||||||
.info-grid{grid-template-columns:1fr}
|
.info-grid{grid-template-columns:1fr}
|
||||||
.brand h1{font-size:24px}
|
.brand h1{font-size:24px}
|
||||||
|
/* On small screens the timeline stacks vertically like the other blocks */
|
||||||
|
.lifecycle{grid-template-columns:1fr}
|
||||||
|
.step{border-top:none;border-left:3px solid var(--line-strong);padding:0 0 4px 16px}
|
||||||
|
.step:first-child{border-left-color:var(--accent)}
|
||||||
|
.step::before{top:2px;left:-7px}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
|
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
|
||||||
@@ -86,9 +119,98 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<header class="hero">
|
<header class="hero">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<div class="mark"><svg class="brand-logo" viewBox="0 0 1036 1036" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Bitcoin After Life logo"><g transform="translate(0.000000,1036.000000) scale(0.100000,-0.100000)" fill="currentColor" stroke="none"><path d="M6130 10203 c-153 -318 -283 -665 -344 -916 -61 -250 -71 -335 -71 -602 1 -223 3 -249 28 -370 52 -244 140 -460 260 -633 72 -106 225 -257 320 -316 179 -111 335 -154 777 -211 232 -30 367 -61 442 -102 76 -41 195 -164 248 -257 170 -302 311 -774 362 -1211 19 -167 16 -591 -6 -745 -68 -484 -201 -871 -436 -1270 -541 -917 -1492 -1525 -2549 -1630 -132 -13 -453 -13 -596 0 -268 24 -530 77 -757 151 -1063 350 -1871 1192 -2187 2280 -63 217 -111 495 -127 742 -7 104 -7 107 -30 107 l-24 0 0 -167 c0 -286 27 -508 95 -773 148 -587 427 -1083 854 -1523 231 -237 423 -391 703 -563 685 -420 1543 -589 2343 -462 1346 213 2458 1211 2814 2524 89 329 116 543 115 919 0 349 -23 544 -100 847 -68 273 10 632 176 799 91 92 165 104 491 77 320 -26 499 36 699 242 171 175 285 422 320 690 15 116 12 401 -6 535 -13 100 -32 200 -91 478 -3 15 -8 27 -12 27 -3 0 -21 -30 -40 -66 -20 -39 -63 -96 -105 -139 -127 -130 -287 -216 -616 -330 -297 -104 -420 -161 -551 -256 -159 -117 -268 -285 -325 -504 -36 -135 -37 -312 -4 -500 12 -71 24 -132 26 -134 2 -2 41 33 87 78 115 115 199 177 369 270 267 146 442 260 590 384 38 32 72 57 74 54 7 -6 -107 -108 -193 -173 -88 -67 -259 -175 -402 -256 -58 -34 -146 -88 -196 -122 -107 -73 -276 -237 -332 -323 -50 -76 -100 -193 -116 -274 l-12 -60 -87 173 c-194 389 -411 680 -731 980 -375 353 -563 553 -677 723 -54 79 -170 297 -170 318 0 7 21 -22 46 -63 179 -288 481 -616 885 -962 265 -227 363 -338 496 -560 32 -54 60 -97 63 -98 9 0 100 229 141 352 99 302 114 589 44 869 -105 419 -325 659 -955 1039 -333 201 -500 322 -642 465 -148 150 -254 318 -297 475 -11 40 -22 75 -25 77 -2 2 -27 -44 -56 -104z"/><path d="M4436 9470 c-1069 -83 -2060 -527 -2825 -1265 -567 -548 -975 -1198 -1195 -1909 -248 -796 -290 -1575 -130 -2365 213 -1049 795 -2006 1609 -2622 696 -527 1487 -889 2377 -1089 232 -52 312 -65 560 -90 658 -66 1267 -10 1850 169 1231 378 2154 1317 2504 2548 89 315 117 524 116 902 0 346 -22 537 -97 828 -69 267 -131 443 -336 956 -22 56 -42 103 -44 105 -2 2 -15 -25 -29 -60 -47 -117 -126 -243 -219 -350 -140 -161 -327 -279 -705 -446 -107 -47 -280 -130 -385 -185 -453 -237 -609 -443 -609 -803 0 -127 17 -212 75 -371 30 -82 46 -114 79 -163 16 -24 33 -43 38 -43 5 0 18 16 29 36 164 295 496 526 988 687 278 91 421 151 569 240 58 34 145 96 195 137 237 198 354 468 314 722 -24 149 -88 275 -195 380 -105 103 -237 174 -472 253 -244 82 -424 158 -547 230 -239 140 -445 368 -575 637 l-39 81 -17 -72 c-123 -526 -575 -917 -1168 -1010 -174 -27 -421 -27 -590 0 -524 83 -937 370 -1179 818 -169 313 -237 640 -197 952 32 244 119 444 268 612 217 247 519 370 882 362 192 -5 356 -39 510 -106 24 -10 32 -10 47 2 24 18 43 92 48 188 9 156 -16 284 -85 436 -23 51 -46 109 -50 129 -5 24 -17 47 -31 59 -40 34 -140 28 -226 -13z"/></g></svg></div>
|
<div class="mark"><svg class="brand-logo" xmlns="http://www.w3.org/2000/svg" viewBox="-116.00 -110.00 2262.00 2262.00" fill="currentColor" role="img" aria-label="Bitcoin After Life logo">
|
||||||
|
<g transform="translate(0.000000,2072.000000) scale(0.100000,-0.100000)">
|
||||||
|
<path d="M12278 20443 c-84 -177 -102 -216 -175 -378 -204 -457 -370 -897
|
||||||
|
-471 -1255 -48 -168 -112 -437 -133 -557 -5 -29 -14 -79 -19 -110 -13 -74 -35
|
||||||
|
-246 -50 -388 -15 -139 -15 -617 -1 -738 32 -266 64 -444 111 -621 142 -538
|
||||||
|
391 -1000 724 -1344 430 -444 818 -601 1781 -721 211 -27 254 -32 325 -42 257
|
||||||
|
-35 414 -68 560 -117 161 -53 255 -116 411 -271 127 -127 209 -242 291 -406
|
||||||
|
203 -404 379 -882 497 -1350 59 -237 69 -284 111 -522 86 -494 120 -1121 85
|
||||||
|
-1583 -42 -559 -115 -952 -277 -1485 -135 -447 -343 -924 -588 -1350 -534
|
||||||
|
-927 -1278 -1709 -2180 -2292 -255 -164 -666 -386 -965 -521 -513 -230 -1203
|
||||||
|
-416 -1845 -497 -393 -49 -1085 -48 -1550 4 -87 10 -349 47 -385 55 -11 3 -49
|
||||||
|
10 -85 16 -97 17 -335 69 -420 92 -41 11 -97 25 -125 33 -280 73 -667 214
|
||||||
|
-991 360 -264 120 -387 186 -709 378 -772 461 -1542 1195 -2040 1942 -449 676
|
||||||
|
-742 1312 -954 2075 -59 215 -128 538 -151 718 -48 358 -60 475 -68 670 -9
|
||||||
|
199 -11 205 -67 200 -22 -2 -31 -9 -36 -28 -22 -80 -1 -836 30 -1075 57 -441
|
||||||
|
166 -902 309 -1315 64 -185 77 -218 130 -350 57 -142 237 -533 284 -619 465
|
||||||
|
-836 991 -1472 1733 -2096 423 -356 1121 -781 1645 -1002 448 -189 902 -335
|
||||||
|
1290 -414 30 -6 75 -15 100 -20 411 -87 986 -139 1523 -139 211 0 572 26 762
|
||||||
|
55 580 88 992 191 1485 372 1215 446 2304 1240 3095 2259 773 994 1256 2155
|
||||||
|
1414 3399 38 295 51 523 51 872 0 367 -22 684 -71 1001 -35 232 -85 484 -139
|
||||||
|
697 -50 197 -64 329 -56 499 22 431 161 834 372 1078 84 98 186 164 297 193
|
||||||
|
80 21 259 28 402 17 551 -45 591 -46 737 -33 217 19 373 61 527 143 179 94
|
||||||
|
296 184 451 344 159 165 269 318 373 521 154 302 233 573 278 958 17 141 17
|
||||||
|
643 0 790 -35 315 -92 651 -161 945 -48 207 -56 234 -66 237 -7 2 -37 -42 -69
|
||||||
|
-98 -70 -127 -118 -191 -214 -292 -128 -134 -287 -252 -476 -353 -206 -111
|
||||||
|
-371 -179 -790 -324 -602 -209 -831 -318 -1105 -523 -336 -251 -562 -642 -657
|
||||||
|
-1134 -14 -69 -17 -142 -17 -333 0 -234 9 -334 43 -520 5 -25 17 -94 27 -154
|
||||||
|
10 -59 23 -110 30 -113 10 -4 47 31 146 137 62 67 223 210 309 276 136 103
|
||||||
|
240 168 429 269 482 257 820 473 1152 737 88 70 162 128 165 128 25 0 -134
|
||||||
|
-153 -285 -273 -170 -136 -577 -398 -902 -582 -174 -99 -346 -209 -465 -299
|
||||||
|
-434 -327 -701 -703 -790 -1111 -23 -104 -23 -105 -32 -105 -5 0 -37 62 -72
|
||||||
|
138 -404 875 -960 1625 -1691 2277 -198 177 -711 687 -855 849 -277 313 -473
|
||||||
|
600 -614 897 -83 175 -81 211 6 71 364 -591 1009 -1283 1868 -2004 225 -188
|
||||||
|
424 -384 546 -538 152 -190 330 -452 420 -618 19 -35 40 -61 47 -60 27 6 215
|
||||||
|
466 297 728 104 331 138 510 157 822 15 261 3 458 -43 708 -24 129 -75 323
|
||||||
|
-108 415 -97 260 -142 352 -261 527 -292 433 -693 770 -1505 1263 -367 223
|
||||||
|
-501 306 -655 408 -480 319 -809 626 -1041 972 -133 197 -204 358 -291 658 -6
|
||||||
|
20 -15 37 -20 37 -5 0 -45 -75 -90 -167z"/>
|
||||||
|
<path d="M9065 18949 c-485 -27 -851 -72 -1295 -159 -164 -32 -200 -41 -400
|
||||||
|
-89 -110 -27 -170 -43 -395 -106 -103 -28 -436 -140 -600 -200 -961 -357
|
||||||
|
-1867 -883 -2670 -1549 -509 -423 -1078 -1018 -1453 -1518 -438 -585 -771
|
||||||
|
-1138 -1028 -1705 -651 -1437 -945 -3111 -814 -4638 17 -189 30 -324 41 -400
|
||||||
|
16 -123 40 -288 49 -345 5 -30 14 -82 19 -115 30 -193 172 -818 210 -925 5
|
||||||
|
-14 14 -43 19 -65 16 -59 150 -472 171 -530 11 -27 36 -95 57 -150 466 -1248
|
||||||
|
1246 -2444 2201 -3375 381 -372 670 -615 1128 -947 130 -94 429 -289 605 -395
|
||||||
|
676 -405 1362 -707 2135 -940 250 -75 647 -172 895 -219 387 -72 712 -115
|
||||||
|
1160 -151 207 -17 1118 -17 1295 0 349 33 547 57 775 93 924 148 1774 418
|
||||||
|
2625 835 1269 621 2400 1547 3266 2674 721 937 1258 2012 1565 3130 23 84 89
|
||||||
|
344 112 445 32 136 87 419 102 522 49 336 66 469 85 678 65 712 33 1528 -92
|
||||||
|
2275 -35 210 -39 230 -73 390 -65 307 -174 714 -250 930 -5 14 -27 79 -50 145
|
||||||
|
-82 239 -80 236 -137 214 -15 -6 -145 -51 -288 -100 -143 -49 -265 -95 -273
|
||||||
|
-102 -11 -11 -10 -21 2 -58 37 -111 103 -363 161 -614 27 -118 81 -400 99
|
||||||
|
-520 34 -223 43 -293 61 -470 35 -351 39 -442 40 -910 0 -459 -4 -563 -36
|
||||||
|
-855 -36 -340 -72 -558 -170 -1025 -119 -574 -428 -1418 -726 -1985 -503 -957
|
||||||
|
-1136 -1765 -1918 -2450 -710 -622 -1518 -1119 -2395 -1472 -240 -97 -668
|
||||||
|
-241 -885 -298 -151 -40 -300 -77 -400 -99 -55 -12 -118 -26 -140 -31 -22 -5
|
||||||
|
-69 -14 -105 -20 -36 -6 -85 -15 -110 -20 -78 -15 -270 -45 -385 -59 -871
|
||||||
|
-111 -1743 -81 -2635 89 -58 12 -123 25 -145 30 -22 5 -69 16 -105 24 -574
|
||||||
|
130 -1129 321 -1665 570 -55 26 -140 66 -190 89 -476 220 -1007 560 -1503 960
|
||||||
|
-426 343 -912 834 -1259 1270 -384 483 -710 999 -979 1552 -281 577 -472 1120
|
||||||
|
-619 1760 -9 39 -20 88 -25 110 -12 50 -39 184 -50 250 -30 172 -39 229 -50
|
||||||
|
305 -6 47 -15 114 -20 150 -86 621 -85 1395 1 2065 23 176 30 225 60 398 27
|
||||||
|
154 35 194 58 300 6 26 15 66 21 90 216 962 583 1840 1113 2662 341 529 676
|
||||||
|
946 1101 1371 731 731 1579 1325 2451 1719 164 74 208 93 450 192 293 120 723
|
||||||
|
258 1065 341 204 50 248 60 385 87 210 40 226 43 305 55 41 6 102 16 135 21
|
||||||
|
584 91 1350 114 1983 58 91 -8 136 -9 143 -2 6 6 15 41 19 79 10 75 25 189 40
|
||||||
|
299 26 194 32 257 23 266 -11 11 -198 41 -438 69 -422 51 -1053 72 -1460 49z"/>
|
||||||
|
<path d="M7765 12995 c-76 -31 -139 -96 -160 -168 -10 -34 -15 -94 -15 -188 0
|
||||||
|
-101 -3 -139 -13 -148 -9 -6 -84 -12 -203 -13 l-189 -3 0 -445 0 -445 195 -3
|
||||||
|
c136 -2 196 -6 201 -14 4 -7 8 -321 9 -698 0 -541 -2 -689 -12 -703 -11 -15
|
||||||
|
-37 -17 -203 -19 l-190 -3 0 -445 0 -445 190 -3 c165 -2 192 -4 203 -19 10
|
||||||
|
-14 12 -164 12 -703 -1 -377 -4 -691 -8 -697 -6 -9 -62 -13 -202 -15 l-195 -3
|
||||||
|
-3 -447 -2 -448 195 0 c194 0 196 0 204 -22 4 -13 9 -93 10 -178 2 -139 4
|
||||||
|
-160 25 -206 13 -28 39 -63 58 -77 67 -52 101 -57 357 -57 288 0 322 7 393 80
|
||||||
|
57 59 68 95 68 220 0 52 3 125 7 163 l6 67 128 0 127 0 4 -197 c3 -226 11
|
||||||
|
-255 81 -301 l40 -27 311 -3 311 -2 52 30 c36 21 61 45 80 77 27 47 28 53 33
|
||||||
|
233 l5 185 510 6 c516 6 541 8 719 49 503 114 963 516 1145 1000 77 206 111
|
||||||
|
385 111 589 -1 471 -225 925 -608 1235 -40 32 -72 62 -72 66 0 5 27 48 59 97
|
||||||
|
361 541 374 1222 33 1771 -228 366 -624 645 -1035 726 -154 31 -227 36 -530
|
||||||
|
36 -240 0 -317 3 -325 13 -6 7 -12 89 -14 199 l-3 186 -30 44 c-17 24 -51 54
|
||||||
|
-75 68 -45 25 -47 25 -328 28 -317 4 -353 -2 -410 -61 -50 -52 -56 -77 -62
|
||||||
|
-282 l-5 -190 -125 0 -125 0 -5 180 c-6 209 -18 249 -93 302 -70 50 -92 53
|
||||||
|
-346 53 -227 0 -238 -1 -296 -25z m2550 -1448 c88 -39 158 -140 193 -274 14
|
||||||
|
-58 17 -116 17 -378 -1 -334 -8 -409 -52 -533 -30 -86 -88 -156 -159 -192
|
||||||
|
l-49 -25 -880 0 -880 0 -3 704 c-2 557 0 706 10 713 7 4 407 7 888 5 818 -2
|
||||||
|
878 -3 915 -20z m291 -2341 c246 -114 416 -573 334 -901 -50 -200 -200 -414
|
||||||
|
-341 -486 -37 -19 -67 -19 -1066 -17 l-1028 3 -3 700 c-1 385 0 706 3 713 3 9
|
||||||
|
218 12 1027 12 l1023 0 51 -24z"/>
|
||||||
|
</g>
|
||||||
|
</svg></div>
|
||||||
<div>
|
<div>
|
||||||
<h1>Terms & Conditions</h1>
|
<h1>Terms & Conditions</h1>
|
||||||
<div class="sub">Bitcoin After Life · Will Executor List</div>
|
<div class="sub">Bitcoin After Life · Will Executor List</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -98,7 +220,7 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
<main class="wrap">
|
<main class="wrap">
|
||||||
|
|
||||||
<section class="info-section">
|
<section class="info-section">
|
||||||
<h2>1. Contact & Support</h2>
|
<h2>1. Contact & Support</h2>
|
||||||
<p class="sub">For URL changes, refunds, or any issues related to your Will Executor listing, contact us at <a href="mailto:welist@bitcoin-after.life">welist@bitcoin-after.life</a>.</p>
|
<p class="sub">For URL changes, refunds, or any issues related to your Will Executor listing, contact us at <a href="mailto:welist@bitcoin-after.life">welist@bitcoin-after.life</a>.</p>
|
||||||
<div class="info-grid">
|
<div class="info-grid">
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
@@ -115,53 +237,92 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="info-section">
|
<section class="info-section">
|
||||||
<h2>2. Ranking</h2>
|
<h2>2. Listing & Renewal</h2>
|
||||||
<p class="sub">Servers are sorted by descending balance, then by ascending base fee for ties, then by descending points.</p>
|
<p class="sub">A listing works like a hosting plan: a flat yearly fee buys your server one year of presence in the list. Your paid amount accumulates and never decays — it is preserved across renewals and also determines your position in the list (see Section 3). Payments are non-refundable (see Section 1) — double-check your server URL before paying.</p>
|
||||||
<div class="info-grid">
|
<div class="info-grid">
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">01</span>
|
<span class="ic">01 · PAYMENT</span>
|
||||||
<h3>Primary Sort: Balance</h3>
|
<h3>One Year at a Time</h3>
|
||||||
<p>Servers with a higher balance appear first in the list. A higher balance signals stronger commitment to the network.</p>
|
<p>The listing fee is <span id="thr-min">50,000</span> sats for 365 days, paid one year at a time. The exact amount in satoshi is shown in the payment request. Your server appears in the list once the payment reaches 3 confirmations on the blockchain (typically around 30 minutes), and your listing period starts at that moment.</p>
|
||||||
|
<p>Payments below the yearly fee will be considered donations and do not add listing time.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">02</span>
|
<span class="ic">02 · RENEWAL</span>
|
||||||
<h3>Secondary Sort: Base Fee</h3>
|
<h3>Renew From 6 Months Before Expiry</h3>
|
||||||
<p>When two servers have the same balance, the one with the higher base fee is ranked first.</p>
|
<p>You can renew for one additional year at any time starting 6 months before your expiry date, by paying the yearly fee for the exact same server URL as published in the list. The new year is added on top of your remaining time — renewing early never costs you days.</p>
|
||||||
|
<p>If the listing is not renewed, the server is removed from the list at expiry.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">03</span>
|
<span class="ic">03 · CAPACITY</span>
|
||||||
<h3>Points & WeTime</h3>
|
<h3>No Cap on Listings</h3>
|
||||||
<p>Points are earned by participating in WeTime rounds. Each executor periodically submits its block hash; the faster the response within the same block, the more points awarded. The win count tracks how many times an executor was the fastest responder.</p>
|
<p>There is no fixed number of slots: every server with remaining listing time is shown. Paying buys presence in the list; the total amount paid also affects your position in it (see Section 3).</p>
|
||||||
|
<p>Removal from the list does not affect users who already have your server in their plugin: the plugin's server list is add-only. Being listed matters for reaching new users.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">04</span>
|
<span class="ic">04 · TRANSITION</span>
|
||||||
<h3>Deposit Threshold</h3>
|
<h3>Deposits Made Under the Previous Rules</h3>
|
||||||
<p>All deposits below <span id="thr-min">50,000</span> sats will be considered donations and will not increase the balance.</p>
|
<p>Balances deposited under the previous, balance-based rules are converted into listing time pro-rata at the same yearly rate (e.g. a 5,000-sat balance becomes 36.5 days of listing). Countdowns for converted balances start on 17 July 2026. To stay listed beyond the converted time, renew as described above.</p>
|
||||||
<p>All servers with a positive balance will be listed.</p>
|
</div>
|
||||||
|
<div class="lifecycle">
|
||||||
|
<div class="step">
|
||||||
|
<h3>Pay</h3>
|
||||||
|
<p>Send the yearly fee shown in the payment request.</p>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<h3>Listed</h3>
|
||||||
|
<p>After 3 confirmations your server appears; 365 days start.</p>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<h3>Renewal window</h3>
|
||||||
|
<p>From 6 months before expiry you can add another year.</p>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<h3>Expiry</h3>
|
||||||
|
<p>If not renewed, the server is removed from the list.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="info-section">
|
<section class="info-section">
|
||||||
<h2>3. Balance Decay (Daily Fee)</h2>
|
<h2>3. List Order & Server Page</h2>
|
||||||
<p class="sub">A daily maintenance fee applies to the top 10 executors on each chain to keep the system active and fair.</p>
|
<p class="sub">The list is ordered by four criteria: first by total excess donated (higher first), then by total amount paid in balance (higher first), then by the base fee charged (lower first), and finally by WeTime points (higher first) as a tie-breaker.</p>
|
||||||
<div class="info-grid">
|
<div class="info-grid">
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">MECHANISM</span>
|
<span class="ic">ORDER</span>
|
||||||
<h3>How It Works</h3>
|
<h3>How Position Is Determined</h3>
|
||||||
<p>Once every 24 hours, if there are at least 10 active executors with a positive balance on a given chain, the system deducts 1/365 of the lowest balance among the top 10 (rounded up) from each of the top 10 executors. All deductions are recorded on the blockchain.</p>
|
<p>Servers are sorted by four criteria, in order: first by the total excess donated (higher first), then by the total paid amount (higher first), then by the base fee they charge (lower first), and finally by WeTime points (higher first) to break any remaining ties.</p>
|
||||||
|
<p>Because excess donated comes first and never decays, over-paying or tipping more — on top of any payment — directly and permanently moves a server up the list. Paying more than the exact yearly fee is the fastest way to improve position.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<span class="ic">CONDITIONS</span>
|
<span class="ic">POINTS</span>
|
||||||
<h3>When It Applies</h3>
|
<h3>WeTime Points</h3>
|
||||||
<p>The decay only activates when there are at least 10 executors with a balance greater than zero for that specific chain. If there are fewer than 10, no fee is charged.</p>
|
<p>Points are earned by participating in WeTime rounds. Each executor periodically submits its block hash; the faster the response within the same block, the more points awarded. The win count tracks how many times an executor was the fastest responder.</p>
|
||||||
|
<p>Points are not transferable, not redeemable and have no monetary value: within this list they act only as a tie-breaker. Points measure presence and reactivity — they do not certify how a server will handle inheritance transactions.</p>
|
||||||
|
</div>
|
||||||
|
<div class="info-block">
|
||||||
|
<span class="ic">DETAILS</span>
|
||||||
|
<h3>Server Detail Page</h3>
|
||||||
|
<p>Clicking a server in the list opens its detail page, showing the server URL, the listing expiry date, and its WeTime activity. The expiry date is shown only there, not in the main list. Since the price per day is fixed and public, the expiry date necessarily reflects how much a server has paid: this is intentional transparency.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="info-section">
|
<section class="info-section">
|
||||||
<h2>4. Changes to These Terms</h2>
|
<h2>4. Changes to These Terms</h2>
|
||||||
<p class="sub">We reserve the right to update these terms at any time.</p>
|
<p class="sub">We reserve the right to update these terms at any time. Material changes will be announced on this page with their effective date.</p>
|
||||||
|
<div class="info-grid">
|
||||||
|
<div class="info-block">
|
||||||
|
<span class="ic">REVIEW</span>
|
||||||
|
<h3>Annual Review</h3>
|
||||||
|
<p>Prices and rules are expected to be reviewed once a year, around 17 July, reflecting the growth of the protocol and market demand. Listing time already purchased remains valid under the conditions in force when it was bought; updated rules apply to new payments and renewals.</p>
|
||||||
|
</div>
|
||||||
|
<div class="info-block">
|
||||||
|
<span class="ic">SCOPE</span>
|
||||||
|
<h3>A Convenience Service</h3>
|
||||||
|
<p>This list is a convenience service operated at our discretion. The BAL protocol does not depend on it: users can add any Will Executor manually in the plugin, import custom lists, or use alternative list services. Anyone is free to run one.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
@@ -175,6 +336,9 @@ footer a{color:var(--accent);text-decoration:none}
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
(async function() {
|
(async function() {
|
||||||
|
// Unchanged from the previous version: fetches the current yearly fee
|
||||||
|
// from the server so the number on this page always matches reality.
|
||||||
|
// The #thr-min span is now inside Section 2 (01 · PAYMENT).
|
||||||
const chain = location.hash ? location.hash.slice(1) : 'bitcoin';
|
const chain = location.hash ? location.hash.slice(1) : 'bitcoin';
|
||||||
try {
|
try {
|
||||||
const r = await fetch('/min_deposit/' + chain);
|
const r = await fetch('/min_deposit/' + chain);
|
||||||
|
|||||||
72
weinfo.html
72
weinfo.html
@@ -1,8 +1,8 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-<|begin▁of▁sentence|>8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-w, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Bal Server List</title>
|
<title>Bal Server List</title>
|
||||||
<link rel="icon" href="Logo_nero.ico" type="image/x-icon">
|
<link rel="icon" href="Logo_nero.ico" type="image/x-icon">
|
||||||
<script src="/qrcode.min.js"></script>
|
<script src="/qrcode.min.js"></script>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
tr:nth-child(even) {
|
tr:nth-child(even) {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
span{
|
span {
|
||||||
margin-left:10px;
|
margin-left:10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
<div><span>Version:</span><span id="weversion"> </span></div>
|
<div><span>Version:</span><span id="weversion"> </span></div>
|
||||||
<div><span>Fees:</span><span id="wefees"> </span></div>
|
<div><span>Fees:</span><span id="wefees"> </span></div>
|
||||||
<div><span>Tld:</span><span id="wetld"> </span></div>
|
<div><span>Tld:</span><span id="wetld"> </span></div>
|
||||||
|
<div><span>Last Update:</span><span id="weupdate"> </span></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="float:left;border:1;margin-right:50px;">
|
<div style="float:left;border:1;margin-right:50px;">
|
||||||
<div><span>Height:</span><span id="weheight"> </span></div>
|
<div><span>Height:</span><span id="weheight"> </span></div>
|
||||||
@@ -49,8 +50,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="border:1;margin-right:50px;">
|
<div style="border:1;margin-right:50px;">
|
||||||
<div><span>Balance:</span><span id="webalance"> </span></div>
|
<div><span>Balance:</span><span id="webalance"> </span></div>
|
||||||
|
<div><span>Donations:</span><span id="wedonations"> </span></div>
|
||||||
<div><span>Status:</span><span id="westatus"> </span></div>
|
<div><span>Status:</span><span id="westatus"> </span></div>
|
||||||
<div><span>Last Update:</span><span id="weupdate"> </span></div>
|
<div><span>Expiry:</span><span id="weexpiry"> </span></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<table id="wetimes">
|
<table id="wetimes">
|
||||||
@@ -81,38 +83,58 @@
|
|||||||
const chain = path[1];
|
const chain = path[1];
|
||||||
const cdate=new Date().toISOString().replace(/[-:T.Z]/g, '').slice(0, 14);
|
const cdate=new Date().toISOString().replace(/[-:T.Z]/g, '').slice(0, 14);
|
||||||
fetchDataAndPopulateTable('/weinfodata/'+chain+"/"+we_id, new URLSearchParams(),(data) => {
|
fetchDataAndPopulateTable('/weinfodata/'+chain+"/"+we_id, new URLSearchParams(),(data) => {
|
||||||
document.getElementById('wename').innerHTML = DOMPurify.sanitize(data.url);
|
document.getElementById('wename').innerHTML = DOMPurify.sanitize(data.url||'—');
|
||||||
document.getElementById('wechain').innerHTML = DOMPurify.sanitize(data.chain);
|
document.getElementById('wechain').innerHTML = DOMPurify.sanitize(data.chain||'—');
|
||||||
document.getElementById('weinfo').innerHTML = DOMPurify.sanitize(data.info);
|
document.getElementById('weinfo').innerHTML = DOMPurify.sanitize(data.info||'—');
|
||||||
document.getElementById('wefees').innerHTML = data.base_fee;
|
document.getElementById('wefees').innerHTML = data.base_fee != null ? data.base_fee : '—';
|
||||||
document.getElementById('weheight').innerHTML = data.last_block;
|
document.getElementById('weheight').innerHTML = data.last_block != null ? data.last_block : '—';
|
||||||
document.getElementById('wepoints').innerHTML = data.points;
|
document.getElementById('wepoints').innerHTML = data.points != null ? data.points : '—';
|
||||||
document.getElementById('wewin').innerHTML = data.count_win;
|
document.getElementById('wewin').innerHTML = data.count_win != null ? data.count_win : '—';
|
||||||
document.getElementById('wetld').innerHTML = DOMPurify.sanitize(data.tld);
|
document.getElementById('wetld').innerHTML = DOMPurify.sanitize(data.tld||'—');
|
||||||
document.getElementById('webalance').innerHTML = data.balance;
|
const bal = data.balance != null ? data.balance : null;
|
||||||
document.getElementById('weversion').innerHTML = data.version;;
|
const unc = data.unconfirmed_balance != null ? data.unconfirmed_balance : null;
|
||||||
document.getElementById('westatus').innerHTML = DOMPurify.sanitize(data.status);
|
document.getElementById('webalance').innerHTML = bal ? (unc ? bal + ' (' + unc + ')' : bal) : '—';
|
||||||
document.getElementById('weupdate').innerHTML = data.last_update;
|
document.getElementById('wedonations').innerHTML = data.donation != null ? data.donation : '—';
|
||||||
|
document.getElementById('weversion').innerHTML = data.version||'—';
|
||||||
|
document.getElementById('weexpiry').innerHTML = '<b>' + (data.expiry_date || '—') + '</b>';
|
||||||
|
document.getElementById('weupdate').innerHTML = data.last_update || '—';
|
||||||
|
const statusMap = {
|
||||||
|
'OK': 'Health check passed',
|
||||||
|
'TIMEOUT': 'Connection timeout',
|
||||||
|
'CONNECTION': 'Connection error',
|
||||||
|
'STATUS': 'HTTP error',
|
||||||
|
'WRONG REPLY': 'Invalid JSON response',
|
||||||
|
'REQUEST': 'Request error',
|
||||||
|
'BODY': 'Body read error',
|
||||||
|
'DECODE': 'Decode error',
|
||||||
|
'KO': 'Generic error'
|
||||||
|
};
|
||||||
|
const st = (data.status||'').split(':')[0];
|
||||||
|
document.getElementById('westatus').innerHTML = statusMap[st] || '—';
|
||||||
|
|
||||||
const tableBody = document.querySelector('#wetimes tbody');
|
const tableBody = document.querySelector('#wetimes tbody');
|
||||||
tableBody.innerHTML ='';
|
tableBody.innerHTML ='';
|
||||||
|
if (data.times && data.times.length) {
|
||||||
Object.entries(data.times).forEach(([key,wetime]) => {
|
Object.entries(data.times).forEach(([key,wetime]) => {
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
const d = new Date(wetime.time/1000);
|
const d = new Date(wetime.time/1000);
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${wetime.blockHeight}</td>
|
<td>${wetime.blockHeight != null ? wetime.blockHeight : '—'}</td>
|
||||||
<td>${DOMPurify.sanitize(wetime.blockHash)}</td>
|
<td>${DOMPurify.sanitize(wetime.blockHash||'—')}</td>
|
||||||
<td>${d}</td>
|
<td>${d}</td>
|
||||||
<td>${wetime.diff/1000000} s</td>
|
<td>${wetime.diff != null ? wetime.diff/1000000 + ' s' : '—'}</td>
|
||||||
<td>${wetime.position+1}</td>
|
<td>${wetime.position != null ? wetime.position+1 : '—'}</td>
|
||||||
<td>${wetime.participants}</td>
|
<td>${wetime.participants != null ? wetime.participants : '—'}</td>
|
||||||
<td>${wetime.points}</td>
|
<td>${wetime.points != null ? wetime.points : '—'}</td>
|
||||||
`;
|
`;
|
||||||
tableBody.appendChild(row);
|
tableBody.appendChild(row);
|
||||||
})
|
});
|
||||||
|
} else {
|
||||||
|
tableBody.innerHTML = '<tr><td colspan="7" style="padding:20px;text-align:center;color:#999">No rounds yet.</td></tr>';
|
||||||
|
}
|
||||||
var prev=0;
|
var prev=0;
|
||||||
var next=0;
|
var next=0;
|
||||||
if (data.times.length > 0){
|
if (data.times && data.times.length > 0){
|
||||||
prev = data.times[0].blockHeight+data.times.length;
|
prev = data.times[0].blockHeight+data.times.length;
|
||||||
next = data.times[data.times.length-1].blockHeight;
|
next = data.times[data.times.length-1].blockHeight;
|
||||||
if (prev < 0 ){
|
if (prev < 0 ){
|
||||||
@@ -126,8 +148,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
getWeInfo();
|
getWeInfo();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user