svm-pay
Version:
A payment solution for SVM networks (Solana, Sonic SVM, Eclipse, s00n)
181 lines • 6.51 kB
JavaScript
;
/**
* SVM-Pay Transfer Request Handler
*
* This file implements the handler for transfer requests in the SVM-Pay protocol.
* Transfer requests are non-interactive requests for simple token transfers.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransferRequestHandler = void 0;
const types_1 = require("./types");
const reference_1 = require("./reference");
/**
* Simple in-memory payment store for transfer handler
*/
class SimpleMemoryPaymentStore {
constructor() {
this.payments = new Map();
}
async save(record) {
this.payments.set(record.id, { ...record });
}
async load(id) {
const record = this.payments.get(id);
return record ? { ...record } : null;
}
async loadByType(type) {
return Array.from(this.payments.values())
.filter(record => record.request.type === type)
.map(record => ({ ...record }));
}
async update(id, updates) {
const existing = this.payments.get(id);
if (!existing) {
throw new Error(`Payment record not found: ${id}`);
}
const updated = {
...existing,
...updates,
updatedAt: Date.now()
};
this.payments.set(id, updated);
return { ...updated };
}
async delete(id) {
return this.payments.delete(id);
}
}
/**
* Handler for transfer requests
*/
class TransferRequestHandler {
/**
* Create a new TransferRequestHandler
*
* @param networkAdapters Map of network adapters for each supported network
* @param paymentStore Optional payment store (defaults to in-memory)
*/
constructor(networkAdapters, paymentStore) {
this.networkAdapters = networkAdapters;
this.paymentStore = paymentStore || new SimpleMemoryPaymentStore();
}
/**
* Process a transfer request
*
* @param request The transfer request to process
* @returns A payment record for the processed request
*/
async processRequest(request) {
// Get the network adapter for this request
const adapter = this.networkAdapters.get(request.network);
if (!adapter) {
throw new Error(`No adapter available for network: ${request.network}`);
}
// Generate a unique ID for this payment
const id = (0, reference_1.generateReference)();
// Create a payment record
const record = {
id,
request,
status: types_1.PaymentStatus.CREATED,
createdAt: Date.now(),
updatedAt: Date.now()
};
try {
// Save initial record
await this.paymentStore.save(record);
// Create a transaction for this request
const _transaction = await adapter.createTransferTransaction(request);
// Update record with pending status
const updatedRecord = await this.paymentStore.update(id, {
status: types_1.PaymentStatus.PENDING
});
return updatedRecord;
}
catch (error) {
// Update record with error
const errorRecord = await this.paymentStore.update(id, {
status: types_1.PaymentStatus.FAILED,
error: error.message
});
return errorRecord;
}
}
/**
* Submit a signed transaction for a transfer request
*
* @param paymentId The ID of the payment record
* @param transaction The transaction to submit
* @param signature The signature for the transaction
* @returns The updated payment record
*/
async submitTransaction(paymentId, transaction, signature) {
// Load the payment record from store
const record = await this.paymentStore.load(paymentId);
if (!record) {
throw new Error(`Payment record not found: ${paymentId}`);
}
try {
// Get the network adapter for this request
const adapter = this.networkAdapters.get(record.request.network);
if (!adapter) {
throw new Error(`No adapter available for network: ${record.request.network}`);
}
// Submit the transaction
const txSignature = await adapter.submitTransaction(transaction, signature);
// Update the payment record
const updatedRecord = await this.paymentStore.update(paymentId, {
status: types_1.PaymentStatus.CONFIRMED,
signature: txSignature
});
return updatedRecord;
}
catch (error) {
// Update record with error
const errorRecord = await this.paymentStore.update(paymentId, {
status: types_1.PaymentStatus.FAILED,
error: error.message
});
return errorRecord;
}
}
/**
* Check the status of a payment
*
* @param paymentId The ID of the payment to check
* @returns The updated payment record
*/
async checkStatus(paymentId) {
// Load the payment record from store
const record = await this.paymentStore.load(paymentId);
if (!record) {
throw new Error(`Payment record not found: ${paymentId}`);
}
try {
// Get the network adapter for this request
const adapter = this.networkAdapters.get(record.request.network);
if (!adapter) {
throw new Error(`No adapter available for network: ${record.request.network}`);
}
// Only check if we have a signature
if (!record.signature) {
return record; // No signature to check yet
}
// Check the transaction status
const status = await adapter.checkTransactionStatus(record.signature);
// Update the payment record
const updatedRecord = await this.paymentStore.update(paymentId, { status });
return updatedRecord;
}
catch (error) {
// Update record with error
const errorRecord = await this.paymentStore.update(paymentId, {
status: types_1.PaymentStatus.FAILED,
error: error.message
});
return errorRecord;
}
}
}
exports.TransferRequestHandler = TransferRequestHandler;
//# sourceMappingURL=transfer-handler.js.map