@alleyboss/micropay-solana-x402-paywall 1.0.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/LICENSE +21 -0
- package/README.md +232 -0
- package/dist/client-kfCr7G-P.d.cts +112 -0
- package/dist/client-kfCr7G-P.d.ts +112 -0
- package/dist/index-DptevtnU.d.cts +71 -0
- package/dist/index-DptevtnU.d.ts +71 -0
- package/dist/index.cjs +396 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +373 -0
- package/dist/index.js.map +1 -0
- package/dist/session/index.cjs +100 -0
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/index.d.cts +1 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.js +95 -0
- package/dist/session/index.js.map +1 -0
- package/dist/solana/index.cjs +196 -0
- package/dist/solana/index.cjs.map +1 -0
- package/dist/solana/index.d.cts +68 -0
- package/dist/solana/index.d.ts +68 -0
- package/dist/solana/index.js +186 -0
- package/dist/solana/index.js.map +1 -0
- package/dist/x402/index.cjs +249 -0
- package/dist/x402/index.cjs.map +1 -0
- package/dist/x402/index.d.cts +71 -0
- package/dist/x402/index.d.ts +71 -0
- package/dist/x402/index.js +239 -0
- package/dist/x402/index.js.map +1 -0
- package/package.json +93 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AlleyBoss
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# @alleyboss/micropay-solana-x402-paywall
|
|
2
|
+
|
|
3
|
+
> Solana micropayments library implementing the x402 protocol for content paywalls.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@alleyboss/micropay-solana-x402-paywall)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🔐 **x402 Protocol** — HTTP 402 Payment Required standard
|
|
11
|
+
- ⚡ **Solana Native** — Fast, low-cost SOL micropayments
|
|
12
|
+
- 🔑 **JWT Sessions** — Secure unlock tracking
|
|
13
|
+
- 📦 **Framework Agnostic** — Works with Next.js, Express, or any Node.js project
|
|
14
|
+
- 🌳 **Tree-shakeable** — Import only what you need
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @alleyboss/micropay-solana-x402-paywall @solana/web3.js
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### 1. Verify a Payment
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { verifyPayment, type SolanaClientConfig } from '@alleyboss/micropay-solana-x402-paywall';
|
|
28
|
+
|
|
29
|
+
const clientConfig: SolanaClientConfig = {
|
|
30
|
+
network: 'devnet',
|
|
31
|
+
tatumApiKey: 'your-tatum-api-key', // Optional: for better RPC
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const result = await verifyPayment({
|
|
35
|
+
signature: 'abc123...',
|
|
36
|
+
expectedRecipient: 'CreatorWalletAddress',
|
|
37
|
+
expectedAmount: BigInt(10000000), // 0.01 SOL
|
|
38
|
+
clientConfig,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (result.valid) {
|
|
42
|
+
console.log('Payment verified!', result.from, 'paid', result.amount);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Create Session After Payment
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { createSession, validateSession } from '@alleyboss/micropay-solana-x402-paywall';
|
|
50
|
+
|
|
51
|
+
const sessionConfig = {
|
|
52
|
+
durationHours: 24,
|
|
53
|
+
secret: 'your-32-character-minimum-secret-key',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// After payment verification
|
|
57
|
+
const { token, session } = await createSession(
|
|
58
|
+
'UserWalletAddress',
|
|
59
|
+
'article-123',
|
|
60
|
+
sessionConfig
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Later, validate the session
|
|
64
|
+
const validation = await validateSession(token, sessionConfig.secret);
|
|
65
|
+
if (validation.valid) {
|
|
66
|
+
console.log('Session valid until', new Date(validation.session!.expiresAt * 1000));
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3. Build x402 Payment Requirement
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { buildPaymentRequirement, create402Headers } from '@alleyboss/micropay-solana-x402-paywall';
|
|
74
|
+
|
|
75
|
+
const requirement = buildPaymentRequirement({
|
|
76
|
+
articleId: 'article-123',
|
|
77
|
+
articleTitle: 'Premium Article',
|
|
78
|
+
priceInLamports: BigInt(10000000),
|
|
79
|
+
creatorWallet: 'CreatorWalletAddress',
|
|
80
|
+
resourceUrl: 'https://example.com/article/123',
|
|
81
|
+
network: 'devnet',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Use in HTTP response
|
|
85
|
+
const headers = create402Headers(requirement);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## API Reference
|
|
89
|
+
|
|
90
|
+
### Solana Module
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import {
|
|
94
|
+
getConnection,
|
|
95
|
+
verifyPayment,
|
|
96
|
+
waitForConfirmation,
|
|
97
|
+
lamportsToSol,
|
|
98
|
+
solToLamports
|
|
99
|
+
} from '@alleyboss/micropay-solana-x402-paywall/solana';
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
| Function | Description |
|
|
103
|
+
|----------|-------------|
|
|
104
|
+
| `getConnection(config)` | Get/create Solana RPC connection |
|
|
105
|
+
| `verifyPayment(params)` | Verify on-chain SOL transfer |
|
|
106
|
+
| `waitForConfirmation(sig, config)` | Wait for transaction confirmation |
|
|
107
|
+
| `lamportsToSol(lamports)` | Convert lamports to SOL |
|
|
108
|
+
| `solToLamports(sol)` | Convert SOL to lamports |
|
|
109
|
+
|
|
110
|
+
### Session Module
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import {
|
|
114
|
+
createSession,
|
|
115
|
+
validateSession,
|
|
116
|
+
addArticleToSession,
|
|
117
|
+
isArticleUnlocked
|
|
118
|
+
} from '@alleyboss/micropay-solana-x402-paywall/session';
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
| Function | Description |
|
|
122
|
+
|----------|-------------|
|
|
123
|
+
| `createSession(wallet, articleId, config)` | Create JWT session token |
|
|
124
|
+
| `validateSession(token, secret)` | Validate and decode session |
|
|
125
|
+
| `addArticleToSession(token, articleId, secret)` | Add article to existing session |
|
|
126
|
+
| `isArticleUnlocked(token, articleId, secret)` | Check if article is unlocked |
|
|
127
|
+
|
|
128
|
+
### x402 Module
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import {
|
|
132
|
+
buildPaymentRequirement,
|
|
133
|
+
verifyX402Payment,
|
|
134
|
+
parsePaymentHeader,
|
|
135
|
+
X402_HEADERS
|
|
136
|
+
} from '@alleyboss/micropay-solana-x402-paywall/x402';
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Function | Description |
|
|
140
|
+
|----------|-------------|
|
|
141
|
+
| `buildPaymentRequirement(params)` | Build x402 payment requirement |
|
|
142
|
+
| `verifyX402Payment(payload, requirement, config)` | Verify x402 payment |
|
|
143
|
+
| `parsePaymentHeader(header)` | Parse base64 payment header |
|
|
144
|
+
| `encodePaymentRequired(requirement)` | Encode requirement for header |
|
|
145
|
+
|
|
146
|
+
## Next.js Integration Example
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// app/api/payment/verify/route.ts
|
|
150
|
+
import {
|
|
151
|
+
verifyX402Payment,
|
|
152
|
+
createSession,
|
|
153
|
+
parsePaymentHeader,
|
|
154
|
+
decodePaymentRequired
|
|
155
|
+
} from '@alleyboss/micropay-solana-x402-paywall';
|
|
156
|
+
import { cookies } from 'next/headers';
|
|
157
|
+
|
|
158
|
+
export async function POST(request: Request) {
|
|
159
|
+
const { signature, articleId } = await request.json();
|
|
160
|
+
|
|
161
|
+
const clientConfig = {
|
|
162
|
+
network: process.env.SOLANA_NETWORK as 'devnet' | 'mainnet-beta',
|
|
163
|
+
tatumApiKey: process.env.TATUM_API_KEY,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const sessionConfig = {
|
|
167
|
+
durationHours: 24,
|
|
168
|
+
secret: process.env.SESSION_SECRET!,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// Build requirement for the article
|
|
172
|
+
const requirement = buildPaymentRequirement({
|
|
173
|
+
articleId,
|
|
174
|
+
articleTitle: 'Article Title',
|
|
175
|
+
priceInLamports: BigInt(process.env.ARTICLE_PRICE || '10000000'),
|
|
176
|
+
creatorWallet: process.env.CREATOR_WALLET!,
|
|
177
|
+
resourceUrl: `${process.env.SITE_URL}/article/${articleId}`,
|
|
178
|
+
network: clientConfig.network,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Verify payment
|
|
182
|
+
const payload = {
|
|
183
|
+
x402Version: 1,
|
|
184
|
+
scheme: 'exact' as const,
|
|
185
|
+
network: requirement.network,
|
|
186
|
+
payload: { signature },
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const result = await verifyX402Payment(payload, requirement, clientConfig);
|
|
190
|
+
|
|
191
|
+
if (!result.valid) {
|
|
192
|
+
return Response.json({ error: result.invalidReason }, { status: 400 });
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Create session
|
|
196
|
+
const { token } = await createSession(
|
|
197
|
+
result.transaction!.signature,
|
|
198
|
+
articleId,
|
|
199
|
+
sessionConfig
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
// Set cookie
|
|
203
|
+
const cookieStore = await cookies();
|
|
204
|
+
cookieStore.set('x402_session', token, {
|
|
205
|
+
httpOnly: true,
|
|
206
|
+
secure: process.env.NODE_ENV === 'production',
|
|
207
|
+
sameSite: 'strict',
|
|
208
|
+
maxAge: sessionConfig.durationHours * 3600,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return Response.json({ success: true });
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## TypeScript Support
|
|
216
|
+
|
|
217
|
+
Full TypeScript support with exported types:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import type {
|
|
221
|
+
PaymentRequirement,
|
|
222
|
+
PaymentPayload,
|
|
223
|
+
VerificationResponse,
|
|
224
|
+
SessionData,
|
|
225
|
+
SessionConfig,
|
|
226
|
+
SolanaClientConfig,
|
|
227
|
+
} from '@alleyboss/micropay-solana-x402-paywall';
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT © AlleyBoss
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Connection } from '@solana/web3.js';
|
|
2
|
+
|
|
3
|
+
/** x402 network identifiers for Solana */
|
|
4
|
+
type X402Network = 'solana-devnet' | 'solana-mainnet';
|
|
5
|
+
/** Solana network types */
|
|
6
|
+
type SolanaNetwork = 'devnet' | 'mainnet-beta';
|
|
7
|
+
/** Payment requirement for x402 protocol */
|
|
8
|
+
interface PaymentRequirement {
|
|
9
|
+
/** Payment scheme - currently only 'exact' is supported */
|
|
10
|
+
scheme: 'exact';
|
|
11
|
+
/** Network identifier for x402 */
|
|
12
|
+
network: X402Network;
|
|
13
|
+
/** Amount in lamports as string (for JSON serialization) */
|
|
14
|
+
maxAmountRequired: string;
|
|
15
|
+
/** URL of the protected resource */
|
|
16
|
+
resource: string;
|
|
17
|
+
/** Human-readable description */
|
|
18
|
+
description: string;
|
|
19
|
+
/** MIME type of the resource */
|
|
20
|
+
mimeType?: string;
|
|
21
|
+
/** Recipient wallet address */
|
|
22
|
+
payTo: string;
|
|
23
|
+
/** Maximum time in seconds to complete payment */
|
|
24
|
+
maxTimeoutSeconds: number;
|
|
25
|
+
/** Asset type - 'native' for SOL */
|
|
26
|
+
asset: string;
|
|
27
|
+
/** Additional metadata */
|
|
28
|
+
extra?: {
|
|
29
|
+
name?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Payment payload sent by client after transaction */
|
|
34
|
+
interface PaymentPayload {
|
|
35
|
+
/** x402 protocol version */
|
|
36
|
+
x402Version: number;
|
|
37
|
+
/** Payment scheme */
|
|
38
|
+
scheme: 'exact';
|
|
39
|
+
/** Network identifier */
|
|
40
|
+
network: X402Network;
|
|
41
|
+
/** Transaction details */
|
|
42
|
+
payload: {
|
|
43
|
+
/** Transaction signature (base58) */
|
|
44
|
+
signature: string;
|
|
45
|
+
/** Base64 encoded transaction (optional) */
|
|
46
|
+
transaction?: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Request to verify a payment */
|
|
50
|
+
interface VerificationRequest {
|
|
51
|
+
paymentPayload: PaymentPayload;
|
|
52
|
+
paymentRequirements: PaymentRequirement;
|
|
53
|
+
}
|
|
54
|
+
/** Response from payment verification */
|
|
55
|
+
interface VerificationResponse {
|
|
56
|
+
/** Whether the payment is valid */
|
|
57
|
+
valid: boolean;
|
|
58
|
+
/** Reason for invalid payment */
|
|
59
|
+
invalidReason?: string;
|
|
60
|
+
/** Whether the transaction is settled on-chain */
|
|
61
|
+
settled?: boolean;
|
|
62
|
+
/** Transaction details */
|
|
63
|
+
transaction?: {
|
|
64
|
+
signature: string;
|
|
65
|
+
blockTime?: number;
|
|
66
|
+
slot?: number;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Payment status for tracking */
|
|
70
|
+
interface PaymentStatus {
|
|
71
|
+
status: 'pending' | 'confirmed' | 'failed' | 'expired';
|
|
72
|
+
signature?: string;
|
|
73
|
+
confirmations?: number;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
/** Configuration for article pricing */
|
|
77
|
+
interface ArticlePaymentConfig {
|
|
78
|
+
articleId: string;
|
|
79
|
+
priceInLamports: bigint;
|
|
80
|
+
title: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Configuration for Solana client */
|
|
85
|
+
interface SolanaClientConfig {
|
|
86
|
+
/** Network to connect to */
|
|
87
|
+
network: SolanaNetwork;
|
|
88
|
+
/** Custom RPC URL (optional) */
|
|
89
|
+
rpcUrl?: string;
|
|
90
|
+
/** Tatum.io API key for RPC (optional) */
|
|
91
|
+
tatumApiKey?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get or create a Solana connection
|
|
95
|
+
* Uses singleton pattern with network-aware caching
|
|
96
|
+
*/
|
|
97
|
+
declare function getConnection(config: SolanaClientConfig): Connection;
|
|
98
|
+
/**
|
|
99
|
+
* Reset the cached connection
|
|
100
|
+
* Useful for testing or network switching
|
|
101
|
+
*/
|
|
102
|
+
declare function resetConnection(): void;
|
|
103
|
+
/**
|
|
104
|
+
* Check if network is mainnet
|
|
105
|
+
*/
|
|
106
|
+
declare function isMainnet(network: SolanaNetwork): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Convert Solana network to x402 network identifier
|
|
109
|
+
*/
|
|
110
|
+
declare function toX402Network(network: SolanaNetwork): 'solana-devnet' | 'solana-mainnet';
|
|
111
|
+
|
|
112
|
+
export { type ArticlePaymentConfig as A, type PaymentRequirement as P, type SolanaNetwork as S, type VerificationRequest as V, type X402Network as X, type PaymentPayload as a, type VerificationResponse as b, type PaymentStatus as c, type SolanaClientConfig as d, getConnection as g, isMainnet as i, resetConnection as r, toX402Network as t };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Connection } from '@solana/web3.js';
|
|
2
|
+
|
|
3
|
+
/** x402 network identifiers for Solana */
|
|
4
|
+
type X402Network = 'solana-devnet' | 'solana-mainnet';
|
|
5
|
+
/** Solana network types */
|
|
6
|
+
type SolanaNetwork = 'devnet' | 'mainnet-beta';
|
|
7
|
+
/** Payment requirement for x402 protocol */
|
|
8
|
+
interface PaymentRequirement {
|
|
9
|
+
/** Payment scheme - currently only 'exact' is supported */
|
|
10
|
+
scheme: 'exact';
|
|
11
|
+
/** Network identifier for x402 */
|
|
12
|
+
network: X402Network;
|
|
13
|
+
/** Amount in lamports as string (for JSON serialization) */
|
|
14
|
+
maxAmountRequired: string;
|
|
15
|
+
/** URL of the protected resource */
|
|
16
|
+
resource: string;
|
|
17
|
+
/** Human-readable description */
|
|
18
|
+
description: string;
|
|
19
|
+
/** MIME type of the resource */
|
|
20
|
+
mimeType?: string;
|
|
21
|
+
/** Recipient wallet address */
|
|
22
|
+
payTo: string;
|
|
23
|
+
/** Maximum time in seconds to complete payment */
|
|
24
|
+
maxTimeoutSeconds: number;
|
|
25
|
+
/** Asset type - 'native' for SOL */
|
|
26
|
+
asset: string;
|
|
27
|
+
/** Additional metadata */
|
|
28
|
+
extra?: {
|
|
29
|
+
name?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Payment payload sent by client after transaction */
|
|
34
|
+
interface PaymentPayload {
|
|
35
|
+
/** x402 protocol version */
|
|
36
|
+
x402Version: number;
|
|
37
|
+
/** Payment scheme */
|
|
38
|
+
scheme: 'exact';
|
|
39
|
+
/** Network identifier */
|
|
40
|
+
network: X402Network;
|
|
41
|
+
/** Transaction details */
|
|
42
|
+
payload: {
|
|
43
|
+
/** Transaction signature (base58) */
|
|
44
|
+
signature: string;
|
|
45
|
+
/** Base64 encoded transaction (optional) */
|
|
46
|
+
transaction?: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Request to verify a payment */
|
|
50
|
+
interface VerificationRequest {
|
|
51
|
+
paymentPayload: PaymentPayload;
|
|
52
|
+
paymentRequirements: PaymentRequirement;
|
|
53
|
+
}
|
|
54
|
+
/** Response from payment verification */
|
|
55
|
+
interface VerificationResponse {
|
|
56
|
+
/** Whether the payment is valid */
|
|
57
|
+
valid: boolean;
|
|
58
|
+
/** Reason for invalid payment */
|
|
59
|
+
invalidReason?: string;
|
|
60
|
+
/** Whether the transaction is settled on-chain */
|
|
61
|
+
settled?: boolean;
|
|
62
|
+
/** Transaction details */
|
|
63
|
+
transaction?: {
|
|
64
|
+
signature: string;
|
|
65
|
+
blockTime?: number;
|
|
66
|
+
slot?: number;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Payment status for tracking */
|
|
70
|
+
interface PaymentStatus {
|
|
71
|
+
status: 'pending' | 'confirmed' | 'failed' | 'expired';
|
|
72
|
+
signature?: string;
|
|
73
|
+
confirmations?: number;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
/** Configuration for article pricing */
|
|
77
|
+
interface ArticlePaymentConfig {
|
|
78
|
+
articleId: string;
|
|
79
|
+
priceInLamports: bigint;
|
|
80
|
+
title: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Configuration for Solana client */
|
|
85
|
+
interface SolanaClientConfig {
|
|
86
|
+
/** Network to connect to */
|
|
87
|
+
network: SolanaNetwork;
|
|
88
|
+
/** Custom RPC URL (optional) */
|
|
89
|
+
rpcUrl?: string;
|
|
90
|
+
/** Tatum.io API key for RPC (optional) */
|
|
91
|
+
tatumApiKey?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get or create a Solana connection
|
|
95
|
+
* Uses singleton pattern with network-aware caching
|
|
96
|
+
*/
|
|
97
|
+
declare function getConnection(config: SolanaClientConfig): Connection;
|
|
98
|
+
/**
|
|
99
|
+
* Reset the cached connection
|
|
100
|
+
* Useful for testing or network switching
|
|
101
|
+
*/
|
|
102
|
+
declare function resetConnection(): void;
|
|
103
|
+
/**
|
|
104
|
+
* Check if network is mainnet
|
|
105
|
+
*/
|
|
106
|
+
declare function isMainnet(network: SolanaNetwork): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Convert Solana network to x402 network identifier
|
|
109
|
+
*/
|
|
110
|
+
declare function toX402Network(network: SolanaNetwork): 'solana-devnet' | 'solana-mainnet';
|
|
111
|
+
|
|
112
|
+
export { type ArticlePaymentConfig as A, type PaymentRequirement as P, type SolanaNetwork as S, type VerificationRequest as V, type X402Network as X, type PaymentPayload as a, type VerificationResponse as b, type PaymentStatus as c, type SolanaClientConfig as d, getConnection as g, isMainnet as i, resetConnection as r, toX402Network as t };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Session data stored in JWT */
|
|
2
|
+
interface SessionData {
|
|
3
|
+
/** Unique session ID */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Wallet address that paid */
|
|
6
|
+
walletAddress: string;
|
|
7
|
+
/** Array of unlocked article IDs */
|
|
8
|
+
unlockedArticles: string[];
|
|
9
|
+
/** Whether site-wide access is granted */
|
|
10
|
+
siteWideUnlock: boolean;
|
|
11
|
+
/** Unix timestamp of creation */
|
|
12
|
+
createdAt: number;
|
|
13
|
+
/** Unix timestamp of expiration */
|
|
14
|
+
expiresAt: number;
|
|
15
|
+
}
|
|
16
|
+
/** Session configuration options */
|
|
17
|
+
interface SessionConfig {
|
|
18
|
+
/** Session duration in hours */
|
|
19
|
+
durationHours: number;
|
|
20
|
+
/** Secret key for JWT signing (min 32 chars) */
|
|
21
|
+
secret: string;
|
|
22
|
+
}
|
|
23
|
+
/** Result of session validation */
|
|
24
|
+
interface SessionValidation {
|
|
25
|
+
/** Whether the session is valid */
|
|
26
|
+
valid: boolean;
|
|
27
|
+
/** Parsed session data if valid */
|
|
28
|
+
session?: SessionData;
|
|
29
|
+
/** Reason for invalid session */
|
|
30
|
+
reason?: string;
|
|
31
|
+
}
|
|
32
|
+
/** JWT payload structure for sessions */
|
|
33
|
+
interface SessionJWTPayload {
|
|
34
|
+
/** Wallet address (subject) */
|
|
35
|
+
sub: string;
|
|
36
|
+
/** Session ID */
|
|
37
|
+
sid: string;
|
|
38
|
+
/** Unlocked article IDs */
|
|
39
|
+
articles: string[];
|
|
40
|
+
/** Site-wide unlock flag */
|
|
41
|
+
siteWide: boolean;
|
|
42
|
+
/** Issued at timestamp */
|
|
43
|
+
iat: number;
|
|
44
|
+
/** Expiration timestamp */
|
|
45
|
+
exp: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create a new session after successful payment
|
|
50
|
+
*/
|
|
51
|
+
declare function createSession(walletAddress: string, articleId: string, config: SessionConfig, siteWide?: boolean): Promise<{
|
|
52
|
+
token: string;
|
|
53
|
+
session: SessionData;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Validate an existing session token
|
|
57
|
+
*/
|
|
58
|
+
declare function validateSession(token: string, secret: string): Promise<SessionValidation>;
|
|
59
|
+
/**
|
|
60
|
+
* Add an article to an existing session
|
|
61
|
+
*/
|
|
62
|
+
declare function addArticleToSession(token: string, articleId: string, secret: string): Promise<{
|
|
63
|
+
token: string;
|
|
64
|
+
session: SessionData;
|
|
65
|
+
} | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Check if an article is unlocked for a session
|
|
68
|
+
*/
|
|
69
|
+
declare function isArticleUnlocked(token: string, articleId: string, secret: string): Promise<boolean>;
|
|
70
|
+
|
|
71
|
+
export { type SessionData as S, type SessionConfig as a, type SessionValidation as b, type SessionJWTPayload as c, createSession as d, addArticleToSession as e, isArticleUnlocked as i, validateSession as v };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Session data stored in JWT */
|
|
2
|
+
interface SessionData {
|
|
3
|
+
/** Unique session ID */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Wallet address that paid */
|
|
6
|
+
walletAddress: string;
|
|
7
|
+
/** Array of unlocked article IDs */
|
|
8
|
+
unlockedArticles: string[];
|
|
9
|
+
/** Whether site-wide access is granted */
|
|
10
|
+
siteWideUnlock: boolean;
|
|
11
|
+
/** Unix timestamp of creation */
|
|
12
|
+
createdAt: number;
|
|
13
|
+
/** Unix timestamp of expiration */
|
|
14
|
+
expiresAt: number;
|
|
15
|
+
}
|
|
16
|
+
/** Session configuration options */
|
|
17
|
+
interface SessionConfig {
|
|
18
|
+
/** Session duration in hours */
|
|
19
|
+
durationHours: number;
|
|
20
|
+
/** Secret key for JWT signing (min 32 chars) */
|
|
21
|
+
secret: string;
|
|
22
|
+
}
|
|
23
|
+
/** Result of session validation */
|
|
24
|
+
interface SessionValidation {
|
|
25
|
+
/** Whether the session is valid */
|
|
26
|
+
valid: boolean;
|
|
27
|
+
/** Parsed session data if valid */
|
|
28
|
+
session?: SessionData;
|
|
29
|
+
/** Reason for invalid session */
|
|
30
|
+
reason?: string;
|
|
31
|
+
}
|
|
32
|
+
/** JWT payload structure for sessions */
|
|
33
|
+
interface SessionJWTPayload {
|
|
34
|
+
/** Wallet address (subject) */
|
|
35
|
+
sub: string;
|
|
36
|
+
/** Session ID */
|
|
37
|
+
sid: string;
|
|
38
|
+
/** Unlocked article IDs */
|
|
39
|
+
articles: string[];
|
|
40
|
+
/** Site-wide unlock flag */
|
|
41
|
+
siteWide: boolean;
|
|
42
|
+
/** Issued at timestamp */
|
|
43
|
+
iat: number;
|
|
44
|
+
/** Expiration timestamp */
|
|
45
|
+
exp: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create a new session after successful payment
|
|
50
|
+
*/
|
|
51
|
+
declare function createSession(walletAddress: string, articleId: string, config: SessionConfig, siteWide?: boolean): Promise<{
|
|
52
|
+
token: string;
|
|
53
|
+
session: SessionData;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Validate an existing session token
|
|
57
|
+
*/
|
|
58
|
+
declare function validateSession(token: string, secret: string): Promise<SessionValidation>;
|
|
59
|
+
/**
|
|
60
|
+
* Add an article to an existing session
|
|
61
|
+
*/
|
|
62
|
+
declare function addArticleToSession(token: string, articleId: string, secret: string): Promise<{
|
|
63
|
+
token: string;
|
|
64
|
+
session: SessionData;
|
|
65
|
+
} | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Check if an article is unlocked for a session
|
|
68
|
+
*/
|
|
69
|
+
declare function isArticleUnlocked(token: string, articleId: string, secret: string): Promise<boolean>;
|
|
70
|
+
|
|
71
|
+
export { type SessionData as S, type SessionConfig as a, type SessionValidation as b, type SessionJWTPayload as c, createSession as d, addArticleToSession as e, isArticleUnlocked as i, validateSession as v };
|