@alleyboss/micropay-solana-x402-paywall 2.1.2 → 2.3.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/dist/index.d.cts CHANGED
@@ -3,9 +3,9 @@ export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as Sess
3
3
  export { R as RpcConnectionWithFallback, S as SolanaClientConfig, g as getConnection, a as getConnectionWithFallback, i as isMainnet, r as resetConnection, t as toX402Network, w as withFallback } from './client-D-dteoJw.cjs';
4
4
  export { PriorityFeeConfig, SPLVerificationResult, TransactionVerificationResult, VerifyPaymentParams, VerifySPLPaymentParams, VersionedTransactionConfig, VersionedTransactionResult, buildVersionedTransaction, calculatePriorityFeeCost, createPriorityFeeInstructions, estimatePriorityFee, fetchLookupTables, getTokenDecimals, getWalletTransactions, isNativeAsset, isVersionedTransaction, lamportsToSol, resolveMintAddress, solToLamports, verifyPayment, verifySPLPayment, waitForConfirmation } from './solana/index.cjs';
5
5
  export { addArticleToSession, createSession, isArticleUnlocked, validateSession } from './session/index.cjs';
6
- export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.cjs';
6
+ export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402Response, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentRequirement, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.cjs';
7
7
  export { StoreConfig, createRedisStore } from './store/index.cjs';
8
- export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallAccess, c as createPaywallMiddleware, w as withPaywall } from './nextjs-Bm272Jkj.cjs';
8
+ export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallAccess, c as createPaywallMiddleware, w as withPaywall } from './nextjs-BDyOqGAq.cjs';
9
9
  export { RetryOptions, isRetryableRPCError, withRetry } from './utils/index.cjs';
10
10
  export { PaymentFlowConfig, SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference } from './client/index.cjs';
11
11
  export { CustomPriceProvider, PriceConfig, PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports } from './pricing/index.cjs';
package/dist/index.d.ts CHANGED
@@ -3,9 +3,9 @@ export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as Sess
3
3
  export { R as RpcConnectionWithFallback, S as SolanaClientConfig, g as getConnection, a as getConnectionWithFallback, i as isMainnet, r as resetConnection, t as toX402Network, w as withFallback } from './client-DfCIRrNG.js';
4
4
  export { PriorityFeeConfig, SPLVerificationResult, TransactionVerificationResult, VerifyPaymentParams, VerifySPLPaymentParams, VersionedTransactionConfig, VersionedTransactionResult, buildVersionedTransaction, calculatePriorityFeeCost, createPriorityFeeInstructions, estimatePriorityFee, fetchLookupTables, getTokenDecimals, getWalletTransactions, isNativeAsset, isVersionedTransaction, lamportsToSol, resolveMintAddress, solToLamports, verifyPayment, verifySPLPayment, waitForConfirmation } from './solana/index.js';
5
5
  export { addArticleToSession, createSession, isArticleUnlocked, validateSession } from './session/index.js';
6
- export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.js';
6
+ export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402Response, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentRequirement, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.js';
7
7
  export { StoreConfig, createRedisStore } from './store/index.js';
8
- export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallAccess, c as createPaywallMiddleware, w as withPaywall } from './nextjs-BK0pVb9Y.js';
8
+ export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallAccess, c as createPaywallMiddleware, w as withPaywall } from './nextjs-CbX8_9yK.js';
9
9
  export { RetryOptions, isRetryableRPCError, withRetry } from './utils/index.js';
10
10
  export { PaymentFlowConfig, SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference } from './client/index.js';
11
11
  export { CustomPriceProvider, PriceConfig, PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports } from './pricing/index.js';
package/dist/index.js CHANGED
@@ -146,7 +146,8 @@ async function verifyPayment(params) {
146
146
  expectedRecipient,
147
147
  expectedAmount,
148
148
  maxAgeSeconds = 300,
149
- clientConfig
149
+ clientConfig,
150
+ signatureStore
150
151
  } = params;
