@mojaloop/central-ledger 19.14.0 → 20.1.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.
Files changed (394) hide show
  1. package/.grype.yaml +3 -0
  2. package/.license-scanner.json +16 -0
  3. package/.ncurc.yaml +19 -13
  4. package/.nvmrc +1 -1
  5. package/.nycrc.yml +14 -2
  6. package/CHANGELOG.md +51 -0
  7. package/Dockerfile +13 -10
  8. package/README.md +39 -89
  9. package/audit-ci.jsonc +1 -1
  10. package/config/default.json +60 -3
  11. package/config/deprecated.default-settlement.json +160 -0
  12. package/docker/ml-api-adapter/default.json +28 -0
  13. package/docker-compose.yml +6 -0
  14. package/nodemon.json +6 -0
  15. package/package.json +128 -64
  16. package/{sbom-v19.13.2.csv → sbom-v20.0.0.csv} +886 -736
  17. package/scripts/_wait4_all.js +5 -5
  18. package/scripts/transferSettlementTemp/interchangeFeeCalculation.js +51 -0
  19. package/src/api/index.ts +30 -0
  20. package/src/api/interface/swagger.json +2249 -2054
  21. package/src/api/participants/routes.js +1 -1
  22. package/src/api/root/handler.int.ts +55 -0
  23. package/src/api/routes.js +7 -6
  24. package/src/api/server.ts +27 -0
  25. package/src/api/server.unit.ts +16 -0
  26. package/src/api/settlementModels/routes.js +4 -4
  27. package/src/domain/participant/index.d.ts +47 -0
  28. package/src/domain/participant/index.int.ts +724 -0
  29. package/src/domain/participant/index.js +4 -5
  30. package/src/domain/position/fx-prepare.js +1 -1
  31. package/src/domain/position/fx-timeout-reserved.js +6 -0
  32. package/src/domain/position/prepare.js +1 -1
  33. package/src/handlers/admin/handler.js +1 -1
  34. package/src/handlers/index.js +30 -0
  35. package/src/handlers/positions/handler.js +0 -2
  36. package/src/handlers/positions/handlerBatch.js +5 -5
  37. package/src/handlers/register.js +44 -29
  38. package/src/handlers/timeouts/handler.js +1 -4
  39. package/src/handlers/transfers/fx-abort.int.ts +209 -0
  40. package/src/handlers/transfers/fx-handlers.int.ts +275 -0
  41. package/src/handlers/transfers/fx-timeout.int.ts +284 -0
  42. package/src/handlers/transfers/handler.js +1 -3
  43. package/src/handlers/transfers/handlers.int.ts +538 -0
  44. package/src/handlers/transfers/prepare.int.ts +1283 -0
  45. package/src/handlers/transfers/prepare.js +2 -2
  46. package/src/knexfile.js +19 -0
  47. package/src/lib/cache.js +1 -1
  48. package/src/lib/config/index.ts +60 -0
  49. package/src/lib/config/resolver.ts +231 -0
  50. package/src/lib/config/resolver.unit.ts +72 -0
  51. package/src/lib/config/types.ts +372 -0
  52. package/src/lib/config/util.ts +523 -0
  53. package/src/lib/config/util.unit.ts +825 -0
  54. package/src/lib/migrator.js +3 -3
  55. package/src/lib/proxyCache.js +3 -3
  56. package/{migrations → src/migrations}/100100_event.js +1 -1
  57. package/{migrations → src/migrations}/110100_contactType.js +1 -1
  58. package/{migrations → src/migrations}/110200_currency.js +1 -1
  59. package/{migrations → src/migrations}/110201_currency-scale.js +1 -1
  60. package/{migrations → src/migrations}/110300_endpointType.js +1 -1
  61. package/{migrations → src/migrations}/110400_ledgerEntryType.js +1 -1
  62. package/{migrations → src/migrations}/110450_ledgerAccountType.js +1 -1
  63. package/{migrations → src/migrations}/110500_participantLimitType.js +1 -1
  64. package/{migrations → src/migrations}/110600_transferParticipantRoleType.js +1 -1
  65. package/{migrations → src/migrations}/110700_transferState.js +1 -1
  66. package/{migrations → src/migrations}/110900_settlementState.js +1 -1
  67. package/{migrations → src/migrations}/112000_bulkTransferState.js +1 -1
  68. package/{migrations → src/migrations}/112100_bulkProcessingState.js +1 -1
  69. package/{migrations → src/migrations}/200100_participant.js +1 -1
  70. package/{migrations → src/migrations}/200200_participantContact.js +1 -1
  71. package/{migrations → src/migrations}/200300_participantEndpoint.js +1 -1
  72. package/{migrations → src/migrations}/200400_participantParty.js +1 -1
  73. package/{migrations → src/migrations}/200600_token.js +1 -1
  74. package/{migrations → src/migrations}/200601_token-indexes.js +1 -1
  75. package/{migrations → src/migrations}/300100_transferDuplicateCheck.js +2 -2
  76. package/{migrations → src/migrations}/300150_bulkTransferDuplicateCheck.js +2 -2
  77. package/{migrations → src/migrations}/300200_transfer.js +2 -2
  78. package/{migrations → src/migrations}/300202_transfer-decimal184.js +1 -1
  79. package/{migrations → src/migrations}/300250_bulkTransfer.js +2 -3
  80. package/{migrations → src/migrations}/300275_bulkTransferAssociation.js +2 -3
  81. package/{migrations → src/migrations}/300300_ilpPacket.js +1 -1
  82. package/{migrations → src/migrations}/300400_transferStateChange.js +1 -1
  83. package/{migrations → src/migrations}/300450_bulkTransferStateChange.js +1 -1
  84. package/{migrations → src/migrations}/300500_segment.js +1 -1
  85. package/{migrations → src/migrations}/310100_participantCurrency.js +1 -1
  86. package/{migrations → src/migrations}/310200_transferParticipant.js +1 -1
  87. package/{migrations → src/migrations}/310202_transferParticipant-decimal184.js +1 -1
  88. package/{migrations → src/migrations}/310204_transferParticipant-participantId.js +2 -2
  89. package/{migrations → src/migrations}/310300_participantPosition.js +1 -1
  90. package/{migrations → src/migrations}/310302_participantPosition-decimal184.js +1 -1
  91. package/{migrations → src/migrations}/310400_participantPositionChange.js +1 -1
  92. package/{migrations → src/migrations}/310402_participantPositionChange-decimal184.js +1 -1
  93. package/{migrations → src/migrations}/310403_participantPositionChange-participantCurrencyId.js +2 -2
  94. package/{migrations → src/migrations}/310404_participantPositionChange-change.js +2 -2
  95. package/{migrations → src/migrations}/310500_participantLimit.js +1 -1
  96. package/{migrations → src/migrations}/310502_participantLimit-decimal184.js +1 -1
  97. package/{migrations → src/migrations}/400100_settlementWindow.js +1 -1
  98. package/{migrations → src/migrations}/400200_settlement.js +1 -1
  99. package/{migrations → src/migrations}/400300_settlementSettlementWindow.js +1 -1
  100. package/{migrations → src/migrations}/400301_settlementSettlementWindow-indexes.js +0 -1
  101. package/{migrations → src/migrations}/400400_settlementWindowStateChange.js +1 -1
  102. package/{migrations → src/migrations}/400500_settlementTransferParticipant.js +1 -1
  103. package/{migrations → src/migrations}/400502_settlementTransferParticipant-decimal184.js +1 -1
  104. package/{migrations → src/migrations}/400600_settlementParticipantCurrency.js +1 -1
  105. package/{migrations → src/migrations}/400602_settlementParticipantCurrency-decimal184.js +1 -1
  106. package/{migrations → src/migrations}/400700_settlementParticipantCurrencyStateChange.js +1 -1
  107. package/{migrations → src/migrations}/400800_settlementStateChange.js +1 -1
  108. package/{migrations → src/migrations}/400900_settlementWindowContent.js +1 -1
  109. package/{migrations → src/migrations}/401000_settlementWindowContentStateChange.js +1 -1
  110. package/{migrations → src/migrations}/401001_settlementWindowContentStateChange-indexes.js +6 -6
  111. package/{migrations → src/migrations}/401200_settlementContentAggregation.js +1 -1
  112. package/{migrations → src/migrations}/401300_settlementModel.js +1 -1
  113. package/{migrations → src/migrations}/410100_transferFulfilmentDuplicateCheck.js +1 -1
  114. package/{migrations → src/migrations}/410102_transferFulfilmentDuplicateCheck-dropForeignTransferId.js +1 -1
  115. package/{migrations → src/migrations}/410103_transferFulfilmentDuplicateCheck-hashNullable.js +1 -1
  116. package/{migrations → src/migrations}/410200_transferFulfilment.js +1 -1
  117. package/{migrations → src/migrations}/410202_transferFulfilment-ilpFulfilment.js +1 -1
  118. package/{migrations → src/migrations}/410203_transferFulfilment-foreignTransferFulfilmentId.js +1 -1
  119. package/{migrations → src/migrations}/410240_bulkTransferFulfilmentDuplicateCheck.js +1 -1
  120. package/{migrations → src/migrations}/410250_bulkTransferFulfilment.js +1 -1
  121. package/{migrations → src/migrations}/410300_transferExtension.js +1 -1
  122. package/{migrations → src/migrations}/410302_transferExtension-transferErrorId.js +1 -1
  123. package/{migrations → src/migrations}/410350_bulkTransferExtension.js +1 -1
  124. package/{migrations → src/migrations}/410400_transferTimeout.js +1 -1
  125. package/{migrations → src/migrations}/410450_transferErrorDuplicateCheck.js +1 -1
  126. package/{migrations → src/migrations}/410500_transferError.js +1 -1
  127. package/{migrations → src/migrations}/410502_transferError-foreignTransferErrorDuplicateCheckId.js +1 -1
  128. package/{migrations → src/migrations}/410550_bulkTransferError.js +1 -1
  129. package/{migrations → src/migrations}/410600_expiringTransfer.js +1 -1
  130. package/{migrations → src/migrations}/500401_quote-hotfix-2719.js +8 -8
  131. package/{migrations → src/migrations}/500501_feature-fixSubIdRef.js +12 -12
  132. package/{migrations → src/migrations}/500601_party-2480.js +3 -3
  133. package/{migrations → src/migrations}/501001_quoteExtension-quote-service-174.js +1 -2
  134. package/{migrations → src/migrations}/501002_quoteExtension-2522.js +3 -3
  135. package/{migrations → src/migrations}/600010_fxTransferType.js +1 -1
  136. package/{migrations → src/migrations}/600012_fxParticipantCurrencyType.js +1 -1
  137. package/{migrations → src/migrations}/600100_fxTransferDuplicateCheck.js +2 -2
  138. package/{migrations → src/migrations}/600110_fxTransferErrorDuplicateCheck.js.js +1 -1
  139. package/{migrations → src/migrations}/600200_fxTransfer.js +2 -2
  140. package/{migrations → src/migrations}/600400_fxTransferStateChange.js +1 -1
  141. package/{migrations → src/migrations}/600501_fxWatchList.js +2 -2
  142. package/{migrations → src/migrations}/600600_fxTransferFulfilmentDuplicateCheck.js +1 -1
  143. package/{migrations → src/migrations}/600700_fxTransferFulfilment.js +1 -1
  144. package/{migrations → src/migrations}/600800_fxTransferExtension.js +1 -1
  145. package/{migrations → src/migrations}/601400_fxTransferTimeout.js +1 -1
  146. package/{migrations → src/migrations}/601500_fxTransferError.js +1 -1
  147. package/{migrations → src/migrations}/610200_fxTransferParticipant.js +1 -1
  148. package/{migrations → src/migrations}/610202_fxTransferParticipant-participantId.js +2 -2
  149. package/{migrations → src/migrations}/610403_participantPositionChange-fxTransfer.js +1 -1
  150. package/{migrations → src/migrations}/800100_quotePartyView.js +1 -1
  151. package/{migrations → src/migrations}/800101_feature-fixSubIdRef.js +1 -1
  152. package/{migrations → src/migrations}/800200_quoteView.js +1 -1
  153. package/{migrations → src/migrations}/800300_quoteResponseView.js +1 -1
  154. package/{migrations → src/migrations}/900100_foreign-keys.js +18 -18
  155. package/{migrations → src/migrations}/900101_foreign-keys.js +6 -6
  156. package/{migrations → src/migrations}/910100_feature904DDL.js +7 -7
  157. package/{migrations → src/migrations}/910101_feature904DataMigration.js +1 -1
  158. package/{migrations → src/migrations}/910102_feature949DataMigration.js +1 -1
  159. package/{migrations → src/migrations}/910103_feature1093SettlementByCurrency.js +3 -3
  160. package/{migrations → src/migrations}/940101_quotePartyIdInfoExtension-2522.js +25 -25
  161. package/{migrations → src/migrations}/950101_transferParticipantStateChange.js +2 -2
  162. package/{migrations → src/migrations}/950102_settlementModel-adjustPosition.js +2 -2
  163. package/{migrations → src/migrations}/950103_dropTransferParticipantStateChange.js +3 -3
  164. package/{migrations → src/migrations}/950104_settlementModel-settlementAccountTypeId.js +3 -3
  165. package/src/migrations/950107_settlementWindowContent_foreign_settlementModel.js +63 -0
  166. package/{migrations → src/migrations}/950108_participantProxy.js +1 -2
  167. package/{migrations → src/migrations}/950120_fxQuoteConversionTerms_sourceAmount_nullable.js +1 -1
  168. package/{migrations → src/migrations}/960100_create_externalParticipant.js +2 -2
  169. package/{migrations → src/migrations}/960110_alter_transferParticipant__addFiled_externalParticipantId.js +2 -2
  170. package/{migrations → src/migrations}/961001_transferForwarded.js +1 -1
  171. package/{migrations → src/migrations}/961002_fxTransferForwarded.js +1 -1
  172. package/src/models/participant/externalParticipant.int.ts +85 -0
  173. package/src/models/participant/facade.js +4 -2
  174. package/src/models/participant/participantCurrencyCached.js +1 -1
  175. package/src/models/position/facade.js +8 -2
  176. package/src/models/transfer/facade.int.ts +139 -0
  177. package/src/models/transfer/facade.js +8 -3
  178. package/src/models/transfer/transferDuplicateCheck.js +2 -2
  179. package/src/models/transfer/transferError.int.ts +112 -0
  180. package/src/models/transfer/transferExtension.int.ts +137 -0
  181. package/src/models/transfer/transferStateChange.int.ts +117 -0
  182. package/{seeds → src/seeds}/participant.js +1 -1
  183. package/{seeds → src/seeds}/settlementInterchange.js +1 -0
  184. package/src/settlement/api/handlerRoutes.js +71 -0
  185. package/src/settlement/api/handlers/health.js +10 -0
  186. package/src/settlement/api/handlers/index.js +57 -0
  187. package/src/settlement/api/handlers/settlementWindows/{id}.js +103 -0
  188. package/src/settlement/api/handlers/settlementWindows.js +77 -0
  189. package/src/settlement/api/handlers/settlements/{id}.js +133 -0
  190. package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}/accounts/{aid}.js +127 -0
  191. package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}.js +127 -0
  192. package/src/settlement/api/handlers/settlements.js +114 -0
  193. package/src/settlement/api/openapiRouting.js +87 -0
  194. package/src/settlement/api/routes.js +176 -0
  195. package/src/settlement/domain/rules/index.js +46 -0
  196. package/src/settlement/domain/settlement/index.js +405 -0
  197. package/src/settlement/domain/settlementWindow/index.js +117 -0
  198. package/src/settlement/domain/transactions/index.js +83 -0
  199. package/src/settlement/domain/transferSettlement/index.js +57 -0
  200. package/src/settlement/handlers/deferredSettlement/handler.js +180 -0
  201. package/src/settlement/handlers/grossSettlement/handler.js +180 -0
  202. package/src/settlement/handlers/index.js +101 -0
  203. package/src/settlement/handlers/register.js +92 -0
  204. package/src/settlement/handlers/rules/handler.js +164 -0
  205. package/src/settlement/interface/swagger-handler.json +34 -0
  206. package/src/settlement/interface/swagger.json +1560 -0
  207. package/src/settlement/lib/db.js +32 -0
  208. package/src/settlement/lib/kafka/index.js +41 -0
  209. package/src/settlement/lib/kafka/producer.js +142 -0
  210. package/src/settlement/lib/scriptEngine.js +99 -0
  211. package/src/settlement/lib/scriptsLoader.js +175 -0
  212. package/src/settlement/lib/utility.js +243 -0
  213. package/src/settlement/models/ilpPackets/ilpPacket.js +42 -0
  214. package/src/settlement/models/lib/enums.js +192 -0
  215. package/src/settlement/models/misc/migrationLock.js +53 -0
  216. package/src/settlement/models/settlement/facade.js +1652 -0
  217. package/src/settlement/models/settlement/index.js +55 -0
  218. package/src/settlement/models/settlement/participantCurrency.js +48 -0
  219. package/src/settlement/models/settlement/settlement.js +49 -0
  220. package/src/settlement/models/settlement/settlementModel.js +44 -0
  221. package/src/settlement/models/settlement/settlementParticipantCurrency.js +61 -0
  222. package/src/settlement/models/settlement/settlementStateChange.js +44 -0
  223. package/src/settlement/models/settlement/settlementTransferParticipant.js +46 -0
  224. package/src/settlement/models/settlementWindow/facade.js +345 -0
  225. package/src/settlement/models/settlementWindow/index.js +47 -0
  226. package/src/settlement/models/settlementWindow/settlementWindowStateChange.js +55 -0
  227. package/src/settlement/models/settlementWindowContent/facade.js +79 -0
  228. package/src/settlement/models/settlementWindowContent/index.js +40 -0
  229. package/src/settlement/models/settlementWindowContent/settlementWindowContentStateChange.js +53 -0
  230. package/src/settlement/models/transferSettlement/facade.js +363 -0
  231. package/src/settlement/models/transferSettlement/index.js +42 -0
  232. package/src/settlement/shared/logger/index.js +7 -0
  233. package/src/settlement/shared/plugins.js +88 -0
  234. package/src/settlement/shared/setup.js +224 -0
  235. package/src/settlement/utils/truthyProperty.js +37 -0
  236. package/src/shared/legacyUtilShim.js +20 -0
  237. package/src/shared/plugins.js +3 -3
  238. package/src/shared/results.ts +22 -0
  239. package/src/shared/results.unit.ts +38 -0
  240. package/src/shared/setup.js +14 -1
  241. package/src/testing/api-helpers.ts +1222 -0
  242. package/src/testing/exec-async.ts +67 -0
  243. package/src/testing/harness.snapshot.sql +3895 -0
  244. package/src/testing/harness.test.ts +15 -0
  245. package/src/testing/harness.ts +1160 -0
  246. package/src/testing/kafka.ts +221 -0
  247. package/src/testing/prng.ts +82 -0
  248. package/src/testing/rdkafka.test.ts +263 -0
  249. package/src/testing/run.ts +559 -0
  250. package/src/testing/snapshot.test.ts +92 -0
  251. package/src/testing/snapshot.ts +549 -0
  252. package/src/testing/tap-stream.ts +164 -0
  253. package/src/testing/types.ts +95 -0
  254. package/src/testing/util.ts +333 -0
  255. package/src/types/central-services-error-handling.d.ts +72 -0
  256. package/src/types/central-services-stream.d.ts +148 -0
  257. package/test-integration.Dockerfile +0 -2
  258. package/test.Dockerfile +0 -2
  259. package/tsconfig.json +40 -0
  260. package/config/knexfile.js +0 -19
  261. package/migrations/950107_settlementWindowContent_foreign_settlementModel.js +0 -63
  262. package/src/api/index.js +0 -16
  263. package/src/lib/config.js +0 -81
  264. /package/{migrations → src/migrations}/110101_contactType-indexes.js +0 -0
  265. /package/{migrations → src/migrations}/110301_endpointType-indexes.js +0 -0
  266. /package/{migrations → src/migrations}/110401_ledgerEntryType-indexes.js +0 -0
  267. /package/{migrations → src/migrations}/110451_ledgerAccountType-indexes.js +0 -0
  268. /package/{migrations → src/migrations}/110501_participantLimitType-indexes.js +0 -0
  269. /package/{migrations → src/migrations}/110601_transferParticipantRoleType-indexes.js +0 -0
  270. /package/{migrations → src/migrations}/110800_settlementWindowState.js +0 -0
  271. /package/{migrations → src/migrations}/111000_amountType.js +0 -0
  272. /package/{migrations → src/migrations}/111001_amountType-indexes.js +0 -0
  273. /package/{migrations → src/migrations}/111100_balanceOfPayments.js +0 -0
  274. /package/{migrations → src/migrations}/111101_balanceOfPayments-indexes.js +0 -0
  275. /package/{migrations → src/migrations}/111200_partyIdentifierType.js +0 -0
  276. /package/{migrations → src/migrations}/111201_partyIdentifierType-indexes.js +0 -0
  277. /package/{migrations → src/migrations}/111300_partyType.js +0 -0
  278. /package/{migrations → src/migrations}/111301_partyType-indexes.js +0 -0
  279. /package/{migrations → src/migrations}/111400_quoteDuplicateCheck.js +0 -0
  280. /package/{migrations → src/migrations}/111500_transactionInitiator.js +0 -0
  281. /package/{migrations → src/migrations}/111501_transactionInitiator-indexes.js +0 -0
  282. /package/{migrations → src/migrations}/111600_transactionInitiatorType.js +0 -0
  283. /package/{migrations → src/migrations}/111601_transactionInitiatorType-indexes.js +0 -0
  284. /package/{migrations → src/migrations}/111700_settlementDelay.js +0 -0
  285. /package/{migrations → src/migrations}/111701_settlementDelay-indexes.js +0 -0
  286. /package/{migrations → src/migrations}/111800_settlementInterchange.js +0 -0
  287. /package/{migrations → src/migrations}/111801_settlementInterchange-indexes.js +0 -0
  288. /package/{migrations → src/migrations}/111900_settlementGranularity.js +0 -0
  289. /package/{migrations → src/migrations}/111901_settlementGranularity-indexes.js +0 -0
  290. /package/{migrations → src/migrations}/112101_bulkProcessingState-indexes.js +0 -0
  291. /package/{migrations → src/migrations}/200101_participant-indexes.js +0 -0
  292. /package/{migrations → src/migrations}/200201_participantContact-indexes.js +0 -0
  293. /package/{migrations → src/migrations}/200301_participantEndpoint-indexes.js +0 -0
  294. /package/{migrations → src/migrations}/200401_participantParty-indexes.js +0 -0
  295. /package/{migrations → src/migrations}/300201_transfer-indexes.js +0 -0
  296. /package/{migrations → src/migrations}/300251_bulkTransfer-indexes.js +0 -0
  297. /package/{migrations → src/migrations}/300276_bulkTransferAssociation-indexes.js +0 -0
  298. /package/{migrations → src/migrations}/300401_transferStateChange-indexes.js +0 -0
  299. /package/{migrations → src/migrations}/300451_bulkTransferStateChange-indexes.js +0 -0
  300. /package/{migrations → src/migrations}/300501_segment-indexes.js +0 -0
  301. /package/{migrations → src/migrations}/310101_participantCurrency-indexes.js +0 -0
  302. /package/{migrations → src/migrations}/310201_transferParticipant-indexes.js +0 -0
  303. /package/{migrations → src/migrations}/310203_transferParticipant-indexes.js +0 -0
  304. /package/{migrations → src/migrations}/310301_participantPosition-indexes.js +0 -0
  305. /package/{migrations → src/migrations}/310401_participantPositionChange-indexes.js +0 -0
  306. /package/{migrations → src/migrations}/310405_participantPositionChange-positionChange.js +0 -0
  307. /package/{migrations → src/migrations}/310406_participantPositionChange-positionChange-revert.js +0 -0
  308. /package/{migrations → src/migrations}/310501_participantLimit-indexes.js +0 -0
  309. /package/{migrations → src/migrations}/310503_participantLimit-indexes-composite.js +0 -0
  310. /package/{migrations → src/migrations}/400401_settlmentWindowStateChange-indexes.js +0 -0
  311. /package/{migrations → src/migrations}/400501_settlementTransferParticipant-indexes.js +0 -0
  312. /package/{migrations → src/migrations}/400601_settlementParticipantCurrency-indexes.js +0 -0
  313. /package/{migrations → src/migrations}/400701_settlementParticipantCurrencyStateChange-indexes.js +0 -0
  314. /package/{migrations → src/migrations}/400801_settlementStateChange-indexes.js +0 -0
  315. /package/{migrations → src/migrations}/401002_settlementWindowContent-indexes.js +0 -0
  316. /package/{migrations → src/migrations}/401201_settlementContentAggregation-indexes.js +0 -0
  317. /package/{migrations → src/migrations}/401301_settlementModel-indexes.js +0 -0
  318. /package/{migrations → src/migrations}/410101_transferFulfilmentDuplicateCheck-indexes.js +0 -0
  319. /package/{migrations → src/migrations}/410201_transferFulfilment-indexes.js +0 -0
  320. /package/{migrations → src/migrations}/410301_transferExtension-indexes.js +0 -0
  321. /package/{migrations → src/migrations}/410351_bulkTransferExtension-indexes.js +0 -0
  322. /package/{migrations → src/migrations}/410401_transferTimeout-indexes.js +0 -0
  323. /package/{migrations → src/migrations}/410501_transferError-indexes.js +0 -0
  324. /package/{migrations → src/migrations}/410551_bulkTransferError-indexes.js +0 -0
  325. /package/{migrations → src/migrations}/410601_expiringTransfer-indexes.js +0 -0
  326. /package/{migrations → src/migrations}/500100_transactionReference.js +0 -0
  327. /package/{migrations → src/migrations}/500101_transactionReference-indexes.js +0 -0
  328. /package/{migrations → src/migrations}/500200_transactionScenario.js +0 -0
  329. /package/{migrations → src/migrations}/500201_transactionScenario-indexes.js +0 -0
  330. /package/{migrations → src/migrations}/500300_transactionSubScenario.js +0 -0
  331. /package/{migrations → src/migrations}/500400_quote.js +0 -0
  332. /package/{migrations → src/migrations}/500500_quoteParty.js +0 -0
  333. /package/{migrations → src/migrations}/500600_party.js +0 -0
  334. /package/{migrations → src/migrations}/500700_quoteResponse.js +0 -0
  335. /package/{migrations → src/migrations}/500800_quoteResponseIlpPacket.js +0 -0
  336. /package/{migrations → src/migrations}/500900_geoCode.js +0 -0
  337. /package/{migrations → src/migrations}/501000_quoteExtension.js +0 -0
  338. /package/{migrations → src/migrations}/501100_quoteResponseDuplicateCheck.js +0 -0
  339. /package/{migrations → src/migrations}/501200_quoteError.js +0 -0
  340. /package/{migrations → src/migrations}/501300_transferRules.js +0 -0
  341. /package/{migrations → src/migrations}/600011_fxTransferType-indexes.js +0 -0
  342. /package/{migrations → src/migrations}/600013_fxParticipantCurrencyType-indexes.js +0 -0
  343. /package/{migrations → src/migrations}/600201_fxTransfer-indexes.js +0 -0
  344. /package/{migrations → src/migrations}/600401_fxTransferStateChange-indexes.js +0 -0
  345. /package/{migrations → src/migrations}/600502_fxWatchList-indexes.js +0 -0
  346. /package/{migrations → src/migrations}/600601_fxTransferFulfilmentDuplicateCheck-indexes.js +0 -0
  347. /package/{migrations → src/migrations}/600701_fxTransferFulfilment-indexes.js +0 -0
  348. /package/{migrations → src/migrations}/601401_fxTransferTimeout-indexes.js +0 -0
  349. /package/{migrations → src/migrations}/601501_fxTransferError-indexes.js +0 -0
  350. /package/{migrations → src/migrations}/610201_fxTransferParticipant-indexes.js +0 -0
  351. /package/{migrations → src/migrations}/910102_hotfix954.js +0 -0
  352. /package/{migrations → src/migrations}/940100_quotePartyIdInfoExtension.js +0 -0
  353. /package/{migrations → src/migrations}/950100_settlementContentAggregation-decimal184.js +0 -0
  354. /package/{migrations → src/migrations}/950106_unique_settlement_model_ledger_account_currency.js +0 -0
  355. /package/{migrations → src/migrations}/950109_fxQuote.js +0 -0
  356. /package/{migrations → src/migrations}/950110_fxQuoteResponse.js +0 -0
  357. /package/{migrations → src/migrations}/950111_fxQuoteError.js +0 -0
  358. /package/{migrations → src/migrations}/950113_fxQuoteDuplicateCheck.js +0 -0
  359. /package/{migrations → src/migrations}/950114_fxQuoteResponseDuplicateCheck.js +0 -0
  360. /package/{migrations → src/migrations}/950115_fxQuoteConversionTerms.js +0 -0
  361. /package/{migrations → src/migrations}/950116_fxQuoteConversionTermsExtension.js +0 -0
  362. /package/{migrations → src/migrations}/950117_fxQuoteResponseConversionTerms.js +0 -0
  363. /package/{migrations → src/migrations}/950118_fxQuoteResponseConversionTermsExtension.js +0 -0
  364. /package/{migrations → src/migrations}/950119_fxCharge.js +0 -0
  365. /package/{migrations → src/migrations}/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js +0 -0
  366. /package/{migrations → src/migrations}/960112_fxTransfer-indexes2.js +0 -0
  367. /package/{migrations → src/migrations}/960113_fxTransferExtension-indexes.js +0 -0
  368. /package/{migrations → src/migrations}/960114_fxTransferTimeout-indexes2.js +0 -0
  369. /package/{migrations → src/migrations}/961000_participantEndpoint_unique.js +0 -0
  370. /package/{migrations → src/migrations}/migration.template +0 -0
  371. /package/{seeds → src/seeds}/amountType.js +0 -0
  372. /package/{seeds → src/seeds}/balanceOfPayments.js +0 -0
  373. /package/{seeds → src/seeds}/bulkProcessingState.js +0 -0
  374. /package/{seeds → src/seeds}/bulkTransferState.js +0 -0
  375. /package/{seeds → src/seeds}/currency.js +0 -0
  376. /package/{seeds → src/seeds}/endpointType.js +0 -0
  377. /package/{seeds → src/seeds}/fxParticipantCurrencyType.js +0 -0
  378. /package/{seeds → src/seeds}/fxTransferType.js +0 -0
  379. /package/{seeds → src/seeds}/ledgerAccountType.js +0 -0
  380. /package/{seeds → src/seeds}/ledgerEntryType.js +0 -0
  381. /package/{seeds → src/seeds}/participantLimitType.js +0 -0
  382. /package/{seeds → src/seeds}/partyIdentifierType.js +0 -0
  383. /package/{seeds → src/seeds}/partyType.js +0 -0
  384. /package/{seeds → src/seeds}/settlementDelay.js +0 -0
  385. /package/{seeds → src/seeds}/settlementGranularity.js +0 -0
  386. /package/{seeds → src/seeds}/settlementState.js +0 -0
  387. /package/{seeds → src/seeds}/settlementWindow1State.js +0 -0
  388. /package/{seeds → src/seeds}/settlementWindow2Open.js +0 -0
  389. /package/{seeds → src/seeds}/transactionInitiator.js +0 -0
  390. /package/{seeds → src/seeds}/transactionInitiatorType.js +0 -0
  391. /package/{seeds → src/seeds}/transactionScenario.js +0 -0
  392. /package/{seeds → src/seeds}/transferParticipantRoleType.js +0 -0
  393. /package/{seeds → src/seeds}/transferState.js +0 -0
  394. /package/{seeds → src/seeds}/z1000_settlementModel-deprecated.js- +0 -0
