@mojaloop/sdk-scheme-adapter 24.11.0-snapshot.5 → 24.12.0-snapshot.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.
package/.yarnrc.yml CHANGED
@@ -4,4 +4,4 @@ enableGlobalCache: false
4
4
 
5
5
  nodeLinker: node-modules
6
6
 
7
- yarnPath: .yarn/releases/yarn-4.9.4.cjs
7
+ yarnPath: .yarn/releases/yarn-4.10.1.cjs
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
 
@@ -55,7 +55,7 @@
55
55
  "TEST_CASES_REPO_OWNER": "mojaloop",
56
56
  "TEST_CASES_REPO_NAME": "testing-toolkit-test-cases",
57
57
  "TEST_CASES_REPO_DEFAULT_RELEASE_TAG": "latest",
58
- "TEST_CASES_REPO_BASE_PATH": "collections/dfsp",
58
+ "TEST_CASES_REPO_BASE_PATH": "collections/pm4ml",
59
59
  "TEST_CASES_REPO_HUB_GP_PATH": "collections/hub/golden_path",
60
60
  "TEST_CASES_REPO_HUB_PROVISIONING_PATH": "collections/hub/provisioning"
61
61
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-api-svc",
3
- "version": "21.0.0-snapshot.63",
3
+ "version": "21.0.0-snapshot.64",
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",
@@ -130,6 +130,7 @@ const createOutboundTransfersModel = (ctx) => new OutboundTransfersModel({
130
130
  logger: ctx.state.logger,
131
131
  wso2: ctx.state.wso2,
132
132
  metricsClient: ctx.state.metricsClient,
133
+ sharedAgents: ctx.state.sharedAgents,
133
134
  });
134
135
 
