@mojaloop/sdk-scheme-adapter 24.11.0-snapshot.4 → 24.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
package/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
1
  # Changelog: [mojaloop/sdk-scheme-adapter](https://github.com/mojaloop/sdk-scheme-adapter)
2
+ ## [24.11.0](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.10.11...v24.11.0) (2025-09-18)
3
+
4
+
5
+ ### Features
6
+
7
+ * **csi-1807:** improve transfer status delivery effort ([#614](https://github.com/mojaloop/sdk-scheme-adapter/issues/614)) ([65c9d1a](https://github.com/mojaloop/sdk-scheme-adapter/commit/65c9d1a5835af0e35b1c0bbe06990f7e26bc4b35))
8
+
9
+
10
+ ### Chore
11
+
12
+ * **sbom:** update sbom [skip ci] ([bdb946f](https://github.com/mojaloop/sdk-scheme-adapter/commit/bdb946f94d330b8f1d0f7f2a13b8962c4b410b11))
13
+
2
14
  ### [24.10.11](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.10.10...v24.10.11) (2025-09-15)
3
15
 
4
16
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-api-svc",
3
- "version": "21.0.0-snapshot.62",
3
+ "version": "21.0.0-snapshot.63",
4
4
  "description": "An adapter for connecting to Mojaloop API enabled switches.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -66,7 +66,7 @@
66
66
  "@koa/cors": "5.0.0",
67
67
  "@mojaloop/api-snippets": "18.1.1",
68
68
  "@mojaloop/central-services-error-handling": "13.1.2",
69
- "@mojaloop/central-services-logger": "11.9.3",
69
+ "@mojaloop/central-services-logger": "11.10.0",
70
70
  "@mojaloop/central-services-metrics": "12.7.1",
71
71
  "@mojaloop/central-services-shared": "18.33.2",
72
72
  "@mojaloop/event-sdk": "14.7.0",
@@ -530,6 +530,7 @@ class InboundTransfersModel {
530
530
  // Mark as notified to prevent duplicate notification
531
531
  await this._cache.set(cacheKey, true, 60);
532
532
  // Send notification to payee
533
+ this._logger.isInfoEnabled && this._logger.push({ transferId }).info('Received transfer callback for GET /transfers/{ID} request, sending notification to payee');
533
534
  await this.sendNotificationToPayee(message.data.body, transferId);
534
535
  break;
535
536
  }
@@ -1056,14 +1057,17 @@ class InboundTransfersModel {
1056
1057
  await new Promise((resolve) => {
1057
1058
  operation.attempt(async (currentAttempt) => {
1058
1059
  try {
1060
+ log.verbose(`putFxTransfersNotification attempt ${currentAttempt} for conversionId ${conversionId}`);
1059
1061
  res = await this._backendRequests.putFxTransfersNotification(responseBody, conversionId);
1060
1062
  // Consider success as long as it doesn't throw
1061
1063
  // `sendRequest` only seems to return `data` of the request which could
1062
1064
  // be empty for a 200 response
1063
- return resolve();
1065
+ log.verbose(`putFxTransfersNotification attempt ${currentAttempt} succeeded for conversionId ${conversionId}`);
1066
+ resolve();
1064
1067
  } catch (err) {
1065
1068
  log.warn(`putFxTransfersNotification attempt ${currentAttempt} threw error, retrying...`, err);
1066
1069
  if (!operation.retry(err)) {
1070
+ log.verbose(`putFxTransfersNotification giving up after ${currentAttempt} attempts`);
1067
1071
  resolve();
1068
1072
  }
1069
1073
  }
@@ -1071,6 +1075,7 @@ class InboundTransfersModel {
1071
1075
  });
1072
1076
  } else {
1073
1077
  try {
1078
+ log.verbose(`putFxTransfersNotification no-retry mode for conversionId ${conversionId}`);
1074
1079
  res = await this._backendRequests.putFxTransfersNotification(responseBody, conversionId);
1075
1080
  } catch (err) {
1076
1081
  log.error('putFxTransfersNotification failed', err);
@@ -1085,6 +1090,7 @@ class InboundTransfersModel {
1085
1090
  * Forwards Switch notification for fulfiled transfer to the DFSP backend, when acting as a payee
1086
1091
  */
1087
1092
  async sendNotificationToPayee(body, transferId) {
1093
+ const log = this._logger.child({ transferId });
1088
1094
  try {
1089
1095
  // load any cached state for this transfer e.g. quote request/response etc...
1090
1096
  this.data = await this._load(transferId);
@@ -1133,16 +1139,19 @@ class InboundTransfersModel {
1133
1139
  await new Promise((resolve) => {
1134
1140
  operation.attempt(async (currentAttempt) => {
1135
1141
  try {
1142
+ log.verbose(`putTransfersNotification attempt ${currentAttempt} for transferId ${transferId}`);
1136
1143
  res = await this._backendRequests.putTransfersNotification(this.data, transferId);
1137
1144
  // Consider success as long as it doesn't throw
1138
1145
  // `sendRequest` only seems to return `data` of the request which could
1139
1146
  // be empty for a 200 response
1140
1147
  const cacheKey = `patchNotificationSent_${transferId}`;
1141
1148
  await this._cache.set(cacheKey, true, 60);
1142
- return resolve();
1149
+ log.verbose(`putTransfersNotification attempt ${currentAttempt} succeeded for transferId ${transferId}`);
1150
+ resolve();
1143
1151
  } catch (err) {
1144
1152
  this._logger.warn(`putTransfersNotification attempt ${currentAttempt} threw error, retrying...`, err);
1145
1153
  if (!operation.retry(err)) {
1154
+ log.verbose(`putTransfersNotification giving up after ${currentAttempt} attempts`);
1146
1155
  resolve();
1147
1156
  }
1148
1157
  }
@@ -1150,6 +1159,7 @@ class InboundTransfersModel {
1150
1159
  });
1151
1160
  } else {
1152
1161
  try {
1162
+ log.verbose(`putTransfersNotification no-retry mode for transferId ${transferId}`);
1153
1163
  res = await this._backendRequests.putTransfersNotification(this.data, transferId);
1154
1164
  const cacheKey = `patchNotificationSent_${transferId}`;
1155
1165
  await this._cache.set(cacheKey, true, 60);
@@ -325,7 +325,6 @@ describe('Inbound API handlers transforming incoming ISO20022 message bodies', (
325
325
  expect(transferRequestSpy.mock.calls[0][0]).not.toEqual(isoBodies.patchTransfersRequest);
326
326
  expect(transferRequestSpy.mock.calls[0][0].transferState).toBe('COMMITTED');
327
327
  expect(mockContext.response.status).toBe(200);
328
- console.log('Response body:', mockContext.response);
329
328
  });
330
329
  });
331
330
 
@@ -1036,7 +1036,7 @@ describe('inboundModel', () => {
1036
1036
  });
1037
1037
 
1038
1038
  test('does not retry notification to fsp backend if disabled', async () => {
1039
- const mockFn = jest.fn().mockResolvedValue({ status: 200 });
1039
+ const mockFn = jest.fn().mockRejectedValue(new Error('fail'));
1040
1040
  BackendRequests.__putTransfersNotification = mockFn;
1041
1041
 
1042
1042
  const notif = JSON.parse(JSON.stringify(notificationToPayee));
@@ -1202,68 +1202,6 @@ describe('inboundModel', () => {
1202
1202
  await expect(model.sendNotificationToPayee(notif.data, 'some-transfer-id')).resolves.toBeUndefined();
1203
1203
  });
1204
1204
 
1205
- test('retries notification to backend on failure for sendFxPutNotificationToBackend if enabled', async () => {
1206
- // Simulate failure for first 2 attempts, then success
1207
- const mockFn = jest.fn()
1208
- .mockRejectedValueOnce(new Error('fail1'))
1209
- .mockRejectedValueOnce(new Error('fail2'))
1210
- .mockResolvedValue({ status: 200 });
1211
- BackendRequests.__putFxTransfersNotification = mockFn;
1212
-
1213
- const notif = JSON.parse(JSON.stringify(fxNotificationToBackend));
1214
- const model = new Model({
1215
- ...config,
1216
- cache,
1217
- logger,
1218
- backendRequestRetry: {
1219
- enabled: true,
1220
- maxRetries: 3,
1221
- retryDelayMs: 10,
1222
- maxRetryDelayMs: 20,
1223
- backoffFactor: 1
1224
- }
1225
- });
1226
- model.saveFxState = jest.fn().mockReturnValue(Promise.resolve({}));
1227
-
1228
- await model.sendFxPutNotificationToBackend(notif.data, conversionId);
1229
- expect(BackendRequests.__putFxTransfersNotification).toHaveBeenCalledTimes(3);
1230
- });
1231
-
1232
- test('does not retry notification to backend for sendFxPutNotificationToBackend if disabled', async () => {
1233
- const mockFn = jest.fn().mockResolvedValue({ status: 200 });
1234
- BackendRequests.__putFxTransfersNotification = mockFn;
1235
-
1236
- const notif = JSON.parse(JSON.stringify(fxNotificationToBackend));
1237
- const model = new Model({
1238
- ...config,
1239
- cache,
1240
- logger,
1241
- backendRequestRetry: {
1242
- enabled: false
1243
- }
1244
- });
1245
- model.saveFxState = jest.fn().mockReturnValue(Promise.resolve({}));
1246
-
1247
- await model.sendFxPutNotificationToBackend(notif.data, conversionId);
1248
- expect(BackendRequests.__putFxTransfersNotification).toHaveBeenCalledTimes(1);
1249
- });
1250
-
1251
- test('sendFxPutNotificationToBackend handles error and still saves state', async () => {
1252
- BackendRequests.__putFxTransfersNotification = jest.fn().mockRejectedValue(new Error('fail'));
1253
- const notif = JSON.parse(JSON.stringify(fxNotificationToBackend));
1254
- const model = new Model({
1255
- ...config,
1256
- cache,
1257
- logger,
1258
- backendRequestRetry: {
1259
- enabled: false
1260
- }
1261
- });
1262
- const saveFxStateSpy = jest.spyOn(model, 'saveFxState').mockResolvedValue({});
1263
- await expect(model.sendFxPutNotificationToBackend(notif.data, conversionId)).resolves.toBeUndefined();
1264
- expect(saveFxStateSpy).toHaveBeenCalled();
1265
- });
1266
-
1267
1205
  test('sendNotificationToPayee handles error and still returns', async () => {
1268
1206
  BackendRequests.__putTransfersNotification = jest.fn().mockRejectedValue(new Error('fail'));
1269
1207
  const notif = JSON.parse(JSON.stringify(notificationToPayee));
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-outbound-command-event-handler",
3
- "version": "0.3.0-snapshot.58",
3
+ "version": "0.3.0-snapshot.59",
4
4
  "description": "Mojaloop sdk scheme adapter command event handler",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter/",
@@ -60,7 +60,7 @@
60
60
  "@types/convict": "6.1.6",
61
61
  "@types/express": "5.0.3",
62
62
  "@types/jest": "30.0.0",
63
- "@types/node": "24.5.1",
63
+ "@types/node": "24.5.2",
64
64
  "@types/node-cache": "4.2.5",
65
65
  "@types/supertest": "6.0.3",
66
66
  "@types/swagger-ui-express": "4.1.8",
@@ -74,7 +74,7 @@
74
74
  "npm-check-updates": "16.7.10",
75
75
  "replace": "1.2.2",
76
76
  "standard-version": "9.5.0",
77
- "ts-jest": "29.4.2",
77
+ "ts-jest": "29.4.3",
78
78
  "ts-node": "10.9.2",
79
79
  "typescript": "5.9.2"
80
80
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-outbound-domain-event-handler",
3
- "version": "0.3.0-snapshot.58",
3
+ "version": "0.3.0-snapshot.59",
4
4
  "description": "mojaloop sdk scheme adapter outbound domain event handler",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter/",
@@ -57,7 +57,7 @@
57
57
  "@types/convict": "6.1.6",
58
58
  "@types/express": "5.0.3",
59
59
  "@types/jest": "30.0.0",
60
- "@types/node": "24.5.1",
60
+ "@types/node": "24.5.2",
61
61
  "@types/node-cache": "4.2.5",
62
62
  "@types/supertest": "6.0.3",
63
63
  "@types/swagger-ui-express": "4.1.8",
@@ -71,7 +71,7 @@
71
71
  "npm-check-updates": "16.7.10",
72
72
  "replace": "1.2.2",
73
73
  "standard-version": "9.5.0",
74
- "ts-jest": "29.4.2",
74
+ "ts-jest": "29.4.3",
75
75
  "ts-node": "10.9.2",
76
76
  "typescript": "5.9.2"
77
77
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-private-shared-lib",
3
- "version": "0.4.0-snapshot.58",
3
+ "version": "0.4.0-snapshot.59",
4
4
  "description": "SDK Scheme Adapter private shared library.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/accounts-and-balances-bc/tree/main/modules/private-types",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@eslint/compat": "1.3.2",
43
- "@types/node": "24.5.1",
43
+ "@types/node": "24.5.2",
44
44
  "@types/uuid": "10.0.0",
45
45
  "@typescript-eslint/eslint-plugin": "8.44.0",
46
46
  "@typescript-eslint/parser": "8.44.0",
@@ -49,7 +49,7 @@
49
49
  "npm-check-updates": "16.7.10",
50
50
  "replace": "1.2.2",
51
51
  "standard-version": "9.5.0",
52
- "ts-jest": "29.4.2",
52
+ "ts-jest": "29.4.3",
53
53
  "tslib": "2.8.1",
54
54
  "typescript": "5.9.2"
55
55
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter",
3
- "version": "24.11.0-snapshot.4",
3
+ "version": "24.11.0",
4
4
  "description": "mojaloop sdk-scheme-adapter",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter",
@@ -82,7 +82,7 @@
82
82
  },
83
83
  "devDependencies": {
84
84
  "@types/jest": "30.0.0",
85
- "@types/node": "24.5.1",
85
+ "@types/node": "24.5.2",
86
86
  "@types/node-cache": "4.2.5",
87
87
  "@typescript-eslint/eslint-plugin": "8.44.0",
88
88
  "@typescript-eslint/parser": "8.44.0",
@@ -97,7 +97,7 @@
97
97
  "npm-check-updates": "16.7.10",
98
98
  "replace": "1.2.2",
99
99
  "standard-version": "9.5.0",
100
- "ts-jest": "29.4.2",
100
+ "ts-jest": "29.4.3",
101
101
  "ts-node": "10.9.2",
102
102
  "typescript": "5.9.2",
103
103
  "yarn-audit-fix": "10.1.1"