UNPKG

@gotake/gotake-sdk

Version:

SDK for interacting with GoTake blockchain contracts

336 lines (335 loc) 12.3 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PaymentUtils = void 0; var ethers_1 = require("ethers"); var types_1 = require("../types"); /** * Utility functions for payment processing */ var PaymentUtils = /** @class */ (function () { function PaymentUtils() { } /** * Validate payment parameters * @param params Purchase parameters * @returns Validation result with errors if any */ PaymentUtils.validatePurchaseParams = function (params) { var errors = []; // Validate content ID if (!Number.isInteger(params.contentId) || params.contentId <= 0) { errors.push('Content ID must be a positive integer'); } // Validate payment method if (!Object.values(types_1.PaymentMethod).includes(params.paymentMethod)) { errors.push('Invalid payment method'); } // Validate token address for ERC20 payments if (params.paymentMethod === types_1.PaymentMethod.ERC20) { if (!params.tokenAddress) { errors.push('Token address is required for ERC20 payments'); } else if (!this.isValidAddress(params.tokenAddress)) { errors.push('Invalid token address format'); } } // Validate amount if provided if (params.amount !== undefined) { try { var amount = ethers_1.BigNumber.from(params.amount); if (amount.lte(0)) { errors.push('Amount must be positive'); } } catch (_a) { errors.push('Invalid amount format'); } } return { isValid: errors.length === 0, errors: errors }; }; /** * Check if address is valid Ethereum address * @param address Address to check * @returns True if address is valid */ PaymentUtils.isValidAddress = function (address) { var ethers = require('ethers'); try { return ethers.utils.isAddress(address); } catch (_a) { return false; } }; /** * Format payment method for display * @param method Payment method * @returns Formatted string */ PaymentUtils.formatPaymentMethod = function (method) { switch (method) { case types_1.PaymentMethod.ETH: return 'Ethereum (ETH)'; case types_1.PaymentMethod.ERC20: return 'ERC20 Token'; default: return 'Unknown'; } }; /** * Get payment method icon/symbol * @param method Payment method * @returns Symbol string */ PaymentUtils.getPaymentMethodSymbol = function (method) { switch (method) { case types_1.PaymentMethod.ETH: return 'ETH'; case types_1.PaymentMethod.ERC20: return 'ERC20'; default: return '?'; } }; /** * Calculate total cost including gas estimate * @param price Content price * @param gasEstimate Estimated gas cost * @param paymentMethod Payment method * @returns Total cost breakdown */ PaymentUtils.calculateTotalCost = function (price, gasEstimate, paymentMethod) { var isETHPayment = paymentMethod === types_1.PaymentMethod.ETH; return { contentPrice: price, gasCost: gasEstimate, total: isETHPayment ? price.add(gasEstimate) : gasEstimate, isETHPayment: isETHPayment }; }; /** * Format purchase result for display * @param result Purchase result * @returns Formatted result object */ PaymentUtils.formatPurchaseResult = function (result) { return { transactionHash: result.transactionHash, shortHash: this.shortenHash(result.transactionHash), contentId: result.contentId, purchaseTime: this.formatTimestamp(result.purchaseTime), viewCount: result.viewCount.toNumber(), validUntil: this.formatTimestamp(result.validUntil), gasUsed: result.gasUsed ? result.gasUsed.toString() : undefined }; }; /** * Shorten transaction hash for display * @param hash Full transaction hash * @returns Shortened hash */ PaymentUtils.shortenHash = function (hash) { if (hash.length <= 10) return hash; return "".concat(hash.slice(0, 6), "...").concat(hash.slice(-4)); }; /** * Format timestamp for display * @param timestamp BigNumber timestamp * @returns Formatted date string */ PaymentUtils.formatTimestamp = function (timestamp) { var date = new Date(timestamp.toNumber() * 1000); return date.toLocaleString(); }; /** * Calculate percentage savings * @param originalPrice Original price * @param discountedPrice Discounted price * @returns Savings percentage */ PaymentUtils.calculateSavings = function (originalPrice, discountedPrice) { if (originalPrice.lte(0)) return 0; var savings = originalPrice.sub(discountedPrice); var percentage = savings.mul(10000).div(originalPrice).toNumber() / 100; return Math.max(0, Math.min(100, percentage)); }; /** * Compare payment costs across different methods * @param costs Array of cost objects with method and price * @returns Sorted costs with savings information */ PaymentUtils.comparePaymentCosts = function (costs) { var _this = this; // Calculate totals var costsWithTotals = costs.map(function (cost) { var gasEstimate = cost.gasEstimate || ethers_1.BigNumber.from(0); var totalCost = _this.calculateTotalCost(cost.price, gasEstimate, cost.method); return { method: cost.method, price: cost.price, total: totalCost.total, tokenSymbol: cost.tokenSymbol }; }); // Sort by total cost costsWithTotals.sort(function (a, b) { if (a.total.lt(b.total)) return -1; if (a.total.gt(b.total)) return 1; return 0; }); // Calculate savings and mark recommended var cheapest = costsWithTotals[0]; return costsWithTotals.map(function (cost, index) { return (__assign(__assign({}, cost), { savings: cheapest.total.eq(cost.total) ? 0 : _this.calculateSavings(cost.total, cheapest.total), isRecommended: index === 0 })); }); }; /** * Generate payment summary text * @param params Purchase parameters * @param price Content price * @returns Summary text */ PaymentUtils.generatePaymentSummary = function (params, price) { var ethers = require('ethers'); var method = this.formatPaymentMethod(params.paymentMethod); var priceStr = ethers.utils.formatEther(price); var summary = "Purchase content ".concat(params.contentId, " for ").concat(priceStr, " ETH"); if (params.paymentMethod === types_1.PaymentMethod.ERC20 && params.tokenAddress) { summary += " (paid with ".concat(params.tokenAddress, ")"); } summary += " using ".concat(method); return summary; }; /** * Estimate gas for purchase transaction * @param paymentMethod Payment method * @param hasApproval Whether token approval is needed (for ERC20) * @returns Estimated gas units */ PaymentUtils.estimateGasUnits = function (paymentMethod, hasApproval) { if (hasApproval === void 0) { hasApproval = true; } switch (paymentMethod) { case types_1.PaymentMethod.ETH: return 65000; // Typical gas for ETH purchase case types_1.PaymentMethod.ERC20: // Add approval gas if needed var approvalGas = hasApproval ? 0 : 46000; var transferGas = 85000; // Typical gas for ERC20 purchase return approvalGas + transferGas; default: return 100000; // Conservative estimate } }; /** * Check if sufficient balance for purchase * @param balance User's balance * @param requiredAmount Required amount * @param gasEstimate Gas cost estimate * @param paymentMethod Payment method * @returns Balance check result */ PaymentUtils.checkSufficientBalance = function (balance, requiredAmount, gasEstimate, paymentMethod) { var totalRequired = paymentMethod === types_1.PaymentMethod.ETH ? requiredAmount.add(gasEstimate) : requiredAmount; if (balance.gte(totalRequired)) { return { sufficient: true, message: 'Sufficient balance' }; } var shortage = totalRequired.sub(balance); var ethers = require('ethers'); var shortageStr = ethers.utils.formatEther(shortage); return { sufficient: false, shortage: shortage, message: "Insufficient balance. Need ".concat(shortageStr, " more ").concat(paymentMethod) }; }; /** * Generate transaction receipt URL for block explorer * @param transactionHash Transaction hash * @param networkId Network ID * @returns Block explorer URL */ PaymentUtils.generateExplorerUrl = function (transactionHash, networkId) { var baseUrls = { 1: 'https://etherscan.io/tx/', 5: 'https://goerli.etherscan.io/tx/', 11155111: 'https://sepolia.etherscan.io/tx/', 8453: 'https://basescan.org/tx/', 84531: 'https://goerli.basescan.org/tx/', 84532: 'https://sepolia.basescan.org/tx/' }; var baseUrl = baseUrls[networkId]; return baseUrl ? "".concat(baseUrl).concat(transactionHash) : '#'; }; /** * Parse error messages from failed transactions * @param error Error object * @returns User-friendly error message */ PaymentUtils.parseTransactionError = function (error) { if (!error) return 'Unknown error occurred'; var errorMessage = error.message || error.toString(); // Common error patterns var patterns = [ { pattern: /insufficient funds/i, message: 'Insufficient funds to complete transaction' }, { pattern: /user rejected/i, message: 'Transaction was rejected by user' }, { pattern: /gas too low/i, message: 'Gas limit too low for transaction' }, { pattern: /nonce too low/i, message: 'Transaction nonce error. Please try again' }, { pattern: /content not active/i, message: 'Content is not available for purchase' }, { pattern: /already purchased/i, message: 'Content has already been purchased' }, { pattern: /token not supported/i, message: 'Payment token is not supported' } ]; for (var _i = 0, patterns_1 = patterns; _i < patterns_1.length; _i++) { var _a = patterns_1[_i], pattern = _a.pattern, message = _a.message; if (pattern.test(errorMessage)) { return message; } } return 'Transaction failed. Please try again'; }; return PaymentUtils; }()); exports.PaymentUtils = PaymentUtils;