@alleyboss/micropay-solana-x402-paywall 1.0.0 → 2.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.
Files changed (66) hide show
  1. package/README.md +100 -167
  2. package/dist/client/index.cjs +99 -0
  3. package/dist/client/index.cjs.map +1 -0
  4. package/dist/client/index.d.cts +112 -0
  5. package/dist/client/index.d.ts +112 -0
  6. package/dist/client/index.js +95 -0
  7. package/dist/client/index.js.map +1 -0
  8. package/dist/client-CSZHI8o8.d.ts +32 -0
  9. package/dist/client-vRr48m2x.d.cts +32 -0
  10. package/dist/index.cjs +803 -41
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +11 -3
  13. package/dist/index.d.ts +11 -3
  14. package/dist/index.js +783 -42
  15. package/dist/index.js.map +1 -1
  16. package/dist/memory-Daxkczti.d.cts +29 -0
  17. package/dist/memory-Daxkczti.d.ts +29 -0
  18. package/dist/middleware/index.cjs +261 -0
  19. package/dist/middleware/index.cjs.map +1 -0
  20. package/dist/middleware/index.d.cts +90 -0
  21. package/dist/middleware/index.d.ts +90 -0
  22. package/dist/middleware/index.js +255 -0
  23. package/dist/middleware/index.js.map +1 -0
  24. package/dist/nextjs-BK0pVb9Y.d.ts +78 -0
  25. package/dist/nextjs-Bm272Jkj.d.cts +78 -0
  26. package/dist/{client-kfCr7G-P.d.cts → payment-CTxdtqmc.d.cts} +23 -34
  27. package/dist/{client-kfCr7G-P.d.ts → payment-CTxdtqmc.d.ts} +23 -34
  28. package/dist/pricing/index.cjs +79 -0
  29. package/dist/pricing/index.cjs.map +1 -0
  30. package/dist/pricing/index.d.cts +67 -0
  31. package/dist/pricing/index.d.ts +67 -0
  32. package/dist/pricing/index.js +72 -0
  33. package/dist/pricing/index.js.map +1 -0
  34. package/dist/session/index.cjs +51 -11
  35. package/dist/session/index.cjs.map +1 -1
  36. package/dist/session/index.d.cts +29 -1
  37. package/dist/session/index.d.ts +29 -1
  38. package/dist/session/index.js +51 -11
  39. package/dist/session/index.js.map +1 -1
  40. package/dist/{index-DptevtnU.d.cts → session-D2IoWAWV.d.cts} +1 -24
  41. package/dist/{index-DptevtnU.d.ts → session-D2IoWAWV.d.ts} +1 -24
  42. package/dist/solana/index.cjs +235 -15
  43. package/dist/solana/index.cjs.map +1 -1
  44. package/dist/solana/index.d.cts +61 -3
  45. package/dist/solana/index.d.ts +61 -3
  46. package/dist/solana/index.js +232 -16
  47. package/dist/solana/index.js.map +1 -1
  48. package/dist/store/index.cjs +99 -0
  49. package/dist/store/index.cjs.map +1 -0
  50. package/dist/store/index.d.cts +38 -0
  51. package/dist/store/index.d.ts +38 -0
  52. package/dist/store/index.js +96 -0
  53. package/dist/store/index.js.map +1 -0
  54. package/dist/utils/index.cjs +68 -0
  55. package/dist/utils/index.cjs.map +1 -0
  56. package/dist/utils/index.d.cts +30 -0
  57. package/dist/utils/index.d.ts +30 -0
  58. package/dist/utils/index.js +65 -0
  59. package/dist/utils/index.js.map +1 -0
  60. package/dist/x402/index.cjs +119 -18
  61. package/dist/x402/index.cjs.map +1 -1
  62. package/dist/x402/index.d.cts +6 -1
  63. package/dist/x402/index.d.ts +6 -1
  64. package/dist/x402/index.js +119 -18
  65. package/dist/x402/index.js.map +1 -1
  66. package/package.json +56 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @alleyboss/micropay-solana-x402-paywall
2
2
 
