perx402-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -0
- package/dist/client.d.ts +69 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +252 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/shadow-fetch.d.ts +25 -0
- package/dist/shadow-fetch.d.ts.map +1 -0
- package/dist/shadow-fetch.js +25 -0
- package/dist/shadow-fetch.js.map +1 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# @shadow-proxy/sdk
|
|
2
|
+
|
|
3
|
+
Dead-simple SDK for Shadow Proxy -- private x402 payments for AI agents on Solana.
|
|
4
|
+
|
|
5
|
+
Shadow Proxy intercepts x402 payment flows and routes them through MagicBlock's Private Ephemeral Rollup (TEE), hiding amount, service identity, and agent identity from the public chain.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @shadow-proxy/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
### Two-line usage with `shadowFetch`
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { shadowFetch } from "@shadow-proxy/sdk";
|
|
19
|
+
|
|
20
|
+
const pay = shadowFetch({
|
|
21
|
+
proxyUrl: "http://localhost:3001",
|
|
22
|
+
agentPubkey: "HwupK...",
|
|
23
|
+
agentAta: "DDoKy...",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const result = await pay("https://any-x402-api.com/market-data");
|
|
27
|
+
console.log(result.data); // { symbol: "SOL/USDC", price: 178.42, ... }
|
|
28
|
+
console.log(result.receiptHash); // "abc123..."
|
|
29
|
+
console.log(result.amount); // 0.1
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Full client
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { ShadowProxyClient } from "@shadow-proxy/sdk";
|
|
36
|
+
|
|
37
|
+
const shadow = new ShadowProxyClient({
|
|
38
|
+
proxyUrl: "http://localhost:3001",
|
|
39
|
+
agentPubkey: "HwupK...",
|
|
40
|
+
agentAta: "DDoKy...",
|
|
41
|
+
autoInitSession: true, // default, calls /session/init on first request
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Single payment
|
|
45
|
+
const result = await shadow.pay("https://api.example.com/data");
|
|
46
|
+
console.log(result.data);
|
|
47
|
+
console.log(result.receiptHash);
|
|
48
|
+
|
|
49
|
+
// Health check
|
|
50
|
+
const health = await shadow.health();
|
|
51
|
+
console.log(health.status); // "ok"
|
|
52
|
+
|
|
53
|
+
// Look up a receipt
|
|
54
|
+
const receipt = await shadow.getReceipt("abc123...");
|
|
55
|
+
|
|
56
|
+
// Get all receipts
|
|
57
|
+
const receipts = await shadow.getReceipts();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Streaming micropayments
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { ShadowProxyClient } from "@shadow-proxy/sdk";
|
|
64
|
+
|
|
65
|
+
const shadow = new ShadowProxyClient({
|
|
66
|
+
proxyUrl: "http://localhost:3001",
|
|
67
|
+
agentPubkey: "HwupK...",
|
|
68
|
+
agentAta: "DDoKy...",
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const stream = shadow.createStream("https://api.example.com/feed", {
|
|
72
|
+
intervalMs: 1000, // pay once per second
|
|
73
|
+
maxPayments: 60, // stop after 60 payments
|
|
74
|
+
maxSpend: 5.0, // or stop after 5 USDC
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
stream.on("data", (chunk) => {
|
|
78
|
+
console.log("Received:", chunk);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
stream.on("receipt", (r) => {
|
|
82
|
+
console.log("Paid:", r.receiptHash, "Amount:", r.amount);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
stream.on("error", (err) => {
|
|
86
|
+
console.error("Stream error:", err.code, err.message);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
stream.on("stopped", (summary) => {
|
|
90
|
+
console.log("Total paid:", summary.totalPaid);
|
|
91
|
+
console.log("Payments:", summary.paymentsCount);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await stream.start();
|
|
95
|
+
|
|
96
|
+
// Later, stop manually:
|
|
97
|
+
const summary = await stream.stop();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Error handling
|
|
101
|
+
|
|
102
|
+
All errors are instances of `ShadowProxyError` with a `code` property:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { ShadowProxyError } from "@shadow-proxy/sdk";
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
await shadow.pay("https://api.example.com/data");
|
|
109
|
+
} catch (err) {
|
|
110
|
+
if (err instanceof ShadowProxyError) {
|
|
111
|
+
switch (err.code) {
|
|
112
|
+
case "PROXY_UNREACHABLE":
|
|
113
|
+
console.error("Cannot reach the proxy server");
|
|
114
|
+
break;
|
|
115
|
+
case "SESSION_INIT_FAILED":
|
|
116
|
+
console.error("Failed to initialize session");
|
|
117
|
+
break;
|
|
118
|
+
case "PAYMENT_FAILED":
|
|
119
|
+
console.error("Payment rejected:", err.message);
|
|
120
|
+
break;
|
|
121
|
+
case "TIMEOUT":
|
|
122
|
+
console.error("Request timed out");
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Error codes
|
|
130
|
+
|
|
131
|
+
| Code | Meaning |
|
|
132
|
+
|-----------------------|----------------------------------------------|
|
|
133
|
+
| `PROXY_UNREACHABLE` | Cannot connect to the Shadow Proxy server |
|
|
134
|
+
| `SESSION_INIT_FAILED` | POST /session/init returned an error |
|
|
135
|
+
| `PAYMENT_FAILED` | POST /proxy returned a non-200 status |
|
|
136
|
+
| `RECEIPT_NOT_FOUND` | GET /receipts/:hash returned an error |
|
|
137
|
+
| `STREAM_ERROR` | Error during a streaming payment tick |
|
|
138
|
+
| `TIMEOUT` | Request exceeded the timeout |
|
|
139
|
+
| `INVALID_CONFIG` | Missing or invalid configuration values |
|
|
140
|
+
|
|
141
|
+
## API reference
|
|
142
|
+
|
|
143
|
+
### `shadowFetch(config: ShadowProxyConfig): ShadowFetchFn`
|
|
144
|
+
|
|
145
|
+
Returns a function `(targetUrl: string) => Promise<PayResult>`. Creates a `ShadowProxyClient` internally with `autoInitSession: true`.
|
|
146
|
+
|
|
147
|
+
### `ShadowProxyClient`
|
|
148
|
+
|
|
149
|
+
| Method | Description |
|
|
150
|
+
|---------------------------------|----------------------------------------------|
|
|
151
|
+
| `pay(url, options?)` | Make a single private payment |
|
|
152
|
+
| `health()` | GET /health |
|
|
153
|
+
| `getReceipt(hash)` | GET /receipts/:hash |
|
|
154
|
+
| `getReceipts()` | GET /receipts |
|
|
155
|
+
| `initSession()` | POST /session/init |
|
|
156
|
+
| `createStream(url, options)` | Create a PaymentStream (call .start() next) |
|
|
157
|
+
|
|
158
|
+
### `PaymentStream` (extends EventEmitter)
|
|
159
|
+
|
|
160
|
+
| Method | Description |
|
|
161
|
+
|-----------|-----------------------------------------------------|
|
|
162
|
+
| `start()` | Begin interval-based payments |
|
|
163
|
+
| `stop()` | Stop the stream, returns `StreamSummary` |
|
|
164
|
+
|
|
165
|
+
| Event | Payload |
|
|
166
|
+
|-----------|------------------------------------------------------|
|
|
167
|
+
| `data` | Response data from the target API |
|
|
168
|
+
| `receipt` | `{ receiptHash, amount, timestamp }` |
|
|
169
|
+
| `error` | `ShadowProxyError` |
|
|
170
|
+
| `stopped` | `StreamSummary` |
|
|
171
|
+
|
|
172
|
+
## Requirements
|
|
173
|
+
|
|
174
|
+
- Node.js >= 18 (uses built-in `fetch` and `AbortSignal.timeout`)
|
|
175
|
+
- A running Shadow Proxy server (default: `http://localhost:3001`)
|
|
176
|
+
- Agent wallet funded with USDC on devnet
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
import type { ShadowProxyConfig, PayResult, PayOptions, HealthStatus, Receipt, SessionResult, StreamOptions, StreamSummary, ShadowProxyErrorCode } from "./types.js";
|
|
3
|
+
/** Custom error class for all Shadow Proxy errors. */
|
|
4
|
+
export declare class ShadowProxyError extends Error {
|
|
5
|
+
readonly code: ShadowProxyErrorCode;
|
|
6
|
+
constructor(code: ShadowProxyErrorCode, message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A streaming payment object that makes interval-based payments to a target URL.
|
|
10
|
+
* Extends EventEmitter so consumers can listen for `data`, `receipt`, `error`, and `stopped`.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PaymentStream extends EventEmitter {
|
|
13
|
+
private readonly client;
|
|
14
|
+
private readonly targetUrl;
|
|
15
|
+
private readonly options;
|
|
16
|
+
private intervalHandle;
|
|
17
|
+
private running;
|
|
18
|
+
private totalPaid;
|
|
19
|
+
private paymentsCount;
|
|
20
|
+
private receiptHashes;
|
|
21
|
+
constructor(client: ShadowProxyClient, targetUrl: string, options: StreamOptions);
|
|
22
|
+
/** Start interval-based payments. Resolves once the stream is running. */
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
/** Stop the stream and return a summary of all payments made. */
|
|
25
|
+
stop(): Promise<StreamSummary>;
|
|
26
|
+
private tick;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Full-featured client for the Shadow Proxy server.
|
|
30
|
+
*
|
|
31
|
+
* Handles session initialization, single payments, receipt lookup, health
|
|
32
|
+
* checks, and streaming micropayments.
|
|
33
|
+
*/
|
|
34
|
+
export declare class ShadowProxyClient {
|
|
35
|
+
private readonly config;
|
|
36
|
+
private readonly baseUrl;
|
|
37
|
+
private sessionInitialized;
|
|
38
|
+
private sessionInitPromise;
|
|
39
|
+
constructor(config: ShadowProxyConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Make a single payment to a target x402-protected URL.
|
|
42
|
+
* On the first call, automatically initializes a session (unless disabled).
|
|
43
|
+
*/
|
|
44
|
+
pay(targetUrl: string, options?: PayOptions): Promise<PayResult>;
|
|
45
|
+
/** Call GET /health on the proxy server. */
|
|
46
|
+
health(): Promise<HealthStatus>;
|
|
47
|
+
/** Look up a receipt by its settlement hash. */
|
|
48
|
+
getReceipt(hash: string): Promise<Receipt | null>;
|
|
49
|
+
/** Get all receipts for this agent. */
|
|
50
|
+
getReceipts(): Promise<Receipt[]>;
|
|
51
|
+
/** Initialize a session with the proxy server. */
|
|
52
|
+
initSession(): Promise<SessionResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Create a streaming payment object for interval-based micropayments.
|
|
55
|
+
* The stream does not start until you call `.start()`.
|
|
56
|
+
*/
|
|
57
|
+
createStream(targetUrl: string, options: StreamOptions): PaymentStream;
|
|
58
|
+
/**
|
|
59
|
+
* Ensures a session is initialized before making a payment.
|
|
60
|
+
* Uses a shared promise to avoid duplicate init calls.
|
|
61
|
+
*/
|
|
62
|
+
private ensureSession;
|
|
63
|
+
/**
|
|
64
|
+
* Internal fetch wrapper. Catches network/timeout errors and wraps them
|
|
65
|
+
* in ShadowProxyError.
|
|
66
|
+
*/
|
|
67
|
+
private fetchWithErrors;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,YAAY,EACZ,OAAO,EACP,aAAa,EACb,aAAa,EACb,aAAa,EACb,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB,sDAAsD;AACtD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;gBAExB,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM;CAKxD;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAgB;gBAGnC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa;IAQxB,0EAA0E;IACpE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,iEAAiE;IAC3D,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;YAetB,IAAI;CA8CnB;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,kBAAkB,CAAuC;gBAErD,MAAM,EAAE,iBAAiB;IAmBrC;;;OAGG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IA4BtE,4CAA4C;IACtC,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAgBrC,gDAAgD;IAC1C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAuBvD,uCAAuC;IACjC,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAgBvC,kDAAkD;IAC5C,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC;IAwB3C;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,aAAa;IAItE;;;OAGG;YACW,aAAa;IAkB3B;;;OAGG;YACW,eAAe;CAmB9B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
+
/** Custom error class for all Shadow Proxy errors. */
|
|
5
|
+
export class ShadowProxyError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "ShadowProxyError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A streaming payment object that makes interval-based payments to a target URL.
|
|
15
|
+
* Extends EventEmitter so consumers can listen for `data`, `receipt`, `error`, and `stopped`.
|
|
16
|
+
*/
|
|
17
|
+
export class PaymentStream extends EventEmitter {
|
|
18
|
+
client;
|
|
19
|
+
targetUrl;
|
|
20
|
+
options;
|
|
21
|
+
intervalHandle = null;
|
|
22
|
+
running = false;
|
|
23
|
+
totalPaid = 0;
|
|
24
|
+
paymentsCount = 0;
|
|
25
|
+
receiptHashes = [];
|
|
26
|
+
constructor(client, targetUrl, options) {
|
|
27
|
+
super();
|
|
28
|
+
this.client = client;
|
|
29
|
+
this.targetUrl = targetUrl;
|
|
30
|
+
this.options = options;
|
|
31
|
+
}
|
|
32
|
+
/** Start interval-based payments. Resolves once the stream is running. */
|
|
33
|
+
async start() {
|
|
34
|
+
if (this.running) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.running = true;
|
|
38
|
+
// Make the first payment immediately.
|
|
39
|
+
await this.tick();
|
|
40
|
+
if (!this.running) {
|
|
41
|
+
// tick() may have stopped the stream (e.g. maxPayments === 1).
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.intervalHandle = setInterval(() => {
|
|
45
|
+
void this.tick();
|
|
46
|
+
}, this.options.intervalMs);
|
|
47
|
+
}
|
|
48
|
+
/** Stop the stream and return a summary of all payments made. */
|
|
49
|
+
async stop() {
|
|
50
|
+
this.running = false;
|
|
51
|
+
if (this.intervalHandle !== null) {
|
|
52
|
+
clearInterval(this.intervalHandle);
|
|
53
|
+
this.intervalHandle = null;
|
|
54
|
+
}
|
|
55
|
+
const summary = {
|
|
56
|
+
totalPaid: this.totalPaid,
|
|
57
|
+
paymentsCount: this.paymentsCount,
|
|
58
|
+
receipts: [...this.receiptHashes],
|
|
59
|
+
};
|
|
60
|
+
this.emit("stopped", summary);
|
|
61
|
+
return summary;
|
|
62
|
+
}
|
|
63
|
+
async tick() {
|
|
64
|
+
if (!this.running) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Check max payments.
|
|
68
|
+
if (this.options.maxPayments !== undefined &&
|
|
69
|
+
this.paymentsCount >= this.options.maxPayments) {
|
|
70
|
+
await this.stop();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Check max spend.
|
|
74
|
+
if (this.options.maxSpend !== undefined &&
|
|
75
|
+
this.totalPaid >= this.options.maxSpend) {
|
|
76
|
+
await this.stop();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const result = await this.client.pay(this.targetUrl);
|
|
81
|
+
this.paymentsCount += 1;
|
|
82
|
+
this.totalPaid += result.amount;
|
|
83
|
+
this.receiptHashes.push(result.receiptHash);
|
|
84
|
+
this.emit("data", result.data);
|
|
85
|
+
this.emit("receipt", {
|
|
86
|
+
receiptHash: result.receiptHash,
|
|
87
|
+
amount: result.amount,
|
|
88
|
+
timestamp: result.timestamp,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
const proxyErr = err instanceof ShadowProxyError
|
|
93
|
+
? err
|
|
94
|
+
: new ShadowProxyError("STREAM_ERROR", err instanceof Error ? err.message : String(err));
|
|
95
|
+
this.emit("error", proxyErr);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Full-featured client for the Shadow Proxy server.
|
|
101
|
+
*
|
|
102
|
+
* Handles session initialization, single payments, receipt lookup, health
|
|
103
|
+
* checks, and streaming micropayments.
|
|
104
|
+
*/
|
|
105
|
+
export class ShadowProxyClient {
|
|
106
|
+
config;
|
|
107
|
+
baseUrl;
|
|
108
|
+
sessionInitialized = false;
|
|
109
|
+
sessionInitPromise = null;
|
|
110
|
+
constructor(config) {
|
|
111
|
+
if (!config.proxyUrl) {
|
|
112
|
+
throw new ShadowProxyError("INVALID_CONFIG", "proxyUrl is required");
|
|
113
|
+
}
|
|
114
|
+
if (!config.agentPubkey) {
|
|
115
|
+
throw new ShadowProxyError("INVALID_CONFIG", "agentPubkey is required");
|
|
116
|
+
}
|
|
117
|
+
if (!config.agentAta) {
|
|
118
|
+
throw new ShadowProxyError("INVALID_CONFIG", "agentAta is required");
|
|
119
|
+
}
|
|
120
|
+
this.config = {
|
|
121
|
+
autoInitSession: true,
|
|
122
|
+
...config,
|
|
123
|
+
};
|
|
124
|
+
// Strip trailing slash.
|
|
125
|
+
this.baseUrl = config.proxyUrl.replace(/\/+$/, "");
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Make a single payment to a target x402-protected URL.
|
|
129
|
+
* On the first call, automatically initializes a session (unless disabled).
|
|
130
|
+
*/
|
|
131
|
+
async pay(targetUrl, options) {
|
|
132
|
+
await this.ensureSession();
|
|
133
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
134
|
+
const response = await this.fetchWithErrors(`${this.baseUrl}/proxy`, {
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: { "Content-Type": "application/json" },
|
|
137
|
+
body: JSON.stringify({
|
|
138
|
+
target: targetUrl,
|
|
139
|
+
agentPubkey: this.config.agentPubkey,
|
|
140
|
+
ata: this.config.agentAta,
|
|
141
|
+
}),
|
|
142
|
+
signal: AbortSignal.timeout(timeout),
|
|
143
|
+
});
|
|
144
|
+
if (!response.ok) {
|
|
145
|
+
const body = await response.text().catch(() => "");
|
|
146
|
+
throw new ShadowProxyError("PAYMENT_FAILED", `Payment failed (HTTP ${String(response.status)}): ${body}`);
|
|
147
|
+
}
|
|
148
|
+
const result = (await response.json());
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
/** Call GET /health on the proxy server. */
|
|
152
|
+
async health() {
|
|
153
|
+
const response = await this.fetchWithErrors(`${this.baseUrl}/health`, {
|
|
154
|
+
method: "GET",
|
|
155
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
|
|
156
|
+
});
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
throw new ShadowProxyError("PROXY_UNREACHABLE", `Health check failed (HTTP ${String(response.status)})`);
|
|
159
|
+
}
|
|
160
|
+
return (await response.json());
|
|
161
|
+
}
|
|
162
|
+
/** Look up a receipt by its settlement hash. */
|
|
163
|
+
async getReceipt(hash) {
|
|
164
|
+
const response = await this.fetchWithErrors(`${this.baseUrl}/receipts/${encodeURIComponent(hash)}`, {
|
|
165
|
+
method: "GET",
|
|
166
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
|
|
167
|
+
});
|
|
168
|
+
if (response.status === 404) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
throw new ShadowProxyError("RECEIPT_NOT_FOUND", `Receipt lookup failed (HTTP ${String(response.status)})`);
|
|
173
|
+
}
|
|
174
|
+
return (await response.json());
|
|
175
|
+
}
|
|
176
|
+
/** Get all receipts for this agent. */
|
|
177
|
+
async getReceipts() {
|
|
178
|
+
const response = await this.fetchWithErrors(`${this.baseUrl}/receipts`, {
|
|
179
|
+
method: "GET",
|
|
180
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
|
|
181
|
+
});
|
|
182
|
+
if (!response.ok) {
|
|
183
|
+
throw new ShadowProxyError("RECEIPT_NOT_FOUND", `Receipts lookup failed (HTTP ${String(response.status)})`);
|
|
184
|
+
}
|
|
185
|
+
return (await response.json());
|
|
186
|
+
}
|
|
187
|
+
/** Initialize a session with the proxy server. */
|
|
188
|
+
async initSession() {
|
|
189
|
+
const response = await this.fetchWithErrors(`${this.baseUrl}/session/init`, {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: { "Content-Type": "application/json" },
|
|
192
|
+
body: JSON.stringify({
|
|
193
|
+
agentPubkey: this.config.agentPubkey,
|
|
194
|
+
ata: this.config.agentAta,
|
|
195
|
+
}),
|
|
196
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
|
|
197
|
+
});
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
const body = await response.text().catch(() => "");
|
|
200
|
+
throw new ShadowProxyError("SESSION_INIT_FAILED", `Session init failed (HTTP ${String(response.status)}): ${body}`);
|
|
201
|
+
}
|
|
202
|
+
const result = (await response.json());
|
|
203
|
+
this.sessionInitialized = true;
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Create a streaming payment object for interval-based micropayments.
|
|
208
|
+
* The stream does not start until you call `.start()`.
|
|
209
|
+
*/
|
|
210
|
+
createStream(targetUrl, options) {
|
|
211
|
+
return new PaymentStream(this, targetUrl, options);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Ensures a session is initialized before making a payment.
|
|
215
|
+
* Uses a shared promise to avoid duplicate init calls.
|
|
216
|
+
*/
|
|
217
|
+
async ensureSession() {
|
|
218
|
+
if (this.sessionInitialized || !this.config.autoInitSession) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (this.sessionInitPromise === null) {
|
|
222
|
+
this.sessionInitPromise = this.initSession();
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
await this.sessionInitPromise;
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
// Reset so the next call retries.
|
|
229
|
+
this.sessionInitPromise = null;
|
|
230
|
+
throw err;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Internal fetch wrapper. Catches network/timeout errors and wraps them
|
|
235
|
+
* in ShadowProxyError.
|
|
236
|
+
*/
|
|
237
|
+
async fetchWithErrors(url, init) {
|
|
238
|
+
try {
|
|
239
|
+
return await fetch(url, init);
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
243
|
+
throw new ShadowProxyError("TIMEOUT", `Request timed out: ${url}`);
|
|
244
|
+
}
|
|
245
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
246
|
+
throw new ShadowProxyError("TIMEOUT", `Request aborted: ${url}`);
|
|
247
|
+
}
|
|
248
|
+
throw new ShadowProxyError("PROXY_UNREACHABLE", `Cannot reach proxy at ${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ShadowProxyClient, ShadowProxyError, PaymentStream } from "./client.js";
|
|
2
|
+
export { shadowFetch } from "./shadow-fetch.js";
|
|
3
|
+
export type { ShadowFetchFn } from "./shadow-fetch.js";
|
|
4
|
+
export type { ShadowProxyConfig, PayResult, PayOptions, StreamOptions, StreamSummary, HealthStatus, Receipt, SessionResult, ShadowProxyErrorCode, } from "./types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EACV,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,OAAO,EACP,aAAa,EACb,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ShadowProxyConfig, PayResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* A pre-configured fetch-like function returned by `shadowFetch()`.
|
|
4
|
+
* Pass a target URL and get back the full PayResult.
|
|
5
|
+
*/
|
|
6
|
+
export type ShadowFetchFn = (targetUrl: string) => Promise<PayResult>;
|
|
7
|
+
/**
|
|
8
|
+
* Create a pre-configured fetch function for making private x402 payments.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { shadowFetch } from "@shadow-proxy/sdk";
|
|
13
|
+
*
|
|
14
|
+
* const client = shadowFetch({
|
|
15
|
+
* proxyUrl: "http://localhost:3001",
|
|
16
|
+
* agentPubkey: "HwupK...",
|
|
17
|
+
* agentAta: "DDoKy...",
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* const data = await client("https://any-x402-api.com/market-data");
|
|
21
|
+
* console.log(data); // PayResult { data, receiptHash, amount, ... }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function shadowFetch(config: ShadowProxyConfig): ShadowFetchFn;
|
|
25
|
+
//# sourceMappingURL=shadow-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow-fetch.d.ts","sourceRoot":"","sources":["../src/shadow-fetch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAMpE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ShadowProxyClient } from "./client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a pre-configured fetch function for making private x402 payments.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { shadowFetch } from "@shadow-proxy/sdk";
|
|
8
|
+
*
|
|
9
|
+
* const client = shadowFetch({
|
|
10
|
+
* proxyUrl: "http://localhost:3001",
|
|
11
|
+
* agentPubkey: "HwupK...",
|
|
12
|
+
* agentAta: "DDoKy...",
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* const data = await client("https://any-x402-api.com/market-data");
|
|
16
|
+
* console.log(data); // PayResult { data, receiptHash, amount, ... }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function shadowFetch(config) {
|
|
20
|
+
const client = new ShadowProxyClient(config);
|
|
21
|
+
return (targetUrl) => {
|
|
22
|
+
return client.pay(targetUrl);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=shadow-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow-fetch.js","sourceRoot":"","sources":["../src/shadow-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAShD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CAAC,MAAyB;IACnD,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE7C,OAAO,CAAC,SAAiB,EAAsB,EAAE;QAC/C,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/** Configuration for the Shadow Proxy client. */
|
|
2
|
+
export interface ShadowProxyConfig {
|
|
3
|
+
/** URL of the Shadow Proxy server. */
|
|
4
|
+
proxyUrl: string;
|
|
5
|
+
/** Solana public key of the AI agent. */
|
|
6
|
+
agentPubkey: string;
|
|
7
|
+
/** Associated token account (ATA) of the agent for USDC. */
|
|
8
|
+
agentAta: string;
|
|
9
|
+
/** Whether to automatically call /session/init on the first request. Defaults to true. */
|
|
10
|
+
autoInitSession?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Result of a single payment through the proxy. */
|
|
13
|
+
export interface PayResult {
|
|
14
|
+
/** The response data from the target API. */
|
|
15
|
+
data: unknown;
|
|
16
|
+
/** On-chain receipt hash (settlement hash). */
|
|
17
|
+
receiptHash: string;
|
|
18
|
+
/** USDC amount paid. */
|
|
19
|
+
amount: number;
|
|
20
|
+
/** Unix timestamp (ms) of the payment. */
|
|
21
|
+
timestamp: number;
|
|
22
|
+
/** Nonce used for this payment. */
|
|
23
|
+
nonce: number;
|
|
24
|
+
/** Solana transaction signature, if available. */
|
|
25
|
+
txSignature?: string;
|
|
26
|
+
/** Solana explorer URL for the transaction. */
|
|
27
|
+
explorerUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Options for a single pay() call. */
|
|
30
|
+
export interface PayOptions {
|
|
31
|
+
/** Request timeout in milliseconds. Defaults to 30000. */
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}
|
|
34
|
+
/** Options for creating a streaming payment. */
|
|
35
|
+
export interface StreamOptions {
|
|
36
|
+
/** How often to make a payment, in milliseconds. */
|
|
37
|
+
intervalMs: number;
|
|
38
|
+
/** Stop after this many payments. */
|
|
39
|
+
maxPayments?: number;
|
|
40
|
+
/** Stop after spending this much USDC total. */
|
|
41
|
+
maxSpend?: number;
|
|
42
|
+
}
|
|
43
|
+
/** Summary returned when a payment stream is stopped. */
|
|
44
|
+
export interface StreamSummary {
|
|
45
|
+
/** Total USDC spent across all payments. */
|
|
46
|
+
totalPaid: number;
|
|
47
|
+
/** Number of successful payments made. */
|
|
48
|
+
paymentsCount: number;
|
|
49
|
+
/** All receipt hashes collected. */
|
|
50
|
+
receipts: string[];
|
|
51
|
+
}
|
|
52
|
+
/** Health check response from the proxy server. */
|
|
53
|
+
export interface HealthStatus {
|
|
54
|
+
/** Overall status (e.g. "ok"). */
|
|
55
|
+
status: string;
|
|
56
|
+
/** TEE connection status. */
|
|
57
|
+
tee: string;
|
|
58
|
+
/** Proxy server status. */
|
|
59
|
+
proxy: string;
|
|
60
|
+
/** Whether the agent is registered in the system. */
|
|
61
|
+
agentRegistered?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** A stored receipt for a past payment. */
|
|
64
|
+
export interface Receipt {
|
|
65
|
+
/** Settlement hash. */
|
|
66
|
+
receiptHash: string;
|
|
67
|
+
/** USDC amount paid. */
|
|
68
|
+
amount: number;
|
|
69
|
+
/** Unix timestamp (ms). */
|
|
70
|
+
timestamp: number;
|
|
71
|
+
/** Target API URL that was called. */
|
|
72
|
+
targetUrl: string;
|
|
73
|
+
/** Solana transaction signature. */
|
|
74
|
+
txSignature?: string;
|
|
75
|
+
}
|
|
76
|
+
/** Result of initializing a session with the proxy. */
|
|
77
|
+
export interface SessionResult {
|
|
78
|
+
/** Whether the session was successfully created. */
|
|
79
|
+
success: boolean;
|
|
80
|
+
/** Session identifier. */
|
|
81
|
+
sessionId: string;
|
|
82
|
+
/** Session expiry time (Unix ms). */
|
|
83
|
+
expiresAt: number;
|
|
84
|
+
}
|
|
85
|
+
/** Error codes emitted by ShadowProxyError. */
|
|
86
|
+
export type ShadowProxyErrorCode = "PROXY_UNREACHABLE" | "SESSION_INIT_FAILED" | "PAYMENT_FAILED" | "RECEIPT_NOT_FOUND" | "STREAM_ERROR" | "TIMEOUT" | "INVALID_CONFIG" | "UNKNOWN";
|
|
87
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,2CAA2C;AAC3C,MAAM,WAAW,OAAO;IACtB,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+CAA+C;AAC/C,MAAM,MAAM,oBAAoB,GAC5B,mBAAmB,GACnB,qBAAqB,GACrB,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,GACd,SAAS,GACT,gBAAgB,GAChB,SAAS,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "perx402-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Private x402 payment SDK for AI agents on Solana — powered by MagicBlock's Private Ephemeral Rollup",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"clean": "rm -rf dist",
|
|
20
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"x402",
|
|
24
|
+
"solana",
|
|
25
|
+
"privacy",
|
|
26
|
+
"ai-agent",
|
|
27
|
+
"shadow-proxy",
|
|
28
|
+
"magicblock",
|
|
29
|
+
"tee"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|