svm-pay
Version:
A payment solution for SVM networks (Solana, Sonic SVM, Eclipse, s00n)
427 lines • 14.7 kB
JavaScript
"use strict";
/**
* Angular Integration for SVM-Pay
*
* This module provides Angular-specific components, services, and utilities
* for integrating SVM-Pay into Angular applications with proper dependency injection,
* reactive patterns, and AOT compilation support.
*
* Note: This module requires Angular to be installed as a peer dependency.
* Install with: npm install @angular/core rxjs
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SVMPayModule = exports.SVMPayButtonComponent = exports.SVMPayService = exports.SVM_PAY_CONFIG = void 0;
exports.validateAngularIntegration = validateAngularIntegration;
exports.createSVMPayService = createSVMPayService;
// Check if Angular is available at runtime
function hasAngularSupport() {
try {
require('@angular/core');
require('rxjs');
return true;
}
catch (_a) {
return false;
}
}
// Dynamic Angular imports (AOT-safe)
let Injectable;
let InjectionToken;
let NgModule;
let Component;
let Input;
let Output;
let EventEmitter;
let Inject;
let Optional;
// Dynamic RxJS imports
let _Observable;
let BehaviorSubject;
let from;
let of;
let _EMPTY;
let catchError;
let map;
let shareReplay;
// Initialize Angular decorators and RxJS if available
if (hasAngularSupport()) {
try {
const angularCore = require('@angular/core');
Injectable = angularCore.Injectable;
InjectionToken = angularCore.InjectionToken;
NgModule = angularCore.NgModule;
Component = angularCore.Component;
Input = angularCore.Input;
Output = angularCore.Output;
EventEmitter = angularCore.EventEmitter;
Inject = angularCore.Inject;
Optional = angularCore.Optional;
const rxjs = require('rxjs');
_Observable = rxjs.Observable;
BehaviorSubject = rxjs.BehaviorSubject;
from = rxjs.from;
of = rxjs.of;
_EMPTY = rxjs.EMPTY;
const operators = require('rxjs/operators');
catchError = operators.catchError;
map = operators.map;
shareReplay = operators.shareReplay;
}
catch (error) {
console.warn('Failed to load Angular decorators or RxJS:', error);
}
}
// Create injection tokens with proper typing
exports.SVM_PAY_CONFIG = hasAngularSupport() && InjectionToken
? new InjectionToken('SVM_PAY_CONFIG', {
providedIn: 'root',
factory: () => ({ debug: false })
})
: 'SVM_PAY_CONFIG';
/**
* Angular service for SVM-Pay with dependency injection and reactive patterns
*/
class SVMPayService {
constructor(config) {
this.paymentState$ = null;
// Cached observables for better performance
this.balance$ = null;
this.paymentHistory$ = null;
this.config = config || { debug: false };
if (hasAngularSupport() && BehaviorSubject) {
this.paymentState$ = new BehaviorSubject({ status: 'idle' });
}
if (!hasAngularSupport()) {
console.warn('Angular integration requires @angular/core and rxjs to be installed');
}
}
/**
* Get current payment state as observable
*/
getPaymentState() {
if (this.paymentState$) {
return this.paymentState$.asObservable();
}
return null;
}
/**
* Create transfer URL (synchronous)
*/
createTransferUrl(recipient, amount, options) {
try {
const { SVMPay } = require('../index');
const svmPay = new SVMPay(this.config);
return svmPay.createTransferUrl(recipient, amount, options);
}
catch (error) {
console.error('Failed to create transfer URL:', error);
throw error;
}
}
/**
* Create transaction URL (synchronous)
*/
createTransactionUrl(link, recipient) {
try {
const { SVMPay } = require('../index');
const svmPay = new SVMPay(this.config);
return svmPay.createTransactionUrl(link, recipient);
}
catch (error) {
console.error('Failed to create transaction URL:', error);
throw error;
}
}
/**
* Check wallet balance (reactive)
*/
checkWalletBalance() {
if (!hasAngularSupport() || !from || !shareReplay || !catchError) {
// Fallback to promise-based approach
return this.getSDKInstance().checkWalletBalance();
}
if (!this.balance$) {
this.balance$ = from(this.getSDKInstance().checkWalletBalance()).pipe(shareReplay(1), catchError((error) => {
console.error('Failed to check wallet balance:', error);
throw error;
}));
}
return this.balance$;
}
/**
* Get payment history (reactive)
*/
getPaymentHistory() {
if (!hasAngularSupport() || !from || !map || !shareReplay || !catchError || !of) {
// Fallback to promise-based approach
return this.getSDKInstance().getPaymentHistory();
}
if (!this.paymentHistory$) {
this.paymentHistory$ = from(this.getSDKInstance().getPaymentHistory()).pipe(map((history) => Array.isArray(history) ? history : []), shareReplay(1), catchError((error) => {
console.error('Failed to get payment history:', error);
return of([]);
}));
}
return this.paymentHistory$;
}
/**
* Process payment with state updates
*/
processPayment(recipient, amount, options) {
if (this.paymentState$) {
this.paymentState$.next({ status: 'pending' });
}
if (!hasAngularSupport() || !from || !map || !catchError) {
// Fallback to promise-based approach
return this.executePayment(recipient, amount, options);
}
return from(this.executePayment(recipient, amount, options)).pipe(map((result) => {
if (this.paymentState$) {
this.paymentState$.next({ status: 'success', data: result });
}
// Invalidate cached data
this.balance$ = null;
this.paymentHistory$ = null;
return result;
}), catchError((error) => {
if (this.paymentState$) {
this.paymentState$.next({ status: 'error', error: error.message });
}
throw error;
}));
}
/**
* Check API usage (reactive)
*/
checkApiUsage() {
if (!hasAngularSupport() || !from || !catchError) {
return this.getSDKInstance().checkApiUsage();
}
return from(this.getSDKInstance().checkApiUsage()).pipe(catchError((error) => {
console.error('Failed to check API usage:', error);
throw error;
}));
}
/**
* Setup wallet configuration
*/
setupWallet(config) {
if (!hasAngularSupport() || !from || !map || !catchError) {
return this.getSDKInstance().setupWallet(config);
}
return from(this.getSDKInstance().setupWallet(config)).pipe(map((result) => {
// Invalidate cached data after setup
this.balance$ = null;
this.paymentHistory$ = null;
return result;
}), catchError((error) => {
console.error('Failed to setup wallet:', error);
throw error;
}));
}
/**
* Reset cached data and state
*/
reset() {
if (this.paymentState$) {
this.paymentState$.next({ status: 'idle' });
}
this.balance$ = null;
this.paymentHistory$ = null;
}
getSDKInstance() {
const { SVMPay } = require('../index');
return new SVMPay(this.config);
}
async executePayment(_recipient, _amount, _options) {
// Placeholder for payment execution logic
// In a real implementation, this would handle the payment flow
throw new Error('Payment execution not implemented in Angular integration');
}
}
exports.SVMPayService = SVMPayService;
/**
* Angular component for payment button with proper decorators
*/
class SVMPayButtonComponent {
constructor(svmPayService) {
this.label = 'Pay';
this.disabled = false;
this.paymentCompleted = null;
this.paymentError = null;
this.svmPayService = svmPayService || new SVMPayService();
// Initialize event emitters if Angular is available
if (hasAngularSupport() && EventEmitter) {
this.paymentCompleted = new EventEmitter();
this.paymentError = new EventEmitter();
}
}
onPaymentClick() {
if (!this.recipient || !this.amount) {
const error = 'Recipient and amount are required';
console.error(error);
if (this.paymentError && this.paymentError.emit) {
this.paymentError.emit(error);
}
return;
}
this.disabled = true;
const paymentResult = this.svmPayService.processPayment(this.recipient, this.amount);
// Handle both Observable and Promise results
if (paymentResult && paymentResult.subscribe) {
// Observable result
paymentResult.subscribe({
next: (result) => {
console.log('Payment completed:', result);
if (this.paymentCompleted && this.paymentCompleted.emit) {
this.paymentCompleted.emit(result);
}
this.disabled = false;
},
error: (error) => {
console.error('Payment failed:', error);
if (this.paymentError && this.paymentError.emit) {
this.paymentError.emit(error.message || 'Payment failed');
}
this.disabled = false;
}
});
}
else if (paymentResult && paymentResult.then) {
// Promise result
paymentResult
.then((result) => {
console.log('Payment completed:', result);
if (this.paymentCompleted && this.paymentCompleted.emit) {
this.paymentCompleted.emit(result);
}
this.disabled = false;
})
.catch((error) => {
console.error('Payment failed:', error);
if (this.paymentError && this.paymentError.emit) {
this.paymentError.emit(error.message || 'Payment failed');
}
this.disabled = false;
});
}
}
}
exports.SVMPayButtonComponent = SVMPayButtonComponent;
/**
* Enhanced Angular service and component with decorators (if Angular is available)
*/
if (hasAngularSupport() && Injectable && Component && Input && Output && Inject && Optional && EventEmitter) {
// Create decorated service class
const DecoratedSVMPayService = Injectable({
providedIn: 'root'
})(class DecoratedSVMPayService extends SVMPayService {
constructor(config) {
super(config);
}
});
// Create decorated component class
const DecoratedSVMPayButtonComponent = Component({
selector: 'svm-pay-button',
template: `
<button
(click)="onPaymentClick()"
[disabled]="disabled"
class="svm-pay-button">
{{ label }}
</button>
`,
styles: [`
.svm-pay-button {
background-color: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.svm-pay-button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
.svm-pay-button:hover:not(:disabled) {
background-color: #0056b3;
}
`]
})(class DecoratedSVMPayButtonComponent extends SVMPayButtonComponent {
constructor(svmPayService) {
super(svmPayService);
this.label = 'Pay';
this.disabled = false;
this.paymentCompleted = new EventEmitter();
this.paymentError = new EventEmitter();
}
});
// Export decorated versions for Angular use
if (typeof exports !== 'undefined') {
exports.AngularSVMPayService = DecoratedSVMPayService;
exports.AngularSVMPayButtonComponent = DecoratedSVMPayButtonComponent;
}
}
/**
* Angular module for SVM-Pay with proper module definition
*/
class SVMPayModule {
static forRoot(config) {
if (!hasAngularSupport() || !NgModule) {
console.warn('SVMPayModule.forRoot() requires Angular NgModule to be available');
return this;
}
const moduleConfig = {
providers: [
SVMPayService,
{
provide: exports.SVM_PAY_CONFIG,
useValue: config || { debug: false }
}
]
};
if (typeof exports !== 'undefined' && exports.AngularSVMPayButtonComponent) {
moduleConfig.declarations = [exports.AngularSVMPayButtonComponent];
moduleConfig.exports = [exports.AngularSVMPayButtonComponent];
}
return NgModule(moduleConfig)(class {
});
}
static forChild() {
if (!hasAngularSupport() || !NgModule) {
console.warn('SVMPayModule.forChild() requires Angular NgModule to be available');
return this;
}
const moduleConfig = {};
if (typeof exports !== 'undefined' && exports.AngularSVMPayButtonComponent) {
moduleConfig.declarations = [exports.AngularSVMPayButtonComponent];
moduleConfig.exports = [exports.AngularSVMPayButtonComponent];
}
return NgModule(moduleConfig)(class {
});
}
}
exports.SVMPayModule = SVMPayModule;
/**
* Utility function to check if Angular integration is properly set up
*/
function validateAngularIntegration() {
if (!hasAngularSupport()) {
console.error('Angular integration requires @angular/core and rxjs dependencies');
return false;
}
if (!Injectable || !NgModule || !Component) {
console.error('Angular decorators are not available - check Angular installation');
return false;
}
return true;
}
/**
* Factory function for creating SVM-Pay service outside Angular DI
*/
function createSVMPayService(config) {
return new SVMPayService(config);
}
//# sourceMappingURL=angular-integration.js.map