@mojaloop/sdk-scheme-adapter 24.2.0-csi-1210.3 → 24.2.0-csi-1210.5
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/.yarn/cache/{@mojaloop-sdk-standard-components-npm-19.9.0-snapshot.1-35a191f95a-3de8196de7.zip → @mojaloop-sdk-standard-components-npm-19.9.0-snapshot.2-0f7ee02ccc-9986c1c680.zip} +0 -0
- package/.yarn/install-state.gz +0 -0
- package/docker-compose.yml +4 -4
- package/modules/api-svc/package.json +1 -1
- package/modules/api-svc/src/InboundServer/handlers.js +31 -33
- package/modules/api-svc/src/lib/model/InboundTransfersModel.js +122 -125
- package/modules/api-svc/src/lib/model/OutboundTransfersModel.js +11 -13
- package/modules/api-svc/src/lib/utils.js +8 -0
- package/package.json +1 -1
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/docker-compose.yml
CHANGED
|
@@ -7,11 +7,11 @@ services:
|
|
|
7
7
|
sdk-scheme-adapter-api-svc:
|
|
8
8
|
networks:
|
|
9
9
|
- mojaloop-net
|
|
10
|
-
image: mojaloop/sdk-scheme-adapter:
|
|
10
|
+
image: mojaloop/sdk-scheme-adapter:local
|
|
11
11
|
container_name: sdk-scheme-adapter-api-svc
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
build:
|
|
13
|
+
context: ./
|
|
14
|
+
dockerfile: ./Dockerfile
|
|
15
15
|
env_file: ./modules/api-svc/test/config/integration.env
|
|
16
16
|
ports:
|
|
17
17
|
- "4000:4000"
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@mojaloop/logging-bc-client-lib": "0.5.8",
|
|
74
74
|
"@mojaloop/ml-schema-transformer-lib": "2.5.6",
|
|
75
75
|
"@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
|
|
76
|
-
"@mojaloop/sdk-standard-components": "v19.9.0-snapshot.
|
|
76
|
+
"@mojaloop/sdk-standard-components": "v19.9.0-snapshot.2",
|
|
77
77
|
"ajv": "8.17.1",
|
|
78
78
|
"axios": "1.8.1",
|
|
79
79
|
"body-parser": "1.20.3",
|
|
@@ -39,6 +39,7 @@ const {
|
|
|
39
39
|
TransfersModel,
|
|
40
40
|
} = require('../lib/model');
|
|
41
41
|
const { CacheKeyPrefixes } = require('../lib/model/common');
|
|
42
|
+
const { generateTraceparent } = require('../lib/utils');
|
|
42
43
|
|
|
43
44
|
const { ReturnCodes } = Enum.Http;
|
|
44
45
|
|
|
@@ -48,6 +49,18 @@ const extractBodyHeadersSourceFspId = ctx => ({
|
|
|
48
49
|
headers: { ...ctx.request.headers },
|
|
49
50
|
});
|
|
50
51
|
|
|
52
|
+
const extractTraceHeaders = ctx => {
|
|
53
|
+
const { traceparent = generateTraceparent(), tracestate } = ctx.request.headers;
|
|
54
|
+
|
|
55
|
+
const traceHeaders = {
|
|
56
|
+
traceparent,
|
|
57
|
+
...(tracestate && { tracestate })
|
|
58
|
+
};
|
|
59
|
+
ctx.state?.logger?.isVerboseEnabled && ctx.state.logger.push({ traceHeaders }).verbose('extracted traceHeaders');
|
|
60
|
+
|
|
61
|
+
return traceHeaders;
|
|
62
|
+
};
|
|
63
|
+
|
|
51
64
|
/**
|
|
52
65
|
* @param {Object} ctx - the Koa context object
|
|
53
66
|
* @returns {InboundTransfersModel}
|
|
@@ -116,7 +129,7 @@ const getParticipantsByTypeAndId = async (ctx) => {
|
|
|
116
129
|
const model = createInboundTransfersModel(ctx);
|
|
117
130
|
|
|
118
131
|
// use the model to handle the request
|
|
119
|
-
const response = await model.getParticipants(idType, idValue, subIdValue, sourceFspId);
|
|
132
|
+
const response = await model.getParticipants(idType, idValue, subIdValue, sourceFspId, extractTraceHeaders(ctx));
|
|
120
133
|
|
|
121
134
|
// log the result
|
|
122
135
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled GET /participants/{idType}/{idValue}');
|
|
@@ -148,16 +161,7 @@ const getPartiesByTypeAndId = async (ctx) => {
|
|
|
148
161
|
// use the transfers model to execute asynchronous stages with the switch
|
|
149
162
|
const model = createInboundTransfersModel(ctx);
|
|
150
163
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// use the model to handle the request
|
|
154
|
-
if (ctx.request.header?.tracestate && ctx.request.header?.traceparent) {
|
|
155
|
-
const { tracestate, traceparent } = ctx.request.header;
|
|
156
|
-
response = await model.getParties(idType, idValue, subIdValue, sourceFspId, { tracestate, traceparent });
|
|
157
|
-
} else {
|
|
158
|
-
response = await model.getParties(idType, idValue, subIdValue, sourceFspId);
|
|
159
|
-
}
|
|
160
|
-
|
|
164
|
+
const response = await model.getParties(idType, idValue, subIdValue, sourceFspId, extractTraceHeaders(ctx));
|
|
161
165
|
|
|
162
166
|
// log the result
|
|
163
167
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled GET /parties/{idType}/{idValue} request');
|
|
@@ -210,15 +214,7 @@ const postQuotes = async (ctx) => {
|
|
|
210
214
|
// use the transfers model to execute asynchronous stages with the switch
|
|
211
215
|
const model = createInboundTransfersModel(ctx);
|
|
212
216
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
// use the model to handle the request
|
|
216
|
-
if (ctx.request.header?.tracestate && ctx.request.header?.traceparent) {
|
|
217
|
-
const { tracestate, traceparent } = ctx.request.header;
|
|
218
|
-
response = await model.quoteRequest(quoteRequest, sourceFspId, { tracestate, traceparent });
|
|
219
|
-
} else {
|
|
220
|
-
response = await model.quoteRequest(quoteRequest, sourceFspId);
|
|
221
|
-
}
|
|
217
|
+
const response = await model.quoteRequest(quoteRequest, sourceFspId, extractTraceHeaders(ctx));
|
|
222
218
|
|
|
223
219
|
// log the result
|
|
224
220
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled POST /quotes request');
|
|
@@ -259,7 +255,7 @@ const postTransfers = async (ctx) => {
|
|
|
259
255
|
const model = createInboundTransfersModel(ctx);
|
|
260
256
|
|
|
261
257
|
// use the model to handle the request
|
|
262
|
-
const response = await model.prepareTransfer(transferRequest, sourceFspId);
|
|
258
|
+
const response = await model.prepareTransfer(transferRequest, sourceFspId, extractTraceHeaders(ctx));
|
|
263
259
|
|
|
264
260
|
// log the result
|
|
265
261
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled POST /transfers request');
|
|
@@ -289,7 +285,7 @@ const getTransfersById = async (ctx) => {
|
|
|
289
285
|
const model = createInboundTransfersModel(ctx);
|
|
290
286
|
|
|
291
287
|
// use the model to handle the request
|
|
292
|
-
const response = await model.getTransfer(transferId, sourceFspId);
|
|
288
|
+
const response = await model.getTransfer(transferId, sourceFspId, extractTraceHeaders(ctx));
|
|
293
289
|
|
|
294
290
|
// log the result
|
|
295
291
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({response}).
|
|
@@ -320,7 +316,7 @@ const postTransactionRequests = async (ctx) => {
|
|
|
320
316
|
const model = createInboundTransfersModel(ctx);
|
|
321
317
|
|
|
322
318
|
// use the model to handle the request
|
|
323
|
-
const response = await model.transactionRequest(transactionRequest, sourceFspId);
|
|
319
|
+
const response = await model.transactionRequest(transactionRequest, sourceFspId, extractTraceHeaders(ctx));
|
|
324
320
|
|
|
325
321
|
// log the result
|
|
326
322
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled POST /transactionRequests request');
|
|
@@ -577,7 +573,7 @@ const getQuoteById = async (ctx) => {
|
|
|
577
573
|
const model = createInboundTransfersModel(ctx);
|
|
578
574
|
|
|
579
575
|
// use the model to handle the request
|
|
580
|
-
const response = await model.getQuoteRequest(quoteId, sourceFspId);
|
|
576
|
+
const response = await model.getQuoteRequest(quoteId, sourceFspId, extractTraceHeaders(ctx));
|
|
581
577
|
|
|
582
578
|
// log the result
|
|
583
579
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled GET /quotes request');
|
|
@@ -619,7 +615,9 @@ const putTransactionRequestsById = async (ctx) => {
|
|
|
619
615
|
const model = createInboundTransfersModel(ctx);
|
|
620
616
|
|
|
621
617
|
// use the model to handle the request
|
|
622
|
-
const response = await model.putTransactionRequest(
|
|
618
|
+
const response = await model.putTransactionRequest(
|
|
619
|
+
putTransactionRequest, transactionRequestId, sourceFspId, extractTraceHeaders(ctx)
|
|
620
|
+
);
|
|
623
621
|
|
|
624
622
|
// log the result
|
|
625
623
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled PUT /transactionRequests/{ID} request');
|
|
@@ -800,7 +798,7 @@ const getBulkQuotesById = async (ctx) => {
|
|
|
800
798
|
const model = createInboundTransfersModel(ctx);
|
|
801
799
|
|
|
802
800
|
// use the model to handle the request
|
|
803
|
-
const response = await model.getBulkQuote(bulkQuoteId, sourceFspId);
|
|
801
|
+
const response = await model.getBulkQuote(bulkQuoteId, sourceFspId, extractTraceHeaders(ctx));
|
|
804
802
|
|
|
805
803
|
// log the result
|
|
806
804
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({response}).
|
|
@@ -830,7 +828,7 @@ const postBulkQuotes = async (ctx) => {
|
|
|
830
828
|
const model = createInboundTransfersModel(ctx);
|
|
831
829
|
|
|
832
830
|
// use the model to handle the request
|
|
833
|
-
const response = await model.bulkQuoteRequest(bulkQuoteRequest, sourceFspId);
|
|
831
|
+
const response = await model.bulkQuoteRequest(bulkQuoteRequest, sourceFspId, extractTraceHeaders(ctx));
|
|
834
832
|
|
|
835
833
|
// log the result
|
|
836
834
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled POST /bulkQuotes request');
|
|
@@ -895,7 +893,7 @@ const getBulkTransfersById = async (ctx) => {
|
|
|
895
893
|
const model = createInboundTransfersModel(ctx);
|
|
896
894
|
|
|
897
895
|
// use the model to handle the request
|
|
898
|
-
const response = await model.getBulkTransfer(bulkTransferId, sourceFspId);
|
|
896
|
+
const response = await model.getBulkTransfer(bulkTransferId, sourceFspId, extractTraceHeaders(ctx));
|
|
899
897
|
|
|
900
898
|
// log the result
|
|
901
899
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({response}).
|
|
@@ -925,7 +923,7 @@ const postBulkTransfers = async (ctx) => {
|
|
|
925
923
|
const model = createInboundTransfersModel(ctx);
|
|
926
924
|
|
|
927
925
|
// use the model to handle the request
|
|
928
|
-
const response = await model.prepareBulkTransfer(bulkPrepareRequest, sourceFspId);
|
|
926
|
+
const response = await model.prepareBulkTransfer(bulkPrepareRequest, sourceFspId, extractTraceHeaders(ctx));
|
|
929
927
|
|
|
930
928
|
// log the result
|
|
931
929
|
ctx.state.logger.isDebugEnabled && ctx.state.logger.push({ response }).debug('Inbound transfers model handled POST /bulkTransfers request');
|
|
@@ -995,8 +993,8 @@ const postFxQuotes = async (ctx) => {
|
|
|
995
993
|
|
|
996
994
|
const model = createInboundTransfersModel(ctx);
|
|
997
995
|
|
|
998
|
-
model.postFxQuotes({ body, headers }, sourceFspId)
|
|
999
|
-
.then(response => logger.push({ response }).
|
|
996
|
+
model.postFxQuotes({ body, headers }, sourceFspId, extractTraceHeaders(ctx))
|
|
997
|
+
.then(response => logger.push({ response }).debug(`${logPrefix} is done`))
|
|
1000
998
|
.catch(err => logger.push({ err }).error(`${logPrefix} error`));
|
|
1001
999
|
|
|
1002
1000
|
prepareResponse(ctx);
|
|
@@ -1040,8 +1038,8 @@ const postFxTransfers = async (ctx) => {
|
|
|
1040
1038
|
const logPrefix = 'Handling POST fxTransfers request';
|
|
1041
1039
|
|
|
1042
1040
|
const model = createInboundTransfersModel(ctx);
|
|
1043
|
-
model.postFxTransfers({ body, headers }, sourceFspId)
|
|
1044
|
-
.then(response => logger.push({ response }).
|
|
1041
|
+
model.postFxTransfers({ body, headers }, sourceFspId, extractTraceHeaders(ctx))
|
|
1042
|
+
.then(response => logger.push({ response }).debug(`${logPrefix} is done`))
|
|
1045
1043
|
.catch(err => logger.push({ err }).error(`${logPrefix} error`));
|
|
1046
1044
|
|
|
1047
1045
|
prepareResponse(ctx);
|
|
@@ -36,6 +36,8 @@ const shared = require('./lib/shared');
|
|
|
36
36
|
const { BackendRequests, HTTPResponseError } = require('./lib/requests');
|
|
37
37
|
const { SDKStateEnum, CacheKeyPrefixes } = require('./common');
|
|
38
38
|
|
|
39
|
+
const TRACESTATE_KEY_CALLBACK_START_TS = 'tx_callback_start_ts';
|
|
40
|
+
|
|
39
41
|
/**
|
|
40
42
|
* Models the operations required for performing inbound transfers
|
|
41
43
|
*/
|
|
@@ -124,7 +126,7 @@ class InboundTransfersModel {
|
|
|
124
126
|
catch(err) {
|
|
125
127
|
this._logger.isErrorEnabled && this._logger.push({ err, transactionRequestId }).error('Error in getOTP');
|
|
126
128
|
const mojaloopError = await this._handleError(err);
|
|
127
|
-
this._logger.
|
|
129
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
128
130
|
return this._mojaloopRequests.putAuthorizationsError(transactionRequestId, mojaloopError, sourceFspId);
|
|
129
131
|
}
|
|
130
132
|
}
|
|
@@ -133,7 +135,7 @@ class InboundTransfersModel {
|
|
|
133
135
|
/**
|
|
134
136
|
* Queries the backend API for the specified party and makes a callback to the originator with our dfspId if found
|
|
135
137
|
*/
|
|
136
|
-
async getParticipants(idType, idValue, idSubValue, sourceFspId) {
|
|
138
|
+
async getParticipants(idType, idValue, idSubValue, sourceFspId, headers) {
|
|
137
139
|
try {
|
|
138
140
|
// make a call to the backend to resolve the party lookup
|
|
139
141
|
const response = await this._backendRequests.getParties(idType, idValue, idSubValue);
|
|
@@ -143,15 +145,22 @@ class InboundTransfersModel {
|
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
// make a callback to the source fsp with our dfspId indicating we own the party
|
|
146
|
-
return this._mojaloopRequests.putParticipants(
|
|
147
|
-
|
|
148
|
+
return this._mojaloopRequests.putParticipants(
|
|
149
|
+
idType,
|
|
150
|
+
idValue,
|
|
151
|
+
idSubValue,
|
|
152
|
+
{ fspId: this._dfspId },
|
|
153
|
+
sourceFspId,
|
|
154
|
+
headers
|
|
155
|
+
);
|
|
148
156
|
}
|
|
149
|
-
catch(err) {
|
|
157
|
+
catch (err) {
|
|
150
158
|
this._logger.isErrorEnabled && this._logger.push({ err, idValue }).error('Error in getParticipants');
|
|
151
159
|
const mojaloopError = await this._handleError(err);
|
|
152
|
-
this._logger.
|
|
153
|
-
return this._mojaloopRequests.putParticipantsError(
|
|
154
|
-
mojaloopError, sourceFspId
|
|
160
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
161
|
+
return this._mojaloopRequests.putParticipantsError(
|
|
162
|
+
idType, idValue, idSubValue, mojaloopError, sourceFspId, headers
|
|
163
|
+
);
|
|
155
164
|
}
|
|
156
165
|
}
|
|
157
166
|
|
|
@@ -173,26 +182,16 @@ class InboundTransfersModel {
|
|
|
173
182
|
party: shared.internalPartyToMojaloopParty(response, this._dfspId, this._supportedCurrencies)
|
|
174
183
|
};
|
|
175
184
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (tracestate && traceparent) {
|
|
179
|
-
const TRACESTATE_KEY_CALLBACK_START_TS = 'tx_callback_start_ts';
|
|
180
|
-
tracestate += `,${TRACESTATE_KEY_CALLBACK_START_TS}=${Date.now()}`;
|
|
181
|
-
return this._mojaloopRequests.putParties(idType, idValue, idSubValue, mlParty, sourceFspId, { tracestate, traceparent });
|
|
185
|
+
if (headers.tracestate && headers.traceparent) {
|
|
186
|
+
headers.tracestate += `,${TRACESTATE_KEY_CALLBACK_START_TS}=${Date.now()}`;
|
|
182
187
|
}
|
|
183
|
-
|
|
184
|
-
// make a callback to the source fsp with the party info
|
|
185
|
-
const partyInfo = await this._mojaloopRequests.putParties(idType, idValue, idSubValue, mlParty, sourceFspId);
|
|
186
|
-
|
|
187
|
-
return partyInfo;
|
|
188
|
-
|
|
188
|
+
return this._mojaloopRequests.putParties(idType, idValue, idSubValue, mlParty, sourceFspId, headers);
|
|
189
189
|
}
|
|
190
|
-
catch(err) {
|
|
190
|
+
catch (err) {
|
|
191
191
|
this._logger.isErrorEnabled && this._logger.push({ err, idValue }).error('Error in getParties');
|
|
192
192
|
const mojaloopError = await this._handleError(err);
|
|
193
|
-
this._logger.
|
|
194
|
-
return this._mojaloopRequests.putPartiesError(idType, idValue, idSubValue,
|
|
195
|
-
mojaloopError, sourceFspId);
|
|
193
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
194
|
+
return this._mojaloopRequests.putPartiesError(idType, idValue, idSubValue, mojaloopError, sourceFspId, headers);
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
|
|
@@ -213,16 +212,21 @@ class InboundTransfersModel {
|
|
|
213
212
|
// have a record of the request in the cache.
|
|
214
213
|
await this._save();
|
|
215
214
|
|
|
215
|
+
const log = this._logger.push({
|
|
216
|
+
transferId: this.data.transferId,
|
|
217
|
+
quoteId: quoteRequest.quoteId
|
|
218
|
+
});
|
|
219
|
+
|
|
216
220
|
try {
|
|
217
221
|
const internalForm = shared.mojaloopQuoteRequestToInternal(quoteRequest);
|
|
218
222
|
|
|
219
223
|
// Check the transactionRequestId exists in cache
|
|
220
224
|
if(quoteRequest.transactionRequestId) {
|
|
221
225
|
const previousTxnReq = await this._cache.get(`txnReqModel_${quoteRequest.transactionRequestId}`);
|
|
222
|
-
if(previousTxnReq) {
|
|
226
|
+
if (previousTxnReq) {
|
|
223
227
|
internalForm.homeR2PTransactionId = previousTxnReq.homeR2PTransactionId;
|
|
224
228
|
} else {
|
|
225
|
-
|
|
229
|
+
log.isErrorEnabled && log.error(`No previous transactionRequest found in cache with transactionRequestId: ${quoteRequest.transactionRequestId}. Unable to fetch homeR2PTransactionId.`);
|
|
226
230
|
}
|
|
227
231
|
}
|
|
228
232
|
|
|
@@ -258,40 +262,32 @@ class InboundTransfersModel {
|
|
|
258
262
|
};
|
|
259
263
|
await this._save();
|
|
260
264
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
let { tracestate = undefined, traceparent = undefined } = headers;
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
// make a callback to the source fsp with the quote response
|
|
267
|
-
if (tracestate && traceparent) {
|
|
268
|
-
const TRACESTATE_KEY_CALLBACK_START_TS = 'tx_callback_start_ts';
|
|
269
|
-
tracestate += `,${TRACESTATE_KEY_CALLBACK_START_TS}=${Date.now()}`;
|
|
270
|
-
res = await this._mojaloopRequests.putQuotes(quoteRequest.quoteId, mojaloopResponse, sourceFspId, { tracestate, traceparent }, { isoPostQuote: request.isoPostQuote });
|
|
271
|
-
} else {
|
|
272
|
-
res = await this._mojaloopRequests.putQuotes(quoteRequest.quoteId, mojaloopResponse, sourceFspId, undefined, { isoPostQuote: request.isoPostQuote });
|
|
265
|
+
if (headers.tracestate && headers.traceparent) {
|
|
266
|
+
headers.tracestate += `,${TRACESTATE_KEY_CALLBACK_START_TS}=${Date.now()}`;
|
|
273
267
|
}
|
|
268
|
+
const res = await this._mojaloopRequests.putQuotes(quoteRequest.quoteId, mojaloopResponse, sourceFspId, headers, { isoPostQuote: request.isoPostQuote });
|
|
269
|
+
|
|
274
270
|
this.data.quoteResponse = {
|
|
275
|
-
headers: res.originalRequest
|
|
271
|
+
headers: res.originalRequest?.headers,
|
|
276
272
|
body: mojaloopResponse,
|
|
277
273
|
};
|
|
278
274
|
this.data.currentState = SDKStateEnum.WAITING_FOR_QUOTE_ACCEPTANCE;
|
|
279
275
|
await this._save();
|
|
276
|
+
|
|
277
|
+
log.isInfoEnabled && log.info('quoteRequest is done');
|
|
280
278
|
return res;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
this._logger.push({ err }).error('Error in quoteRequest');
|
|
279
|
+
} catch (err) {
|
|
280
|
+
log.push({ err }).error('Error in quoteRequest');
|
|
284
281
|
const mojaloopError = await this._handleError(err);
|
|
285
|
-
|
|
286
|
-
return
|
|
287
|
-
mojaloopError, sourceFspId);
|
|
282
|
+
log.isInfoEnabled && log.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
283
|
+
return this._mojaloopRequests.putQuotesError(quoteRequest.quoteId, mojaloopError, sourceFspId, headers);
|
|
288
284
|
}
|
|
289
285
|
}
|
|
290
286
|
|
|
291
287
|
/**
|
|
292
288
|
* Notifies backend about the transactionRequest callback
|
|
293
289
|
*/
|
|
294
|
-
async putTransactionRequest(request, transactionRequestId, sourceFspId) {
|
|
290
|
+
async putTransactionRequest(request, transactionRequestId, sourceFspId, headers) {
|
|
295
291
|
const putTransactionRequest = request.body;
|
|
296
292
|
|
|
297
293
|
try {
|
|
@@ -316,12 +312,11 @@ class InboundTransfersModel {
|
|
|
316
312
|
// make a call to the backend about this notification anyway
|
|
317
313
|
await this._backendRequests.putRequestToPayNotification(internalForm, transactionRequestId);
|
|
318
314
|
}
|
|
319
|
-
catch(err) {
|
|
315
|
+
catch (err) {
|
|
320
316
|
this._logger.push({ err, transactionRequestId }).error('Error in putTransactionRequest');
|
|
321
317
|
const mojaloopError = await this._handleError(err);
|
|
322
|
-
this._logger.
|
|
323
|
-
return await this._mojaloopRequests.putQuotesError(transactionRequestId,
|
|
324
|
-
mojaloopError, sourceFspId);
|
|
318
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
319
|
+
return await this._mojaloopRequests.putQuotesError(transactionRequestId, mojaloopError, sourceFspId, headers);
|
|
325
320
|
}
|
|
326
321
|
}
|
|
327
322
|
|
|
@@ -329,7 +324,7 @@ class InboundTransfersModel {
|
|
|
329
324
|
* This is executed as when GET /quotes/{ID} request is made to get the response of a previous POST /quotes request.
|
|
330
325
|
* Gets the quoteResponse from the cache and makes a callback to the originator with result
|
|
331
326
|
*/
|
|
332
|
-
async getQuoteRequest(quoteId, sourceFspId) {
|
|
327
|
+
async getQuoteRequest(quoteId, sourceFspId, headers) {
|
|
333
328
|
try {
|
|
334
329
|
// Get the quoteResponse data for the quoteId from the cache to be sent as a response to GET /quotes/{ID}
|
|
335
330
|
const quoteResponse = await this._cache.get(`quoteResponse_${quoteId}`);
|
|
@@ -339,16 +334,16 @@ class InboundTransfersModel {
|
|
|
339
334
|
const err = new Error('Quote Id not found');
|
|
340
335
|
const mojaloopError = await this._handleError(err, Errors.MojaloopApiErrorCodes.QUOTE_ID_NOT_FOUND);
|
|
341
336
|
this._logger.push({ mojaloopError, quoteId }).warn(`Sending error response to ${sourceFspId}`);
|
|
342
|
-
return await this._mojaloopRequests.putQuotesError(quoteId, mojaloopError, sourceFspId);
|
|
337
|
+
return await this._mojaloopRequests.putQuotesError(quoteId, mojaloopError, sourceFspId, headers);
|
|
343
338
|
}
|
|
344
339
|
// Make a PUT /quotes/{ID} callback to the source fsp with the quote response
|
|
345
|
-
return this._mojaloopRequests.putQuotes(quoteId, quoteResponse, sourceFspId);
|
|
340
|
+
return this._mojaloopRequests.putQuotes(quoteId, quoteResponse, sourceFspId, headers);
|
|
346
341
|
}
|
|
347
342
|
catch(err) {
|
|
348
343
|
this._logger.push({ err, quoteId }).error('Error in getQuoteRequest');
|
|
349
344
|
const mojaloopError = await this._handleError(err);
|
|
350
|
-
this._logger.
|
|
351
|
-
return
|
|
345
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
346
|
+
return this._mojaloopRequests.putQuotesError(quoteId, mojaloopError, sourceFspId, headers);
|
|
352
347
|
}
|
|
353
348
|
}
|
|
354
349
|
|
|
@@ -356,7 +351,7 @@ class InboundTransfersModel {
|
|
|
356
351
|
* Asks the backend for a response to an incoming transactoin request and makes a callback to the originator with
|
|
357
352
|
* the result
|
|
358
353
|
*/
|
|
359
|
-
async transactionRequest(transactionRequest, sourceFspId) {
|
|
354
|
+
async transactionRequest(transactionRequest, sourceFspId, headers) {
|
|
360
355
|
try {
|
|
361
356
|
const internalForm = shared.mojaloopTransactionRequestToInternal(transactionRequest);
|
|
362
357
|
|
|
@@ -372,14 +367,17 @@ class InboundTransfersModel {
|
|
|
372
367
|
const mojaloopResponse = shared.internalTransactionRequestResponseToMojaloop(response);
|
|
373
368
|
|
|
374
369
|
// make a callback to the source fsp with the quote response
|
|
375
|
-
return this._mojaloopRequests.putTransactionRequests(
|
|
370
|
+
return this._mojaloopRequests.putTransactionRequests(
|
|
371
|
+
transactionRequest.transactionRequestId, mojaloopResponse, sourceFspId, headers
|
|
372
|
+
);
|
|
376
373
|
}
|
|
377
|
-
catch(err) {
|
|
374
|
+
catch (err) {
|
|
378
375
|
this._logger.push({ err }).error(`Error in transactionRequest ${transactionRequest?.transactionRequestId}`);
|
|
379
376
|
const mojaloopError = await this._handleError(err);
|
|
380
|
-
this._logger.
|
|
381
|
-
return this._mojaloopRequests.putTransactionRequestsError(
|
|
382
|
-
mojaloopError, sourceFspId
|
|
377
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
378
|
+
return this._mojaloopRequests.putTransactionRequestsError(
|
|
379
|
+
transactionRequest.transactionRequestId, mojaloopError, sourceFspId, headers
|
|
380
|
+
);
|
|
383
381
|
}
|
|
384
382
|
}
|
|
385
383
|
|
|
@@ -388,7 +386,7 @@ class InboundTransfersModel {
|
|
|
388
386
|
* Validates an incoming transfer prepare request and makes a callback to the originator with
|
|
389
387
|
* the result
|
|
390
388
|
*/
|
|
391
|
-
async prepareTransfer(request, sourceFspId) {
|
|
389
|
+
async prepareTransfer(request, sourceFspId, headers) {
|
|
392
390
|
const prepareRequest = request.body;
|
|
393
391
|
try {
|
|
394
392
|
// retrieve our quote data
|
|
@@ -408,8 +406,10 @@ class InboundTransfersModel {
|
|
|
408
406
|
// This is a different to the a typical mojaloop sdk-scheme-adapter setup which allows this as an option.
|
|
409
407
|
|
|
410
408
|
// Check whether to allow transfers without a previous quote.
|
|
411
|
-
if(!this._allowTransferWithoutQuote) {
|
|
412
|
-
|
|
409
|
+
if (!this._allowTransferWithoutQuote) {
|
|
410
|
+
const errMessage = `Corresponding quote not found for transfer ${prepareRequest.transferId}`;
|
|
411
|
+
this._logger.isWarnEnabled && this._logger.warn(errMessage);
|
|
412
|
+
throw new Error(errMessage);
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
if (!this.data) {
|
|
@@ -425,18 +425,19 @@ class InboundTransfersModel {
|
|
|
425
425
|
// Calculate or retrieve fulfilment and condition
|
|
426
426
|
let fulfilment = null;
|
|
427
427
|
let condition = null;
|
|
428
|
-
if(quote) {
|
|
428
|
+
if (quote) {
|
|
429
429
|
fulfilment = quote.fulfilment;
|
|
430
430
|
condition = quote.mojaloopResponse.condition;
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
431
|
+
} else {
|
|
433
432
|
fulfilment = this._ilp.calculateFulfil(prepareRequest.ilpPacket);
|
|
434
433
|
condition = this._ilp.calculateConditionFromFulfil(fulfilment);
|
|
435
434
|
}
|
|
436
435
|
|
|
437
436
|
// check incoming ILP matches our persisted values
|
|
438
|
-
if(this._checkIlp && (prepareRequest.condition !== condition)) {
|
|
439
|
-
|
|
437
|
+
if (this._checkIlp && (prepareRequest.condition !== condition)) {
|
|
438
|
+
const errMessage = `ILP condition in transfer prepare for ${prepareRequest.transferId} does not match quote`;
|
|
439
|
+
this._logger.isWarnEnabled && this._logger.warn(errMessage);
|
|
440
|
+
throw new Error(errMessage);
|
|
440
441
|
}
|
|
441
442
|
|
|
442
443
|
if (this._rejectTransfersOnExpiredQuotes) {
|
|
@@ -446,7 +447,7 @@ class InboundTransfersModel {
|
|
|
446
447
|
const error = Errors.MojaloopApiErrorObjectFromCode(Errors.MojaloopApiErrorCodes.QUOTE_EXPIRED);
|
|
447
448
|
this._logger.isErrorEnabled && this._logger.error(`Error in prepareTransfer: quote expired for transfer ${prepareRequest.transferId}, system time=${now} > quote time=${expiration}`);
|
|
448
449
|
await this.updateStateWithError(error);
|
|
449
|
-
return this._mojaloopRequests.putTransfersError(prepareRequest.transferId, error, sourceFspId);
|
|
450
|
+
return this._mojaloopRequests.putTransfersError(prepareRequest.transferId, error, sourceFspId, headers);
|
|
450
451
|
}
|
|
451
452
|
}
|
|
452
453
|
|
|
@@ -461,7 +462,7 @@ class InboundTransfersModel {
|
|
|
461
462
|
return 'No response from backend';
|
|
462
463
|
}
|
|
463
464
|
|
|
464
|
-
this._logger.
|
|
465
|
+
this._logger.isVerboseEnabled && this._logger.verbose(`Transfer accepted by backend returning homeTransactionId: ${response.homeTransactionId} for mojaloop transferId: ${prepareRequest.transferId}`);
|
|
465
466
|
this.data.homeTransactionId = response.homeTransactionId;
|
|
466
467
|
|
|
467
468
|
// create a mojaloop transfer fulfil response
|
|
@@ -477,29 +478,32 @@ class InboundTransfersModel {
|
|
|
477
478
|
};
|
|
478
479
|
|
|
479
480
|
// make a callback to the source fsp with the transfer fulfilment
|
|
480
|
-
const res = await this._mojaloopRequests.putTransfers(
|
|
481
|
-
sourceFspId
|
|
481
|
+
const res = await this._mojaloopRequests.putTransfers(
|
|
482
|
+
prepareRequest.transferId, mojaloopResponse, sourceFspId, headers
|
|
483
|
+
);
|
|
482
484
|
|
|
483
485
|
this.data.fulfil = {
|
|
484
486
|
headers: res.originalRequest.headers,
|
|
485
487
|
body: mojaloopResponse,
|
|
486
488
|
};
|
|
487
489
|
this.data.currentState = response.transferState || (this._reserveNotification ? SDKStateEnum.RESERVED : SDKStateEnum.COMPLETED);
|
|
490
|
+
|
|
488
491
|
await this._save();
|
|
489
492
|
return res;
|
|
490
493
|
} catch(err) {
|
|
491
|
-
this._logger.isErrorEnabled && this._logger.push({ err }).error(`Error in prepareTransfer: ${
|
|
494
|
+
this._logger.isErrorEnabled && this._logger.push({ err }).error(`Error in prepareTransfer: ${prepareRequest?.transferId}`);
|
|
492
495
|
const mojaloopError = await this._handleError(err);
|
|
493
|
-
this._logger.
|
|
494
|
-
return
|
|
495
|
-
mojaloopError, sourceFspId
|
|
496
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
497
|
+
return this._mojaloopRequests.putTransfersError(
|
|
498
|
+
prepareRequest.transferId, mojaloopError, sourceFspId, headers
|
|
499
|
+
);
|
|
496
500
|
}
|
|
497
501
|
}
|
|
498
502
|
|
|
499
503
|
/**
|
|
500
504
|
* Queries details of a transfer
|
|
501
505
|
*/
|
|
502
|
-
async getTransfer(transferId, sourceFspId) {
|
|
506
|
+
async getTransfer(transferId, sourceFspId, headers) {
|
|
503
507
|
try {
|
|
504
508
|
// make a call to the backend to get transfer details
|
|
505
509
|
const response = await this._backendRequests.getTransfers(transferId);
|
|
@@ -541,19 +545,17 @@ class InboundTransfersModel {
|
|
|
541
545
|
};
|
|
542
546
|
|
|
543
547
|
// make a callback to the source fsp with the transfer fulfilment
|
|
544
|
-
return this._mojaloopRequests.putTransfers(transferId, mojaloopResponse,
|
|
545
|
-
sourceFspId);
|
|
548
|
+
return this._mojaloopRequests.putTransfers(transferId, mojaloopResponse, sourceFspId, headers);
|
|
546
549
|
}
|
|
547
550
|
catch (err) {
|
|
548
551
|
this._logger.isErrorEnabled && this._logger.push({ err, transferId }).error('Error in getTransfers');
|
|
549
552
|
const mojaloopError = await this._handleError(err);
|
|
550
|
-
this._logger.
|
|
551
|
-
return this._mojaloopRequests.putTransfersError(transferId,
|
|
552
|
-
mojaloopError, sourceFspId);
|
|
553
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
554
|
+
return this._mojaloopRequests.putTransfersError(transferId, mojaloopError, sourceFspId, headers);
|
|
553
555
|
}
|
|
554
556
|
}
|
|
555
557
|
|
|
556
|
-
async postFxQuotes(request, sourceFspId) {
|
|
558
|
+
async postFxQuotes(request, sourceFspId, headers) {
|
|
557
559
|
const { body } = request;
|
|
558
560
|
try {
|
|
559
561
|
this.data = dto.fxQuoteRequestStateDto(request);
|
|
@@ -579,11 +581,11 @@ class InboundTransfersModel {
|
|
|
579
581
|
response: beResponse,
|
|
580
582
|
mojaloopResponse,
|
|
581
583
|
fulfilment
|
|
582
|
-
//
|
|
584
|
+
// think, if we need to store ilpPacket as well
|
|
583
585
|
};
|
|
584
586
|
await this.saveFxState();
|
|
585
587
|
|
|
586
|
-
const res = await this._mojaloopRequests.putFxQuotes(body.conversionRequestId, mojaloopResponse, sourceFspId);
|
|
588
|
+
const res = await this._mojaloopRequests.putFxQuotes(body.conversionRequestId, mojaloopResponse, sourceFspId, headers);
|
|
587
589
|
|
|
588
590
|
this.data.fxQuoteResponse = {
|
|
589
591
|
headers: res.originalRequest.headers,
|
|
@@ -595,15 +597,16 @@ class InboundTransfersModel {
|
|
|
595
597
|
|
|
596
598
|
return res;
|
|
597
599
|
} catch (err) {
|
|
598
|
-
this._logger.push({ err }).error(
|
|
600
|
+
this._logger.push({ err }).error(`Error in postFxQuotes [conversionRequestId: ${body.conversionRequestId}]`);
|
|
599
601
|
const mojaloopError = await this._handleError(err);
|
|
600
602
|
this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
601
|
-
return this._mojaloopRequests
|
|
602
|
-
|
|
603
|
+
return this._mojaloopRequests.putFxQuotesError(
|
|
604
|
+
body.conversionRequestId, mojaloopError, sourceFspId, headers
|
|
605
|
+
);
|
|
603
606
|
}
|
|
604
607
|
}
|
|
605
608
|
|
|
606
|
-
async postFxTransfers(request, sourceFspId) {
|
|
609
|
+
async postFxTransfers(request, sourceFspId, headers) {
|
|
607
610
|
const { body } = request;
|
|
608
611
|
try {
|
|
609
612
|
// todo: assume commitRequestId from fxTransfer should be same as conversionTerms.conversionId from fxQuotes
|
|
@@ -634,7 +637,7 @@ class InboundTransfersModel {
|
|
|
634
637
|
this._logger.error(`Error in prepareFxTransfer: fxQuote expired for fxTransfer ${body.commitRequestId}, system time=${now} > fxQuote time=${expiration}`);
|
|
635
638
|
await this.updateStateWithError(error);
|
|
636
639
|
// todo: maybe, throw error here, and process it in catch block?
|
|
637
|
-
return this._mojaloopRequests.putFxTransfersError(body.commitRequestId, error, sourceFspId);
|
|
640
|
+
return this._mojaloopRequests.putFxTransfersError(body.commitRequestId, error, sourceFspId, headers);
|
|
638
641
|
}
|
|
639
642
|
}
|
|
640
643
|
|
|
@@ -651,23 +654,23 @@ class InboundTransfersModel {
|
|
|
651
654
|
|
|
652
655
|
// create a mojaloop fxTransfer fulfil response
|
|
653
656
|
const mojaloopResponse = shared.internalFxTransferResponseToMojaloop(beResponse, fulfilment);
|
|
654
|
-
const res = await this._mojaloopRequests.putFxTransfers(body.commitRequestId, mojaloopResponse, sourceFspId);
|
|
657
|
+
const res = await this._mojaloopRequests.putFxTransfers(body.commitRequestId, mojaloopResponse, sourceFspId, headers);
|
|
655
658
|
|
|
656
659
|
this.data.fulfil = {
|
|
657
660
|
headers: res.originalRequest.headers,
|
|
658
661
|
body: mojaloopResponse,
|
|
659
662
|
};
|
|
660
|
-
|
|
661
663
|
this.data.currentState = beResponse.conversionState;
|
|
662
664
|
await this.saveFxState();
|
|
663
665
|
|
|
664
666
|
return res;
|
|
665
667
|
} catch (err) {
|
|
666
|
-
this._logger.push({ err }).error(
|
|
668
|
+
this._logger.push({ err }).error(`Error in postFxTransfer [commitRequestId: ${body.commitRequestId}]`);
|
|
667
669
|
const mojaloopError = await this._handleError(err);
|
|
668
670
|
this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
669
|
-
return this._mojaloopRequests
|
|
670
|
-
|
|
671
|
+
return this._mojaloopRequests.putFxTransfersError(
|
|
672
|
+
body.commitRequestId, mojaloopError, sourceFspId, headers
|
|
673
|
+
);
|
|
671
674
|
}
|
|
672
675
|
}
|
|
673
676
|
|
|
@@ -675,7 +678,7 @@ class InboundTransfersModel {
|
|
|
675
678
|
* Asks the backend for a response to an incoming bulk quotes request and makes a callback to the originator with
|
|
676
679
|
* the results.
|
|
677
680
|
*/
|
|
678
|
-
async bulkQuoteRequest(bulkQuoteRequest, sourceFspId) {
|
|
681
|
+
async bulkQuoteRequest(bulkQuoteRequest, sourceFspId, headers) {
|
|
679
682
|
const { bulkQuoteId } = bulkQuoteRequest;
|
|
680
683
|
const fulfilments = {};
|
|
681
684
|
try {
|
|
@@ -703,7 +706,7 @@ class InboundTransfersModel {
|
|
|
703
706
|
const mojaloopIndividualQuote = mojaloopResponse.individualQuoteResults.find(
|
|
704
707
|
(quoteResult) => quoteResult.quoteId === quote.quoteId
|
|
705
708
|
);
|
|
706
|
-
if(!mojaloopIndividualQuote.errorInformation) {
|
|
709
|
+
if (!mojaloopIndividualQuote.errorInformation) {
|
|
707
710
|
const quoteRequest = {
|
|
708
711
|
transactionId: quote.transactionId,
|
|
709
712
|
quoteId: quote.quoteId,
|
|
@@ -718,8 +721,7 @@ class InboundTransfersModel {
|
|
|
718
721
|
transferAmount: mojaloopIndividualQuote.transferAmount,
|
|
719
722
|
note: mojaloopIndividualQuote.note || '',
|
|
720
723
|
};
|
|
721
|
-
const { fulfilment, ilpPacket, condition } = this._ilp.getQuoteResponseIlp(
|
|
722
|
-
quoteRequest, quoteResponse);
|
|
724
|
+
const { fulfilment, ilpPacket, condition } = this._ilp.getQuoteResponseIlp(quoteRequest, quoteResponse);
|
|
723
725
|
|
|
724
726
|
// mutate individual quotes in `mojaloopResponse`
|
|
725
727
|
mojaloopIndividualQuote.ilpPacket = ilpPacket;
|
|
@@ -739,21 +741,20 @@ class InboundTransfersModel {
|
|
|
739
741
|
});
|
|
740
742
|
|
|
741
743
|
// make a callback to the source fsp with the quote response
|
|
742
|
-
return this._mojaloopRequests.putBulkQuotes(bulkQuoteId, mojaloopResponse, sourceFspId);
|
|
744
|
+
return this._mojaloopRequests.putBulkQuotes(bulkQuoteId, mojaloopResponse, sourceFspId, headers);
|
|
743
745
|
}
|
|
744
746
|
catch (err) {
|
|
745
747
|
this._logger.isErrorEnabled && this._logger.push({ err }).error('Error in bulkQuotesRequest');
|
|
746
748
|
const mojaloopError = await this._handleError(err);
|
|
747
|
-
this._logger.
|
|
748
|
-
return
|
|
749
|
-
mojaloopError, sourceFspId);
|
|
749
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
750
|
+
return this._mojaloopRequests.putBulkQuotesError(bulkQuoteId, mojaloopError, sourceFspId, headers);
|
|
750
751
|
}
|
|
751
752
|
}
|
|
752
753
|
|
|
753
754
|
/**
|
|
754
755
|
* Queries details of a bulk quote
|
|
755
756
|
*/
|
|
756
|
-
async getBulkQuote(bulkQuoteId, sourceFspId) {
|
|
757
|
+
async getBulkQuote(bulkQuoteId, sourceFspId, headers) {
|
|
757
758
|
try {
|
|
758
759
|
// make a call to the backend to get bulk quote details
|
|
759
760
|
const response = await this._backendRequests.getBulkQuotes(bulkQuoteId);
|
|
@@ -766,15 +767,13 @@ class InboundTransfersModel {
|
|
|
766
767
|
const mojaloopResponse = shared.internalBulkQuotesResponseToMojaloop(response);
|
|
767
768
|
|
|
768
769
|
// make a callback to the source fsp with the bulk quote response
|
|
769
|
-
return this._mojaloopRequests.putBulkQuotes(bulkQuoteId, mojaloopResponse,
|
|
770
|
-
sourceFspId);
|
|
770
|
+
return this._mojaloopRequests.putBulkQuotes(bulkQuoteId, mojaloopResponse, sourceFspId, headers);
|
|
771
771
|
}
|
|
772
772
|
catch (err) {
|
|
773
773
|
this._logger.isErrorEnabled && this._logger.push({ err, bulkQuoteId }).error('Error in getBulkQuote');
|
|
774
774
|
const mojaloopError = await this._handleError(err);
|
|
775
|
-
this._logger.
|
|
776
|
-
return this._mojaloopRequests.putBulkQuotesError(bulkQuoteId,
|
|
777
|
-
mojaloopError, sourceFspId);
|
|
775
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
776
|
+
return this._mojaloopRequests.putBulkQuotesError(bulkQuoteId, mojaloopError, sourceFspId, headers);
|
|
778
777
|
}
|
|
779
778
|
}
|
|
780
779
|
|
|
@@ -782,7 +781,7 @@ class InboundTransfersModel {
|
|
|
782
781
|
* Validates an incoming bulk transfer prepare request and makes a callback to the originator with
|
|
783
782
|
* the result
|
|
784
783
|
*/
|
|
785
|
-
async prepareBulkTransfer(bulkPrepareRequest, sourceFspId) {
|
|
784
|
+
async prepareBulkTransfer(bulkPrepareRequest, sourceFspId, headers) {
|
|
786
785
|
try {
|
|
787
786
|
// retrieve bulk quote data
|
|
788
787
|
const bulkQuote = await this._cache.get(`bulkQuotes_${bulkPrepareRequest.bulkQuoteId}`);
|
|
@@ -790,7 +789,9 @@ class InboundTransfersModel {
|
|
|
790
789
|
if (!bulkQuote) {
|
|
791
790
|
// Check whether to allow transfers without a previous quote.
|
|
792
791
|
if (!this._allowTransferWithoutQuote) {
|
|
793
|
-
|
|
792
|
+
const errMessage = `Corresponding bulk quotes not found for bulk transfers ${bulkPrepareRequest.bulkTransferId}`;
|
|
793
|
+
this._logger.isWarnEnabled && this._logger.warn(errMessage);
|
|
794
|
+
throw new Error(errMessage);
|
|
794
795
|
}
|
|
795
796
|
}
|
|
796
797
|
|
|
@@ -846,7 +847,7 @@ class InboundTransfersModel {
|
|
|
846
847
|
// TODO: Verify and align with actual schema for bulk transfers error endpoint
|
|
847
848
|
const error = Errors.MojaloopApiErrorObjectFromCode(Errors.MojaloopApiErrorCodes.QUOTE_EXPIRED);
|
|
848
849
|
this._logger.isErrorEnabled && this._logger.error(`Error in prepareBulkTransfers: bulk quotes expired for bulk transfers ${bulkPrepareRequest.bulkTransferId}, system time=${now.toISOString()} > quote time=${expiration.toISOString()}`);
|
|
849
|
-
return this._mojaloopRequests.putBulkTransfersError(bulkPrepareRequest.bulkTransferId, error, sourceFspId);
|
|
850
|
+
return this._mojaloopRequests.putBulkTransfersError(bulkPrepareRequest.bulkTransferId, error, sourceFspId, headers);
|
|
850
851
|
}
|
|
851
852
|
}
|
|
852
853
|
|
|
@@ -863,8 +864,7 @@ class InboundTransfersModel {
|
|
|
863
864
|
this._logger.isErrorEnabled && this._logger.push({ ...individualTransferErrors }).error('Error in prepareBulkTransfers');
|
|
864
865
|
this._logger.isDebugEnabled && this._logger.push({ ...individualTransferErrors }).debug(`Sending error response to ${sourceFspId}`);
|
|
865
866
|
|
|
866
|
-
return
|
|
867
|
-
mojaloopErrorResponse, sourceFspId);
|
|
867
|
+
return this._mojaloopRequests.putBulkTransfersError(bulkPrepareRequest.transferId, mojaloopErrorResponse, sourceFspId, headers);
|
|
868
868
|
}
|
|
869
869
|
|
|
870
870
|
// project the incoming bulk transfer prepare into an internal bulk transfer request
|
|
@@ -884,21 +884,20 @@ class InboundTransfersModel {
|
|
|
884
884
|
const mojaloopResponse = shared.internalBulkTransfersResponseToMojaloop(response, fulfilments);
|
|
885
885
|
|
|
886
886
|
// make a callback to the source fsp with the transfer fulfilment
|
|
887
|
-
return this._mojaloopRequests.putBulkTransfers(bulkPrepareRequest.bulkTransferId, mojaloopResponse, sourceFspId);
|
|
887
|
+
return this._mojaloopRequests.putBulkTransfers(bulkPrepareRequest.bulkTransferId, mojaloopResponse, sourceFspId, headers);
|
|
888
888
|
}
|
|
889
889
|
catch (err) {
|
|
890
890
|
this._logger.isErrorEnabled && this._logger.push({ err }).error('Error in prepareBulkTransfers');
|
|
891
891
|
const mojaloopError = await this._handleError(err);
|
|
892
|
-
this._logger.
|
|
893
|
-
return
|
|
894
|
-
mojaloopError, sourceFspId);
|
|
892
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
893
|
+
return this._mojaloopRequests.putBulkTransfersError(bulkPrepareRequest.bulkTransferId, mojaloopError, sourceFspId, headers);
|
|
895
894
|
}
|
|
896
895
|
}
|
|
897
896
|
|
|
898
897
|
/**
|
|
899
898
|
* Queries details of a bulk transfer
|
|
900
899
|
*/
|
|
901
|
-
async getBulkTransfer(bulkTransferId, sourceFspId) {
|
|
900
|
+
async getBulkTransfer(bulkTransferId, sourceFspId, headers) {
|
|
902
901
|
try {
|
|
903
902
|
// make a call to the backend to get bulk transfer details
|
|
904
903
|
const response = await this._backendRequests.getBulkTransfers(bulkTransferId);
|
|
@@ -944,15 +943,13 @@ class InboundTransfersModel {
|
|
|
944
943
|
};
|
|
945
944
|
|
|
946
945
|
// make a callback to the source fsp with the bulk transfer fulfilments
|
|
947
|
-
return this._mojaloopRequests.putBulkTransfers(bulkTransferId, mojaloopResponse,
|
|
948
|
-
sourceFspId);
|
|
946
|
+
return this._mojaloopRequests.putBulkTransfers(bulkTransferId, mojaloopResponse, sourceFspId, headers);
|
|
949
947
|
}
|
|
950
948
|
catch (err) {
|
|
951
949
|
this._logger.isErrorEnabled && this._logger.push({ err, bulkTransferId }).error('Error in getBulkTransfer');
|
|
952
950
|
const mojaloopError = await this._handleError(err);
|
|
953
|
-
this._logger.
|
|
954
|
-
return this._mojaloopRequests.putBulkTransfersError(bulkTransferId,
|
|
955
|
-
mojaloopError, sourceFspId);
|
|
951
|
+
this._logger.isInfoEnabled && this._logger.push({ mojaloopError }).info(`Sending error response to ${sourceFspId}`);
|
|
952
|
+
return this._mojaloopRequests.putBulkTransfersError(bulkTransferId, mojaloopError, sourceFspId, headers);
|
|
956
953
|
}
|
|
957
954
|
}
|
|
958
955
|
|
|
@@ -33,6 +33,7 @@ const { Enum, Util: { id: idGenerator } } = require('@mojaloop/central-services-
|
|
|
33
33
|
const { Ilp, MojaloopRequests } = require('@mojaloop/sdk-standard-components');
|
|
34
34
|
|
|
35
35
|
const { API_TYPES } = require('../../constants');
|
|
36
|
+
const { generateTraceparent } = require('../../lib/utils');
|
|
36
37
|
const dto = require('../dto');
|
|
37
38
|
const shared = require('./lib/shared');
|
|
38
39
|
const PartiesModel = require('./PartiesModel');
|
|
@@ -1233,7 +1234,7 @@ class OutboundTransfersModel {
|
|
|
1233
1234
|
* Modifies the data being stored in the cache for UI before it is stored.
|
|
1234
1235
|
* Works on a copy of original object to avoid side effects
|
|
1235
1236
|
*/
|
|
1236
|
-
_modifyDataForUi(
|
|
1237
|
+
_modifyDataForUi(data) {
|
|
1237
1238
|
// deep cloning to avoid side effects
|
|
1238
1239
|
let modifiedData = JSON.parse(JSON.stringify(data));
|
|
1239
1240
|
// Removing iso quote response and extension lists
|
|
@@ -1516,21 +1517,18 @@ class OutboundTransfersModel {
|
|
|
1516
1517
|
}
|
|
1517
1518
|
}
|
|
1518
1519
|
|
|
1519
|
-
#createOtelHeaders() {
|
|
1520
|
-
const { traceId } = this.data;
|
|
1521
|
-
const spanId = randomBytes(8).toString('hex');
|
|
1522
|
-
const flags = '01';
|
|
1523
|
-
|
|
1524
|
-
return Object.freeze({
|
|
1525
|
-
traceparent: `00-${traceId}-${spanId}-${flags}`,
|
|
1526
|
-
});
|
|
1527
|
-
}
|
|
1528
|
-
|
|
1529
1520
|
#generateTraceId() {
|
|
1530
1521
|
// todo: add possibility to generate traceId based on transferId
|
|
1531
1522
|
this.data.traceId = randomBytes(16).toString('hex');
|
|
1532
|
-
|
|
1533
|
-
|
|
1523
|
+
const { traceId, transferId } = this.data;
|
|
1524
|
+
this._logger.isInfoEnabled && this._logger.push({ traceId, transferId }).info('traceId is generated');
|
|
1525
|
+
return traceId;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
#createOtelHeaders() {
|
|
1529
|
+
return Object.freeze({
|
|
1530
|
+
traceparent: generateTraceparent(this.data.traceId),
|
|
1531
|
+
});
|
|
1534
1532
|
}
|
|
1535
1533
|
}
|
|
1536
1534
|
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
******/
|
|
27
27
|
|
|
28
28
|
const { hostname } = require('node:os');
|
|
29
|
+
const { randomBytes } = require('node:crypto');
|
|
29
30
|
const { WSO2Auth, Logger } = require('@mojaloop/sdk-standard-components');
|
|
30
31
|
|
|
31
32
|
const SDK_LOGGER_HIERARCHY = Logger.Logger.logLevels.reverse();
|
|
@@ -79,8 +80,15 @@ const transformHeadersIsoToFspiop = (isoHeaders) => {
|
|
|
79
80
|
return fspiopHeaders;
|
|
80
81
|
};
|
|
81
82
|
|
|
83
|
+
const generateTraceparent = (traceId = randomBytes(16).toString('hex')) => {
|
|
84
|
+
const spanId = randomBytes(8).toString('hex');
|
|
85
|
+
const flags = '01';
|
|
86
|
+
return `00-${traceId}-${spanId}-${flags}`;
|
|
87
|
+
};
|
|
88
|
+
|
|
82
89
|
module.exports = {
|
|
83
90
|
createAuthClient,
|
|
84
91
|
createLogger,
|
|
92
|
+
generateTraceparent,
|
|
85
93
|
transformHeadersIsoToFspiop
|
|
86
94
|
};
|
package/package.json
CHANGED