Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const prepareChangeParticipantPositionTransaction = async (transferList) => {
try {
const knex = await Db.getKnex()
const participantName = transferList[0].value.content.payload.payerFsp
const currencyId = transferList[0].value.content.payload.amount.currency
const participantCurrency = await participantFacade.getByNameAndCurrency(participantName, currencyId, Enum.Accounts.LedgerAccountType.POSITION)
const processedTransfers = {} // The list of processed transfers - so that we can store the additional information around the decision. Most importantly the "running" position
const reservedTransfers = []
const abortedTransfers = []
const initialTransferStateChangePromises = []
const transferIdList = []
const limitAlarms = []
let sumTransfersInBatch = 0
await knex.transaction(async (trx) => {
try {
const transactionTimestamp = Time.getUTCString(new Date())
for (const transfer of transferList) {
// const initialTransferStateChangeList = await knex('transferStateChange').transacting(trx).whereIn('transferId', transferIdList).forUpdate().orderBy('transferStateChangeId', 'desc')
// ^^^^^ this is how we want to get this later to reduce the DB queries into one.
/*
TODO Possibly the commented block of validations in this comment block will be validated with message validations for each topic
exports.prepareData = async (name, currencyId = 'USD', isUnique = true) => {
try {
const participantId = await Model.create(Object.assign(
{},
testParticipant,
{
name: (name || testParticipant.name) + (isUnique ? time.msToday().toString() : '')
}
))
const participantCurrencyId = await ParticipantCurrencyModel.create(participantId, currencyId, Enum.Accounts.LedgerAccountType.POSITION, false)
const participantCurrencyId2 = await ParticipantCurrencyModel.create(participantId, currencyId, Enum.Accounts.LedgerAccountType.SETTLEMENT, false)
const participant = await Model.getById(participantId)
return {
participant,
participantCurrencyId,
participantCurrencyId2
}
} catch (err) {
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
exports.prepareData = async (name, currencyId = 'USD', isUnique = true) => {
try {
const participantId = await Model.create(Object.assign(
{},
testParticipant,
{
name: (name || testParticipant.name) + (isUnique ? time.msToday().toString() : '')
}
))
const participantCurrencyId = await ParticipantCurrencyModel.create(participantId, currencyId, Enum.Accounts.LedgerAccountType.POSITION, false)
const participantCurrencyId2 = await ParticipantCurrencyModel.create(participantId, currencyId, Enum.Accounts.LedgerAccountType.SETTLEMENT, false)
const participant = await Model.getById(participantId)
return {
participant,
participantCurrencyId,
participantCurrencyId2
}
} catch (err) {
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
transferStateId = Enum.Transfers.TransferInternalState.ABORTED_ERROR
}
const isReversal = true
const transferStateChange = {
transferId: transferInfo.transferId,
transferStateId,
reason: transferInfo.reason
}
await PositionService.changeParticipantPosition(transferInfo.participantCurrencyId, isReversal, transferInfo.amount, transferStateChange)
await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, eventDetail })
histTimerEnd({ success: true, fspId: Config.INSTRUMENTATION_METRICS_LABELS.fspId })
return true
} else if (eventType === Enum.Events.Event.Type.POSITION && [Enum.Events.Event.Action.TIMEOUT_RESERVED, Enum.Events.Event.Action.BULK_TIMEOUT_RESERVED].includes(action)) {
Logger.info(Utility.breadcrumb(location, { path: 'timeout' }))
span.setTags({ transactionId: transferId })
const transferInfo = await TransferService.getTransferInfoToChangePosition(transferId, Enum.Accounts.TransferParticipantRoleType.PAYER_DFSP, Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE)
if (transferInfo.transferStateId !== Enum.Transfers.TransferInternalState.RESERVED_TIMEOUT) {
Logger.info(Utility.breadcrumb(location, `validationFailed::notReceivedFulfilState2--${actionLetter}6`))
throw ErrorHandler.Factory.createInternalServerFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR.message)
} else {
Logger.info(Utility.breadcrumb(location, `validationPassed2--${actionLetter}7`))
const isReversal = true
const transferStateChange = {
transferId: transferInfo.transferId,
transferStateId: Enum.Transfers.TransferInternalState.EXPIRED_RESERVED,
reason: ErrorHandler.Enums.FSPIOPErrorCodes.TRANSFER_EXPIRED.message
}
await PositionService.changeParticipantPosition(transferInfo.participantCurrencyId, isReversal, transferInfo.amount, transferStateChange)
const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.EXPIRED_ERROR, null, null, null, payload.extensionList)
if (action === Enum.Events.Event.Action.TIMEOUT_RESERVED) {
eventDetail.action = Enum.Events.Event.Action.ABORT
}
const validatePositionAccountByNameAndCurrency = async function (participantName, currency) {
const account = await Participant.getAccountByNameAndCurrency(participantName, currency, Enum.Accounts.LedgerAccountType.POSITION)
let validationPassed = false
if (!account) {
reasons.push(`Participant ${participantName} ${currency} account not found`)
} else if (!account.currencyIsActive) {
reasons.push(`Participant ${participantName} ${currency} account is inactive`)
} else {
validationPassed = true
}
return validationPassed
}
.innerJoin('transferParticipant AS tp1', function () {
this.on('tp1.transferId', 'tt.transferId')
.andOn('tp1.transferParticipantRoleTypeId', Enum.Accounts.TransferParticipantRoleType.PAYER_DFSP)
.andOn('tp1.ledgerEntryTypeId', Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE)
})
.innerJoin('transferParticipant AS tp2', function () {
const getLimits = async (name, { currency = null, type = null }) => {
try {
let participant
if (currency != null) {
participant = await ParticipantFacade.getByNameAndCurrency(name, currency, Enum.Accounts.LedgerAccountType.POSITION)
participantExists(participant)
return ParticipantFacade.getParticipantLimitsByCurrencyId(participant.participantCurrencyId, type)
} else {
participant = await ParticipantModel.getByName(name)
participantExists(participant)
return ParticipantFacade.getParticipantLimitsByParticipantId(participant.participantId, type, Enum.Accounts.LedgerAccountType.POSITION)
}
} catch (err) {
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const saveTransferPrepared = async (payload, stateReason = null, hasPassedValidation = true) => {
try {
const participants = []
const names = [payload.payeeFsp, payload.payerFsp]
for (const name of names) {
const participant = await ParticipantFacade.getByNameAndCurrency(name, payload.amount.currency, Enum.Accounts.LedgerAccountType.POSITION)
if (participant) {
participants.push(participant)
}
}
const participantCurrencyIds = await _.reduce(participants, (m, acct) =>
_.set(m, acct.name, acct.participantCurrencyId), {})
const transferRecord = {
transferId: payload.transferId,
amount: payload.amount.amount,
currencyId: payload.amount.currency,
ilpCondition: payload.condition,
expirationDate: Time.getUTCString(new Date(payload.expiration))
}