@@ -0,0 +1,139 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2026 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * TigerBeetle
23
+ - Lewis Daly <lewis@tigerbeetle.com>
24
+ --------------
25
+
26
+ ******/
27
+ import { after, before, describe, it } from "node:test"
28
+ import Harness from '../../testing/harness'
29
+ import { Snapshot } from "../../testing/snapshot"
30
+ import * as ApiHelpers from '../../testing/api-helpers'
31
+
32
+ import TransferHandler from '../../handlers/transfers/handler'
33
+
34
+ const harness = Harness.getInstance()
35
+ import TransferFacade from "./facade"
36
+
37
+
38
+ describe('models/tranfer/facade', () => {
39
+ before(async () => {
40
+ await harness.up()
41
+ await harness.setupGlobals()
42
+
43
+ await TransferHandler.registerPrepareHandler()
44
+ await TransferHandler.registerFulfilHandler()
45
+
46
+ // Create the hub accounts + settlement model.
47
+ const createHubPayload: ApiHelpers.CreateHubPayload = {
48
+ currencies: ['USD'],
49
+ settlementModels: [{
50
+ name: `DEFERRED_MULTILATERAL_NET_USD`,
51
+ settlementGranularity: "NET",
52
+ settlementInterchange: "MULTILATERAL",
53
+ settlementDelay: "DEFERRED",
54
+ currency: 'USD',
55
+ requireLiquidityCheck: true,
56
+ ledgerAccountType: "POSITION",
57
+ settlementAccountType: "SETTLEMENT",
58
+ autoPositionReset: true
59
+ }]
60
+ }
61
+ await ApiHelpers.createHub(harness, createHubPayload)
62
+ // Create 2 test dfsps to transfer between.
63
+ await ApiHelpers.createDfsp(harness, {
64
+ name: 'dfsp_a',
65
+ currencies: ['USD'],
66
+ isProxy: false,
67
+ initialPostionsAndLimits: [
68
+ {
69
+ initialPosition: 0,
70
+ value: 100000
71
+ }
72
+ ],
73
+ deposits: [10000]
74
+ })
75
+ await ApiHelpers.createDfsp(harness, {
76
+ name: 'dfsp_b',
77
+ currencies: ['USD'],
78
+ isProxy: false,
79
+ initialPostionsAndLimits: [
80
+ {
81
+ initialPosition: 0,
82
+ value: 100000
83
+ }
84
+ ],
85
+ deposits: [10000]
86
+ })
87
+
88
+ // Create payment of $100.00 USD from dfsp_a to dfsp_b with id 1000001.
89
+ await ApiHelpers.buildPayment()
90
+ .deps(harness, TransferHandler)
91
+ .parties('dfsp_a', 'dfsp_b')
92
+ .transferId('1000001')
93
+ .build()
94
+ .prepareAndFulfil()
95
+ })
96
+
97
+ after(async () => {
98
+ await harness.teardownGlobals()
99
+ await harness.down()
100
+ })
101
+
102
+ it('getById() - gets one transfer.', async () => {
103
+ const transfer = await TransferFacade.getById('1000001')
104
+ Snapshot.from(`{
105
+ "transferId": "1000001",
106
+ "amount": "100.0000",
107
+ "currencyId": "USD",
108
+ "ilpCondition": :ignore
109
+ "expirationDate": :ignore
110
+ "createdDate": :ignore
111
+ "currency": "USD",
112
+ "payerParticipantCurrencyId": 3,
113
+ "payerAmount": "100.0000",
114
+ "payerParticipantId": 2,
115
+ "payerFsp": "dfsp_a",
116
+ "payerIsProxy": 0,
117
+ "payeeParticipantCurrencyId": null,
118
+ "payeeAmount": "-100.0000",
119
+ "payeeParticipantId": 3,
120
+ "payeeFsp": "dfsp_b",
121
+ "payeeIsProxy": 0,
122
+ "transferStateChangeId": 12,
123
+ "transferState": "COMMITTED",
124
+ "reason": null,
125
+ "completedTimestamp": :ignore
126
+ "transferStateEnumeration": "COMMITTED",
127
+ "transferStateDescription": "The switch has successfully performed the transfer.",
128
+ "ilpPacket": :ignore
129
+ "condition": :ignore
130
+ "fulfilment": :ignore
131
+ "errorCode": null,
132
+ "errorDescription": null,
133
+ "externalPayerName": null,
134
+ "externalPayeeName": null,
135
+ "extensionList": [],
136
+ "isTransferReadModel": true
137
+ }`).checkUnwrap(transfer)
138
+ })
139
+ })
@@ -188,6 +188,7 @@ const getByIdLight = async (id) => {
188
188
  }