135
136
  const createOutboundBulkTransfersModel = (ctx) => new OutboundBulkTransfersModel({
@@ -466,6 +467,7 @@ const postAccounts = async (ctx) => {
466
467
  cache: ctx.state.cache,
467
468
  logger: ctx.state.logger,
468
469
  wso2: ctx.state.wso2,
470
+ sharedAgents: ctx.state.sharedAgents,
469
471
  });
470
472
 
471
473
  const state = {
@@ -496,6 +498,7 @@ const deleteAccountByTypeAndId = async (ctx) => {
496
498
  cache: ctx.state.cache,
497
499
  logger: ctx.state.logger,
498
500
  wso2: ctx.state.wso2,
501
+ sharedAgents: ctx.state.sharedAgents,
499
502
  });
500
503
 
501
504
  const args = {
@@ -25,6 +25,7 @@
25
25
  --------------
26
26
  ******/
27
27
  const http = require('http');
28
+ const https = require('https');
28
29
 
29
30
  const Koa = require('koa');
30
31
  const koaBody = require('koa-body').default;
@@ -51,7 +52,7 @@ const _validator = new Validate({ logExcludePaths });
51
52
  let _initialize;
52
53
 
53
54
  class OutboundApi extends EventEmitter {
54
- constructor(conf, logger, cache, validator, metricsClient, wso2, eventProducer, eventLogger) {
55
+ constructor(conf, logger, cache, validator, metricsClient, wso2, eventProducer, eventLogger, sharedAgents) {
55
56
  super({ captureExceptions: true });
56
57
  this._logger = logger.push({ component: this.constructor.name });
57
58
  this._api = new Koa();
@@ -72,7 +73,8 @@ class OutboundApi extends EventEmitter {
72
73
  metricsClient,
73
74
  logExcludePaths,
74
75
  eventProducer,
75
- eventLogger
76
+ eventLogger,
77
+ sharedAgents
76
78
  }));
77
79
  this._api.use(middlewares.createLogger(this._logger));
78
80
 
@@ -110,6 +112,27 @@ class OutboundServer extends EventEmitter {
110
112
  this._conf = conf;
111
113
  this._logger = logger.push({ app: this.constructor.name });
112
114
  this._server = null;
115
+
116
+ // Create shared HTTP and HTTPS agents to prevent agent recreation per request
117
+ this._httpAgent = new http.Agent({
118
+ keepAlive: true,
119
+ maxSockets: conf.outbound.maxSockets || 256,
120
+ });
121
+
122
+ // Create HTTPS agent based on TLS configuration
123
+ const httpsAgentOptions = {
124
+ keepAlive: true,
125
+ maxSockets: conf.outbound.maxSockets || 256,
126
+ };
127
+
128
+ // Apply TLS configuration if mTLS is enabled
129
+ if (conf.outbound.tls.mutualTLS.enabled && conf.outbound.tls.creds) {
130
+ Object.assign(httpsAgentOptions, conf.outbound.tls.creds);
131
+ }
132
+
133
+ this._httpsAgent = new https.Agent(httpsAgentOptions);
134
+
135
+ this._logger.isInfoEnabled && this._logger.info('Created shared HTTP and HTTPS agents with keepAlive enabled');
113
136
  if (conf.backendEventHandler.enabled) {
114
137
  this._eventLogger = new DefaultLogger(BC_CONFIG.bcName, 'backend-api-handler', '0.0.1', conf.logLevel);
115
138
  this._eventProducer = new KafkaDomainEventProducer(conf.backendEventHandler.domainEventProducer, this._eventLogger);
@@ -124,6 +147,10 @@ class OutboundServer extends EventEmitter {
124
147
  wso2,
125
148
  this._eventProducer,
126
149
  this._eventLogger,
150
+ {
151
+ httpAgent: this._httpAgent,
152
+ httpsAgent: this._httpsAgent
153
+ }
127
154
  );
128
155
  this._api.on('error', (...args) => {
129
156
  this.emit('error', ...args);
@@ -48,8 +48,9 @@ class AccountsModel {
48
48
  this._logger = config.logger;
49
49
  this._requestProcessingTimeoutSeconds = config.requestProcessingTimeoutSeconds;
50
50
  this._dfspId = config.dfspId;
51
+ this._sharedAgents = config.sharedAgents;
51
52
 
52
- this._requests = new MojaloopRequests({
53
+ const mojaloopRequestsConfig = {
53
54
  logger: this._logger,
54
55
  peerEndpoint: config.alsEndpoint,
55
56
  dfspId: config.dfspId,
@@ -62,7 +63,16 @@ class AccountsModel {
62
63
  wso2: config.wso2,
63
64
  resourceVersions: config.resourceVersions,
64
65
  apiType: config.apiType
65
- });
66
+ };
67
+
68
+ // Add shared agents to prevent HTTPS agent recreation per request
69
+ if (this._sharedAgents) {
70
+ mojaloopRequestsConfig.httpAgent = this._sharedAgents.httpAgent;
71
+ mojaloopRequestsConfig.httpsAgent = this._sharedAgents.httpsAgent;
72
+ this._logger.isDebugEnabled && this._logger.debug('Using shared HTTP/HTTPS agents for AccountsModel MojaloopRequests');
73
+ }
74
+
75
+ this._requests = new MojaloopRequests(mojaloopRequestsConfig);
66
76
  }
67
77
 
68
78
 
@@ -71,6 +71,7 @@ class OutboundTransfersModel {
71
71
  this._useQuoteSourceFSPAsTransferPayeeFSP = config.useQuoteSourceFSPAsTransferPayeeFSP;
72
72
  this._checkIlp = config.checkIlp;
73
73
  this._multiplePartiesResponse = config.multiplePartiesResponse;
74
+ this._sharedAgents = config.sharedAgents;
74
75
  this._multiplePartiesResponseSeconds = config.multiplePartiesResponseSeconds;
75
76
  this._sendFinalNotificationIfRequested = config.sendFinalNotificationIfRequested;
76
77
  this._apiType = config.apiType;
@@ -82,7 +83,7 @@ class OutboundTransfersModel {
82
83
 
83
84
  this._cacheTtl = config.redisCacheTtl;
84
85
 
85
- this._requests = new MojaloopRequests({
86
+ const mojaloopRequestsConfig = {
86
87
  logger: this._logger,
87
88
  peerEndpoint: config.peerEndpoint,
88
89
  alsEndpoint: config.alsEndpoint,
@@ -102,7 +103,16 @@ class OutboundTransfersModel {
102
103
  wso2: config.wso2,
103
104
  resourceVersions: config.resourceVersions,
104
105
  apiType: config.apiType,
105
- });
106
+ };
107
+
108
+ // Add shared agents to prevent HTTPS agent recreation per request
109
+ if (this._sharedAgents) {
110
+ mojaloopRequestsConfig.httpAgent = this._sharedAgents.httpAgent;
111
+ mojaloopRequestsConfig.httpsAgent = this._sharedAgents.httpsAgent;
112
+ this._logger.isDebugEnabled && this._logger.debug('Using shared HTTP/HTTPS agents for MojaloopRequests');
113
+ }
114
+
115
+ this._requests = new MojaloopRequests(mojaloopRequestsConfig);
106
116
 
107
117
  // default to ILP 1 unless v4 is set
108
118
  const ilpVersion = config.ilpVersion === '4' ? Ilp.ILP_VERSIONS.v4 : Ilp.ILP_VERSIONS.v1;
@@ -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));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter",
3
- "version": "24.11.0-snapshot.5",
3
+ "version": "24.12.0-snapshot.0",
4
4
  "description": "mojaloop sdk-scheme-adapter",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter",
@@ -18,7 +18,7 @@
18
18
  "Yevhen Kyriukha <yevhen.kyriukha@modusbox.com>",
19
19
  "Vijay Kumar Guthi <vijaya.guthi@modusbox.com>"
20
20
  ],
21
- "packageManager": "yarn@4.9.4",
21
+ "packageManager": "yarn@4.10.1",
22
22
  "engines": {
23
23
  "yarn": "3.2.0"
24
24
  },