Skip to content

Commit b2b132f

Browse files
docs+manifest: bring macOS/Linux connect to parity with Windows (native CLI)
All three agent-facing surfaces now document a real, source-verified macOS/Linux connect path using Sentinel's native sentinel-dvpncli, instead of a bare GitHub link. Payment is identical on every OS; only the connect step differs. Verified against sentinel-dvpncli @ v4.0.0 source (cobra command tree + sentinel-go-sdk config flags), not its README: - install: go install github.com/sentinel-official/sentinel-dvpncli@latest (Go 1.24+) - keys: echo "$MNEMONIC" | sentinel-dvpncli keys add agent --keyring.backend test - session: sentinel-dvpncli tx session-start <nodeAddress> --subscription-id <id> --tx.fee-granter-addr <feeGranter> --tx.from-name agent --keyring.backend test - connect: sentinel-dvpncli connect <sessionId> Flags map 1:1 onto the x402 200 response (subscriptionId, feeGranter, nodeAddress). Fedora called out as the sole unsupported OS (SELinux blocks VPN interfaces). docs/llms.txt - rewrote Prerequisites (two equal paths), split Agent-flow step 8 by OS, retitled the JS reference as "payment + Windows connect", added a full "macOS & Linux - native CLI connect" section, added sentinel-dvpncli to Packages. docs/index.html - relabelled Step 3 as the Windows JS path, added a parity "Step 3 - macOS & Linux (easiest)" CLI code block, taught the embedded manifest JSON the connectMacLinux/connectWindows split, annotated the full-flow example. server/src/index.ts - /manifest now carries the platform split in tldr, flow step 8, and a new sentinel.connectMacLinux block (+ platform notes on setup/connect/disconnect). tsc --noEmit passes. NOTE: live server runs an older image; manifest reflects this only after the host redeploys.
1 parent 01aaf99 commit b2b132f

3 files changed

Lines changed: 134 additions & 15 deletions

File tree

docs/index.html

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@
5353
"lcd": "https://lcd.sentinel.co",
5454
"rpcFallbacks": ["https://rpc.sentinel.co:443", "https://sentinel-rpc.polkachu.com", "https://rpc.mathnodes.com", "https://sentinel-rpc.publicnode.com", "https://rpc.sentinel.quokkastake.io", "https://rpc.sentinel.suchnode.net:443"],
5555
"lcdFallbacks": ["https://lcd.sentinel.co", "https://sentinel-api.polkachu.com", "https://api.sentinel.quokkastake.io", "https://sentinel-rest.publicnode.com", "https://api.sentinel.suchnode.net"],
56-
"setup": "await setup() from blue-js-sdk/ai-path — run once on a fresh machine; auto-downloads V2Ray (no admin), checks WireGuard; returns { ready, capabilities, recommended, issues }",
56+
"platforms": "Payment is identical everywhere; only the connect step differs by OS.",
57+
"connectMacLinux": "EASIEST. WireGuard ships with the OS. Use native CLI sentinel-dvpncli (go install github.com/sentinel-official/sentinel-dvpncli@latest): (1) echo \"$MNEMONIC\" | sentinel-dvpncli keys add agent --keyring.backend test; (2) sentinel-dvpncli tx session-start <nodeAddress> --subscription-id <subscriptionId> --tx.fee-granter-addr <feeGranter> --tx.from-name agent --keyring.backend test → capture session id; (3) sentinel-dvpncli connect <sessionId>. Exception: Fedora (SELinux blocks VPNs).",
58+
"connectWindows": "Heavier JS path. await setup() from blue-js-sdk/ai-path — run once on a fresh machine; auto-downloads V2Ray (no admin), checks/installs WireGuard (MSI needs admin); returns { ready, capabilities, recommended, issues }",
5759
"walletCreate": "createWallet() from blue-js-sdk/ai-path → { address, mnemonic }",
58-
"connect": "connect({ mnemonic, subscriptionId, feeGranter, nodeAddress }) → { connected, ip, protocol }",
59-
"disconnect": "disconnect() ends session on-chain (fee-granted), tears down tunnel",
60+
"connect": "Windows JS tunnel: connect({ mnemonic, subscriptionId, feeGranter, nodeAddress }) → { connected, ip, protocol }. On macOS/Linux use connectMacLinux (native CLI) instead.",
61+
"disconnect": "JS: disconnect() ends session on-chain (fee-granted), tears down tunnel. CLI: sentinel-dvpncli tx session-cancel <sessionId>",
6062
"nodeFallback": "If provision.nodeAddress is empty, call rpcQueryNodesForPlan(rpc, provision.planId, { status: 1 }) and pick from items[]"
6163
},
6264
"moreEndpoints": {
@@ -1995,7 +1997,7 @@ <h3 style="font-size: 13px; color: var(--accent); margin-bottom: 18px; letter-sp
19951997

19961998
<div class="code-block" style="margin-bottom: 24px;">
19971999
<div class="bar">
1998-
<div class="label">Step 3: Connect to VPN &mdash; use provisioned credentials</div>
2000+
<div class="label">Step 3 &mdash; Windows: connect via blue-js-sdk (JS tunnel)</div>
19992001
</div>
20002002
<pre><code><span class="cm">// connect(), createWallet(), rpcQueryNodesForPlan(), createRpcQueryClientWithFallback()</span>
20012003
<span class="cm">// already imported above from 'blue-js-sdk/ai-path'</span>
@@ -2026,6 +2028,40 @@ <h3 style="font-size: 13px; color: var(--accent); margin-bottom: 18px; letter-sp
20262028
<span class="kw">await</span> <span class="fn">disconnect</span>()<span class="op">;</span></code></pre>
20272029
</div>
20282030

2031+
<div class="code-block" style="margin-bottom: 24px;">
2032+
<div class="bar">
2033+
<div class="label">Step 3 &mdash; macOS &amp; Linux (easiest): connect via native CLI</div>
2034+
</div>
2035+
<pre><code><span class="cm">// Payment (Steps 0-2 above) is identical. macOS &amp; Linux skip the JS connect()</span>
2036+
<span class="cm">// and use Sentinel's native CLI instead &mdash; WireGuard already ships with the OS,</span>
2037+
<span class="cm">// so there's nothing to install for the tunnel. Three flag-driven commands, no prompts.</span>
2038+
<span class="cm">// CLI: https://github.com/sentinel-official/sentinel-dvpncli</span>
2039+
2040+
<span class="cm">// Install once (Go 1.24+):</span>
2041+
<span class="cm">// go install github.com/sentinel-official/sentinel-dvpncli@latest</span>
2042+
2043+
<span class="cm">// 1. Import the SAME wallet whose sentinelAddr you sent to x402.</span>
2044+
<span class="cm">// Mnemonic is read from stdin; --keyring.backend test = non-interactive.</span>
2045+
<span class="kw">echo</span> <span class="str">"$AGENT_MNEMONIC"</span> | sentinel-dvpncli keys add agent --keyring.backend test
2046+
2047+
<span class="cm">// 2. Start the session against the subscription x402 shared with you.</span>
2048+
<span class="cm">// --tx.fee-granter-addr = provision.feeGranter &rarr; operator pays the P2P gas (you pay 0).</span>
2049+
sentinel-dvpncli tx session-start <span class="str">"$NODE_ADDRESS"</span> \
2050+
--subscription-id <span class="str">"$SUBSCRIPTION_ID"</span> \
2051+
--tx.fee-granter-addr <span class="str">"$FEE_GRANTER"</span> \
2052+
--tx.from-name agent --keyring.backend test \
2053+
--rpc.chain-id sentinelhub-2 --output-format json
2054+
<span class="cm">// &rarr; capture the new session id from the tx result/events</span>
2055+
2056+
<span class="cm">// 3. Bring the tunnel up (takes the SESSION id, not the subscription id).</span>
2057+
<span class="cm">// WireGuard may need sudo to create the interface, same as any wg client.</span>
2058+
sentinel-dvpncli connect <span class="str">"$SESSION_ID"</span>
2059+
<span class="cm">// &rarr; tunnel up. Tear down with: sentinel-dvpncli tx session-cancel "$SESSION_ID"</span>
2060+
<span class="cm">//</span>
2061+
<span class="cm">// Defaults: --rpc.addrs https://rpc.sentinel.co:443, --rpc.chain-id sentinelhub-2.</span>
2062+
<span class="cm">// Only exception across all platforms: Fedora (SELinux blocks VPN interfaces).</span></code></pre>
2063+
</div>
2064+
20292065
<div class="code-block" style="margin-bottom: 24px;">
20302066
<div class="bar">
20312067
<div class="label">Under the hood &mdash; what x402 does for you</div>
@@ -2344,6 +2380,9 @@ <h2>End-to-end: USDC to VPN tunnel</h2>
23442380
}
23452381

