@mojaloop/sdk-scheme-adapter 24.14.0-snapshot.0 → 24.14.0-snapshot.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-api-svc",
3
- "version": "21.0.0-snapshot.71",
3
+ "version": "21.0.0-snapshot.72",
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",
@@ -147,11 +147,9 @@ class Client extends ws {
147
147
  * `Client` instances outside of this class should be created via the `Create(...args)` static method.
148
148
  */
149
149
  constructor({ address = 'localhost', port, logger, appConfig }) {
150
- const wsUrl = `ws://${address}:${port}`;
151
- super(wsUrl);
150
+ super(`ws://${address}:${port}`);
152
151
  this._logger = logger.push({ component: 'ControlClientWs' });
153
152
  this._appConfig = appConfig;
154
- this._wsUrl = wsUrl;
155
153
  }
156
154
 
157
155
  // Really only exposed so that a user can import only the client for convenience
@@ -214,7 +212,7 @@ class Client extends ws {
214
212
  * Call the Connector Manager in Management API to get the updated config
215
213
  */
216
214
  async getUpdatedConfig() { // clarify naming - why config is updated?
217
- this._logger.info(`Getting updated config from Management API at ${this._wsUrl}...`);
215
+ this._logger.info(`Getting updated config from Management API at ${this.url}...`);
218
216
  const wsSendResponse = await this.send(build.CONFIGURATION.READ());
219
217
  this._logger.debug('wsSendResponse: ', { wsSendResponse });
220
218
 
@@ -53,7 +53,7 @@ const { ReturnCodes } = Enum.Http;
53
53
  * Error handling logic shared by outbound API handlers
54
54
  */
55
55
  const handleError = (method, err, ctx, stateField) => {
56
- ctx.state.logger.push({ err, stateField }).error(`Error handling ${method}`);
56
+ ctx.state.logger.push({ stateField }).error(`Error handling ${method}: `, err);
57
57
  ctx.response.status = err.httpStatusCode || ReturnCodes.INTERNALSERVERERRROR.CODE;
58
58
  ctx.response.body = {
59
59
  message: err.message || 'Unspecified error',
@@ -26,6 +26,7 @@
26
26
  ******/
27
27
  'use strict';
28
28
 
29
+ const { hostname } = require('node:os');
29
30
  const EventEmitter = require('node:events');
30
31
  const http = require('http');
31
32
  const https = require('https');
@@ -250,7 +251,7 @@ class Server extends EventEmitter {
250
251
  this.logger.warn('No config received from polling');
251
252
  return;
252
253
  }
253
- this.logger.info('polling config from Management API is done, restarting server...');
254
+ this.logger.info('polling config from mgmt-api is done, checking if SDK server restart needed...');
254
255
 
255
256
  const mergedConfig = _.merge({}, this.conf, newConfig);
256
257
  await this.restart(mergedConfig, { source: 'polling' });
@@ -326,7 +327,7 @@ class Server extends EventEmitter {
326
327
 
327
328
  // Race condition prevention
328
329
  if (this._configUpdateInProgress) {
329
- this.logger.info('Restart already in progress, skipping', { source });
330
+ this.logger.info('restart already in progress, skipping', { source });
330
331
  return;
331
332
  }
332
333
 
@@ -592,7 +593,7 @@ async function start(config) {
592
593
  process.exit(1);
593
594
  });
594
595
 
595
- logger.info('SDK server is started', { name, version });
596
+ logger.info('SDK server is started', { name, version, hostname: hostname() });
596
597
  }
597
598
 
598
599
  if (require.main === module) {
@@ -25,15 +25,14 @@
25
25
  --------------
26
26
  ******/
27
27
 
28
- const { hostname } = require('node:os');
29
28
  const { loggerFactory, LOG_LEVELS } = require('@mojaloop/sdk-standard-components').Logger;
30
29
 
31
30
  const createLogger = (conf = {}) => {
32
31
  const {
33
32
  context = {
33
+ context: 'SDK',
34
34
  // If we're running from a Mojaloop helm chart deployment, we'll have a SIM_NAME
35
35
  simulator: process.env['SIM_NAME'],
36
- hostname: hostname(),
37
36
  },
38
37
  isJsonOutput = false,
39
38
  } = conf;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-outbound-command-event-handler",
3
- "version": "0.3.0-snapshot.66",
3
+ "version": "0.3.0-snapshot.67",
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/",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-outbound-domain-event-handler",
3
- "version": "0.3.0-snapshot.66",
3
+ "version": "0.3.0-snapshot.67",
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/",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter-private-shared-lib",
3
- "version": "0.4.0-snapshot.66",
3
+ "version": "0.4.0-snapshot.67",
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter",
3
- "version": "24.14.0-snapshot.0",
3
+ "version": "24.14.0-snapshot.1",
4
4
  "description": "mojaloop sdk-scheme-adapter",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter",
@@ -1,74 +0,0 @@
1
- You are a senior backend engineer mentoring interns/junior JS developers. Your task is to study this repository
2
- (it also cn be found by link: https://github.com/mojaloop/sdk-scheme-adapter)
3
-
4
- Target branch: `main`; if multiple active branches or major forks exist, compare and note differences)
5
-
6
- ## Mission
7
- 1) Understand and explain Business Logic and Architecture.
8
- 2) Produce accurate, implementation-level notes (no hand-waving).
9
- 3) Save all findings as Markdown files in `./_cc/docs` folder suitable for onboarding juniors.
10
- 4) Prefer concise, example-driven explanations with TypeScript/JavaScript snippets and Mermaid diagrams.
11
- 5) Link all new files in `CLAUDE.md` with really brief explanation what each file is about.
12
-
13
- ## Critical Focus Areas (business logic, architecture, and main implementation details)
14
- - Inbound server (FSPIOP / ISO 20022 formats)
15
- - Outbound server (Mojaloop SDK Outbound Scheme Adapter API)
16
- - Request state management (Redis usage, keys, TTLs, state-machine/lifecycle)
17
- - ControlAgent (WebSocket agent) integration with PM4ML management API:
18
- https://github.com/pm4ml/mojaloop-payment-manager-management-api
19
- - Mojaloop SDK Backend API (interactions with core connectors and DFSP backend systems)
20
-
21
- ## Deliverables (Markdown in ./_cc/docs)
22
- Create separate files (add more if helpful):
23
- - High-level overview + quickstart. Who uses this service, how it fits Mojaloop hub DFSP workflows.
24
- - System context, containers/components, runtime topology, configs/env. Include:
25
- - Sequence diagrams (PlantUML) for key flows (e.g., Payer DFSP -> Inbound -> Backend -> Outbound -> Switch -> callback).
26
- - Inbound Server: Purpose, routes, request/response schemas, auth/security, validation, error handling, retry/backoff, logging/tracing.
27
- - Outbound Server: Outbound API surface, happy-path + failure flows, idempotency, correlation IDs, callback handling.
28
- - Request State Management (using Redis):
29
- - Keys, value shapes, expirations, pub/sub usage (if any), transactionality.
30
- - State machine diagram (Mermaid) for request lifecycle (init → pending → fulfilled/errored/cancelled).
31
- - Recovery logic on restarts, exactly-once/at-least-once semantics, race-condition mitigations.
32
- - ControlAgent design:
33
- - WebSocket lifecycle, message formats, heartbeats, reconnection, auth.
34
- - Interface with PM4ML management API (endpoints used, commands, examples) - https://github.com/pm4ml/mojaloop-payment-manager-management-api
35
- - Backend API: Mojaloop SDK Backend API spec relevant here:
36
- - Endpoints, payload shapes, correlation rules, error codes.
37
- - Mapping between inbound/outbound and backend calls (table).
38
- - Error handling patterns: Error taxonomy, standardized problem codes, logs, metrics, traces.
39
- - Glossary — Mojaloop terms, DFSP, transfer, quote, callback, ILP, FSPIOP, etc., with links to code.
40
-
41
- ## Analysis Instructions
42
- - Read source code, package.json scripts, config files, OpenAPI/Swagger specs, and README(s).
43
- - Infer actual behavior from code over docs when they disagree; call out discrepancies.
44
- - Capture all external dependencies (libraries, services, ports).
45
- - Map end-to-end flows for: party lookup, quote, transfer, and callback handling.
46
- - Document correlation and idempotency strategies (HTTP headers, FSPIOP signatures/urls, state keys).
47
- - Note security: TLS, signing, auth between components, any PII handling, and compliance concerns.
48
- - For Redis, provide concrete key examples and short JS code snippets showing set/get patterns used here.
49
- - For each HTTP/WebSocket route: method, path, request schema, response schema, main side effects, and error paths.
50
- - Include small, runnable TS/JS examples that mimic real requests (curl + axios snippets).
51
-
52
- ## Writing Style
53
- - Audience: junior JS devs. Prioritize clarity and accuracy; keep sections short with examples.
54
- - Use TypeScript types where feasible. Avoid framework-agnostic pseudocode when real code exists.
55
- - Provide “Why it’s designed this way” notes and trade-offs.
56
- - Link to source files by path (e.g., `src/handlers/inbound/…`).
57
- - Avoid speculation; if unknown, create a TODO in a “Gaps & Open Questions” section.
58
-
59
- ## Output Rules
60
- - DO NOT execute the code; perform static analysis only.
61
- - Produce all files in `./_cc/docs`.
62
- - Use GitHub-flavored Markdown; keep line length reasonable.
63
- - Include a short “Onboarding in 30 minutes” section.
64
- - Update `CLAUDE.md` with links to new files.
65
-
66
- ## Validation Checklist (include at end of each file)
67
- - [ ] Routes and payloads verified against code
68
- - [ ] Error paths documented
69
- - [ ] Examples compile in TS
70
- - [ ] Links/paths correct
71
-
72
- Begin now. If repo structure suggests different file splits, propose and proceed.
73
-
74
- If you have any questions or hesitations, please ask immediately.
@@ -1,45 +0,0 @@
1
-
2
- 1. Read `CLAUDE.md`
3
- 2. Read additional _docs_ to get better context:
4
- 1. `[api-svc-01-overview.md](../docs/api-svc/api-svc-01-overview.md)`
5
- 2. `[api-svc-07-control-agent.md](../docs/api-svc/api-svc-07-control-agent.md)`
6
- 3. Read Jira ticket CSI-1864: https://infitx-technologies.atlassian.net/jira/software/c/projects/CSI/boards/12/backlog?assignee=712020%3A5680aa00-ab49-4175-96be-384e78ebaa45&selectedIssue=CSI-1864
7
- 1. Analyze description, check Acceptance Criteria. If not able to access Jira, see the `Jira Details` section below
8
- 2. Understand the problem we want to solve in scope of the story, identify which components need to be added/modified.
9
- 3. Check in huge detail actual code implementation of involved components, understand how related logic works now.
10
- 4. Ask any clarification if needed!
11
- 4. Create high-level implementation plan, split on tasks, suggest testing plan (with test cases for new logic)
12
- 5. One of my junior colleague provided me detailed implementation plan for the story: `/home/eugen/projects/ML/sdk-scheme-adapter/_cc/specs/story-CSI-1864-plan.md`:
13
- 1. Analyze it, and give your feedback how to improve and/or optimize that plan
14
- 2. Compare your high-level plan with that one, come up with suggestion how to combine there two plans into one final plan
15
- 3. Suggestion from my side how to improve colleague's plan:
16
- 1. For polling, try to reuse `controlClient` which we already use for listening to `ControlAgent.EVENT.RECONFIGURE` event instead of creating new one
17
- 2. Pass this `controlClient` to `_startConfigPolling()` or access `this.controlClient` inside it
18
- 4. Suggest any changes you think needed, and ask my approval!
19
- 5. Store final plan in `/home/eugen/projects/ML/sdk-scheme-adapter/_cc/specs/story-CSI-1864-final-plan.md`
20
- 6. Ask me to review your final plan, before any code changes!
21
- 7. Update `CLAUDE.md` and `api-svc-07-control-agent.md` with new changes details
22
-
23
- ## Jira Details
24
-
25
- ### Story description:
26
- ```
27
- Implement Failsafe Mechanism in SDK to Poll Configuration Changes from Management API
28
- This problem results in transactions failing through that connection, which can be a DFSP connection, or a proxy connection to another scheme. I.e. if this occurs in a proxy, then in the current configuration all transaction will fail. There have been numerous attempts to fix the stale certificate sdk problem, yet the problem perisists. This story is about taking a new approach that will elimitate this problem.
29
-
30
- Currently, the SDK Scheme Adapter relies on notifications from the Management API to update its configuration — for example, when new participant certificates or JWS keys are updated.
31
- However, in some cases these notifications may not be delivered reliably (due to network issues, restarts, or transient errors), which can lead to JWS desynchronization between the SDK and the Management Service.
32
-
33
- To address this, introduce a failsafe polling mechanism within the SDK that periodically polls the Management API for configuration updates. This ensures that even if event-driven updates fail, the SDK eventually synchronizes its configuration.
34
- ```
35
-
36
- ## Acceptance Criteria:
37
- 1. The SDK includes a background polling mechanism that periodically checks for configuration updates from the Management API.
38
- 2. Polling frequency is configurable through an environment variable, e.g. MANAGEMENT_API_POLL_INTERVAL_MS.
39
- 3. If no interval is configured, the failsafe polling feature is disabled (default behavior).
40
- 4. When polling is enabled, the SDK should:
41
- 1. Fetch and compare the configuration with the current state.
42
- 2. Apply updates if changes are detected.
43
- 3. Log both successful updates and polling errors with clear messages.
44
- 5. The implementation must not cause race conditions with live notifications — if both notification and polling update the config simultaneously, the state remains consistent.
45
- 6. Unit tests added to validate: