import { Payment, PaymentProcessingState } from '../types';
import { tracer } from '@capchase/tracer';
import {
publish,
Channel,
InternalPaymentAdded,
InternalPaymentAddedBody,
} from '@capchase/messaging-system';
import { callLog } from '../call_log';
/**
* Computes the name of the topic based on the contract name.
*
* @function
* @memberOf module:payments/actions
* @access private
*/
const channelNameForContract = (contractName: string): string => {
if (contractName.length === 0) {
throw new Error('Contract name should not be empty');
}
return `${Channel.INTERNAL_PAYMENT_ADDED}.contract.${contractName}`;
};
const internalPublishPaymentAdded = async (
payment: Payment,
actionBy: string
) => {
await callLog({
callName: 'publishPayment',
actionBy,
args: [payment, actionBy],
});
const span = tracer?.scope()?.active();
span?.addTags({
payment_id: payment.id,
payment_key: payment.key,
payment_processing_key: payment.processingKey,
payment_processing_state: payment.processingState,
action_by: actionBy,
});
// TODO(SHI-1454): Validate actual user permissions
if (actionBy.length === 0) {
throw new Error('Action by should be set');
}
// If the payment is already processed, do nothing
if (payment.processingState === PaymentProcessingState.PROCESSED) {
return;
}
const body: InternalPaymentAddedBody = {
paymentKey: payment.key,
processingKey: payment.processingKey,
contractName: payment.contractName,
status: payment.status,
};
// Send both to the general channel and the status specific channel
await Promise.all([
publish<InternalPaymentAdded>(Channel.INTERNAL_PAYMENT_ADDED, body),
publish<InternalPaymentAdded>(
channelNameForContract(payment.contractName),
body
),
]);
};
/**
* Publishes that a non processed payment has been added.
*
* @param {Payment} payment Payment ot be published
* @param {string} actionBy Action executor
* @return {Promise<void>}
*
* @async
* @function
* @memberOf module:payments/actions
* @access public
*/
const publishPaymentAdded =
tracer?.wrap('payments.publishPaymentAdded', internalPublishPaymentAdded) ||
internalPublishPaymentAdded;
export { publishPaymentAdded, channelNameForContract };