151
152
  if (!isValidSignature(signature)) {
152
153
  return { valid: false, confirmed: false, signature, error: "Invalid signature format" };
@@ -157,6 +158,12 @@ async function verifyPayment(params) {
157
158
  if (expectedAmount <= 0n) {
158
159
  return { valid: false, confirmed: false, signature, error: "Invalid expected amount" };
159
160
  }
161
+ if (signatureStore) {
162
+ const isUsed = await signatureStore.hasBeenUsed(signature);
163
+ if (isUsed) {
164
+ return { valid: false, confirmed: true, signature, error: "Signature already used" };
165
+ }
166
+ }
160
167
  const effectiveMaxAge = Math.min(Math.max(maxAgeSeconds, 60), 3600);
161
168
  const connection = getConnection(clientConfig);
162
169
  try {
@@ -265,8 +272,6 @@ function solToLamports(sol) {
265
272
  }
266
273
  return BigInt(Math.floor(sol * LAMPORTS_PER_SOL));
267
274
  }
268
-
269
- // src/solana/spl.ts
270
275
  var SIGNATURE_REGEX2 = /^[1-9A-HJ-NP-Za-km-z]{87,88}$/;
271
276
  var WALLET_REGEX2 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
272
277
  function resolveMintAddress(asset, network) {
@@ -360,8 +365,15 @@ async function verifySPLPayment(params) {
360
365
  expectedAmount,
361
366
  asset,
362
367
  clientConfig,
363
- maxAgeSeconds = 300
368
+ maxAgeSeconds = 300,
369
+ signatureStore
364
370
  } = params;
371
+ if (signatureStore) {
372
+ const isUsed = await signatureStore.hasBeenUsed(signature);
373
+ if (isUsed) {
374
+ return { valid: false, confirmed: true, signature, error: "Signature already used" };
375
+ }
376
+ }
365
377
  if (!SIGNATURE_REGEX2.test(signature)) {
366
378
  return { valid: false, confirmed: false, signature, error: "Invalid signature format" };
367
379
  }
@@ -406,6 +418,27 @@ async function verifySPLPayment(params) {
406
418
  error: "No valid token transfer to recipient found"
407
419
  };
408
420
  }
421
+ if (transfer.to) {
422
+ try {
423
+ const destinationInfo = await connection.getParsedAccountInfo(new PublicKey(transfer.to));
424
+ const owner = destinationInfo.value?.data?.parsed?.info?.owner;
425
+ if (owner && owner !== expectedRecipient) {
426
+ return {
427
+ valid: false,
428
+ confirmed: true,
429
+ signature,
430
+ error: "Recipient mismatch: Token account not owned by merchant"
431
+ };
432
+ }
433
+ } catch (e) {
434
+ return {
435
+ valid: false,
436
+ confirmed: true,
437
+ signature,
438
+ error: "Could not verify token account owner"
439
+ };
440
+ }
441
+ }
409
442
  if (transfer.mint !== mintAddress) {
410
443
  return {
411
444
  valid: false,
@@ -827,9 +860,28 @@ function parsePaymentHeader(header) {
827
860
  return null;
828
861
  }
829
862
  }
863
+ function encodePaymentRequirement(requirement) {
864
+ return Buffer.from(JSON.stringify(requirement)).toString("base64");
865
+ }
830
866
  function encodePaymentResponse(response) {
831
867
  return Buffer.from(JSON.stringify(response)).toString("base64");
832
868
  }
869
+ function create402Response(requirement, body) {
870
+ const headers = new Headers({
871
+ "Content-Type": "application/json",
872
+ "X-Payment-Required": encodePaymentRequirement(requirement)
873
+ });
874
+ const responseBody = body || {
875
+ error: "Payment Required",
876
+ message: "This resource requires payment to access",
877
+ x402Version: 1,
878
+ accepts: [requirement]
879
+ };
880
+ return new Response(JSON.stringify(responseBody), {
881
+ status: 402,
882
+ headers
883
+ });
884
+ }
833
885
 
834
886
  // src/store/memory.ts
835
887
  function createMemoryStore(options = {}) {
@@ -974,16 +1026,22 @@ function createPaywallMiddleware(config2) {
974
1026
  const sessionToken = cookies[cookieName];
975
1027
  const result = await checkPaywallAccess(path, sessionToken, config2);
976
1028
  if (!result.allowed && result.requiresPayment) {
1029
+ const headers = {
1030
+ "Content-Type": "application/json"
1031
+ };
1032
+ if (config2.paymentRequirement) {
1033
+ const requirement = typeof config2.paymentRequirement === "function" ? config2.paymentRequirement(path) : config2.paymentRequirement;
1034
+ headers["X-Payment-Required"] = encodePaymentRequirement(requirement);
1035
+ }
977
1036
  const body = config2.custom402Response ? config2.custom402Response(path) : {
978
1037
  error: "Payment Required",
979
1038
  message: "This resource requires payment to access",
1039
+ x402Version: 1,
980
1040
  path
981
1041
  };
982
1042
  return new Response(JSON.stringify(body), {
983
1043
  status: 402,
984
- headers: {
985
- "Content-Type": "application/json"
986
- }
1044
+ headers
987
1045
  });
988
1046
  }
989
1047
  return null;
@@ -1259,14 +1317,14 @@ async function getSolPrice() {
1259
1317
  }
1260
1318
  }
1261
1319
  if (cachedPrice) {
1262
- return cachedPrice;
1320
+ return {
1321
+ ...cachedPrice,
1322
+ source: `${cachedPrice.source} (stale)`
1323
+ };
1263
1324
  }
1264
- return {
1265
- solPrice: 150,
1266
- // Reasonable fallback
1267
- fetchedAt: /* @__PURE__ */ new Date(),
1268
- source: "fallback"
1269
- };
1325
+ throw new Error(
1326
+ "Failed to fetch SOL price from all providers. Configure a custom provider or ensure network connectivity."
1327
+ );
1270
1328
  }
1271
1329
  async function lamportsToUsd(lamports) {
1272
1330
  const { solPrice } = await getSolPrice();
@@ -1301,6 +1359,6 @@ function getProviders() {
1301
1359
  return PROVIDERS.map((p) => ({ name: p.name, url: p.url }));
1302
1360
  }
1303
1361
 
1304
- export { TOKEN_MINTS, X402_HEADERS, addArticleToSession, buildPaymentRequirement, buildSolanaPayUrl, buildVersionedTransaction, calculatePriorityFeeCost, checkPaywallAccess, clearPriceCache, configurePricing, create402Headers, create402ResponseBody, createMemoryStore, createPaymentFlow, createPaymentReference, createPaywallMiddleware, createPriorityFeeInstructions, createRedisStore, createSession, decodePaymentRequired, encodePaymentRequired, encodePaymentResponse, estimatePriorityFee, fetchLookupTables, formatPriceDisplay, formatPriceSync, getConnection, getConnectionWithFallback, getProviders, getSolPrice, getTokenDecimals, getWalletTransactions, isArticleUnlocked, isMainnet, isNativeAsset, isRetryableRPCError, isVersionedTransaction, lamportsToSol, lamportsToUsd, parsePaymentHeader, resetConnection, resolveMintAddress, solToLamports, toX402Network, usdToLamports, validateSession, verifyPayment, verifySPLPayment, verifyX402Payment, waitForConfirmation, withFallback, withPaywall, withRetry };
1362
+ export { TOKEN_MINTS, X402_HEADERS, addArticleToSession, buildPaymentRequirement, buildSolanaPayUrl, buildVersionedTransaction, calculatePriorityFeeCost, checkPaywallAccess, clearPriceCache, configurePricing, create402Headers, create402Response, create402ResponseBody, createMemoryStore, createPaymentFlow, createPaymentReference, createPaywallMiddleware, createPriorityFeeInstructions, createRedisStore, createSession, decodePaymentRequired, encodePaymentRequired, encodePaymentRequirement, encodePaymentResponse, estimatePriorityFee, fetchLookupTables, formatPriceDisplay, formatPriceSync, getConnection, getConnectionWithFallback, getProviders, getSolPrice, getTokenDecimals, getWalletTransactions, isArticleUnlocked, isMainnet, isNativeAsset, isRetryableRPCError, isVersionedTransaction, lamportsToSol, lamportsToUsd, parsePaymentHeader, resetConnection, resolveMintAddress, solToLamports, toX402Network, usdToLamports, validateSession, verifyPayment, verifySPLPayment, verifyX402Payment, waitForConfirmation, withFallback, withPaywall, withRetry };
1305
1363
  //# sourceMappingURL=index.js.map
1306
1364
  //# sourceMappingURL=index.js.map