@alleyboss/micropay-solana-x402-paywall 1.0.1 → 2.0.1

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 (62) 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 +696 -15
  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 +674 -16
  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 +142 -0
  29. package/dist/pricing/index.cjs.map +1 -0
  30. package/dist/pricing/index.d.cts +111 -0
  31. package/dist/pricing/index.d.ts +111 -0
  32. package/dist/pricing/index.js +133 -0
  33. package/dist/pricing/index.js.map +1 -0
  34. package/dist/session/index.d.cts +29 -1
  35. package/dist/session/index.d.ts +29 -1
  36. package/dist/{index-uxMb72hH.d.cts → session-D2IoWAWV.d.cts} +1 -27
  37. package/dist/{index-uxMb72hH.d.ts → session-D2IoWAWV.d.ts} +1 -27
  38. package/dist/solana/index.cjs +193 -0
  39. package/dist/solana/index.cjs.map +1 -1
  40. package/dist/solana/index.d.cts +60 -3
  41. package/dist/solana/index.d.ts +60 -3
  42. package/dist/solana/index.js +190 -1
  43. package/dist/solana/index.js.map +1 -1
  44. package/dist/store/index.cjs +99 -0
  45. package/dist/store/index.cjs.map +1 -0
  46. package/dist/store/index.d.cts +38 -0
  47. package/dist/store/index.d.ts +38 -0
  48. package/dist/store/index.js +96 -0
  49. package/dist/store/index.js.map +1 -0
  50. package/dist/utils/index.cjs +68 -0
  51. package/dist/utils/index.cjs.map +1 -0
  52. package/dist/utils/index.d.cts +30 -0
  53. package/dist/utils/index.d.ts +30 -0
  54. package/dist/utils/index.js +65 -0
  55. package/dist/utils/index.js.map +1 -0
  56. package/dist/x402/index.cjs +2 -1
  57. package/dist/x402/index.cjs.map +1 -1
  58. package/dist/x402/index.d.cts +2 -1
  59. package/dist/x402/index.d.ts +2 -1
  60. package/dist/x402/index.js +2 -1
  61. package/dist/x402/index.js.map +1 -1
  62. package/package.json +56 -3
