Skip to content

Commit 4f46116

Browse files
authored
Merge pull request #9 from Sentinel-Bluebuilder/claude/quirky-hofstadter-d0913b
Claude/quirky hofstadter d0913b
2 parents 96eaa03 + d38ba1b commit 4f46116

5 files changed

Lines changed: 40 additions & 44 deletions

File tree

MANIFESTO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ client.register('eip155:8453', scheme);
164164
const paidFetch = wrapFetchWithPayment(fetch, client);
165165

166166
// 3. Buy 30 days of VPN — 402 → auto-sign EIP-3009 → settle → provision
167-
const res = await paidFetch('https://x402.blue/vpn/connect/30days', {
167+
const res = await paidFetch('https://x402.sentinel.co/vpn/connect/30days', {
168168
method: 'POST',
169169
headers: { 'Content-Type': 'application/json' },
170170
body: JSON.stringify({ sentinelAddr: wallet.address }),

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
**AI agents pay USDC on Base for private internet access through Sentinel's decentralized VPN network.**
44

5+
Live at **[x402.sentinel.co](https://x402.sentinel.co)**.
6+
57
One HTTP request. No KYC. No accounts. No P2P tokens. No custom contract to deploy. The agent signs an EIP-3009 USDC transfer, our facilitator settles it on Base, the server provisions a Sentinel subscription with a gas fee grant, and the agent connects to the VPN — paying zero gas.
68

79
```typescript
@@ -16,7 +18,7 @@ const client = new x402Client();
1618
client.register('eip155:8453', scheme);
1719
const paidFetch = wrapFetchWithPayment(fetch, client);
1820

19-
const res = await paidFetch('https://x402.blue/vpn/connect/30days', {
21+
const res = await paidFetch('https://x402.sentinel.co/vpn/connect/30days', {
2022
method: 'POST',
2123
body: JSON.stringify({ sentinelAddr: wallet.address }),
2224
});
@@ -77,7 +79,7 @@ x402/
7779
└── fresh-test/ — End-to-end tests against a live server
7880
```
7981

80-
> **Note — `contracts/` and `api/`:** Earlier iterations of this project included a custom Solidity payment contract (`BlueVpnPayment.sol`) plus an event-watcher relayer in `api/`. That flow is **deprecated** in favor of the HTTP 402 + EIP-3009 design. The contract directory and `api/` watcher remain in the repo as historical reference only — do not deploy or run them. All current development happens in `server/`.
82+
The `api/`, `contracts/`, and `sdk/` directories contain an earlier event-watcher design (custom payment contract + agentId registration + polling). The HTTP 402 + EIP-3009 flow in `server/` is the canonical implementation — it needs no contract, no event watcher, and no database, and auto-creates Sentinel subscriptions on demand. The live deployment at [x402.sentinel.co](https://x402.sentinel.co) runs `server/`.
8183

8284
## Chains
8385

@@ -147,7 +149,7 @@ client.register('eip155:8453', scheme);
147149
const paidFetch = wrapFetchWithPayment(fetch, client);
148150

149151
// 3. Buy 30 days of VPN — 402 → auto-sign → settle → provision
150-
const res = await paidFetch('https://x402.blue/vpn/connect/30days', {
152+
const res = await paidFetch('https://x402.sentinel.co/vpn/connect/30days', {
151153
method: 'POST',
152154
headers: { 'Content-Type': 'application/json' },
153155
body: JSON.stringify({ sentinelAddr: wallet.address }),

api/README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
# x402 API — DEPRECATED
1+
# x402 API
22

3-
> **This directory is deprecated and no longer used.**
4-
>
5-
> Earlier iterations of x402 used a custom Solidity payment contract (`contracts/base/BlueVpnPayment.sol`) plus this event-watcher relayer to bridge on-chain payments to Sentinel allocations. That design has been replaced by the HTTP 402 + EIP-3009 flow in `server/`, which uses native USDC `transferWithAuthorization` (no custom contract, no event watcher, no SQLite database).
6-
>
7-
> **Live implementation:** `server/` — see `server/README.md`.
8-
>
9-
> The contents below are kept only as historical reference. Do not run, deploy, or build against this code.
3+
Event-watcher relayer that bridges on-chain Base payments to Sentinel allocations. Agents register off-chain to get an `agentId`, then call `BlueVpnPayment.pay(agentId, numDays)` on a custom contract; this service watches for the resulting `VpnPayment` event and provisions Sentinel access.
104

11-
---
5+
The canonical x402 implementation is `server/` — it uses HTTP 402 + EIP-3009 `transferWithAuthorization` instead, which needs no custom contract, no event watcher, no SQLite, and auto-creates Sentinel subscriptions on demand. The live deployment at [x402.sentinel.co](https://x402.sentinel.co) runs `server/`. This directory is an alternative implementation kept for the on-chain-event design.
126

13-
## Historical Reference
7+
## What it does
148

15-
What this service used to do:
9+
1. **Registers agents** — maps `agentId` to a Sentinel address
10+
2. **Watches Base** — listens for `VpnPayment` events from `contracts/base/BlueVpnPayment.sol`
11+
3. **Watches Solana** — listens for USDC transfers with x402 memo via Helius webhooks
12+
4. **Provisions on Sentinel**`MsgShareSubscription` + `MsgGrantAllowance` in one atomic TX
13+
5. **Manages a subscription pool** — 8 allocations per subscription; operator pre-creates pool entries (no auto-create)
14+
6. **Retries failed provisioning** — exponential backoff
1615

17-
1. Registered agents — mapped agentId to Sentinel address
18-
2. Watched Base for `VpnPayment` events from `BlueVpnPayment.sol`
19-
3. Watched Solana for USDC transfers with x402 memo (via Helius webhooks)
20-
4. Provisioned on Sentinel — MsgShareSubscription + MsgGrantAllowance in one atomic TX
21-
5. Managed subscription pool — handled the 8-allocation-per-subscription limit
22-
6. Retried failed provisioning — exponential backoff
16+
## Requirements
2317

24-
The current `server/` implementation does steps 4–6 directly from the HTTP 402 payment handler, with no event watching, no agentId registration, no SQLite, and no payment contract.
18+
- Deployed `BlueVpnPayment` on Base (see `contracts/base/`)
19+
- `PAYMENT_CONTRACT_ADDRESS`, `OPERATOR_EVM_ADDRESS`, `SENTINEL_OPERATOR_MNEMONIC`, `SENTINEL_PLAN_ID` in env
20+
- Pre-populated subscription pool (call `db.insertSubscription(subId, planId)` after creating subs on-chain)
21+
22+
## Why `server/` instead
23+
24+
The on-chain-event design has more moving parts: a contract to deploy + maintain, an event watcher that must stay connected to a Base WS endpoint, an operator-managed subscription pool, and a SQLite store for payment state. The EIP-3009 design in `server/` collapses all of that into a single HTTP handler — the payment, settlement, and provisioning happen in one request/response cycle, with subscription auto-creation when the pool runs dry.

docs/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ <h3 style="font-size: 13px; color: var(--accent); margin-bottom: 18px; letter-sp
14041404
<div class="label">Step 2: Buy 30 days of VPN &mdash; Base mainnet</div>
14051405
</div>
14061406
<pre><code><span class="cm">// Request VPN access &mdash; 402 &rarr; auto-sign &rarr; facilitator settles &rarr; provisioned</span>
1407-
<span class="kw">const</span> res <span class="op">=</span> <span class="kw">await</span> <span class="fn">paidFetch</span>(<span class="str">'https://x402.blue/vpn/connect/30days'</span><span class="op">,</span> {
1407+
<span class="kw">const</span> res <span class="op">=</span> <span class="kw">await</span> <span class="fn">paidFetch</span>(<span class="str">'https://x402.sentinel.co/vpn/connect/30days'</span><span class="op">,</span> {
14081408
<span class="prop">method</span><span class="op">:</span> <span class="str">'POST'</span><span class="op">,</span>
14091409
<span class="prop">headers</span><span class="op">:</span> { <span class="str">'Content-Type'</span><span class="op">:</span> <span class="str">'application/json'</span> }<span class="op">,</span>
14101410
<span class="prop">body</span><span class="op">:</span> JSON<span class="op">.</span><span class="fn">stringify</span>({ <span class="prop">sentinelAddr</span><span class="op">:</span> wallet<span class="op">.</span>address })<span class="op">,</span>
@@ -1506,7 +1506,7 @@ <h3 style="font-size: 13px; color: var(--text-muted); margin-bottom: 16px; margi
15061506
<div class="dots"><span></span><span></span><span></span></div>
15071507
<div class="label">Check pricing (free, no payment)</div>
15081508
</div>
1509-
<pre><code><span class="kw">const</span> res <span class="op">=</span> <span class="kw">await</span> <span class="fn">fetch</span>(<span class="str">'https://x402.blue/pricing'</span>)<span class="op">;</span>
1509+
<pre><code><span class="kw">const</span> res <span class="op">=</span> <span class="kw">await</span> <span class="fn">fetch</span>(<span class="str">'https://x402.sentinel.co/pricing'</span>)<span class="op">;</span>
15101510
<span class="kw">const</span> pricing <span class="op">=</span> <span class="kw">await</span> res<span class="op">.</span><span class="fn">json</span>()<span class="op">;</span>
15111511
<span class="cm">// {</span>
15121512
<span class="cm">// protocol: 'x402', network: 'eip155:8453', asset: 'USDC',</span>
@@ -1698,7 +1698,7 @@ <h2>End-to-end: USDC to VPN tunnel</h2>
16981698
<span class="kw">const</span> paidFetch <span class="op">=</span> <span class="fn">wrapFetchWithPayment</span>(fetch<span class="op">,</span> client)<span class="op">;</span>
16991699

17001700
<span class="cm">// ── Step 3: Pay USDC on Base via x402 ──</span>
1701-
<span class="kw">const</span> res <span class="op">=</span> <span class="kw">await</span> <span class="fn">paidFetch</span>(<span class="str">'https://x402.blue/vpn/connect/30days'</span><span class="op">,</span> {
1701+
<span class="kw">const</span> res <span class="op">=</span> <span class="kw">await</span> <span class="fn">paidFetch</span>(<span class="str">'https://x402.sentinel.co/vpn/connect/30days'</span><span class="op">,</span> {
17021702
<span class="prop">method</span><span class="op">:</span> <span class="str">'POST'</span><span class="op">,</span>
17031703
<span class="prop">headers</span><span class="op">:</span> { <span class="str">'Content-Type'</span><span class="op">:</span> <span class="str">'application/json'</span> }<span class="op">,</span>
17041704
<span class="prop">body</span><span class="op">:</span> JSON<span class="op">.</span><span class="fn">stringify</span>({ <span class="prop">sentinelAddr</span><span class="op">:</span> wallet<span class="op">.</span>address })<span class="op">,</span>

sdk/README.md

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
1-
# x402-connect — DEPRECATED
1+
# x402-connect
22

3-
> **This package is deprecated and was never published.**
4-
>
5-
> The agent-facing flow it described (custom payment contract + agentId registration + polling API for allocation) has been replaced by the HTTP 402 + EIP-3009 flow.
6-
>
7-
> **Use these instead:**
8-
>
9-
> - **`@x402/fetch`** — wraps `fetch` to auto-sign EIP-3009 USDC transfers when a server returns HTTP 402
10-
> - **`blue-agent-connect`** — establishes the actual Sentinel VPN tunnel (WireGuard / V2Ray) once the server has provisioned the subscription + fee grant
11-
>
12-
> See the root `README.md` for the current agent example, and `server/README.md` for the server side.
13-
>
14-
> The contents of this directory remain only as historical reference. Do not install, build, or publish.
3+
Earlier sketch of an all-in-one agent client — a single `connect()` call that bundled payment, provisioning, and tunnel setup.
154

16-
---
5+
The live agent flow uses two composed packages instead:
176

18-
## What replaced it
7+
- **`@x402/fetch`** — wraps `fetch` to auto-sign EIP-3009 USDC transfers when a server returns HTTP 402
8+
- **`blue-agent-connect`** — establishes the Sentinel VPN tunnel (WireGuard / V2Ray) once the server has provisioned the subscription + fee grant
199

20-
Old (this directory):
10+
See the root `README.md` for the current agent example, and `server/README.md` for the server side.
11+
12+
## The two designs side by side
13+
14+
This package's API:
2115

2216
```typescript
2317
import { connect } from 'x402-connect';
@@ -27,7 +21,7 @@ const vpn = await connect({
2721
});
2822
```
2923

30-
New (live):
24+
The live design:
3125

3226
```typescript
3327
import { x402Client, wrapFetchWithPayment } from '@x402/fetch';
@@ -40,12 +34,12 @@ const client = new x402Client();
4034
client.register('eip155:8453', scheme);
4135
const paidFetch = wrapFetchWithPayment(fetch, client);
4236

43-
const res = await paidFetch('https://x402.blue/vpn/connect/30days', {
37+
const res = await paidFetch('https://x402.sentinel.co/vpn/connect/30days', {
4438
method: 'POST',
4539
body: JSON.stringify({ sentinelAddr: wallet.address }),
4640
});
4741
const { subscriptionId, feeGranter, nodeAddress } = await res.json();
4842
const vpn = await connect({ mnemonic: wallet.mnemonic, subscriptionId, feeGranter, nodeAddress });
4943
```
5044

51-
No payment contract. No agentId. No polling. The server settles the EIP-3009 USDC transfer, provisions Sentinel atomically, and returns the credentials in the HTTP 200 response.
45+
No payment contract. No `agentId`. No polling. The server settles the EIP-3009 USDC transfer, provisions Sentinel atomically, and returns the credentials in the HTTP 200 response.

0 commit comments

Comments
 (0)