Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.665.0",
"@jadonamite/automata-core": "^1.0.1",
"@aws-sdk/s3-request-presigner": "^3.665.0",
"@jadonamite/automata-sdk": "^1.0.1",
"@sentry/node": "^8.0.0",
"chessify-protocol": "^0.1.0",
"cors": "^2.8.6",
Expand Down
25 changes: 10 additions & 15 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@

const express = require('express');
const cors = require('cors');
const { callSorobanContract } = require('./services/soroban');

Check failure on line 23 in src/app.js

View workflow job for this annotation

GitHub Actions / Lint

'callSorobanContract' is assigned a value but never used. Allowed unused vars must match /^_/u
const invoiceService = require('./services/invoiceService');
const { resolveEscrowAddress } = require('./config/escrowMap');
const { getEscrowStateWithProjection } = require('./services/escrowRead');
const { createCorsOptions, isCorsOriginRejectedError } = require('./config/cors');
const { validateInvoiceQueryParams, validateInvoicePayload } = require('./utils/validators');
const {
Expand Down Expand Up @@ -198,27 +199,21 @@
});
}

/**
* Soroban operation for escrow lookup using resolved contract address.
*
* @returns {Promise<object>} Escrow state with contract address
*/
const operation = async () => {
return {
invoiceId,
escrowAddress,
status: 'not_found',
fundedAmount: 0
};
};
// Read from projection, cache, or live read fallback
const state = await getEscrowStateWithProjection(invoiceId);

const data = await callSorobanContract(operation);
const data = {
...state,
escrowAddress
};

// Include escrow address in response headers
res.set('X-Escrow-Address', escrowAddress);
res.json({
data,
message: 'Escrow state read from Soroban contract via robust integration wrapper.',
message: state.fromProjection
? 'Escrow state read from event projection.'
: 'Escrow state read from live Soroban contract.',
});
} catch (error) {
res.status(500).json({ error: error.message || 'Error fetching escrow state' });
Expand Down
20 changes: 10 additions & 10 deletions src/routes/invoiceStateRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function conditionalKycGate(req, res, next) {
return next();
}

router.post('/:id/transition', conditionalKycGate, (req, res, next) => {
router.post('/:id/transition', conditionalKycGate, async (req, res, next) => {
const { id } = req.params;
const { targetState, reason } = req.body;

Expand Down Expand Up @@ -148,7 +148,7 @@ router.post('/:id/transition', conditionalKycGate, (req, res, next) => {
const userAgent = req.get('user-agent') || 'unknown';

// Execute transition
const result = executeTransition({
const result = await executeTransition({
invoiceId: id,
currentState,
targetState,
Expand Down Expand Up @@ -198,7 +198,7 @@ router.post('/:id/transition', conditionalKycGate, (req, res, next) => {
* POST /api/invoices/:id/approve
* Convenience endpoint to approve an invoice
*/
router.post('/:id/approve', (req, res, next) => {
router.post('/:id/approve', async (req, res, next) => {
const { id } = req.params;
const { reason } = req.body;

Expand All @@ -217,7 +217,7 @@ router.post('/:id/approve', (req, res, next) => {
const ipAddress = req.ip || req.socket.remoteAddress || 'unknown';
const userAgent = req.get('user-agent') || 'unknown';

const result = executeTransition({
const result = await executeTransition({
invoiceId: id,
currentState,
targetState: INVOICE_STATES.APPROVED,
Expand Down Expand Up @@ -266,7 +266,7 @@ router.post('/:id/approve', (req, res, next) => {
* This is a capital-movement endpoint: it initiates the escrow funding
* lifecycle. KYC must be verified before the link can be made.
*/
router.post('/:id/link-escrow', requireKycForFunding, (req, res, next) => {
router.post('/:id/link-escrow', requireKycForFunding, async (req, res, next) => {
const { id } = req.params;
const { escrowId, reason } = req.body;

Expand Down Expand Up @@ -294,7 +294,7 @@ router.post('/:id/link-escrow', requireKycForFunding, (req, res, next) => {
const ipAddress = req.ip || req.socket.remoteAddress || 'unknown';
const userAgent = req.get('user-agent') || 'unknown';

const result = executeTransition({
const result = await executeTransition({
invoiceId: id,
currentState,
targetState: INVOICE_STATES.LINKED_ESCROW,
Expand Down Expand Up @@ -343,7 +343,7 @@ router.post('/:id/link-escrow', requireKycForFunding, (req, res, next) => {
* GET /api/invoices/:id/history
* Get state transition history for an invoice
*/
router.get('/:id/history', (req, res) => {
router.get('/:id/history', async (req, res) => {
const { id } = req.params;

// Check if invoice exists
Expand All @@ -356,7 +356,7 @@ router.get('/:id/history', (req, res) => {
});
}

const history = getTransitionHistory(id, getAuditLogs);
const history = await getTransitionHistory(id, getAuditLogs);

res.json({
data: {
Expand All @@ -373,7 +373,7 @@ router.get('/:id/history', (req, res) => {
* POST /api/invoices/:id/reject
* Convenience endpoint to reject an invoice
*/
router.post('/:id/reject', (req, res, next) => {
router.post('/:id/reject', async (req, res, next) => {
const { id } = req.params;
const { reason } = req.body;

Expand All @@ -399,7 +399,7 @@ router.post('/:id/reject', (req, res, next) => {
const ipAddress = req.ip || req.socket.remoteAddress || 'unknown';
const userAgent = req.get('user-agent') || 'unknown';

const result = executeTransition({
const result = await executeTransition({
invoiceId: id,
currentState,
targetState: INVOICE_STATES.REJECTED,
Expand Down
Loading
Loading