@alleyboss/micropay-solana-x402-paywall 2.2.0 → 2.3.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.
- package/README.md +35 -1
- package/dist/agent/index.cjs +359 -0
- package/dist/agent/index.cjs.map +1 -0
- package/dist/agent/index.d.cts +212 -0
- package/dist/agent/index.d.ts +212 -0
- package/dist/agent/index.js +348 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/index.cjs +343 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +335 -13
- package/dist/index.js.map +1 -1
- package/dist/pricing/index.cjs +7 -7
- package/dist/pricing/index.cjs.map +1 -1
- package/dist/pricing/index.js +7 -7
- package/dist/pricing/index.js.map +1 -1
- package/dist/priority-fees-C-OH4Trr.d.cts +50 -0
- package/dist/priority-fees-C-OH4Trr.d.ts +50 -0
- package/dist/solana/index.cjs +37 -2
- package/dist/solana/index.cjs.map +1 -1
- package/dist/solana/index.d.cts +9 -49
- package/dist/solana/index.d.ts +9 -49
- package/dist/solana/index.js +37 -2
- package/dist/solana/index.js.map +1 -1
- package/dist/x402/index.cjs +8 -1
- package/dist/x402/index.cjs.map +1 -1
- package/dist/x402/index.js +8 -1
- package/dist/x402/index.js.map +1 -1
- package/package.json +11 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { A as ArticlePaymentConfig, d as PaymentAsset, a as PaymentPayload, P as PaymentRequirement, c as PaymentStatus, e as SPLTokenAsset, S as SolanaNetwork, T as TOKEN_MINTS, V as VerificationRequest, b as VerificationResponse, X as X402Network } from './payment-BGp7eMQl.cjs';
|
|
2
2
|
export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as SessionValidation } from './session-D2IoWAWV.cjs';
|
|
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
|
-
export {
|
|
4
|
+
export { SPLVerificationResult, TransactionVerificationResult, VerifyPaymentParams, VerifySPLPaymentParams, VersionedTransactionConfig, VersionedTransactionResult, buildVersionedTransaction, fetchLookupTables, getTokenDecimals, getWalletTransactions, isNativeAsset, isVersionedTransaction, lamportsToSol, resolveMintAddress, solToLamports, verifyPayment, verifySPLPayment, waitForConfirmation } from './solana/index.cjs';
|
|
5
|
+
export { P as PriorityFeeConfig, a as calculatePriorityFeeCost, c as createPriorityFeeInstructions, e as estimatePriorityFee } from './priority-fees-C-OH4Trr.cjs';
|
|
5
6
|
export { addArticleToSession, createSession, isArticleUnlocked, validateSession } from './session/index.cjs';
|
|
6
7
|
export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402Response, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentRequirement, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.cjs';
|
|
7
8
|
export { StoreConfig, createRedisStore } from './store/index.cjs';
|
|
@@ -9,5 +10,6 @@ export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallA
|
|
|
9
10
|
export { RetryOptions, isRetryableRPCError, withRetry } from './utils/index.cjs';
|
|
10
11
|
export { PaymentFlowConfig, SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference } from './client/index.cjs';
|
|
11
12
|
export { CustomPriceProvider, PriceConfig, PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports } from './pricing/index.cjs';
|
|
13
|
+
export { AgentPaymentResult, CreditSessionClaims, CreditSessionConfig, CreditSessionData, CreditValidation, ExecuteAgentPaymentParams, UseCreditResult, addCredits, createCreditSession, executeAgentPayment, generateAgentKeypair, getAgentBalance, getRemainingCredits, hasAgentSufficientBalance, keypairFromBase58, useCredit, validateCreditSession } from './agent/index.cjs';
|
|
12
14
|
export { S as SignatureStore, a as SignatureUsage, c as createMemoryStore } from './memory-Daxkczti.cjs';
|
|
13
15
|
import '@solana/web3.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { A as ArticlePaymentConfig, d as PaymentAsset, a as PaymentPayload, P as PaymentRequirement, c as PaymentStatus, e as SPLTokenAsset, S as SolanaNetwork, T as TOKEN_MINTS, V as VerificationRequest, b as VerificationResponse, X as X402Network } from './payment-BGp7eMQl.js';
|
|
2
2
|
export { a as SessionConfig, S as SessionData, c as SessionJWTPayload, b as SessionValidation } from './session-D2IoWAWV.js';
|
|
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
|
-
export {
|
|
4
|
+
export { SPLVerificationResult, TransactionVerificationResult, VerifyPaymentParams, VerifySPLPaymentParams, VersionedTransactionConfig, VersionedTransactionResult, buildVersionedTransaction, fetchLookupTables, getTokenDecimals, getWalletTransactions, isNativeAsset, isVersionedTransaction, lamportsToSol, resolveMintAddress, solToLamports, verifyPayment, verifySPLPayment, waitForConfirmation } from './solana/index.js';
|
|
5
|
+
export { P as PriorityFeeConfig, a as calculatePriorityFeeCost, c as createPriorityFeeInstructions, e as estimatePriorityFee } from './priority-fees-C-OH4Trr.js';
|
|
5
6
|
export { addArticleToSession, createSession, isArticleUnlocked, validateSession } from './session/index.js';
|
|
6
7
|
export { BuildPaymentParams, X402_HEADERS, buildPaymentRequirement, create402Headers, create402Response, create402ResponseBody, decodePaymentRequired, encodePaymentRequired, encodePaymentRequirement, encodePaymentResponse, parsePaymentHeader, verifyX402Payment } from './x402/index.js';
|
|
7
8
|
export { StoreConfig, createRedisStore } from './store/index.js';
|
|
@@ -9,5 +10,6 @@ export { M as MiddlewareResult, P as PaywallMiddlewareConfig, a as checkPaywallA
|
|
|
9
10
|
export { RetryOptions, isRetryableRPCError, withRetry } from './utils/index.js';
|
|
10
11
|
export { PaymentFlowConfig, SolanaPayUrlParams, buildSolanaPayUrl, createPaymentFlow, createPaymentReference } from './client/index.js';
|
|
11
12
|
export { CustomPriceProvider, PriceConfig, PriceData, clearPriceCache, configurePricing, formatPriceDisplay, formatPriceSync, getProviders, getSolPrice, lamportsToUsd, usdToLamports } from './pricing/index.js';
|
|
13
|
+
export { AgentPaymentResult, CreditSessionClaims, CreditSessionConfig, CreditSessionData, CreditValidation, ExecuteAgentPaymentParams, UseCreditResult, addCredits, createCreditSession, executeAgentPayment, generateAgentKeypair, getAgentBalance, getRemainingCredits, hasAgentSufficientBalance, keypairFromBase58, useCredit, validateCreditSession } from './agent/index.js';
|
|
12
14
|
export { S as SignatureStore, a as SignatureUsage, c as createMemoryStore } from './memory-Daxkczti.js';
|
|
13
15
|
import '@solana/web3.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublicKey, LAMPORTS_PER_SOL, ComputeBudgetProgram, TransactionMessage, VersionedTransaction, clusterApiUrl, Connection } from '@solana/web3.js';
|
|
1
|
+
import { PublicKey, LAMPORTS_PER_SOL, ComputeBudgetProgram, TransactionMessage, VersionedTransaction, SystemProgram, Keypair, clusterApiUrl, Connection } from '@solana/web3.js';
|
|
2
2
|
import { SignJWT, jwtVerify } from 'jose';
|
|
3
3
|
import { v4 } from 'uuid';
|
|
4
4
|
|
|
@@ -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,
|
|
@@ -1284,14 +1317,14 @@ async function getSolPrice() {
|
|
|
1284
1317
|
}
|
|
1285
1318
|
}
|
|
1286
1319
|
if (cachedPrice) {
|
|
1287
|
-
return
|
|
1320
|
+
return {
|
|
1321
|
+
...cachedPrice,
|
|
1322
|
+
source: `${cachedPrice.source} (stale)`
|
|
1323
|
+
};
|
|
1288
1324
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
fetchedAt: /* @__PURE__ */ new Date(),
|
|
1293
|
-
source: "fallback"
|
|
1294
|
-
};
|
|
1325
|
+
throw new Error(
|
|
1326
|
+
"Failed to fetch SOL price from all providers. Configure a custom provider or ensure network connectivity."
|
|
1327
|
+
);
|
|
1295
1328
|
}
|
|
1296
1329
|
async function lamportsToUsd(lamports) {
|
|
1297
1330
|
const { solPrice } = await getSolPrice();
|
|
@@ -1325,7 +1358,296 @@ function clearPriceCache() {
|
|
|
1325
1358
|
function getProviders() {
|
|
1326
1359
|
return PROVIDERS.map((p) => ({ name: p.name, url: p.url }));
|
|
1327
1360
|
}
|
|
1361
|
+
var WALLET_REGEX4 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
1362
|
+
function isValidWalletAddress2(address) {
|
|
1363
|
+
if (!address || typeof address !== "string") return false;
|
|
1364
|
+
return WALLET_REGEX4.test(address);
|
|
1365
|
+
}
|
|
1366
|
+
async function executeAgentPayment(params) {
|
|
1367
|
+
const {
|
|
1368
|
+
connection,
|
|
1369
|
+
agentKeypair,
|
|
1370
|
+
recipientAddress,
|
|
1371
|
+
amountLamports,
|
|
1372
|
+
priorityFee,
|
|
1373
|
+
confirmationTimeout = 6e4
|
|
1374
|
+
} = params;
|
|
1375
|
+
if (!isValidWalletAddress2(recipientAddress)) {
|
|
1376
|
+
return {
|
|
1377
|
+
success: false,
|
|
1378
|
+
error: "Invalid recipient address format"
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
if (amountLamports <= 0n) {
|
|
1382
|
+
return {
|
|
1383
|
+
success: false,
|
|
1384
|
+
error: "Amount must be greater than 0"
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1387
|
+
try {
|
|
1388
|
+
const recipientPubkey = new PublicKey(recipientAddress);
|
|
1389
|
+
const transferInstruction = SystemProgram.transfer({
|
|
1390
|
+
fromPubkey: agentKeypair.publicKey,
|
|
1391
|
+
toPubkey: recipientPubkey,
|
|
1392
|
+
lamports: amountLamports
|
|
1393
|
+
});
|
|
1394
|
+
const { transaction, lastValidBlockHeight } = await buildVersionedTransaction({
|
|
1395
|
+
connection,
|
|
1396
|
+
payer: agentKeypair.publicKey,
|
|
1397
|
+
instructions: [transferInstruction],
|
|
1398
|
+
priorityFee
|
|
1399
|
+
});
|
|
1400
|
+
transaction.sign([agentKeypair]);
|
|
1401
|
+
const signature = await connection.sendTransaction(transaction, {
|
|
1402
|
+
maxRetries: 3,
|
|
1403
|
+
skipPreflight: false
|
|
1404
|
+
});
|
|
1405
|
+
const confirmationPromise = connection.confirmTransaction(
|
|
1406
|
+
{
|
|
1407
|
+
signature,
|
|
1408
|
+
lastValidBlockHeight,
|
|
1409
|
+
blockhash: transaction.message.recentBlockhash
|
|
1410
|
+
},
|
|
1411
|
+
"confirmed"
|
|
1412
|
+
);
|
|
1413
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1414
|
+
setTimeout(() => reject(new Error("Confirmation timeout")), confirmationTimeout);
|
|
1415
|
+
});
|
|
1416
|
+
const confirmation = await Promise.race([confirmationPromise, timeoutPromise]);
|
|
1417
|
+
if (confirmation.value.err) {
|
|
1418
|
+
return {
|
|
1419
|
+
success: false,
|
|
1420
|
+
signature,
|
|
1421
|
+
error: "Transaction failed on-chain"
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
const txDetails = await connection.getTransaction(signature, {
|
|
1425
|
+
commitment: "confirmed",
|
|
1426
|
+
maxSupportedTransactionVersion: 0
|
|
1427
|
+
});
|
|
1428
|
+
return {
|
|
1429
|
+
success: true,
|
|
1430
|
+
signature,
|
|
1431
|
+
confirmedAt: txDetails?.blockTime ?? Math.floor(Date.now() / 1e3),
|
|
1432
|
+
slot: txDetails?.slot ?? confirmation.context.slot,
|
|
1433
|
+
amountLamports,
|
|
1434
|
+
amountSol: Number(amountLamports) / LAMPORTS_PER_SOL
|
|
1435
|
+
};
|
|
1436
|
+
} catch (error) {
|
|
1437
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1438
|
+
return {
|
|
1439
|
+
success: false,
|
|
1440
|
+
error: errorMessage
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
async function getAgentBalance(connection, agentKeypair) {
|
|
1445
|
+
const balance = await connection.getBalance(agentKeypair.publicKey);
|
|
1446
|
+
return {
|
|
1447
|
+
balance: BigInt(balance),
|
|
1448
|
+
balanceSol: balance / LAMPORTS_PER_SOL
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
async function hasAgentSufficientBalance(connection, agentKeypair, requiredLamports) {
|
|
1452
|
+
const { balance } = await getAgentBalance(connection, agentKeypair);
|
|
1453
|
+
const totalRequired = requiredLamports + 10000n;
|
|
1454
|
+
return {
|
|
1455
|
+
sufficient: balance >= totalRequired,
|
|
1456
|
+
balance,
|
|
1457
|
+
required: totalRequired
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
function keypairFromBase58(base58Secret) {
|
|
1461
|
+
const bytes = Buffer.from(base58Secret, "base64");
|
|
1462
|
+
if (bytes.length !== 64) {
|
|
1463
|
+
const parts = base58Secret.split(",").map((n) => parseInt(n.trim(), 10));
|
|
1464
|
+
if (parts.length === 64) {
|
|
1465
|
+
return Keypair.fromSecretKey(Uint8Array.from(parts));
|
|
1466
|
+
}
|
|
1467
|
+
throw new Error("Invalid secret key format. Expected base58 string or comma-separated bytes.");
|
|
1468
|
+
}
|
|
1469
|
+
return Keypair.fromSecretKey(bytes);
|
|
1470
|
+
}
|
|
1471
|
+
function generateAgentKeypair() {
|
|
1472
|
+
const keypair = Keypair.generate();
|
|
1473
|
+
const secretBytes = Array.from(keypair.secretKey);
|
|
1474
|
+
return {
|
|
1475
|
+
keypair,
|
|
1476
|
+
secretBase58: secretBytes.join(","),
|
|
1477
|
+
// Comma-separated for easy storage
|
|
1478
|
+
publicKey: keypair.publicKey.toBase58()
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
var MAX_CREDITS = 1e3;
|
|
1482
|
+
var MIN_SECRET_LENGTH2 = 32;
|
|
1483
|
+
function getSecretKey2(secret) {
|
|
1484
|
+
if (!secret || typeof secret !== "string") {
|
|
1485
|
+
throw new Error("Session secret is required");
|
|
1486
|
+
}
|
|
1487
|
+
if (secret.length < MIN_SECRET_LENGTH2) {
|
|
1488
|
+
throw new Error(`Session secret must be at least ${MIN_SECRET_LENGTH2} characters`);
|
|
1489
|
+
}
|
|
1490
|
+
return new TextEncoder().encode(secret);
|
|
1491
|
+
}
|
|
1492
|
+
function validateWalletAddress2(address) {
|
|
1493
|
+
if (!address || typeof address !== "string") return false;
|
|
1494
|
+
const base58Regex = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
1495
|
+
return base58Regex.test(address);
|
|
1496
|
+
}
|
|
1497
|
+
async function createCreditSession(walletAddress, purchaseId, config2) {
|
|
1498
|
+
if (!validateWalletAddress2(walletAddress)) {
|
|
1499
|
+
throw new Error("Invalid wallet address format");
|
|
1500
|
+
}
|
|
1501
|
+
if (config2.initialCredits <= 0 || config2.initialCredits > MAX_CREDITS) {
|
|
1502
|
+
throw new Error(`Credits must be between 1 and ${MAX_CREDITS}`);
|
|
1503
|
+
}
|
|
1504
|
+
if (!config2.durationHours || config2.durationHours <= 0 || config2.durationHours > 8760) {
|
|
1505
|
+
throw new Error("Session duration must be between 1 and 8760 hours (1 year)");
|
|
1506
|
+
}
|
|
1507
|
+
const sessionId = v4();
|
|
1508
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1509
|
+
const expiresAt = now + config2.durationHours * 3600;
|
|
1510
|
+
const bundleExpiry = config2.bundleExpiryHours ? now + config2.bundleExpiryHours * 3600 : expiresAt;
|
|
1511
|
+
const session = {
|
|
1512
|
+
id: sessionId,
|
|
1513
|
+
walletAddress,
|
|
1514
|
+
unlockedArticles: [purchaseId],
|
|
1515
|
+
siteWideUnlock: false,
|
|
1516
|
+
createdAt: now,
|
|
1517
|
+
expiresAt,
|
|
1518
|
+
credits: config2.initialCredits,
|
|
1519
|
+
bundleExpiry,
|
|
1520
|
+
bundleType: config2.bundleType
|
|
1521
|
+
};
|
|
1522
|
+
const payload = {
|
|
1523
|
+
sub: walletAddress,
|
|
1524
|
+
sid: sessionId,
|
|
1525
|
+
articles: session.unlockedArticles,
|
|
1526
|
+
siteWide: false,
|
|
1527
|
+
credits: config2.initialCredits,
|
|
1528
|
+
bundleExpiry,
|
|
1529
|
+
bundleType: config2.bundleType,
|
|
1530
|
+
iat: now,
|
|
1531
|
+
exp: expiresAt
|
|
1532
|
+
};
|
|
1533
|
+
const token = await new SignJWT(payload).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime(`${config2.durationHours}h`).sign(getSecretKey2(config2.secret));
|
|
1534
|
+
return { token, session };
|
|
1535
|
+
}
|
|
1536
|
+
async function validateCreditSession(token, secret) {
|
|
1537
|
+
if (!token || typeof token !== "string") {
|
|
1538
|
+
return { valid: false, reason: "Invalid token format" };
|
|
1539
|
+
}
|
|
1540
|
+
try {
|
|
1541
|
+
const { payload } = await jwtVerify(token, getSecretKey2(secret));
|
|
1542
|
+
const creditPayload = payload;
|
|
1543
|
+
if (!creditPayload.sub || !creditPayload.sid || !creditPayload.exp) {
|
|
1544
|
+
return { valid: false, reason: "Malformed session payload" };
|
|
1545
|
+
}
|
|
1546
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1547
|
+
if (creditPayload.exp < now) {
|
|
1548
|
+
return { valid: false, reason: "Session expired" };
|
|
1549
|
+
}
|
|
1550
|
+
if (creditPayload.bundleExpiry && creditPayload.bundleExpiry < now) {
|
|
1551
|
+
return { valid: false, reason: "Bundle expired" };
|
|
1552
|
+
}
|
|
1553
|
+
if (!validateWalletAddress2(creditPayload.sub)) {
|
|
1554
|
+
return { valid: false, reason: "Invalid session data" };
|
|
1555
|
+
}
|
|
1556
|
+
const session = {
|
|
1557
|
+
id: creditPayload.sid,
|
|
1558
|
+
walletAddress: creditPayload.sub,
|
|
1559
|
+
unlockedArticles: Array.isArray(creditPayload.articles) ? creditPayload.articles : [],
|
|
1560
|
+
siteWideUnlock: Boolean(creditPayload.siteWide),
|
|
1561
|
+
createdAt: creditPayload.iat ?? 0,
|
|
1562
|
+
expiresAt: creditPayload.exp,
|
|
1563
|
+
credits: creditPayload.credits ?? 0,
|
|
1564
|
+
bundleExpiry: creditPayload.bundleExpiry,
|
|
1565
|
+
bundleType: creditPayload.bundleType
|
|
1566
|
+
};
|
|
1567
|
+
return { valid: true, session };
|
|
1568
|
+
} catch {
|
|
1569
|
+
return { valid: false, reason: "Invalid session" };
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
async function useCredit(token, secret, creditsToUse = 1) {
|
|
1573
|
+
if (creditsToUse <= 0) {
|
|
1574
|
+
return { success: false, remainingCredits: 0, error: "Invalid credit amount" };
|
|
1575
|
+
}
|
|
1576
|
+
const validation = await validateCreditSession(token, secret);
|
|
1577
|
+
if (!validation.valid || !validation.session) {
|
|
1578
|
+
return {
|
|
1579
|
+
success: false,
|
|
1580
|
+
remainingCredits: 0,
|
|
1581
|
+
error: validation.reason || "Invalid session"
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
const session = validation.session;
|
|
1585
|
+
if (session.credits < creditsToUse) {
|
|
1586
|
+
return {
|
|
1587
|
+
success: false,
|
|
1588
|
+
remainingCredits: session.credits,
|
|
1589
|
+
error: "Insufficient credits"
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
const newCredits = session.credits - creditsToUse;
|
|
1593
|
+
const payload = {
|
|
1594
|
+
sub: session.walletAddress,
|
|
1595
|
+
sid: session.id,
|
|
1596
|
+
articles: session.unlockedArticles,
|
|
1597
|
+
siteWide: session.siteWideUnlock,
|
|
1598
|
+
credits: newCredits,
|
|
1599
|
+
bundleExpiry: session.bundleExpiry,
|
|
1600
|
+
bundleType: session.bundleType,
|
|
1601
|
+
iat: session.createdAt,
|
|
1602
|
+
exp: session.expiresAt
|
|
1603
|
+
};
|
|
1604
|
+
const newToken = await new SignJWT(payload).setProtectedHeader({ alg: "HS256" }).sign(getSecretKey2(secret));
|
|
1605
|
+
return {
|
|
1606
|
+
success: true,
|
|
1607
|
+
remainingCredits: newCredits,
|
|
1608
|
+
newToken
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
async function addCredits(token, secret, creditsToAdd) {
|
|
1612
|
+
if (creditsToAdd <= 0 || creditsToAdd > MAX_CREDITS) {
|
|
1613
|
+
return { success: false, error: "Invalid credit amount" };
|
|
1614
|
+
}
|
|
1615
|
+
const validation = await validateCreditSession(token, secret);
|
|
1616
|
+
if (!validation.valid || !validation.session) {
|
|
1617
|
+
return { success: false, error: validation.reason || "Invalid session" };
|
|
1618
|
+
}
|
|
1619
|
+
const session = validation.session;
|
|
1620
|
+
const newCredits = Math.min(session.credits + creditsToAdd, MAX_CREDITS);
|
|
1621
|
+
const payload = {
|
|
1622
|
+
sub: session.walletAddress,
|
|
1623
|
+
sid: session.id,
|
|
1624
|
+
articles: session.unlockedArticles,
|
|
1625
|
+
siteWide: session.siteWideUnlock,
|
|
1626
|
+
credits: newCredits,
|
|
1627
|
+
bundleExpiry: session.bundleExpiry,
|
|
1628
|
+
bundleType: session.bundleType,
|
|
1629
|
+
iat: session.createdAt,
|
|
1630
|
+
exp: session.expiresAt
|
|
1631
|
+
};
|
|
1632
|
+
const newToken = await new SignJWT(payload).setProtectedHeader({ alg: "HS256" }).sign(getSecretKey2(secret));
|
|
1633
|
+
return {
|
|
1634
|
+
success: true,
|
|
1635
|
+
newToken,
|
|
1636
|
+
totalCredits: newCredits
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
async function getRemainingCredits(token, secret) {
|
|
1640
|
+
const validation = await validateCreditSession(token, secret);
|
|
1641
|
+
if (!validation.valid || !validation.session) {
|
|
1642
|
+
return { credits: 0, valid: false };
|
|
1643
|
+
}
|
|
1644
|
+
return {
|
|
1645
|
+
credits: validation.session.credits,
|
|
1646
|
+
valid: true,
|
|
1647
|
+
bundleExpiry: validation.session.bundleExpiry
|
|
1648
|
+
};
|
|
1649
|
+
}
|
|
1328
1650
|
|
|
1329
|
-
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 };
|
|
1651
|
+
export { TOKEN_MINTS, X402_HEADERS, addArticleToSession, addCredits, buildPaymentRequirement, buildSolanaPayUrl, buildVersionedTransaction, calculatePriorityFeeCost, checkPaywallAccess, clearPriceCache, configurePricing, create402Headers, create402Response, create402ResponseBody, createCreditSession, createMemoryStore, createPaymentFlow, createPaymentReference, createPaywallMiddleware, createPriorityFeeInstructions, createRedisStore, createSession, decodePaymentRequired, encodePaymentRequired, encodePaymentRequirement, encodePaymentResponse, estimatePriorityFee, executeAgentPayment, fetchLookupTables, formatPriceDisplay, formatPriceSync, generateAgentKeypair, getAgentBalance, getConnection, getConnectionWithFallback, getProviders, getRemainingCredits, getSolPrice, getTokenDecimals, getWalletTransactions, hasAgentSufficientBalance, isArticleUnlocked, isMainnet, isNativeAsset, isRetryableRPCError, isVersionedTransaction, keypairFromBase58, lamportsToSol, lamportsToUsd, parsePaymentHeader, resetConnection, resolveMintAddress, solToLamports, toX402Network, usdToLamports, useCredit, validateCreditSession, validateSession, verifyPayment, verifySPLPayment, verifyX402Payment, waitForConfirmation, withFallback, withPaywall, withRetry };
|
|
1330
1652
|
//# sourceMappingURL=index.js.map
|
|
1331
1653
|
//# sourceMappingURL=index.js.map
|