3
- > Solana micropayments library implementing the x402 protocol for content paywalls.
3
+ > Production-ready Solana micropayments library implementing the x402 protocol with SPL token support.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@alleyboss/micropay-solana-x402-paywall)](https://www.npmjs.com/package/@alleyboss/micropay-solana-x402-paywall)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
@@ -8,10 +8,12 @@
8
8
  ## Features
9
9
 
10
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
11
+ - ⚡ **Solana Native** — Fast, low-cost SOL & USDC micropayments
12
+ - 🔑 **JWT Sessions** — Secure unlock tracking with anti-replay
13
+ - 📦 **Framework Agnostic** — Express, Next.js, Fastify ready
14
+ - 🌳 **Tree-shakeable** — Import only what you need (35KB full, 1-13KB per module)
15
+ - 💰 **SPL Tokens** — USDC, USDT, and custom token support
16
+ - 🔄 **Retry Logic** — Built-in resilience for RPC failures
15
17
 
16
18
  ## Installation
17
19
 
@@ -21,212 +23,143 @@ npm install @alleyboss/micropay-solana-x402-paywall @solana/web3.js
21
23
 
22
24
  ## Quick Start
23
25
 
24
- ### 1. Verify a Payment
26
+ ### Verify a Payment (SOL or USDC)
25
27
 
26
28
  ```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
- };
29
+ import { verifyPayment, verifySPLPayment } from '@alleyboss/micropay-solana-x402-paywall';
33
30
 
31
+ // SOL payment
34
32
  const result = await verifyPayment({
35
- signature: 'abc123...',
36
- expectedRecipient: 'CreatorWalletAddress',
37
- expectedAmount: BigInt(10000000), // 0.01 SOL
38
- clientConfig,
33
+ signature: 'tx...',
34
+ expectedRecipient: 'CreatorWallet',
35
+ expectedAmount: 10_000_000n, // 0.01 SOL
36
+ clientConfig: { network: 'devnet' },
39
37
  });
40
38
 
41
- if (result.valid) {
42
- console.log('Payment verified!', result.from, 'paid', result.amount);
43
- }
39
+ // USDC payment
40
+ const usdcResult = await verifySPLPayment({
41
+ signature: 'tx...',
42
+ expectedRecipient: 'CreatorWallet',
43
+ expectedAmount: 1_000_000n, // 1 USDC
44
+ asset: 'usdc',
45
+ clientConfig: { network: 'mainnet-beta' },
46
+ });
44
47
  ```
45
48
 
46
- ### 2. Create Session After Payment
49
+ ### Express Middleware (Zero Boilerplate)
47
50
 
48
51
  ```typescript
49
- import { createSession, validateSession } from '@alleyboss/micropay-solana-x402-paywall';
52
+ import express from 'express';
53
+ import { createExpressMiddleware } from '@alleyboss/micropay-solana-x402-paywall/middleware';
50
54
 
51
- const sessionConfig = {
52
- durationHours: 24,
53
- secret: 'your-32-character-minimum-secret-key',
54
- };
55
+ const app = express();
55
56
 
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
- }
57
+ app.use('/api/premium', createExpressMiddleware({
58
+ sessionSecret: process.env.SESSION_SECRET!,
59
+ protectedPaths: ['/**'],
60
+ }));
61
+
62
+ app.get('/api/premium/content', (req, res) => {
63
+ res.json({ content: 'Premium!', wallet: req.session?.walletAddress });
64
+ });
68
65
  ```
69
66
 
70
- ### 3. Build x402 Payment Requirement
67
+ ### Next.js Middleware
71
68
 
72
69
  ```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',
70
+ // middleware.ts
71
+ import { createPaywallMiddleware } from '@alleyboss/micropay-solana-x402-paywall/middleware';
72
+
73
+ export const middleware = createPaywallMiddleware({
74
+ sessionSecret: process.env.SESSION_SECRET!,
75
+ protectedPaths: ['/api/premium/*', '/api/content/*'],
82
76
  });
83
77
 
84
- // Use in HTTP response
85
- const headers = create402Headers(requirement);
78
+ export const config = { matcher: ['/api/premium/:path*'] };
86
79
  ```
87
80
 
88
- ## API Reference
89
-
90
- ### Solana Module
81
+ ### Prevent Signature Replay (Anti-Double-Spend)
91
82
 
92
83
  ```typescript
93
- import {
94
- getConnection,
95
- verifyPayment,
96
- waitForConfirmation,
97
- lamportsToSol,
98
- solToLamports
99
- } from '@alleyboss/micropay-solana-x402-paywall/solana';
100
- ```
84
+ import { createMemoryStore, createRedisStore } from '@alleyboss/micropay-solana-x402-paywall/store';
101
85
 
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 |
86
+ // Development
87
+ const store = createMemoryStore();
109
88
 
110
- ### Session Module
89
+ // Production (with ioredis or node-redis)
90
+ const store = createRedisStore({ client: redisClient });
111
91
 
112
- ```typescript
113
- import {
114
- createSession,
115
- validateSession,
116
- addArticleToSession,
117
- isArticleUnlocked
118
- } from '@alleyboss/micropay-solana-x402-paywall/session';
119
- ```
92
+ // Check before verification
93
+ if (await store.hasBeenUsed(signature)) {
94
+ throw new Error('Payment already used');
95
+ }
120
96
 
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 |
97
+ // Mark after successful verification
98
+ await store.markAsUsed(signature, articleId, new Date(Date.now() + 86400000));
99
+ ```
127
100
 
128
- ### x402 Module
101
+ ### Client-Side Payment Flow
129
102
 
130
103
  ```typescript
131
- import {
132
- buildPaymentRequirement,
133
- verifyX402Payment,
134
- parsePaymentHeader,
135
- X402_HEADERS
136
- } from '@alleyboss/micropay-solana-x402-paywall/x402';
137
- ```
104
+ import { createPaymentFlow, formatPriceDisplay } from '@alleyboss/micropay-solana-x402-paywall';
138
105
 
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 |
106
+ const flow = createPaymentFlow({
107
+ network: 'mainnet-beta',
108
+ recipientWallet: 'CreatorWallet',
109
+ amount: 10_000_000n,
110
+ });
145
111
 
146
- ## Next.js Integration Example
112
+ // Generate QR code for mobile wallets
113
+ const qrUrl = flow.getSolanaPayUrl({ label: 'Unlock Article' });
147
114
 
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
- }
115
+ // Display price with USD equivalent
116
+ const price = await formatPriceDisplay(10_000_000n);
117
+ // "0.0100 SOL (~$1.50)"
213
118
  ```
214
119
 
120
+ ## Module Exports
121
+
122
+ Import only what you need for minimal bundle size:
123
+
124
+ | Import Path | Size | Functions |
125
+ |-------------|------|-----------|
126
+ | `@.../solana` | 13KB | `verifyPayment`, `verifySPLPayment`, `getConnection` |
127
+ | `@.../session` | 4.5KB | `createSession`, `validateSession`, `isArticleUnlocked` |
128
+ | `@.../x402` | 10KB | `buildPaymentRequirement`, `verifyX402Payment` |
129
+ | `@.../middleware` | 8KB | `createExpressMiddleware`, `createPaywallMiddleware` |
130
+ | `@.../store` | 2.6KB | `createMemoryStore`, `createRedisStore` |
131
+ | `@.../client` | 3.3KB | `createPaymentFlow`, `buildSolanaPayUrl` |
132
+ | `@.../pricing` | 2KB | `getSolPrice`, `formatPriceDisplay` |
133
+ | `@.../utils` | 1.7KB | `withRetry`, `isRetryableRPCError` |
134
+
215
135
  ## TypeScript Support
216
136
 
217
- Full TypeScript support with exported types:
137
+ Full TypeScript with exported types:
218
138
 
219
139
  ```typescript
220
140
  import type {
221
141
  PaymentRequirement,
222
- PaymentPayload,
223
- VerificationResponse,
142
+ PaymentAsset,
224
143
  SessionData,
225
- SessionConfig,
226
- SolanaClientConfig,
144
+ SignatureStore,
145
+ PaywallMiddlewareConfig,
227
146
  } from '@alleyboss/micropay-solana-x402-paywall';
228
147
  ```
229
148
 
149
+ ## RPC Configuration
150
+
151
+ Supports multiple RPC providers:
152
+
153
+ ```typescript
154
+ const clientConfig = {
155
+ network: 'mainnet-beta',
156
+ // Option 1: Tatum.io
157
+ tatumApiKey: 'your-api-key',
158
+ // Option 2: Custom RPC (Helius, QuickNode, etc.)
159
+ rpcUrl: 'https://your-rpc-endpoint.com',
160
+ };
161
+ ```
162
+
230
163
  ## License
231
164
 
232
165
  MIT © AlleyBoss
@@ -0,0 +1,99 @@
1
+ 'use strict';
2
+
3
+ // src/types/payment.ts
4
+ var TOKEN_MINTS = {
5
+ /** USDC on mainnet */
6
+ USDC_MAINNET: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
7
+ /** USDC on devnet */
8
+ USDC_DEVNET: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
9
+ /** USDT on mainnet */
10
+ USDT_MAINNET: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
11
+ };
12
+
13
+ // src/client/payment.ts
14
+ function buildSolanaPayUrl(params) {
15
+ const { recipient, amount, splToken, reference, label, message } = params;
16
+ const url = new URL(`solana:${recipient}`);
17
+ if (amount !== void 0) {
18
+ url.searchParams.set("amount", amount.toString());
19
+ }
20
+ if (splToken) {
21
+ url.searchParams.set("spl-token", splToken);
22
+ }
23
+ if (reference) {
24
+ url.searchParams.set("reference", reference);
25
+ }
26
+ if (label) {
27
+ url.searchParams.set("label", label);
28
+ }
29
+ if (message) {
30
+ url.searchParams.set("message", message);
31
+ }
32
+ return url.toString();
33
+ }
34
+ function createPaymentFlow(config) {
35
+ const { network, recipientWallet, amount, asset = "native", memo } = config;
36
+ let decimals = 9;
37
+ let mintAddress;
38
+ if (asset === "usdc") {
39
+ decimals = 6;
40
+ mintAddress = network === "mainnet-beta" ? TOKEN_MINTS.USDC_MAINNET : TOKEN_MINTS.USDC_DEVNET;
41
+ } else if (asset === "usdt") {
42
+ decimals = 6;
43
+ mintAddress = TOKEN_MINTS.USDT_MAINNET;
44
+ } else if (typeof asset === "object" && "mint" in asset) {
45
+ decimals = asset.decimals ?? 6;
46
+ mintAddress = asset.mint;
47
+ }
48
+ const naturalAmount = Number(amount) / Math.pow(10, decimals);
49
+ return {
50
+ /** Get the payment configuration */
51
+ getConfig: () => ({ ...config }),
52
+ /** Get amount in natural display units (e.g., 0.01 SOL) */
53
+ getDisplayAmount: () => naturalAmount,
54
+ /** Get amount formatted with symbol */
55
+ getFormattedAmount: () => {
56
+ const symbol = asset === "native" ? "SOL" : asset === "usdc" ? "USDC" : asset === "usdt" ? "USDT" : "tokens";
57
+ return `${naturalAmount.toFixed(decimals > 6 ? 4 : 2)} ${symbol}`;
58
+ },
59
+ /** Generate Solana Pay URL for QR codes */
60
+ getSolanaPayUrl: (options = {}) => {
61
+ return buildSolanaPayUrl({
62
+ recipient: recipientWallet,
63
+ amount: naturalAmount,
64
+ splToken: mintAddress,
65
+ label: options.label,
66
+ reference: options.reference,
67
+ message: memo
68
+ });
69
+ },
70
+ /** Get the token mint address (undefined for native SOL) */
71
+ getMintAddress: () => mintAddress,
72
+ /** Check if this is a native SOL payment */
73
+ isNativePayment: () => asset === "native",
74
+ /** Get network information */
75
+ getNetworkInfo: () => ({
76
+ network,
77
+ isMainnet: network === "mainnet-beta",
78
+ explorerUrl: network === "mainnet-beta" ? "https://explorer.solana.com" : "https://explorer.solana.com?cluster=devnet"
79
+ }),
80
+ /** Build explorer URL for a transaction */
81
+ getExplorerUrl: (signature) => {
82
+ const baseUrl = "https://explorer.solana.com/tx";
83
+ const cluster = network === "mainnet-beta" ? "" : "?cluster=devnet";
84
+ return `${baseUrl}/${signature}${cluster}`;
85
+ }
86
+ };
87
+ }
88
+ function createPaymentReference() {
89
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
90
+ return crypto.randomUUID();
91
+ }
92
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
93
+ }
94
+
95
+ exports.buildSolanaPayUrl = buildSolanaPayUrl;
96
+ exports.createPaymentFlow = createPaymentFlow;
97
+ exports.createPaymentReference = createPaymentReference;
98
+ //# sourceMappingURL=index.cjs.map
99
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/payment.ts","../../src/client/payment.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// Payment-related TypeScript types for x402 protocol\n\n/** x402 network identifiers for Solana */\nexport type X402Network = 'solana-devnet' | 'solana-mainnet';\n\n/** Solana network types */\nexport type SolanaNetwork = 'devnet' | 'mainnet-beta';\n\n/** SPL Token asset specification */\nexport interface SPLTokenAsset {\n /** Token mint address */\n mint: string;\n /** Token decimals (default: 6 for USDC/USDT) */\n decimals?: number;\n}\n\n/** Asset types for payments */\nexport type PaymentAsset = 'native' | 'usdc' | 'usdt' | SPLTokenAsset;\n\n/** Known SPL token mint addresses */\nexport const TOKEN_MINTS = {\n /** USDC on mainnet */\n USDC_MAINNET: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',\n /** USDC on devnet */\n USDC_DEVNET: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',\n /** USDT on mainnet */\n USDT_MAINNET: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',\n} as const;\n\n/** Payment requirement for x402 protocol */\nexport interface PaymentRequirement {\n /** Payment scheme - currently only 'exact' is supported */\n scheme: 'exact';\n /** Network identifier for x402 */\n network: X402Network;\n /** Amount in smallest unit as string (lamports for SOL, base units for tokens) */\n maxAmountRequired: string;\n /** URL of the protected resource */\n resource: string;\n /** Human-readable description */\n description: string;\n /** MIME type of the resource */\n mimeType?: string;\n /** Recipient wallet address */\n payTo: string;\n /** Maximum time in seconds to complete payment */\n maxTimeoutSeconds: number;\n /** Asset type - 'native' for SOL, 'usdc', 'usdt', or custom mint */\n asset: PaymentAsset;\n /** Additional metadata */\n extra?: {\n name?: string;\n articleId?: string;\n [key: string]: unknown;\n };\n}\n\n/** Payment payload sent by client after transaction */\nexport interface PaymentPayload {\n /** x402 protocol version */\n x402Version: number;\n /** Payment scheme */\n scheme: 'exact';\n /** Network identifier */\n network: X402Network;\n /** Transaction details */\n payload: {\n /** Transaction signature (base58) */\n signature: string;\n /** Base64 encoded transaction (optional) */\n transaction?: string;\n };\n}\n\n/** Request to verify a payment */\nexport interface VerificationRequest {\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirement;\n}\n\n/** Response from payment verification */\nexport interface VerificationResponse {\n /** Whether the payment is valid */\n valid: boolean;\n /** Reason for invalid payment */\n invalidReason?: string;\n /** Whether the transaction is settled on-chain */\n settled?: boolean;\n /** Transaction details */\n transaction?: {\n signature: string;\n blockTime?: number;\n slot?: number;\n };\n}\n\n/** Payment status for tracking */\nexport interface PaymentStatus {\n status: 'pending' | 'confirmed' | 'failed' | 'expired';\n signature?: string;\n confirmations?: number;\n error?: string;\n}\n\n/** x402 HTTP header constants */\nexport const X402_HEADERS = {\n PAYMENT_REQUIRED: 'x-payment-required',\n PAYMENT: 'x-payment',\n PAYMENT_RESPONSE: 'x-payment-response',\n} as const;\n\n/** Configuration for article pricing */\nexport interface ArticlePaymentConfig {\n articleId: string;\n priceInLamports: bigint;\n title: string;\n description?: string;\n}\n","// Client-Side Payment Flow Helper\n// Headless payment flow for frontend integration (no Node.js dependencies)\n\nimport { TOKEN_MINTS, type PaymentAsset, type SolanaNetwork } from '../types';\n\n/**\n * Payment flow configuration\n */\nexport interface PaymentFlowConfig {\n /** Solana network */\n network: SolanaNetwork;\n /** Recipient wallet address */\n recipientWallet: string;\n /** Amount in smallest unit (lamports or token base units) */\n amount: bigint;\n /** Asset to pay with */\n asset?: PaymentAsset;\n /** Optional memo for the transaction */\n memo?: string;\n}\n\n/**\n * Solana Pay URL parameters\n */\nexport interface SolanaPayUrlParams {\n /** Recipient address */\n recipient: string;\n /** Amount in token's natural units (e.g., SOL, not lamports) */\n amount?: number;\n /** SPL token mint address */\n splToken?: string;\n /** Transaction reference */\n reference?: string;\n /** Label for the recipient */\n label?: string;\n /** Memo/message */\n message?: string;\n}\n\n/**\n * Build a Solana Pay URL for QR codes and deep linking\n * Compatible with Phantom, Solflare, and other Solana Pay wallets\n * \n * @example\n * ```typescript\n * const url = buildSolanaPayUrl({\n * recipient: 'CreatorWalletAddress',\n * amount: 0.01,\n * label: 'Article Unlock',\n * message: 'Premium Content Access',\n * });\n * // Returns: solana:CreatorWalletAddress?amount=0.01&label=Article%20Unlock&message=Premium%20Content%20Access\n * ```\n */\nexport function buildSolanaPayUrl(params: SolanaPayUrlParams): string {\n const { recipient, amount, splToken, reference, label, message } = params;\n\n const url = new URL(`solana:${recipient}`);\n\n if (amount !== undefined) {\n url.searchParams.set('amount', amount.toString());\n }\n\n if (splToken) {\n url.searchParams.set('spl-token', splToken);\n }\n\n if (reference) {\n url.searchParams.set('reference', reference);\n }\n\n if (label) {\n url.searchParams.set('label', label);\n }\n\n if (message) {\n url.searchParams.set('message', message);\n }\n\n return url.toString();\n}\n\n/**\n * Create a payment flow helper for frontend use\n * Provides utilities for building transactions and generating QR codes\n * \n * @example\n * ```typescript\n * const flow = createPaymentFlow({\n * network: 'devnet',\n * recipientWallet: 'CreatorAddress',\n * amount: 10000000n, // 0.01 SOL\n * });\n * \n * // Generate QR code URL\n * const qrUrl = flow.getSolanaPayUrl({ label: 'Unlock Article' });\n * \n * // Get transaction amount in natural units\n * const amountInSol = flow.getDisplayAmount();\n * ```\n */\nexport function createPaymentFlow(config: PaymentFlowConfig) {\n const { network, recipientWallet, amount, asset = 'native', memo } = config;\n\n // Determine decimals and mint\n let decimals = 9; // SOL default\n let mintAddress: string | undefined;\n\n if (asset === 'usdc') {\n decimals = 6;\n mintAddress = network === 'mainnet-beta' ? TOKEN_MINTS.USDC_MAINNET : TOKEN_MINTS.USDC_DEVNET;\n } else if (asset === 'usdt') {\n decimals = 6;\n mintAddress = TOKEN_MINTS.USDT_MAINNET;\n } else if (typeof asset === 'object' && 'mint' in asset) {\n decimals = asset.decimals ?? 6;\n mintAddress = asset.mint;\n }\n\n // Convert to natural units (from lamports/base units)\n const naturalAmount = Number(amount) / Math.pow(10, decimals);\n\n return {\n /** Get the payment configuration */\n getConfig: () => ({ ...config }),\n\n /** Get amount in natural display units (e.g., 0.01 SOL) */\n getDisplayAmount: () => naturalAmount,\n\n /** Get amount formatted with symbol */\n getFormattedAmount: () => {\n const symbol = asset === 'native' ? 'SOL'\n : asset === 'usdc' ? 'USDC'\n : asset === 'usdt' ? 'USDT'\n : 'tokens';\n return `${naturalAmount.toFixed(decimals > 6 ? 4 : 2)} ${symbol}`;\n },\n\n /** Generate Solana Pay URL for QR codes */\n getSolanaPayUrl: (options: { label?: string; reference?: string } = {}) => {\n return buildSolanaPayUrl({\n recipient: recipientWallet,\n amount: naturalAmount,\n splToken: mintAddress,\n label: options.label,\n reference: options.reference,\n message: memo,\n });\n },\n\n /** Get the token mint address (undefined for native SOL) */\n getMintAddress: () => mintAddress,\n\n /** Check if this is a native SOL payment */\n isNativePayment: () => asset === 'native',\n\n /** Get network information */\n getNetworkInfo: () => ({\n network,\n isMainnet: network === 'mainnet-beta',\n explorerUrl: network === 'mainnet-beta'\n ? 'https://explorer.solana.com'\n : 'https://explorer.solana.com?cluster=devnet',\n }),\n\n /** Build explorer URL for a transaction */\n getExplorerUrl: (signature: string) => {\n const baseUrl = 'https://explorer.solana.com/tx';\n const cluster = network === 'mainnet-beta' ? '' : '?cluster=devnet';\n return `${baseUrl}/${signature}${cluster}`;\n },\n };\n}\n\n/**\n * Create a unique reference for payment tracking\n * Uses crypto.randomUUID when available\n */\nexport function createPaymentReference(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID\n return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n"]}
@@ -0,0 +1,112 @@
1
+ import { S as SolanaNetwork, d as PaymentAsset } from '../payment-CTxdtqmc.cjs';
2
+
3
+ /**
4
+ * Payment flow configuration
5
+ */
6
+ interface PaymentFlowConfig {
7
+ /** Solana network */
8
+ network: SolanaNetwork;
9
+ /** Recipient wallet address */
10
+ recipientWallet: string;
11
+ /** Amount in smallest unit (lamports or token base units) */
12
+ amount: bigint;
13
+ /** Asset to pay with */
14
+ asset?: PaymentAsset;
15
+ /** Optional memo for the transaction */
16
+ memo?: string;
17
+ }
18
+ /**
19
+ * Solana Pay URL parameters
20
+ */
21
+ interface SolanaPayUrlParams {
22
+ /** Recipient address */
23
+ recipient: string;
24
+ /** Amount in token's natural units (e.g., SOL, not lamports) */
25
+ amount?: number;
26
+ /** SPL token mint address */
27
+ splToken?: string;
28
+ /** Transaction reference */
29
+ reference?: string;
30
+ /** Label for the recipient */
31
+ label?: string;
32
+ /** Memo/message */
33
+ message?: string;
34
+ }
35
+ /**
36
+ * Build a Solana Pay URL for QR codes and deep linking
37
+ * Compatible with Phantom, Solflare, and other Solana Pay wallets
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const url = buildSolanaPayUrl({
42
+ * recipient: 'CreatorWalletAddress',
43
+ * amount: 0.01,
44
+ * label: 'Article Unlock',
45
+ * message: 'Premium Content Access',
46
+ * });
47
+ * // Returns: solana:CreatorWalletAddress?amount=0.01&label=Article%20Unlock&message=Premium%20Content%20Access
48
+ * ```
49
+ */
50
+ declare function buildSolanaPayUrl(params: SolanaPayUrlParams): string;
51
+ /**
52
+ * Create a payment flow helper for frontend use
53
+ * Provides utilities for building transactions and generating QR codes
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const flow = createPaymentFlow({
58
+ * network: 'devnet',
59
+ * recipientWallet: 'CreatorAddress',
60
+ * amount: 10000000n, // 0.01 SOL
61
+ * });
62
+ *
63
+ * // Generate QR code URL
64
+ * const qrUrl = flow.getSolanaPayUrl({ label: 'Unlock Article' });
65
+ *
66
+ * // Get transaction amount in natural units
67
+ * const amountInSol = flow.getDisplayAmount();
68
+ * ```
69
+ */
70
+ declare function createPaymentFlow(config: PaymentFlowConfig): {
71
+ /** Get the payment configuration */
72
+ getConfig: () => {
73
+ /** Solana network */
74
+ network: SolanaNetwork;
75
+ /** Recipient wallet address */
76
+ recipientWallet: string;
77
+ /** Amount in smallest unit (lamports or token base units) */
78
+ amount: bigint;
79
+ /** Asset to pay with */
80
+ asset?: PaymentAsset;
81
+ /** Optional memo for the transaction */
82
+ memo?: string;
83
+ };
84
+ /** Get amount in natural display units (e.g., 0.01 SOL) */
85
+ getDisplayAmount: () => number;
86
+ /** Get amount formatted with symbol */
87
+ getFormattedAmount: () => string;
88
+ /** Generate Solana Pay URL for QR codes */
89
+ getSolanaPayUrl: (options?: {
90
+ label?: string;
91
+ reference?: string;
92
+ }) => string;
93
+ /** Get the token mint address (undefined for native SOL) */
94
+ getMintAddress: () => string | undefined;
95
+ /** Check if this is a native SOL payment */
96
+ isNativePayment: () => boolean;
97
+ /** Get network information */
98
+ getNetworkInfo: () => {
99
+ network: SolanaNetwork;
100
+ isMainnet: boolean;
101
+ explorerUrl: string;
102
+ };
103
+ /** Build explorer URL for a transaction */
104
+ getExplorerUrl: (signature: string) => string;
105
+ };
106
+ /**
107
+ * Create a unique reference for payment tracking
108
+ * Uses crypto.randomUUID when available
109
+ */
110
+ declare function createPaymentReference(): string;
111
+
112
+ export { type PaymentFlowConfig, type SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference };
@@ -0,0 +1,112 @@
1
+ import { S as SolanaNetwork, d as PaymentAsset } from '../payment-CTxdtqmc.js';
2
+
3
+ /**
4
+ * Payment flow configuration
5
+ */
6
+ interface PaymentFlowConfig {
7
+ /** Solana network */
8
+ network: SolanaNetwork;
9
+ /** Recipient wallet address */
10
+ recipientWallet: string;
11
+ /** Amount in smallest unit (lamports or token base units) */
12
+ amount: bigint;
13
+ /** Asset to pay with */
14
+ asset?: PaymentAsset;
15
+ /** Optional memo for the transaction */
16
+ memo?: string;
17
+ }
18
+ /**
19
+ * Solana Pay URL parameters
20
+ */
21
+ interface SolanaPayUrlParams {
22
+ /** Recipient address */
23
+ recipient: string;
24
+ /** Amount in token's natural units (e.g., SOL, not lamports) */
25
+ amount?: number;
26
+ /** SPL token mint address */
27
+ splToken?: string;
28
+ /** Transaction reference */
29
+ reference?: string;
30
+ /** Label for the recipient */
31
+ label?: string;
32
+ /** Memo/message */
33
+ message?: string;
34
+ }
35
+ /**
36
+ * Build a Solana Pay URL for QR codes and deep linking
37
+ * Compatible with Phantom, Solflare, and other Solana Pay wallets
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const url = buildSolanaPayUrl({
42
+ * recipient: 'CreatorWalletAddress',
43
+ * amount: 0.01,
44
+ * label: 'Article Unlock',
45
+ * message: 'Premium Content Access',
46
+ * });
47
+ * // Returns: solana:CreatorWalletAddress?amount=0.01&label=Article%20Unlock&message=Premium%20Content%20Access
48
+ * ```
49
+ */
50
+ declare function buildSolanaPayUrl(params: SolanaPayUrlParams): string;
51
+ /**
52
+ * Create a payment flow helper for frontend use
53
+ * Provides utilities for building transactions and generating QR codes
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const flow = createPaymentFlow({
58
+ * network: 'devnet',
59
+ * recipientWallet: 'CreatorAddress',
60
+ * amount: 10000000n, // 0.01 SOL
61
+ * });
62
+ *
63
+ * // Generate QR code URL
64
+ * const qrUrl = flow.getSolanaPayUrl({ label: 'Unlock Article' });
65
+ *
66
+ * // Get transaction amount in natural units
67
+ * const amountInSol = flow.getDisplayAmount();
68
+ * ```
69
+ */
70
+ declare function createPaymentFlow(config: PaymentFlowConfig): {
71
+ /** Get the payment configuration */
72
+ getConfig: () => {
73
+ /** Solana network */
74
+ network: SolanaNetwork;
75
+ /** Recipient wallet address */
76
+ recipientWallet: string;
77
+ /** Amount in smallest unit (lamports or token base units) */
78
+ amount: bigint;
79
+ /** Asset to pay with */
80
+ asset?: PaymentAsset;
81
+ /** Optional memo for the transaction */
82
+ memo?: string;
83
+ };
84
+ /** Get amount in natural display units (e.g., 0.01 SOL) */
85
+ getDisplayAmount: () => number;
86
+ /** Get amount formatted with symbol */
87
+ getFormattedAmount: () => string;
88
+ /** Generate Solana Pay URL for QR codes */
89
+ getSolanaPayUrl: (options?: {
90
+ label?: string;
91
+ reference?: string;
92
+ }) => string;
93
+ /** Get the token mint address (undefined for native SOL) */
94
+ getMintAddress: () => string | undefined;
95
+ /** Check if this is a native SOL payment */
96
+ isNativePayment: () => boolean;
97
+ /** Get network information */
98
+ getNetworkInfo: () => {
99
+ network: SolanaNetwork;
100
+ isMainnet: boolean;
101
+ explorerUrl: string;
102
+ };
103
+ /** Build explorer URL for a transaction */
104
+ getExplorerUrl: (signature: string) => string;
105
+ };
106
+ /**
107
+ * Create a unique reference for payment tracking
108
+ * Uses crypto.randomUUID when available
109
+ */
110
+ declare function createPaymentReference(): string;
111
+
112
+ export { type PaymentFlowConfig, type SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference };