-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
252 lines (241 loc) · 16.2 KB
/
Copy pathindex.html
File metadata and controls
252 lines (241 loc) · 16.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<!doctype html><html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SolidPay — money is trust</title>
<meta name="description" content="SolidPay revives Ryan Fugger's original Ripple (2004) with Solid ideas: every user is a URI, every transition is hash-chained, signatures via did:nostr. No blockchain, no token — bilateral credit and routed payments over a web of trust.">
<link rel="canonical" href="https://jss.live/solidpay/">
<link rel="icon" type="image/svg+xml" href="assets/favicon.svg">
<link rel="apple-touch-icon" href="assets/icon-512.png">
<meta name="theme-color" content="#0E7D6C">
<meta property="og:type" content="website">
<meta property="og:site_name" content="SolidPay">
<meta property="og:title" content="SolidPay — money is trust">
<meta property="og:description" content="The original Ripple (2004) rebuilt with Solid ideas: every user is a URI, every transition hash-chained, nostr signatures. Pay through chains of trust — no blockchain, no token, no bank in the middle.">
<meta property="og:url" content="https://jss.live/solidpay/">
<meta property="og:image" content="https://jss.live/solidpay/assets/og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="SolidPay — Money is trust. SolidPay makes it routable. A payment routed alice → bob → carol through chains of trust.">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="SolidPay — money is trust">
<meta name="twitter:description" content="The original Ripple (2004) rebuilt with Solid ideas: every user a URI, hash-chained ledger, nostr signatures. No blockchain, no token.">
<meta name="twitter:image" content="https://jss.live/solidpay/assets/og.png">
<style>
:root{
--bg:#EFF3F2; --surface:#FFFFFF; --surface2:#F7FAF9; --ink:#16211F;
--soft:#5A6B67; --faint:#8CA09B; --line:#D6DEDB;
--acc:#0E7D6C; --acc-ink:#0A5F52; --acc-soft:#DDEEEA;
--warn:#9A6417;
--shadow:0 1px 2px rgba(22,33,31,.05),0 10px 30px rgba(22,33,31,.07);
--mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}
@media (prefers-color-scheme:dark){:root{
--bg:#0D1413; --surface:#131B1A; --surface2:#182221; --ink:#E5ECEA;
--soft:#8FA19C; --faint:#5F726D; --line:#263230;
--acc:#3FB59F; --acc-ink:#7BD2C1; --acc-soft:#12302A;
--shadow:0 1px 2px rgba(0,0,0,.35),0 12px 32px rgba(0,0,0,.4);
}}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.6 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;-webkit-font-smoothing:antialiased}
a{color:var(--acc)}
.wrap{max-width:960px;margin:0 auto;padding:0 22px}
header{padding:14px 0;border-bottom:1px solid var(--line)}
header .wrap{display:flex;align-items:center;gap:14px}
.brand{display:flex;align-items:center;gap:9px;font-weight:700;font-size:17px;color:var(--ink);text-decoration:none}
header nav{margin-left:auto;display:flex;gap:18px;font-size:14.5px}
header nav a{color:var(--soft);text-decoration:none;font-weight:550}
header nav a:hover{color:var(--acc)}
.hero{padding:76px 0 60px;text-align:center}
.hero .arcs{margin:0 auto 26px;display:block}
h1{font-size:clamp(34px,6vw,54px);line-height:1.06;letter-spacing:-.025em;margin:0 0 18px;text-wrap:balance}
.hero p.sub{font-size:19px;color:var(--soft);max-width:44rem;margin:0 auto 30px;text-wrap:balance}
.cta{display:inline-flex;gap:12px;flex-wrap:wrap;justify-content:center}
.btn{display:inline-block;padding:12px 22px;border-radius:10px;font-weight:600;font-size:15.5px;text-decoration:none;border:1px solid var(--line)}
.btn.primary{background:var(--acc);border-color:var(--acc);color:#fff}
.btn.primary:hover{filter:brightness(1.07)}
.btn.ghost{color:var(--acc);background:var(--surface)}
.btn.ghost:hover{border-color:var(--acc)}
.lineage{margin-top:26px;font-size:13.5px;color:var(--faint)}
.demo{background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);max-width:660px;margin:0 auto;padding:26px;text-align:left}
.demo .cap{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:14px}
.chain{display:flex;align-items:center;flex-wrap:wrap;gap:8px;justify-content:center;padding:8px 0 2px}
.nodechip{display:inline-flex;align-items:center;gap:8px;background:var(--surface2);border:1px solid var(--line);border-radius:99px;padding:6px 15px 6px 7px;font-weight:600;font-size:14.5px}
.dot{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;color:#fff;font-size:11.5px;font-weight:700}
.arrow{color:var(--acc);font-weight:700;animation:flow 1.8s ease infinite}
@keyframes flow{0%,100%{opacity:.3}50%{opacity:1}}
.demo .note{text-align:center;font-size:13.5px;color:var(--soft);margin-top:14px}
@media (prefers-reduced-motion:reduce){*{animation:none!important}}
section{padding:54px 0;border-top:1px solid var(--line)}
.eyebrow{font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--acc);margin:0 0 10px}
h2{font-size:26px;letter-spacing:-.02em;margin:0 0 12px;text-wrap:balance}
p.lead{color:var(--soft);max-width:46rem;margin:0 0 26px}
.cards{display:grid;gap:16px}
@media(min-width:760px){.cards.c3{grid-template-columns:repeat(3,1fr)}.cards.c2{grid-template-columns:1fr 1fr}}
.card{background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);padding:20px}
.card h3{margin:0 0 8px;font-size:16px;display:flex;align-items:center;gap:9px}
.card p{margin:0;font-size:14.5px;color:var(--soft)}
.card .ic{width:28px;height:28px;border-radius:8px;background:var(--acc-soft);color:var(--acc-ink);display:grid;place-items:center;font-size:14px;flex:0 0 auto}
pre{background:var(--surface2);border:1px solid var(--line);border-radius:10px;padding:16px 18px;overflow-x:auto;font:13px/1.6 var(--mono);color:var(--ink);margin:0}
pre .c{color:var(--faint)} pre .g{color:var(--acc-ink)}
.steps{counter-reset:s;display:grid;gap:14px;margin:0;padding:0;list-style:none}
.steps li{display:flex;gap:14px;align-items:flex-start}
.steps li::before{counter-increment:s;content:counter(s);flex:0 0 auto;width:26px;height:26px;border-radius:50%;background:var(--acc-soft);color:var(--acc-ink);display:grid;place-items:center;font:600 13px var(--mono)}
.steps b{display:block;margin-bottom:2px}
.steps p{margin:0;font-size:14.5px;color:var(--soft)}
.road{display:grid;gap:0;margin:0;padding:0;list-style:none}
.road li{display:flex;gap:16px;padding:14px 0;border-bottom:1px dashed var(--line);align-items:baseline}
.road li:last-child{border-bottom:0}
.road .v{font:700 13px var(--mono);color:var(--acc-ink);flex:0 0 3.2rem}
.road b{font-size:15px}
.road p{margin:2px 0 0;font-size:14px;color:var(--soft)}
.road .now{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;background:var(--acc-soft);color:var(--acc-ink);border-radius:99px;padding:2px 9px;margin-left:8px}
footer{border-top:1px solid var(--line);padding:34px 0 60px;font-size:14px;color:var(--faint)}
footer .wrap{display:flex;gap:18px;flex-wrap:wrap;align-items:baseline}
footer a{color:var(--soft)}
</style></head><body>
<header><div class="wrap">
<a class="brand" href="#">
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<circle cx="9" cy="12" r="3.1" stroke="var(--acc)" stroke-width="2"/>
<path d="M14.5 7.5a6.4 6.4 0 0 1 0 9" stroke="var(--acc)" stroke-width="2" stroke-linecap="round"/>
<path d="M17.8 5a10.4 10.4 0 0 1 0 14" stroke="var(--acc)" stroke-width="2" stroke-linecap="round" opacity=".45"/>
</svg>
SolidPay
</a>
<nav>
<a href="#how">How it works</a>
<a href="#stack">The stack</a>
<a href="#run">Run a node</a>
<a href="docs/spec/">Spec</a>
<a href="https://github.com/JavaScriptSolidServer/solidpay">GitHub</a>
</nav>
</div></header>
<div class="hero"><div class="wrap">
<svg class="arcs" width="64" height="64" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<circle cx="9" cy="12" r="3.1" stroke="var(--acc)" stroke-width="1.6"/>
<path d="M14.5 7.5a6.4 6.4 0 0 1 0 9" stroke="var(--acc)" stroke-width="1.6" stroke-linecap="round"/>
<path d="M17.8 5a10.4 10.4 0 0 1 0 14" stroke="var(--acc)" stroke-width="1.6" stroke-linecap="round" opacity=".5"/>
<path d="M20.9 2.6a14.6 14.6 0 0 1 0 18.8" stroke="var(--acc)" stroke-width="1.6" stroke-linecap="round" opacity=".25"/>
</svg>
<h1>Money is trust.<br>SolidPay makes it routable.</h1>
<p class="sub">The original Ripple — Ryan Fugger, 2004 — rebuilt with Solid ideas.
Extend credit to people you trust; pay anyone your network can reach. Every user is a URI,
every transition is hash-chained, and signatures come from keys you hold.
No blockchain. No token. No bank in the middle.</p>
<div class="cta">
<a class="btn primary" href="https://solidpay.melvin.me/">Try the testnet</a>
<a class="btn ghost" href="https://github.com/JavaScriptSolidServer/solidpay#quickstart">Run a node</a>
<a class="btn ghost" href="docs/spec/">Read the spec</a>
</div>
<div style="margin-top:44px">
<div class="demo">
<div class="cap">A payment, routed through trust</div>
<div class="chain">
<span class="nodechip"><span class="dot" style="background:hsl(210 42% 46%)">A</span>alice</span>
<span class="arrow">→</span>
<span class="nodechip"><span class="dot" style="background:hsl(96 42% 40%)">B</span>bob</span>
<span class="arrow">→</span>
<span class="nodechip"><span class="dot" style="background:hsl(275 42% 50%)">C</span>carol</span>
</div>
<div class="note">Bob trusts alice for 1,000. Carol trusts bob for 500.
So alice can pay carol 300 <em>through</em> bob — using only credit already granted.
Nobody mid-path approves anything; that's the whole trick.</div>
</div>
</div>
<div class="lineage">solidpay.org · an idea from 2018, an engine from 2026 · grown out of the
<a href="https://github.com/JavaScriptSolidServer/plugins">JSS plugin experiment</a> and
<a href="https://github.com/webcontracts/webcontracts.github.io/issues/4">trustline.v1</a></div>
</div></div>
<section id="how"><div class="wrap">
<p class="eyebrow">How it works</p>
<h2>Three verbs, one graph</h2>
<p class="lead">Fugger's 2004 insight: trust relationships between people <em>are</em> the payment network.
SolidPay keeps the model exactly that small.</p>
<div class="cards c3">
<div class="card"><h3><span class="ic">+</span>Extend trust</h3>
<p>A trustline is one-way credit: "you may owe me up to 500 USD." Only the creditor creates,
resizes, or removes it — it's their risk, nobody else's signature required.</p></div>
<div class="card"><h3><span class="ic">→</span>Pay through it</h3>
<p>Payments route hop-by-hop through unused credit. Every hop rides a grant its next node already
made, so intermediaries need no per-payment consent. Owed-to-you credit spends with no line at all —
paying back clears debt first.</p></div>
<div class="card"><h3><span class="ic">✓</span>Settle outside</h3>
<p>IOUs clear out-of-band — cash, sats, a favour returned. The creditor records repayment, and only
a claim you hold can shrink. Books are one signed number per pair: they cannot desync.</p></div>
</div>
</div></section>
<section id="stack"><div class="wrap">
<p class="eyebrow">The Solid ideas</p>
<h2>What 2004 didn't have</h2>
<div class="cards c2">
<div class="card"><h3><span class="ic">⌾</span>Every user is a URI</h3>
<p>Your identity is an address, not a row in someone's database: a WebID, a
<code>did:nostr</code>, or this node's own <code>/u/name#me</code> — which dereferences to a real
profile document. One agent, one canonical spelling, globally linkable.</p></div>
<div class="card"><h3><span class="ic">⛓</span>A ledger that proves itself</h3>
<p>Every transition is hash-chained — <code>seq</code>, <code>prev</code>, SHA-256 over the
RFC 8785-canonical entry. Anyone can re-derive the whole chain from
<code>/api/log</code>; the UI shows the verification badge live.</p></div>
<div class="card"><h3><span class="ic">✎</span>Signatures, not sessions</h3>
<p><strong>Live:</strong> every transition is a schnorr-signed nostr event — sign with any
nostr key (extension or xlogin), <code>POST /api/tx</code>, done. The node verifies, never
attributes: authorship is provable by anyone replaying the log. The server is a coordinator,
not an authority — verify, don't trust.</p></div>
<div class="card"><h3><span class="ic">⇄</span>A network of nodes</h3>
<p><strong>Two nodes live.</strong> Cross-node payments flow through did:nostr gateway agents —
signatures are the only coordination — and both nodes' audited tips are anchored to Bitcoin
testnet4 on a <a href="https://blocktrails.org">Blocktrails</a> trail. Atomic routes
(hold/commit) are the next protocol level.</p></div>
</div>
</div></section>
<section id="run"><div class="wrap">
<p class="eyebrow">Run a node</p>
<h2>A testnet in one file, one dependency</h2>
<p class="lead">The whole node — engine, API, product UI — is plain Node.js. Clone it, run it,
open the app, and start a trust network with your friends. Testnet: play money, real protocol.</p>
<div class="cards c2">
<div><pre><span class="c"># get a node running</span>
git clone https://github.com/JavaScriptSolidServer/solidpay
cd solidpay
node server.js
<span class="g">solidpay node listening on port 3480</span>
<span class="c"># behind a reverse proxy (the solidpay.<domain> convention)</span>
PUBLIC_URL=https://solidpay.yourdomain TRUST_PROXY=1 HOST=127.0.0.1 node server.js</pre></div>
<ol class="steps">
<li><div><b>Create an account</b><p>Open the app, pick a name — you are now
<code>…/u/you#me</code>, a URI that dereferences.</p></div></li>
<li><div><b>Extend trust</b><p>Give a friend a credit limit in any currency — USD, SATS, HRS,
anything <code>[A-Z0-9]</code>.</p></div></li>
<li><div><b>Pay through the graph</b><p>Type a name and an amount; the route previews live
before you commit, then settles atomically.</p></div></li>
</ol>
</div>
</div></section>
<section id="roadmap"><div class="wrap">
<p class="eyebrow">Roadmap</p>
<h2>Testnet first, then the hard parts</h2>
<ul class="road">
<li><span class="v">v0</span><div><b>Standalone testnet node<span class="now">now</span></b>
<p>Trustlines, routed payments, settle, hash-chained ledger, product UI, URIs for users, nostr sign-in. Live nodes: <a href="https://solidpay.melvin.me/">solidpay.melvin.me</a> · <a href="https://solidpay.melvincarvalho.com/">solidpay.melvincarvalho.com</a> · <a href="https://solidpay.nostr.social/">solidpay.nostr.social</a> — the <code>solidpay.</code> subdomain convention.</p></div></li>
<li><span class="v">v1</span><div><b>did:nostr signatures<span class="now">live</span></b>
<p>Shipped: schnorr-signed transitions as nostr events (kinds 8801–8804) — the ledger is
verify-don't-trust, and <a href="docs/spec/#signatures">spec §9</a> is normative. Remaining in
v1: per-agent privacy views, WebID agents, custody export.</p></div></li>
<li><span class="v">v2</span><div><b>Federation<span class="now">first light</span></b>
<p>Two live nodes; cross-node payments through did:nostr gateways — demonstrated on the open
internet (<a href="docs/spec/#federation">spec §13</a>). Next: atomic routes (hold/commit).</p></div></li>
<li><span class="v">v3</span><div><b>Anchoring<span class="now">live</span></b>
<p>Both nodes' audited tips anchored to Bitcoin testnet4 on a
<a href="https://blocktrails.org">Blocktrails</a> federation trail —
chained P2TR marks, served at <code>/api/anchors</code>.</p></div></li>
</ul>
</div></section>
<footer><div class="wrap">
<span>SolidPay · MIT</span>
<a href="https://github.com/JavaScriptSolidServer/solidpay">GitHub</a>
<a href="docs/spec/">Spec</a>
<a href="docs/roadmap.md">Roadmap</a>
<a href="https://classic.ripplepay.com/">RipplePay (2004)</a>
<span style="margin-left:auto">an idea whose time has come back</span>
</div></footer>
</body></html>