23462382
<span class="cm">// ── Step 5: Connect to VPN (0 gas, 0 P2P) ──</span>
2383+
<span class="cm">// This connect() is the Windows path. On macOS/Linux (easiest) use the native CLI instead:</span>
2384+
<span class="cm">// sentinel-dvpncli tx session-start &lt;nodeAddress&gt; --subscription-id &lt;id&gt; --tx.fee-granter-addr &lt;feeGranter&gt; --tx.from-name agent --keyring.backend test</span>
2385+
<span class="cm">// sentinel-dvpncli connect &lt;sessionId&gt; (WireGuard ships with the OS; nothing to install)</span>
23472386
<span class="kw">const</span> vpn <span class="op">=</span> <span class="kw">await</span> <span class="fn">connect</span>({
23482387
<span class="prop">mnemonic</span><span class="op">:</span> wallet<span class="op">.</span>mnemonic<span class="op">,</span>
23492388
<span class="prop">nodeAddress</span><span class="op">,</span>

docs/llms.txt

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ The agent signs an EIP-3009 message off-chain. The self-hosted facilitator settl
88

99
The agent needs exactly one thing before calling x402: an EVM private key with at least $1.00 USDC on Base (chainId 8453). Everything else — Sentinel wallet, P2P gas, node selection, tunnel keys — is provisioned by x402 or generated locally by `blue-js-sdk/ai-path`.
1010

11-
On a fresh machine with no tunnel binaries, run `await setup()` from `blue-js-sdk/ai-path` once before `connect()`. It auto-downloads V2Ray 5.2.1 to `~/.sentinel-sdk/bin` (no admin rights needed) and detects/auto-installs WireGuard (the Windows MSI install needs admin). It returns `{ ready, capabilities, recommended, issues }` — if `capabilities` includes `v2ray`, you can connect with zero manual installs. For macOS and Linux Sentinel's CLI tool shall be used to connect (ideally, compile it locally): https://github.com/sentinel-official/sentinel-dvpncli
11+
**Payment is identical on every platform.** What differs is *connecting* the tunnel after the server returns 200. There are two equally-supported connect paths — pick by OS:
12+
13+
- **macOS & Linux (easiest):** WireGuard already ships with the OS, so there is nothing to install for the tunnel itself. Use the native `sentinel-dvpncli` (one `go install`), then drive it with three flag-only commands — see **"macOS & Linux — native CLI connect"** below. No admin/sudo for V2Ray; WireGuard may need sudo to bring an interface up, same as any WireGuard client. **Only exception: Fedora** — its SELinux blocks VPN interfaces and cannot be worked around programmatically; macOS, Ubuntu, Debian and other mainstream Linux are fine.
14+
- **Windows (heavier):** run `await setup()` from `blue-js-sdk/ai-path` once on a fresh machine before `connect()`. It auto-downloads V2Ray 5.2.1 to `~/.sentinel-sdk/bin` (no admin) and detects/auto-installs WireGuard (the MSI install needs admin). It returns `{ ready, capabilities, recommended, issues }` — if `capabilities` includes `v2ray`, you can connect with zero manual installs. See **"Windows — JS-SDK connect"** below.
15+
16+
Both paths consume the exact same 200 response (`subscriptionId`, `planId`, `feeGranter`, `nodeAddress`) and end in the same `MsgStartSession` + direct WireGuard/V2Ray handshake.
1217

1318
How to fund a fresh EVM key with USDC on Base:
1419
- **Coinbase / Coinbase CDP**: withdraw USDC and pick "Base" as the network. ~30 seconds, no bridge fee.
@@ -53,11 +58,17 @@ Free:
5358
5. Facilitator settles USDC on Base.
5459
6. Server submits atomic `MsgShareSubscription` + `MsgGrantAllowance` on Sentinel.
5560
7. Server returns 200 `{ provisioned, subscriptionId, planId, feeGranter, nodeAddress, nodeCountry, nodes[], sentinelTxHash, expiresAt }`.
56-
8. Agent runs `setup()` once on a fresh machine, then `connect({ mnemonic, subscriptionId, feeGranter, nodeAddress })`.
57-
9. `MsgStartSession` on Sentinel — gas paid by `feeGranter`.
58-
10. Direct WireGuard/V2Ray handshake — tunnel up.
61+
8. Agent connects, using the path for its OS (both consume the same 200 fields):
62+
- **macOS/Linux:** `sentinel-dvpncli tx session-start <nodeAddress> --subscription-id <subscriptionId> --tx.fee-granter-addr <feeGranter> --tx.from-name <key>` → note the returned session id → `sentinel-dvpncli connect <sessionId>`. (See "macOS & Linux — native CLI connect".)
63+
- **Windows:** `setup()` once on a fresh machine, then `connect({ mnemonic, subscriptionId, feeGranter, nodeAddress })`. (See "Windows — JS-SDK connect".)
64+
9. `MsgStartSession` on Sentinel — gas paid by `feeGranter` (the fee grant the server created in step 6, so the agent's session start costs zero P2P).
65+
10. Direct WireGuard/V2Ray handshake — tunnel up. The operator never sees it.
66+
67+
## Reference code — payment (all platforms) + Windows connect
5968

60-
## Reference code
69+
The payment half of this snippet is identical on every OS. The trailing `connect()` is the
70+
Windows path (JS-SDK tunnel). On macOS/Linux, stop after you have `provision` and switch to the
71+
CLI recipe in the next section — the request/response is byte-for-byte the same.
6172

6273
```typescript
6374
import { x402Client, wrapFetchWithPayment } from '@x402/fetch';
@@ -99,11 +110,63 @@ const vpn = await connect({
99110
// vpn.connected === true
100111
```
101112

113+
## macOS & Linux — native CLI connect
114+
115+
This is the easiest connect path. After the `paidFetch` call above returns `provision`
116+
(`{ subscriptionId, planId, feeGranter, nodeAddress, ... }`), do NOT call the JS `connect()`.
117+
Instead drive Sentinel's native `sentinel-dvpncli` — three fully flag-driven commands, no config
118+
files, no interactive prompts when you pass the flags below. WireGuard already ships with macOS
119+
and mainstream Linux, so there is nothing to install for the tunnel itself.
120+
121+
**Install once (Go 1.24+):**
122+
123+
```bash
124+
go install github.com/sentinel-official/sentinel-dvpncli@latest # binary lands in $(go env GOPATH)/bin
125+
# or from source: git clone https://github.com/sentinel-official/sentinel-dvpncli && cd sentinel-dvpncli && make install
126+
sentinel-dvpncli version
127+
```
128+
129+
**Connect (drive these with the fields from `provision`):**
130+
131+
```bash
132+
# 1. Import the SAME wallet whose sentinelAddr (sent1...) you sent to x402.
133+
# The mnemonic is read from stdin; --keyring.backend test makes it non-interactive (no OS keychain prompt).
134+
echo "$AGENT_MNEMONIC" | sentinel-dvpncli keys add agent --keyring.backend test
135+
# (keyring.backend defaults to "os"; use "test" or "file" for scripted/agent use.)
136+
137+
# 2. Start the session against the subscription x402 shared with you.
138+
# --tx.fee-granter-addr = provision.feeGranter => the operator pays the P2P gas, you pay zero.
139+
# Positional arg = provision.nodeAddress (sentnode1...).
140+
sentinel-dvpncli tx session-start "$NODE_ADDRESS" \
141+
--subscription-id "$SUBSCRIPTION_ID" \
142+
--tx.fee-granter-addr "$FEE_GRANTER" \
143+
--tx.from-name agent \
144+
--keyring.backend test \
145+
--rpc.chain-id sentinelhub-2 \
146+
--output-format json
147+
# Capture the session id from the tx result / events (it is the session just created on-chain).
148+
149+
# 3. Bring the tunnel up. Takes the SESSION id (not the subscription id).
150+
# WireGuard nodes may need sudo to create the interface — same as any wg client.
151+
sentinel-dvpncli connect "$SESSION_ID"
152+
```
153+
154+
Defaults baked into the CLI (override only if needed): `--rpc.addrs https://rpc.sentinel.co:443`,
155+
`--rpc.chain-id sentinelhub-2`, `--keyring.name sentinel`. Useful extras: `sentinel-dvpncli keys list`,
156+
`sentinel-dvpncli query ...` (sessions/subscriptions/nodes), `sentinel-dvpncli inspect`,
157+
`sentinel-dvpncli tx session-cancel <id>` to tear down. `connect` traps SIGINT/SIGTERM and runs a
158+
clean down sequence on exit.
159+
160+
> **Fedora caveat:** Fedora's SELinux blocks VPN interfaces and an agent cannot bypass it. macOS,
161+
> Ubuntu, Debian, Arch and other mainstream distros work out of the box. This is the only OS x402
162+
> cannot connect on.
163+
102164
## Packages
103165

104166
- `@x402/fetch` — wraps `fetch`, auto-signs 402 responses
105167
- `@x402/evm` — `ExactEvmScheme` EIP-3009 signer
106-
- `blue-js-sdk/ai-path` — environment setup (`setup` — auto-installs tunnel binaries), Sentinel wallet (`createWallet`, `importWallet`), tunnel (`connect`, `disconnect`), and plan/node discovery (`rpcQueryNodesForPlan`, `createRpcQueryClientWithFallback`) — WireGuard/V2Ray
168+
- `blue-js-sdk/ai-path` — Windows connect path: environment setup (`setup` — auto-installs tunnel binaries), Sentinel wallet (`createWallet`, `importWallet`), tunnel (`connect`, `disconnect`), and plan/node discovery (`rpcQueryNodesForPlan`, `createRpcQueryClientWithFallback`) — WireGuard/V2Ray
169+
- `sentinel-dvpncli` — macOS/Linux connect path: native Go CLI (`go install github.com/sentinel-official/sentinel-dvpncli@latest`). Flag-driven `keys` / `tx session-start` / `connect` — drives the tunnel without the JS SDK. WireGuard ships with the OS.
107170

108171
## Request schema
109172

0 commit comments

Comments
 (0)