189
189
 
190
190
  const getAll = async () => {
191
+ logger.error('TransferFacade.getAll() has been broken for some time. Are we even using it?')
191
192
  try {
192
193
  return await Db.from('transfer').query(async (builder) => {
193
194
  const transferResultList = await builder
@@ -549,7 +550,7 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida
549
550
  'facade_saveTransferPrepared_transaction - Metrics for transfer model',
550
551
  ['success', 'queryName']
551
552
  ).startTimer()
552
- return await knex.transaction(async (trx) => {
553
+ const result = await knex.transaction(async (trx) => {
553
554
  try {
554
555
  await knex('transfer').transacting(trx).insert(transferRecord)
555
556
  await knex('transferParticipant').transacting(trx).insert(payerTransferParticipantRecord)
@@ -575,6 +576,10 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida
575
576
  rethrow.rethrowDatabaseError(err)
576
577
  }
577
578
  })
579
+ // The inner timer above stops inside the transaction callback, i.e. before Knex
580
+ // issues COMMIT. This outer one stops after it, so the commit cost is measured.
581
+ histTimerSaveTransferPreparedEnd({ success: true, queryName: 'transfer_model_facade_saveTransferPrepared' })
582
+ return result
578
583
  } else {
579
584
  const histTimerSaveTransferNoValidationEnd = Metrics.getHistogram(
580
585
  'model_transfer',
@@ -938,8 +943,8 @@ const _getFxTransferList = async (knex, tableName = 'fxTransferTimeout', transac
938
943
  * Returns the list of transfers/fxTransfers that have timed out
939
944
  *
940
945
  * @returns {Promise<{
941
- * transferTimeoutList: TimedOutTransfer,
942
- * fxTransferTimeoutList: TimedOutFxTransfer
946
+ * transferTimeoutList: Array<TimedOutTransfer>
947
+ * fxTransferTimeoutList: Array<TimedOutFxTransfer>
943
948
  * }>}
944
949
  */
945
950
  const timeoutExpireReserved = async (segmentId, intervalMin, intervalMax, fxSegmentId, fxIntervalMin, fxIntervalMax) => {
@@ -55,7 +55,7 @@ const getTransferDuplicateCheck = async (transferId) => {
55
55
  ).startTimer()
56
56
  Logger.isDebugEnabled && Logger.debug(`get transferDuplicateCheck (transferId=${transferId})`)
57
57
  try {
58
- const result = Db.from('transferDuplicateCheck').findOne({ transferId })
58
+ const result = await Db.from('transferDuplicateCheck').findOne({ transferId })
59
59
  histTimerGetTransferDuplicateCheckEnd({ success: true, queryName: 'transferDuplicateCheck_getTransferDuplicateCheck' })
60
60
  return result
61
61
  } catch (err) {
@@ -84,7 +84,7 @@ const saveTransferDuplicateCheck = async (transferId, hash) => {
84
84
  ).startTimer()
85
85
  Logger.isDebugEnabled && Logger.debug(`save transferDuplicateCheck (transferId=${transferId}, hash=${hash})`)
86
86
  try {
87
- const result = Db.from('transferDuplicateCheck').insert({ transferId, hash })
87
+ const result = await Db.from('transferDuplicateCheck').insert({ transferId, hash })
88
88
  histTimerSaveTransferDuplicateCheckEnd({ success: true, queryName: 'transferDuplicateCheck_saveTransferDuplicateCheck' })
89
89
  return result
90
90
  } catch (err) {
@@ -0,0 +1,112 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2026 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * TigerBeetle
23
+ - Lewis Daly <lewis@tigerbeetle.com>
24
+ --------------
25
+
26
+ ******/
27
+ import { after, before, describe, it } from "node:test"
28
+ import Harness from '../../testing/harness'
29
+ import { Snapshot } from "../../testing/snapshot"
30
+ import * as ApiHelpers from '../../testing/api-helpers'
31
+
32
+ import TransferHandler from '../../handlers/transfers/handler'
33
+ const harness = Harness.getInstance()
34
+ const TransferError = require('./transferError')
35
+
36
+ describe('models/tranfer/transferError', () => {
37
+ before(async () => {
38
+ await harness.up()
39
+ await harness.setupGlobals()
40
+
41
+ await TransferHandler.registerPrepareHandler()
42
+ await TransferHandler.registerFulfilHandler()
43
+
44
+ // Create the hub accounts + settlement model.
45
+ const createHubPayload: ApiHelpers.CreateHubPayload = {
46
+ currencies: ['USD'],
47
+ settlementModels: [{
48
+ name: `DEFERRED_MULTILATERAL_NET_USD`,
49
+ settlementGranularity: "NET",
50
+ settlementInterchange: "MULTILATERAL",
51
+ settlementDelay: "DEFERRED",
52
+ currency: 'USD',
53
+ requireLiquidityCheck: true,
54
+ ledgerAccountType: "POSITION",
55
+ settlementAccountType: "SETTLEMENT",
56
+ autoPositionReset: true
57
+ }]
58
+ }
59
+ await ApiHelpers.createHub(harness, createHubPayload)
60
+ // Create 2 test dfsps to transfer between.
61
+ await ApiHelpers.createDfsp(harness, {
62
+ name: 'dfsp_a',
63
+ currencies: ['USD'],
64
+ isProxy: false,
65
+ initialPostionsAndLimits: [
66
+ {
67
+ initialPosition: 0,
68
+ value: 100000
69
+ }
70
+ ],
71
+ deposits: [10000]
72
+ })
73
+ await ApiHelpers.createDfsp(harness, {
74
+ name: 'dfsp_b',
75
+ currencies: ['USD'],
76
+ isProxy: false,
77
+ initialPostionsAndLimits: [
78
+ {
79
+ initialPosition: 0,
80
+ value: 100000
81
+ }
82
+ ],
83
+ deposits: [10000]
84
+ })
85
+ })
86
+
87
+ after(async () => {
88
+ await harness.teardownGlobals()
89
+ await harness.down()
90
+ })
91
+
92
+ it('insert() is called on a failed payment.', async () => {
93
+ // Create payment which will liquidity check.
94
+ await ApiHelpers.buildPayment()
95
+ .deps(harness, TransferHandler)
96
+ .parties('dfsp_a', 'dfsp_b')
97
+ .transferId('1000001')
98
+ .amount('10001.00')
99
+ .build()
100
+ .prepare()
101
+
102
+ // Look up the transferErrors table.
103
+ const transferError = await TransferError.getByTransferId('1000001')
104
+ Snapshot.from(`{
105
+ "transferId": "1000001",
106
+ "transferStateChangeId": 10,
107
+ "errorCode": "4001",
108
+ "errorDescription": "Payer FSP insufficient liquidity",
109
+ "createdDate": :ignore
110
+ }`).checkUnwrap(transferError)
111
+ })
112
+ })
@@ -0,0 +1,137 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2026 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * TigerBeetle
23
+ - Lewis Daly <lewis@tigerbeetle.com>
24
+ --------------
25
+
26
+ ******/
27
+ import { after, before, describe, it } from "node:test"
28
+ import Harness from '../../testing/harness'
29
+ import { Snapshot } from "../../testing/snapshot"
30
+ import * as ApiHelpers from '../../testing/api-helpers'
31
+
32
+ import TransferHandler from '../../handlers/transfers/handler'
33
+ const harness = Harness.getInstance()
34
+ const TransferExtension = require('./transferExtension')
35
+
36
+ describe('models/tranfer/transferExtension', () => {
37
+ before(async () => {
38
+ await harness.up()
39
+ await harness.setupGlobals()
40
+
41
+ await TransferHandler.registerPrepareHandler()
42
+ await TransferHandler.registerFulfilHandler()
43
+
44
+ // Create the hub accounts + settlement model.
45
+ const createHubPayload: ApiHelpers.CreateHubPayload = {
46
+ currencies: ['USD'],
47
+ settlementModels: [{
48
+ name: `DEFERRED_MULTILATERAL_NET_USD`,
49
+ settlementGranularity: "NET",
50
+ settlementInterchange: "MULTILATERAL",
51
+ settlementDelay: "DEFERRED",
52
+ currency: 'USD',
53
+ requireLiquidityCheck: true,
54
+ ledgerAccountType: "POSITION",
55
+ settlementAccountType: "SETTLEMENT",
56
+ autoPositionReset: true
57
+ }]
58
+ }
59
+ await ApiHelpers.createHub(harness, createHubPayload)
60
+ // Create 2 test dfsps to transfer between.
61
+ await ApiHelpers.createDfsp(harness, {
62
+ name: 'dfsp_a',
63
+ currencies: ['USD'],
64
+ isProxy: false,
65
+ initialPostionsAndLimits: [
66
+ {
67
+ initialPosition: 0,
68
+ value: 100000
69
+ }
70
+ ],
71
+ deposits: [10000]
72
+ })
73
+ await ApiHelpers.createDfsp(harness, {
74
+ name: 'dfsp_b',
75
+ currencies: ['USD'],
76
+ isProxy: false,
77
+ initialPostionsAndLimits: [
78
+ {
79
+ initialPosition: 0,
80
+ value: 100000
81
+ }
82
+ ],
83
+ deposits: [10000]
84
+ })
85
+
86
+ await ApiHelpers.buildPayment()
87
+ .deps(harness, TransferHandler)
88
+ .parties('dfsp_a', 'dfsp_b')
89
+ .transferId('5000001')
90
+ .amount('1.50')
91
+ .build()
92
+ .prepareAndFulfil()
93
+ })
94
+
95
+ after(async () => {
96
+ await harness.teardownGlobals()
97
+ await harness.down()
98
+ })
99
+
100
+ it('saveTransferExtension() and getByTransferId()', async () => {
101
+ await TransferExtension.saveTransferExtension({
102
+ transferId: '5000001',
103
+ key: 'key_1',
104
+ value: 'value_1',
105
+ createdDate: new Date(),
106
+ })
107
+
108
+ const result = await TransferExtension.getByTransferId('5000001')
109
+ Snapshot.from(`[
110
+ {
111
+ "transferExtensionId": 3,
112
+ "transferId": "5000001",
113
+ "key": "key_1",
114
+ "value": "value_1",
115
+ "isFulfilment": 0,
116
+ "isError": 0,
117
+ "createdDate": :ignore
118
+ }
119
+ ]`).checkUnwrap(result)
120
+ })
121
+
122
+ it('saveTransferExtension() without a transferId fails', { expectFailure: true }, async () => {
123
+ await TransferExtension.saveTransferExtension({
124
+ key: 'key_1',
125
+ value: 'value_1',
126
+ createdDate: new Date(),
127
+ })
128
+ })
129
+
130
+ it('saveTransferExtension() without a value fails', { expectFailure: true }, async () => {
131
+ await TransferExtension.saveTransferExtension({
132
+ transferId: '5000001',
133
+ key: 'key_1',
134
+ createdDate: new Date(),
135
+ })
136
+ })
137
+ })
@@ -0,0 +1,117 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2026 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * TigerBeetle
23
+ - Lewis Daly <lewis@tigerbeetle.com>
24
+ --------------
25
+
26
+ ******/
27
+ import { after, before, describe, it } from "node:test"
28
+ import Harness from '../../testing/harness'
29
+ import { Snapshot } from "../../testing/snapshot"
30
+ import * as ApiHelpers from '../../testing/api-helpers'
31
+
32
+ import TransferHandler from '../../handlers/transfers/handler'
33
+ const harness = Harness.getInstance()
34
+ const TransferStateChange = require('./transferStateChange')
35
+
36
+ describe('models/tranfer/transferExtension', () => {
37
+ before(async () => {
38
+ await harness.up()
39
+ await harness.setupGlobals()
40
+
41
+ await TransferHandler.registerPrepareHandler()
42
+ await TransferHandler.registerFulfilHandler()
43
+
44
+ // Create the hub accounts + settlement model.
45
+ const createHubPayload: ApiHelpers.CreateHubPayload = {
46
+ currencies: ['USD'],
47
+ settlementModels: [{
48
+ name: `DEFERRED_MULTILATERAL_NET_USD`,
49
+ settlementGranularity: "NET",
50
+ settlementInterchange: "MULTILATERAL",
51
+ settlementDelay: "DEFERRED",
52
+ currency: 'USD',
53
+ requireLiquidityCheck: true,
54
+ ledgerAccountType: "POSITION",
55
+ settlementAccountType: "SETTLEMENT",
56
+ autoPositionReset: true
57
+ }]
58
+ }
59
+ await ApiHelpers.createHub(harness, createHubPayload)
60
+ // Create 2 test dfsps to transfer between.
61
+ await ApiHelpers.createDfsp(harness, {
62
+ name: 'dfsp_a',
63
+ currencies: ['USD'],
64
+ isProxy: false,
65
+ initialPostionsAndLimits: [
66
+ {
67
+ initialPosition: 0,
68
+ value: 100000
69
+ }
70
+ ],
71
+ deposits: [10000]
72
+ })
73
+ await ApiHelpers.createDfsp(harness, {
74
+ name: 'dfsp_b',
75
+ currencies: ['USD'],
76
+ isProxy: false,
77
+ initialPostionsAndLimits: [
78
+ {
79
+ initialPosition: 0,
80
+ value: 100000
81
+ }
82
+ ],
83
+ deposits: [10000]
84
+ })
85
+
86
+ await ApiHelpers.buildPayment()
87
+ .deps(harness, TransferHandler)
88
+ .parties('dfsp_a', 'dfsp_b')
89
+ .transferId('5000001')
90
+ .amount('1.50')
91
+ .build()
92
+ .prepareAndFulfil()
93
+ })
94
+
95
+ after(async () => {
96
+ await harness.teardownGlobals()
97
+ await harness.down()
98
+ })
99
+
100
+ it('getByTransferId()', async () => {
101
+ const stateChange = await TransferStateChange.getByTransferId('5000001')
102
+ Snapshot.from(`{
103
+ "transferStateChangeId": 12,
104
+ "transferId": "5000001",
105
+ "transferStateId": "COMMITTED",
106
+ "reason": null,
107
+ "createdDate": :ignore
108
+ }`).checkUnwrap(stateChange)
109
+ })
110
+
111
+ it('getByTransferId()', async () => {
112
+ const latest = await TransferStateChange.getLatest()
113
+ Snapshot.from(`{
114
+ "transferStateChangeId": 12
115
+ }`).checkUnwrap(latest)
116
+ })
117
+ })
@@ -28,7 +28,7 @@
28
28
  ******/
29
29
 
30
30
  'use strict'
31
- const Config = require('../src/lib/config')
31
+ const Config = require('../lib/config')
32
32
 
33
33
  const participant = [
34
34
  {
@@ -1,3 +1,4 @@
1
+ /* istanbul ignore next */
1
2
  /*****
2
3
  License
3
4
  --------------
@@ -0,0 +1,71 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2026 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ - Georgi Georgiev <georgi.georgiev@modusbox.com>
27
+ --------------
28
+ ******/
29
+ 'use strict'
30
+
31
+ const OpenapiBackend = require('@mojaloop/central-services-shared').Util.OpenapiBackend
32
+ const Path = require('path')
33
+ const Handlers = require('./handlers')
34
+ const { getBasePath, handleRequest, assertHandlersRegistered } = require('./openapiRouting')
35
+
36
+ /**
37
+ * Handlers monitoring API Routes
38
+ *
39
+ * @param {object} api OpenAPIBackend instance
40
+ */
41
+ const APIRoutes = (api) => {
42
+ const basePath = getBasePath(api)
43
+ return [
44
+ {
45
+ method: 'GET',
46
+ path: `${basePath}/health`,
47
+ handler: (req, h) => handleRequest(api, req, h),
48
+ config: {
49
+ id: 'handlers getHealth',
50
+ tags: ['api', 'getHealth'],
51
+ description: 'GET health'
52
+ }
53
+ }
54
+ ]
55
+ }
56
+
57
+ module.exports = {
58
+ plugin: {
59
+ name: 'settlement handler api routes',
60
+ register: async function (server) {
61
+ const api = await OpenapiBackend.initialise(Path.resolve(process.cwd(), 'src/settlement/interface/swagger-handler.json'), {
62
+ getHealth: Handlers.getHealth,
63
+ validationFail: Handlers.validationFail,
64
+ notFound: Handlers.notFound,
65
+ methodNotAllowed: Handlers.methodNotAllowed
66
+ })
67
+ assertHandlersRegistered(api)
68
+ server.route(APIRoutes(api))
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,10 @@
1
+ 'use strict'
2
+
3
+ // Reuse the existing health handler from central-ledger.
4
+ // We should remove this separate health check altogether, we need to update the Golden path
5
+ // tests first.
6
+ const { getHealth } = require('../../../api/root/handler')
7
+
8
+ module.exports = {
9
+ get: (context, request, h) => getHealth(request, h)
10
+ }