@@ -0,0 +1,142 @@
1
+ 'use strict';
2
+
3
+ // src/pricing/index.ts
4
+ var cachedPrice = null;
5
+ var config = {};
6
+ var lastProviderIndex = -1;
7
+ function configurePricing(newConfig) {
8
+ config = { ...config, ...newConfig };
9
+ cachedPrice = null;
10
+ }
11
+ var PROVIDERS = [
12
+ {
13
+ name: "coincap",
14
+ url: "https://api.coincap.io/v2/assets/solana",
15
+ parse: (data) => parseFloat(data.data?.priceUsd || "0")
16
+ },
17
+ {
18
+ name: "binance",
19
+ url: "https://api.binance.com/api/v3/ticker/price?symbol=SOLUSDT",
20
+ parse: (data) => parseFloat(data.price || "0")
21
+ },
22
+ {
23
+ name: "coingecko",
24
+ url: "https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd",
25
+ parse: (data) => data.solana?.usd || 0
26
+ },
27
+ {
28
+ name: "kraken",
29
+ url: "https://api.kraken.com/0/public/Ticker?pair=SOLUSD",
30
+ parse: (data) => parseFloat(data.result?.SOLUSD?.c?.[0] || "0")
31
+ }
32
+ ];
33
+ async function fetchFromProvider(provider, timeout) {
34
+ const controller = new AbortController();
35
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
36
+ try {
37
+ const response = await fetch(provider.url, {
38
+ headers: { "Accept": "application/json" },
39
+ signal: controller.signal
40
+ });
41
+ if (!response.ok) {
42
+ throw new Error(`HTTP ${response.status}`);
43
+ }
44
+ const data = await response.json();
45
+ const price = provider.parse(data);
46
+ if (!price || price <= 0) {
47
+ throw new Error("Invalid price");
48
+ }
49
+ return price;
50
+ } finally {
51
+ clearTimeout(timeoutId);
52
+ }
53
+ }
54
+ async function getSolPrice() {
55
+ const cacheTTL = config.cacheTTL ?? 6e4;
56
+ const timeout = config.timeout ?? 5e3;
57
+ if (cachedPrice && Date.now() - cachedPrice.fetchedAt.getTime() < cacheTTL) {
58
+ return cachedPrice;
59
+ }
60
+ if (config.customProvider) {
61
+ try {
62
+ const price = await config.customProvider();
63
+ if (price > 0) {
64
+ cachedPrice = {
65
+ solPrice: price,
66
+ fetchedAt: /* @__PURE__ */ new Date(),
67
+ source: "custom"
68
+ };
69
+ return cachedPrice;
70
+ }
71
+ } catch {
72
+ }
73
+ }
74
+ for (let i = 0; i < PROVIDERS.length; i++) {
75
+ const idx = (lastProviderIndex + 1 + i) % PROVIDERS.length;
76
+ const provider = PROVIDERS[idx];
77
+ try {
78
+ const price = await fetchFromProvider(provider, timeout);
79
+ lastProviderIndex = idx;
80
+ cachedPrice = {
81
+ solPrice: price,
82
+ fetchedAt: /* @__PURE__ */ new Date(),
83
+ source: provider.name
84
+ };
85
+ return cachedPrice;
86
+ } catch {
87
+ continue;
88
+ }
89
+ }
90
+ if (cachedPrice) {
91
+ return cachedPrice;
92
+ }
93
+ return {
94
+ solPrice: 150,
95
+ // Reasonable fallback
96
+ fetchedAt: /* @__PURE__ */ new Date(),
97
+ source: "fallback"
98
+ };
99
+ }
100
+ async function lamportsToUsd(lamports) {
101
+ const { solPrice } = await getSolPrice();
102
+ const sol = Number(lamports) / 1e9;
103
+ return sol * solPrice;
104
+ }
105
+ async function usdToLamports(usd) {
106
+ const { solPrice } = await getSolPrice();
107
+ const sol = usd / solPrice;
108
+ return BigInt(Math.floor(sol * 1e9));
109
+ }
110
+ async function formatPriceDisplay(lamports) {
111
+ const { solPrice } = await getSolPrice();
112
+ const sol = Number(lamports) / 1e9;
113
+ const usd = sol * solPrice;
114
+ return `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`;
115
+ }
116
+ function formatPriceSync(lamports, solPrice) {
117
+ const sol = Number(lamports) / 1e9;
118
+ const usd = sol * solPrice;
119
+ return {
120
+ sol,
121
+ usd,
122
+ formatted: `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`
123
+ };
124
+ }
125
+ function clearPriceCache() {
126
+ cachedPrice = null;
127
+ lastProviderIndex = -1;
128
+ }
129
+ function getProviders() {
130
+ return PROVIDERS.map((p) => ({ name: p.name, url: p.url }));
131
+ }
132
+
133
+ exports.clearPriceCache = clearPriceCache;
134
+ exports.configurePricing = configurePricing;
135
+ exports.formatPriceDisplay = formatPriceDisplay;
136
+ exports.formatPriceSync = formatPriceSync;
137
+ exports.getProviders = getProviders;
138
+ exports.getSolPrice = getSolPrice;
139
+ exports.lamportsToUsd = lamportsToUsd;
140
+ exports.usdToLamports = usdToLamports;
141
+ //# sourceMappingURL=index.cjs.map
142
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pricing/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// Price Conversion Helpers\n// Multi-provider SOL price fetching with fallback rotation\n\n/**\n * Price data from API\n */\nexport interface PriceData {\n /** SOL price in USD */\n solPrice: number;\n /** Timestamp of price fetch */\n fetchedAt: Date;\n /** Source of price data */\n source: string;\n}\n\n/**\n * Custom price provider function type\n */\nexport type CustomPriceProvider = () => Promise<number>;\n\n/**\n * Price provider configuration\n */\nexport interface PriceConfig {\n /** Custom price provider (if set, skips built-in providers) */\n customProvider?: CustomPriceProvider;\n /** Cache TTL in milliseconds (default: 60000) */\n cacheTTL?: number;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n}\n\n// Cached price data\nlet cachedPrice: PriceData | null = null;\nlet config: PriceConfig = {};\nlet lastProviderIndex = -1;\n\n/**\n * Configure price fetching\n * \n * @example\n * ```typescript\n * // Use custom API\n * configurePricing({\n * customProvider: async () => {\n * const res = await fetch('https://my-api.com/sol-price');\n * return (await res.json()).price;\n * },\n * });\n * \n * // Or just adjust cache TTL\n * configurePricing({ cacheTTL: 30000 }); // 30 seconds\n * ```\n */\nexport function configurePricing(newConfig: PriceConfig): void {\n config = { ...config, ...newConfig };\n cachedPrice = null; // Clear cache on config change\n}\n\n/**\n * Built-in price providers with reliability rotation\n */\nconst PROVIDERS = [\n {\n name: 'coincap',\n url: 'https://api.coincap.io/v2/assets/solana',\n parse: (data: { data?: { priceUsd?: string } }) => parseFloat(data.data?.priceUsd || '0'),\n },\n {\n name: 'binance',\n url: 'https://api.binance.com/api/v3/ticker/price?symbol=SOLUSDT',\n parse: (data: { price?: string }) => parseFloat(data.price || '0'),\n },\n {\n name: 'coingecko',\n url: 'https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd',\n parse: (data: { solana?: { usd?: number } }) => data.solana?.usd || 0,\n },\n {\n name: 'kraken',\n url: 'https://api.kraken.com/0/public/Ticker?pair=SOLUSD',\n parse: (data: { result?: { SOLUSD?: { c?: string[] } } }) =>\n parseFloat(data.result?.SOLUSD?.c?.[0] || '0'),\n },\n];\n\n/**\n * Fetch price from a single provider\n */\nasync function fetchFromProvider(\n provider: typeof PROVIDERS[0],\n timeout: number\n): Promise<number> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(provider.url, {\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const price = provider.parse(data as Parameters<typeof provider.parse>[0]);\n\n if (!price || price <= 0) {\n throw new Error('Invalid price');\n }\n\n return price;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Get SOL price with multi-provider fallback\n * \n * Provider rotation order:\n * 1. CoinCap (primary)\n * 2. Binance (backup #1)\n * 3. CoinGecko (backup #2)\n * 4. Kraken (backup #3)\n * \n * @example\n * ```typescript\n * const { solPrice, source } = await getSolPrice();\n * console.log(`SOL is $${solPrice} (from ${source})`);\n * ```\n */\nexport async function getSolPrice(): Promise<PriceData> {\n const cacheTTL = config.cacheTTL ?? 60000;\n const timeout = config.timeout ?? 5000;\n\n // Return cached price if valid\n if (cachedPrice && Date.now() - cachedPrice.fetchedAt.getTime() < cacheTTL) {\n return cachedPrice;\n }\n\n // Try custom provider first if configured\n if (config.customProvider) {\n try {\n const price = await config.customProvider();\n if (price > 0) {\n cachedPrice = {\n solPrice: price,\n fetchedAt: new Date(),\n source: 'custom',\n };\n return cachedPrice;\n }\n } catch {\n // Fall through to built-in providers\n }\n }\n\n // Try providers in rotation, starting after the last successful one\n for (let i = 0; i < PROVIDERS.length; i++) {\n const idx = (lastProviderIndex + 1 + i) % PROVIDERS.length;\n const provider = PROVIDERS[idx];\n\n try {\n const price = await fetchFromProvider(provider, timeout);\n lastProviderIndex = idx;\n\n cachedPrice = {\n solPrice: price,\n fetchedAt: new Date(),\n source: provider.name,\n };\n return cachedPrice;\n } catch {\n // Try next provider\n continue;\n }\n }\n\n // All providers failed, use stale cache or fallback\n if (cachedPrice) {\n return cachedPrice;\n }\n\n // Last resort fallback\n return {\n solPrice: 150, // Reasonable fallback\n fetchedAt: new Date(),\n source: 'fallback',\n };\n}\n\n/**\n * Convert lamports to USD\n * \n * @example\n * ```typescript\n * const usd = await lamportsToUsd(10_000_000n); // 0.01 SOL\n * console.log(`$${usd.toFixed(2)}`);\n * ```\n */\nexport async function lamportsToUsd(lamports: bigint): Promise<number> {\n const { solPrice } = await getSolPrice();\n const sol = Number(lamports) / 1_000_000_000;\n return sol * solPrice;\n}\n\n/**\n * Convert USD to lamports\n * \n * @example\n * ```typescript\n * const lamports = await usdToLamports(1.50); // $1.50\n * console.log(`${lamports} lamports`);\n * ```\n */\nexport async function usdToLamports(usd: number): Promise<bigint> {\n const { solPrice } = await getSolPrice();\n const sol = usd / solPrice;\n return BigInt(Math.floor(sol * 1_000_000_000));\n}\n\n/**\n * Format a price for display with both SOL and USD\n * \n * @example\n * ```typescript\n * const display = await formatPriceDisplay(10_000_000n);\n * // Returns: \"0.0100 SOL (~$1.50)\"\n * ```\n */\nexport async function formatPriceDisplay(lamports: bigint): Promise<string> {\n const { solPrice } = await getSolPrice();\n const sol = Number(lamports) / 1_000_000_000;\n const usd = sol * solPrice;\n\n return `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`;\n}\n\n/**\n * Synchronous price formatting (requires pre-fetched price)\n */\nexport function formatPriceSync(lamports: bigint, solPrice: number): {\n sol: number;\n usd: number;\n formatted: string;\n} {\n const sol = Number(lamports) / 1_000_000_000;\n const usd = sol * solPrice;\n\n return {\n sol,\n usd,\n formatted: `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`,\n };\n}\n\n/**\n * Clear the price cache (for testing or manual refresh)\n */\nexport function clearPriceCache(): void {\n cachedPrice = null;\n lastProviderIndex = -1;\n}\n\n/**\n * Get list of available built-in providers\n */\nexport function getProviders(): { name: string; url: string }[] {\n return PROVIDERS.map(p => ({ name: p.name, url: p.url }));\n}\n"]}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Price data from API
3
+ */
4
+ interface PriceData {
5
+ /** SOL price in USD */
6
+ solPrice: number;
7
+ /** Timestamp of price fetch */
8
+ fetchedAt: Date;
9
+ /** Source of price data */
10
+ source: string;
11
+ }
12
+ /**
13
+ * Custom price provider function type
14
+ */
15
+ type CustomPriceProvider = () => Promise<number>;
16
+ /**
17
+ * Price provider configuration
18
+ */
19
+ interface PriceConfig {
20
+ /** Custom price provider (if set, skips built-in providers) */
21
+ customProvider?: CustomPriceProvider;
22
+ /** Cache TTL in milliseconds (default: 60000) */
23
+ cacheTTL?: number;
24
+ /** Request timeout in milliseconds (default: 5000) */
25
+ timeout?: number;
26
+ }
27
+ /**
28
+ * Configure price fetching
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Use custom API
33
+ * configurePricing({
34
+ * customProvider: async () => {
35
+ * const res = await fetch('https://my-api.com/sol-price');
36
+ * return (await res.json()).price;
37
+ * },
38
+ * });
39
+ *
40
+ * // Or just adjust cache TTL
41
+ * configurePricing({ cacheTTL: 30000 }); // 30 seconds
42
+ * ```
43
+ */
44
+ declare function configurePricing(newConfig: PriceConfig): void;
45
+ /**
46
+ * Get SOL price with multi-provider fallback
47
+ *
48
+ * Provider rotation order:
49
+ * 1. CoinCap (primary)
50
+ * 2. Binance (backup #1)
51
+ * 3. CoinGecko (backup #2)
52
+ * 4. Kraken (backup #3)
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const { solPrice, source } = await getSolPrice();
57
+ * console.log(`SOL is $${solPrice} (from ${source})`);
58
+ * ```
59
+ */
60
+ declare function getSolPrice(): Promise<PriceData>;
61
+ /**
62
+ * Convert lamports to USD
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const usd = await lamportsToUsd(10_000_000n); // 0.01 SOL
67
+ * console.log(`$${usd.toFixed(2)}`);
68
+ * ```
69
+ */
70
+ declare function lamportsToUsd(lamports: bigint): Promise<number>;
71
+ /**
72
+ * Convert USD to lamports
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const lamports = await usdToLamports(1.50); // $1.50
77
+ * console.log(`${lamports} lamports`);
78
+ * ```
79
+ */
80
+ declare function usdToLamports(usd: number): Promise<bigint>;
81
+ /**
82
+ * Format a price for display with both SOL and USD
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const display = await formatPriceDisplay(10_000_000n);
87
+ * // Returns: "0.0100 SOL (~$1.50)"
88
+ * ```
89
+ */
90
+ declare function formatPriceDisplay(lamports: bigint): Promise<string>;
91
+ /**
92
+ * Synchronous price formatting (requires pre-fetched price)
93
+ */
94
+ declare function formatPriceSync(lamports: bigint, solPrice: number): {
95
+ sol: number;
96
+ usd: number;
97
+ formatted: string;
98
+ };
99
+ /**
100
+ * Clear the price cache (for testing or manual refresh)
101
+ */
102
+ declare function clearPriceCache(): void;
103
+ /**
104
+ * Get list of available built-in providers
105
+ */
106
+ declare function getProviders(): {
107
+ name: string;
108
+ url: string;
109
+ }[];
110
+
111
+ export { type CustomPriceProvider, type PriceConfig, type PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports };
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Price data from API
3
+ */
4
+ interface PriceData {
5
+ /** SOL price in USD */
6
+ solPrice: number;
7
+ /** Timestamp of price fetch */
8
+ fetchedAt: Date;
9
+ /** Source of price data */
10
+ source: string;
11
+ }
12
+ /**
13
+ * Custom price provider function type
14
+ */
15
+ type CustomPriceProvider = () => Promise<number>;
16
+ /**
17
+ * Price provider configuration
18
+ */
19
+ interface PriceConfig {
20
+ /** Custom price provider (if set, skips built-in providers) */
21
+ customProvider?: CustomPriceProvider;
22
+ /** Cache TTL in milliseconds (default: 60000) */
23
+ cacheTTL?: number;
24
+ /** Request timeout in milliseconds (default: 5000) */
25
+ timeout?: number;
26
+ }
27
+ /**
28
+ * Configure price fetching
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Use custom API
33
+ * configurePricing({
34
+ * customProvider: async () => {
35
+ * const res = await fetch('https://my-api.com/sol-price');
36
+ * return (await res.json()).price;
37
+ * },
38
+ * });
39
+ *
40
+ * // Or just adjust cache TTL
41
+ * configurePricing({ cacheTTL: 30000 }); // 30 seconds
42
+ * ```
43
+ */
44
+ declare function configurePricing(newConfig: PriceConfig): void;
45
+ /**
46
+ * Get SOL price with multi-provider fallback
47
+ *
48
+ * Provider rotation order:
49
+ * 1. CoinCap (primary)
50
+ * 2. Binance (backup #1)
51
+ * 3. CoinGecko (backup #2)
52
+ * 4. Kraken (backup #3)
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const { solPrice, source } = await getSolPrice();
57
+ * console.log(`SOL is $${solPrice} (from ${source})`);
58
+ * ```
59
+ */
60
+ declare function getSolPrice(): Promise<PriceData>;
61
+ /**
62
+ * Convert lamports to USD
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const usd = await lamportsToUsd(10_000_000n); // 0.01 SOL
67
+ * console.log(`$${usd.toFixed(2)}`);
68
+ * ```
69
+ */
70
+ declare function lamportsToUsd(lamports: bigint): Promise<number>;
71
+ /**
72
+ * Convert USD to lamports
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const lamports = await usdToLamports(1.50); // $1.50
77
+ * console.log(`${lamports} lamports`);
78
+ * ```
79
+ */
80
+ declare function usdToLamports(usd: number): Promise<bigint>;
81
+ /**
82
+ * Format a price for display with both SOL and USD
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const display = await formatPriceDisplay(10_000_000n);
87
+ * // Returns: "0.0100 SOL (~$1.50)"
88
+ * ```
89
+ */
90
+ declare function formatPriceDisplay(lamports: bigint): Promise<string>;
91
+ /**
92
+ * Synchronous price formatting (requires pre-fetched price)
93
+ */
94
+ declare function formatPriceSync(lamports: bigint, solPrice: number): {
95
+ sol: number;
96
+ usd: number;
97
+ formatted: string;
98
+ };
99
+ /**
100
+ * Clear the price cache (for testing or manual refresh)
101
+ */
102
+ declare function clearPriceCache(): void;
103
+ /**
104
+ * Get list of available built-in providers
105
+ */
106
+ declare function getProviders(): {
107
+ name: string;
108
+ url: string;
109
+ }[];
110
+
111
+ export { type CustomPriceProvider, type PriceConfig, type PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports };
@@ -0,0 +1,133 @@
1
+ // src/pricing/index.ts
2
+ var cachedPrice = null;
3
+ var config = {};
4
+ var lastProviderIndex = -1;
5
+ function configurePricing(newConfig) {
6
+ config = { ...config, ...newConfig };
7
+ cachedPrice = null;
8
+ }
9
+ var PROVIDERS = [
10
+ {
11
+ name: "coincap",
12
+ url: "https://api.coincap.io/v2/assets/solana",
13
+ parse: (data) => parseFloat(data.data?.priceUsd || "0")
14
+ },
15
+ {
16
+ name: "binance",
17
+ url: "https://api.binance.com/api/v3/ticker/price?symbol=SOLUSDT",
18
+ parse: (data) => parseFloat(data.price || "0")
19
+ },
20
+ {
21
+ name: "coingecko",
22
+ url: "https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd",
23
+ parse: (data) => data.solana?.usd || 0
24
+ },
25
+ {
26
+ name: "kraken",
27
+ url: "https://api.kraken.com/0/public/Ticker?pair=SOLUSD",
28
+ parse: (data) => parseFloat(data.result?.SOLUSD?.c?.[0] || "0")
29
+ }
30
+ ];
31
+ async function fetchFromProvider(provider, timeout) {
32
+ const controller = new AbortController();
33
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
34
+ try {
35
+ const response = await fetch(provider.url, {
36
+ headers: { "Accept": "application/json" },
37
+ signal: controller.signal
38
+ });
39
+ if (!response.ok) {
40
+ throw new Error(`HTTP ${response.status}`);
41
+ }
42
+ const data = await response.json();
43
+ const price = provider.parse(data);
44
+ if (!price || price <= 0) {
45
+ throw new Error("Invalid price");
46
+ }
47
+ return price;
48
+ } finally {
49
+ clearTimeout(timeoutId);
50
+ }
51
+ }
52
+ async function getSolPrice() {
53
+ const cacheTTL = config.cacheTTL ?? 6e4;
54
+ const timeout = config.timeout ?? 5e3;
55
+ if (cachedPrice && Date.now() - cachedPrice.fetchedAt.getTime() < cacheTTL) {
56
+ return cachedPrice;
57
+ }
58
+ if (config.customProvider) {
59
+ try {
60
+ const price = await config.customProvider();
61
+ if (price > 0) {
62
+ cachedPrice = {
63
+ solPrice: price,
64
+ fetchedAt: /* @__PURE__ */ new Date(),
65
+ source: "custom"
66
+ };
67
+ return cachedPrice;
68
+ }
69
+ } catch {
70
+ }
71
+ }
72
+ for (let i = 0; i < PROVIDERS.length; i++) {
73
+ const idx = (lastProviderIndex + 1 + i) % PROVIDERS.length;
74
+ const provider = PROVIDERS[idx];
75
+ try {
76
+ const price = await fetchFromProvider(provider, timeout);
77
+ lastProviderIndex = idx;
78
+ cachedPrice = {
79
+ solPrice: price,
80
+ fetchedAt: /* @__PURE__ */ new Date(),
81
+ source: provider.name
82
+ };
83
+ return cachedPrice;
84
+ } catch {
85
+ continue;
86
+ }
87
+ }
88
+ if (cachedPrice) {
89
+ return cachedPrice;
90
+ }
91
+ return {
92
+ solPrice: 150,
93
+ // Reasonable fallback
94
+ fetchedAt: /* @__PURE__ */ new Date(),
95
+ source: "fallback"
96
+ };
97
+ }
98
+ async function lamportsToUsd(lamports) {
99
+ const { solPrice } = await getSolPrice();
100
+ const sol = Number(lamports) / 1e9;
101
+ return sol * solPrice;
102
+ }
103
+ async function usdToLamports(usd) {
104
+ const { solPrice } = await getSolPrice();
105
+ const sol = usd / solPrice;
106
+ return BigInt(Math.floor(sol * 1e9));
107
+ }
108
+ async function formatPriceDisplay(lamports) {
109
+ const { solPrice } = await getSolPrice();
110
+ const sol = Number(lamports) / 1e9;
111
+ const usd = sol * solPrice;
112
+ return `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`;
113
+ }
114
+ function formatPriceSync(lamports, solPrice) {
115
+ const sol = Number(lamports) / 1e9;
116
+ const usd = sol * solPrice;
117
+ return {
118
+ sol,
119
+ usd,
120
+ formatted: `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`
121
+ };
122
+ }
123
+ function clearPriceCache() {
124
+ cachedPrice = null;
125
+ lastProviderIndex = -1;
126
+ }
127
+ function getProviders() {
128
+ return PROVIDERS.map((p) => ({ name: p.name, url: p.url }));
129
+ }
130
+
131
+ export { clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports };
132
+ //# sourceMappingURL=index.js.map
133
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pricing/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Price Conversion Helpers\n// Multi-provider SOL price fetching with fallback rotation\n\n/**\n * Price data from API\n */\nexport interface PriceData {\n /** SOL price in USD */\n solPrice: number;\n /** Timestamp of price fetch */\n fetchedAt: Date;\n /** Source of price data */\n source: string;\n}\n\n/**\n * Custom price provider function type\n */\nexport type CustomPriceProvider = () => Promise<number>;\n\n/**\n * Price provider configuration\n */\nexport interface PriceConfig {\n /** Custom price provider (if set, skips built-in providers) */\n customProvider?: CustomPriceProvider;\n /** Cache TTL in milliseconds (default: 60000) */\n cacheTTL?: number;\n /** Request timeout in milliseconds (default: 5000) */\n timeout?: number;\n}\n\n// Cached price data\nlet cachedPrice: PriceData | null = null;\nlet config: PriceConfig = {};\nlet lastProviderIndex = -1;\n\n/**\n * Configure price fetching\n * \n * @example\n * ```typescript\n * // Use custom API\n * configurePricing({\n * customProvider: async () => {\n * const res = await fetch('https://my-api.com/sol-price');\n * return (await res.json()).price;\n * },\n * });\n * \n * // Or just adjust cache TTL\n * configurePricing({ cacheTTL: 30000 }); // 30 seconds\n * ```\n */\nexport function configurePricing(newConfig: PriceConfig): void {\n config = { ...config, ...newConfig };\n cachedPrice = null; // Clear cache on config change\n}\n\n/**\n * Built-in price providers with reliability rotation\n */\nconst PROVIDERS = [\n {\n name: 'coincap',\n url: 'https://api.coincap.io/v2/assets/solana',\n parse: (data: { data?: { priceUsd?: string } }) => parseFloat(data.data?.priceUsd || '0'),\n },\n {\n name: 'binance',\n url: 'https://api.binance.com/api/v3/ticker/price?symbol=SOLUSDT',\n parse: (data: { price?: string }) => parseFloat(data.price || '0'),\n },\n {\n name: 'coingecko',\n url: 'https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd',\n parse: (data: { solana?: { usd?: number } }) => data.solana?.usd || 0,\n },\n {\n name: 'kraken',\n url: 'https://api.kraken.com/0/public/Ticker?pair=SOLUSD',\n parse: (data: { result?: { SOLUSD?: { c?: string[] } } }) =>\n parseFloat(data.result?.SOLUSD?.c?.[0] || '0'),\n },\n];\n\n/**\n * Fetch price from a single provider\n */\nasync function fetchFromProvider(\n provider: typeof PROVIDERS[0],\n timeout: number\n): Promise<number> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(provider.url, {\n headers: { 'Accept': 'application/json' },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as Record<string, unknown>;\n const price = provider.parse(data as Parameters<typeof provider.parse>[0]);\n\n if (!price || price <= 0) {\n throw new Error('Invalid price');\n }\n\n return price;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Get SOL price with multi-provider fallback\n * \n * Provider rotation order:\n * 1. CoinCap (primary)\n * 2. Binance (backup #1)\n * 3. CoinGecko (backup #2)\n * 4. Kraken (backup #3)\n * \n * @example\n * ```typescript\n * const { solPrice, source } = await getSolPrice();\n * console.log(`SOL is $${solPrice} (from ${source})`);\n * ```\n */\nexport async function getSolPrice(): Promise<PriceData> {\n const cacheTTL = config.cacheTTL ?? 60000;\n const timeout = config.timeout ?? 5000;\n\n // Return cached price if valid\n if (cachedPrice && Date.now() - cachedPrice.fetchedAt.getTime() < cacheTTL) {\n return cachedPrice;\n }\n\n // Try custom provider first if configured\n if (config.customProvider) {\n try {\n const price = await config.customProvider();\n if (price > 0) {\n cachedPrice = {\n solPrice: price,\n fetchedAt: new Date(),\n source: 'custom',\n };\n return cachedPrice;\n }\n } catch {\n // Fall through to built-in providers\n }\n }\n\n // Try providers in rotation, starting after the last successful one\n for (let i = 0; i < PROVIDERS.length; i++) {\n const idx = (lastProviderIndex + 1 + i) % PROVIDERS.length;\n const provider = PROVIDERS[idx];\n\n try {\n const price = await fetchFromProvider(provider, timeout);\n lastProviderIndex = idx;\n\n cachedPrice = {\n solPrice: price,\n fetchedAt: new Date(),\n source: provider.name,\n };\n return cachedPrice;\n } catch {\n // Try next provider\n continue;\n }\n }\n\n // All providers failed, use stale cache or fallback\n if (cachedPrice) {\n return cachedPrice;\n }\n\n // Last resort fallback\n return {\n solPrice: 150, // Reasonable fallback\n fetchedAt: new Date(),\n source: 'fallback',\n };\n}\n\n/**\n * Convert lamports to USD\n * \n * @example\n * ```typescript\n * const usd = await lamportsToUsd(10_000_000n); // 0.01 SOL\n * console.log(`$${usd.toFixed(2)}`);\n * ```\n */\nexport async function lamportsToUsd(lamports: bigint): Promise<number> {\n const { solPrice } = await getSolPrice();\n const sol = Number(lamports) / 1_000_000_000;\n return sol * solPrice;\n}\n\n/**\n * Convert USD to lamports\n * \n * @example\n * ```typescript\n * const lamports = await usdToLamports(1.50); // $1.50\n * console.log(`${lamports} lamports`);\n * ```\n */\nexport async function usdToLamports(usd: number): Promise<bigint> {\n const { solPrice } = await getSolPrice();\n const sol = usd / solPrice;\n return BigInt(Math.floor(sol * 1_000_000_000));\n}\n\n/**\n * Format a price for display with both SOL and USD\n * \n * @example\n * ```typescript\n * const display = await formatPriceDisplay(10_000_000n);\n * // Returns: \"0.0100 SOL (~$1.50)\"\n * ```\n */\nexport async function formatPriceDisplay(lamports: bigint): Promise<string> {\n const { solPrice } = await getSolPrice();\n const sol = Number(lamports) / 1_000_000_000;\n const usd = sol * solPrice;\n\n return `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`;\n}\n\n/**\n * Synchronous price formatting (requires pre-fetched price)\n */\nexport function formatPriceSync(lamports: bigint, solPrice: number): {\n sol: number;\n usd: number;\n formatted: string;\n} {\n const sol = Number(lamports) / 1_000_000_000;\n const usd = sol * solPrice;\n\n return {\n sol,\n usd,\n formatted: `${sol.toFixed(4)} SOL (~$${usd.toFixed(2)})`,\n };\n}\n\n/**\n * Clear the price cache (for testing or manual refresh)\n */\nexport function clearPriceCache(): void {\n cachedPrice = null;\n lastProviderIndex = -1;\n}\n\n/**\n * Get list of available built-in providers\n */\nexport function getProviders(): { name: string; url: string }[] {\n return PROVIDERS.map(p => ({ name: p.name, url: p.url }));\n}\n"]}
@@ -1 +1,29 @@
1
- export { e as addArticleToSession, d as createSession, i as isArticleUnlocked, v as validateSession } from '../index-uxMb72hH.cjs';
1
+ import { a as SessionConfig, S as SessionData, b as SessionValidation } from '../session-D2IoWAWV.cjs';
2
+
3
+ /**
4
+ * Create a new session after successful payment
5
+ * SECURITY: Validates inputs, enforces limits
6
+ */
7
+ declare function createSession(walletAddress: string, articleId: string, config: SessionConfig, siteWide?: boolean): Promise<{
8
+ token: string;
9
+ session: SessionData;
10
+ }>;
11
+ /**
12
+ * Validate an existing session token
13
+ * SECURITY: jose library handles timing-safe comparison internally
14
+ */
15
+ declare function validateSession(token: string, secret: string): Promise<SessionValidation>;
16
+ /**
17
+ * Add an article to an existing session
18
+ * SECURITY: Enforces article limit to prevent token bloat
19
+ */
20
+ declare function addArticleToSession(token: string, articleId: string, secret: string): Promise<{
21
+ token: string;
22
+ session: SessionData;
23
+ } | null>;
24
+ /**
25
+ * Check if an article is unlocked for a session
26
+ */
27
+ declare function isArticleUnlocked(token: string, articleId: string, secret: string): Promise<boolean>;
28
+
29
+ export { addArticleToSession, createSession, isArticleUnlocked, validateSession };
@@ -1 +1,29 @@
1
- export { e as addArticleToSession, d as createSession, i as isArticleUnlocked, v as validateSession } from '../index-uxMb72hH.js';
1
+ import { a as SessionConfig, S as SessionData, b as SessionValidation } from '../session-D2IoWAWV.js';
2
+
3
+ /**
4
+ * Create a new session after successful payment
5
+ * SECURITY: Validates inputs, enforces limits
6
+ */
7
+ declare function createSession(walletAddress: string, articleId: string, config: SessionConfig, siteWide?: boolean): Promise<{
8
+ token: string;
9
+ session: SessionData;
10
+ }>;
11
+ /**
12
+ * Validate an existing session token
13
+ * SECURITY: jose library handles timing-safe comparison internally
14
+ */
15
+ declare function validateSession(token: string, secret: string): Promise<SessionValidation>;
16
+ /**
17
+ * Add an article to an existing session
18
+ * SECURITY: Enforces article limit to prevent token bloat
19
+ */
20
+ declare function addArticleToSession(token: string, articleId: string, secret: string): Promise<{
21
+ token: string;
22
+ session: SessionData;
23
+ } | null>;
24
+ /**
25
+ * Check if an article is unlocked for a session
26
+ */
27
+ declare function isArticleUnlocked(token: string, articleId: string, secret: string): Promise<boolean>;
28
+
29
+ export { addArticleToSession, createSession, isArticleUnlocked, validateSession };
@@ -45,30 +45,4 @@ interface SessionJWTPayload {
45
45
  exp: number;
46
46
  }
47
47
 
48
- /**
49
- * Create a new session after successful payment
50
- * SECURITY: Validates inputs, enforces limits
51
- */
52
- declare function createSession(walletAddress: string, articleId: string, config: SessionConfig, siteWide?: boolean): Promise<{
53
- token: string;
54
- session: SessionData;
55
- }>;
56
- /**
57
- * Validate an existing session token
58
- * SECURITY: jose library handles timing-safe comparison internally
59
- */
60
- declare function validateSession(token: string, secret: string): Promise<SessionValidation>;
61
- /**
62
- * Add an article to an existing session
63
- * SECURITY: Enforces article limit to prevent token bloat
64
- */
65
- declare function addArticleToSession(token: string, articleId: string, secret: string): Promise<{
66
- token: string;
67
- session: SessionData;
68
- } | null>;
69
- /**
70
- * Check if an article is unlocked for a session
71
- */
72
- declare function isArticleUnlocked(token: string, articleId: string, secret: string): Promise<boolean>;
73
-
74
- 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 };
48
+ export type { SessionData as S, SessionConfig as a, SessionValidation as b, SessionJWTPayload as c };
@@ -45,30 +45,4 @@ interface SessionJWTPayload {
45
45
  exp: number;
46
46
  }
47
47
 
48
- /**
49
- * Create a new session after successful payment
50
- * SECURITY: Validates inputs, enforces limits
51
- */
52
- declare function createSession(walletAddress: string, articleId: string, config: SessionConfig, siteWide?: boolean): Promise<{
53
- token: string;
54
- session: SessionData;
55
- }>;
56
- /**
57
- * Validate an existing session token
58
- * SECURITY: jose library handles timing-safe comparison internally
59
- */
60
- declare function validateSession(token: string, secret: string): Promise<SessionValidation>;
61
- /**
62
- * Add an article to an existing session
63
- * SECURITY: Enforces article limit to prevent token bloat
64
- */
65
- declare function addArticleToSession(token: string, articleId: string, secret: string): Promise<{
66
- token: string;
67
- session: SessionData;
68
- } | null>;
69
- /**
70
- * Check if an article is unlocked for a session
71
- */
72
- declare function isArticleUnlocked(token: string, articleId: string, secret: string): Promise<boolean>;
73
-
74
- 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 };
48
+ export type { SessionData as S, SessionConfig as a, SessionValidation as b, SessionJWTPayload as c };