Files
smom-dbis-138/services/settlement-middleware/dist/workflows/transfer.js
zaragoza444 458f3b420b
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m31s
CI/CD Pipeline / Security Scanning (push) Successful in 3m4s
CI/CD Pipeline / Lint and Format (push) Failing after 45s
CI/CD Pipeline / Terraform Validation (push) Failing after 28s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 44s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 36s
Validation / validate-genesis (push) Successful in 30s
Validation / validate-terraform (push) Failing after 30s
Validation / validate-kubernetes (push) Failing after 10s
Validation / validate-smart-contracts (push) Failing after 12s
Validation / validate-security (push) Failing after 1m52s
Validation / validate-documentation (push) Failing after 18s
Verify Deployment / Verify Deployment (push) Failing after 57s
feat: wire production settlement rails for M2 mint, transfers, and bank SWIFT
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 02:54:53 -07:00

154 lines
6.7 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.processTransfer = processTransfer;
const uuid_1 = require("uuid");
const settlement_core_1 = require("@dbis/settlement-core");
const config_1 = require("../config");
const fineract_1 = require("../adapters/fineract");
const hybx_production_1 = require("../adapters/hybx-production");
const omnl_1 = require("../adapters/omnl");
const swift_1 = require("../adapters/swift");
const settlement_store_1 = require("../store/settlement-store");
async function processTransfer(input) {
const cfg = (0, config_1.loadConfig)();
const profile = (0, config_1.loadOfficeProfile)();
const officeId = (0, config_1.settlementOfficeId)(input.officeId);
const req = { ...input, officeId };
const isExternal = req.rail === 'SWIFT' || req.rail === 'RTGS';
const existing = settlement_store_1.settlementStore.getByIdempotencyKey(req.idempotencyKey);
if (existing?.phase === 'SETTLED')
return existing;
const now = new Date().toISOString();
let record = existing ?? {
settlementId: (0, uuid_1.v4)(),
idempotencyKey: req.idempotencyKey,
phase: 'RECEIVED',
request: {
idempotencyKey: req.idempotencyKey,
officeId,
valueDate: now.slice(0, 10),
currency: req.currency ?? 'USD',
amount: req.amount,
creditorIban: req.creditorIban ?? (isExternal ? '' : 'INTERNAL-CHAIN138'),
beneficiaryName: req.beneficiaryName ?? req.recipientAddress,
remittanceInfo: req.remittanceInfo ?? `Transfer ${req.tokenSymbol}${req.recipientAddress}`,
moneyLayers: req.moneyLayers.length ? req.moneyLayers : ['M2'],
rail: req.rail === 'CHAIN138' ? 'CHAIN138' : req.rail === 'INTERNAL' ? 'INTERNAL' : 'SWIFT',
},
errors: [],
createdAt: now,
updatedAt: now,
};
const advance = (phase, patch = {}) => {
record = { ...record, phase, updatedAt: new Date().toISOString(), ...patch };
settlement_store_1.settlementStore.save(record);
};
try {
if (isExternal && !req.creditorIban) {
throw new Error('creditorIban required for external transfer');
}
advance('VALIDATED');
advance('VERBIAGE_ROLLED', {
verbiageDocument: [
`OMNL ${req.rail} transfer · ${req.tokenSymbol}`,
`M2 layer · ${req.amount}`,
`To ${req.recipientAddress}`,
isExternal ? `IBAN ${req.creditorIban}` : 'Internal / Chain 138',
].join('\n'),
});
const amount = parseFloat(req.amount) || 0;
if (amount > 0) {
const [debitGlId, creditGlId] = await Promise.all([
(0, fineract_1.resolveGlAccountId)(profile.settlement.glM2 ?? settlement_core_1.GL_CODES.M2_BROAD),
(0, fineract_1.resolveGlAccountId)(profile.settlement.glSettlement ?? settlement_core_1.GL_CODES.SETTLEMENT_SUSPENSE),
]);
const je = await (0, fineract_1.postJournalEntry)({
officeId,
transactionDate: now.slice(0, 10),
referenceNumber: req.idempotencyKey,
comments: `${req.rail} transfer ${req.tokenSymbol}`,
debits: [{ glAccountId: debitGlId, amount }],
credits: [{ glAccountId: creditGlId, amount }],
});
advance('FINERACT_POSTED', { fineractJournalRef: String(je.resourceId) });
}
else {
advance('FINERACT_POSTED');
}
if (isExternal && cfg.rails.hybx.enabled) {
const hybx = new hybx_production_1.HybxProductionRail();
const pay = await hybx.dispatchPayment({
idempotencyKey: req.idempotencyKey,
amount: req.amount,
currency: req.currency ?? 'USD',
creditorIban: req.creditorIban,
beneficiaryName: req.beneficiaryName ?? req.recipientAddress,
remittanceInfo: req.remittanceInfo ?? `OMNL ${req.tokenSymbol} external transfer`,
rail: req.rail === 'RTGS' ? 'RTGS' : 'SWIFT',
});
advance('HYBX_RAIL_DISPATCHED', { hybxPaymentId: pay.paymentId });
}
else {
advance('HYBX_RAIL_DISPATCHED');
}
if (isExternal && cfg.rails.swift.enabled && req.creditorIban) {
const swiftRaw = (0, swift_1.buildMt103Stub)({
senderRef: req.idempotencyKey,
currency: req.currency ?? 'USD',
amount: req.amount,
valueDate: now.slice(0, 10),
orderingCustomer: cfg.omnlLegalName,
beneficiary: req.beneficiaryName ?? req.recipientAddress,
iban: req.creditorIban,
remittance: req.remittanceInfo ?? `OMNL ${req.tokenSymbol}`,
});
await (0, swift_1.forwardSwiftToListener)(swiftRaw);
const iso = await (0, omnl_1.archiveIso20022)({
messageType: 'pacs.008',
direction: 'OUTBOUND',
raw: swiftRaw,
settlementRef: record.settlementId,
});
advance('ISO20022_ARCHIVED', { iso20022MessageId: iso.messageId });
}
else {
advance('ISO20022_ARCHIVED');
}
if (!isExternal && req.tokenAddress && cfg.production.allowChainMintExecute) {
const xfer = await (0, omnl_1.requestTokenTransfer)({
tokenAddress: req.tokenAddress,
amount: req.amount,
recipient: req.recipientAddress,
settlementRef: record.settlementId,
dryRun: false,
symbol: req.tokenSymbol,
});
advance('CHAIN_MINT_REQUESTED', {
chainTxHash: xfer.txHash,
verbiageDocument: [
record.verbiageDocument,
`On-chain ERC-20 transfer: ${req.tokenAddress}${req.recipientAddress}`,
xfer.txHash ? `tx ${xfer.txHash}` : `status ${xfer.status}`,
].join('\n'),
});
}
else {
advance('CHAIN_MINT_REQUESTED', {
verbiageDocument: [
record.verbiageDocument,
isExternal
? 'Bank rail (SWIFT/IBAN) — no on-chain transfer'
: `On-chain ERC-20 transfer prepared: ${req.tokenAddress}${req.recipientAddress}`,
].join('\n'),
});
}
advance('SETTLED');
return record;
}
catch (err) {
record.errors.push(err instanceof Error ? err.message : String(err));
advance('FAILED');
return record;
}
}