account-lookup-service 15.6.0-snapshot.2 → 16.1.0-iso.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 (68) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/LICENSE.md +3 -4
  3. package/README.md +2 -0
  4. package/audit-ci.jsonc +2 -27
  5. package/config/default.json +1 -0
  6. package/docker/mock-proxy/README.md +21 -0
  7. package/docker/mock-proxy/src/config.ts +7 -0
  8. package/docs/Proxy/Discovery.md +20 -0
  9. package/docs/Proxy/FXAPI_POC_payer_conversion_RECEIVE.plantuml +577 -0
  10. package/docs/Proxy/FXAPI_POC_payer_conversion_SEND.plantuml +1423 -0
  11. package/docs/Proxy/P2P.md +11 -0
  12. package/docs/Proxy/Proxy pattern - Happy path.plantuml +98 -0
  13. package/docs/Proxy/Proxy pattern - Lazy Discovery - No Oracles.plantuml +105 -0
  14. package/docs/Proxy/Proxy pattern - Lazy Discovery - No Oracles.png +0 -0
  15. package/docs/Proxy/Proxy pattern - Lazy Discovery - Oracles.plantuml +130 -0
  16. package/docs/Proxy/Proxy pattern - Lazy Discovery - Oracles.png +0 -0
  17. package/docs/Proxy/Proxy pattern - Lazy Discovery Identifier Cache Invalid.plantuml +72 -0
  18. package/docs/Proxy/Proxy pattern - Lazy Discovery Identifier Cache Invalid.png +0 -0
  19. package/docs/Proxy/Proxy pattern - P2P.plantuml +186 -0
  20. package/docs/Proxy/Proxy pattern - P2P.png +0 -0
  21. package/docs/Proxy/Proxy pattern - Unhappy path.plantuml +103 -0
  22. package/docs/Proxy/Proxy pattern - Unhappy path.png +0 -0
  23. package/docs/Proxy/Proxy pattern - happy path.png +0 -0
  24. package/docs/Proxy/Readme.md +39 -0
  25. package/docs/Proxy/SettingUpProxys.plantuml +31 -0
  26. package/docs/Proxy/SettingUpProxys.png +0 -0
  27. package/package.json +33 -18
  28. package/src/constants.js +2 -1
  29. package/src/domain/oracle/oracle.js +63 -4
  30. package/src/domain/participants/participants.js +246 -129
  31. package/src/domain/parties/getPartiesByTypeAndID.js +28 -7
  32. package/src/domain/parties/parties.js +43 -14
  33. package/src/domain/timeout/index.js +12 -1
  34. package/src/handlers/index.js +4 -4
  35. package/src/handlers/monitoring/index.js +1 -1
  36. package/src/interface/api-swagger-iso20022-parties.yaml +7 -6
  37. package/src/interface/api-swagger.yaml +7 -6
  38. package/src/lib/config.js +2 -1
  39. package/src/lib/db.js +2 -1
  40. package/src/models/currency/currency.js +10 -1
  41. package/src/models/endpointType/endpointType.js +10 -1
  42. package/src/models/oracle/facade.js +42 -16
  43. package/src/models/oracle/oracleEndpoint.js +65 -10
  44. package/src/models/oracle/oracleEndpointCached.js +29 -9
  45. package/src/models/participantEndpoint/facade.js +40 -4
  46. package/src/models/partyIdType/partyIdType.js +10 -1
  47. package/src/plugins.js +8 -21
  48. package/src/server.js +11 -0
  49. package/test/fixtures/index.js +30 -6
  50. package/test/unit/api/health.test.js +3 -0
  51. package/test/unit/api/participants/participants.test.js +5 -7
  52. package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +0 -3
  53. package/test/unit/api/participants/{Type}/{ID}.test.js +0 -3
  54. package/test/unit/api/participants.test.js +36 -3
  55. package/test/unit/domain/oracle/oracle.test.js +8 -0
  56. package/test/unit/domain/participants/participants.test.js +83 -48
  57. package/test/unit/domain/parties/parties.test.js +8 -0
  58. package/test/unit/domain/timeout/index.test.js +8 -0
  59. package/test/unit/lib/config.test.js +7 -0
  60. package/test/unit/mocks.js +16 -11
  61. package/test/unit/models/oracle/oracleEndpointCached.test.js +32 -0
  62. package/test/unit/plugins.test.js +2 -2
  63. package/test/util/apiClients/BasicApiClient.js +2 -2
  64. package/src/lib/requestLogger.js +0 -54
  65. package/src/metrics/handler.js +0 -33
  66. package/src/metrics/plugin.js +0 -52
  67. package/src/metrics/routes.js +0 -43
  68. package/test/unit/lib/requestLogger.test.js +0 -115
@@ -0,0 +1,11 @@
1
+ # P2P flow across network using Proxy
2
+ This design make the following assumptions
3
+ 1. No two connected participant have the same identifier
4
+ 1. No limit checks are done against proxy participants
5
+ 1. Get /transactionRequests are resolved at the payee scheme
6
+ 1. Timeouts in non-payee schemes are disabled (maybe enlarged)
7
+
8
+ ## Sequence Diagram
9
+ Here is a sequence diagram show the Agreement and Transfer stages of a transaction, and how the Get Transfer is resolved.
10
+
11
+ ![P2P flow](./Proxy%20pattern%20-%20P2P.png)
@@ -0,0 +1,98 @@
1
+ @startuml
2
+
3
+ title Proxy Patterns - Happy Path
4
+
5
+ participant "Payer DFSP" as payerDFSP
6
+ box "Scheme A"
7
+ participant "Handler\nScheme A" as schemeA
8
+ participant "Proxy Cache\nScheme A" as pc_A
9
+ end box
10
+ participant "Proxy AB" as xnp
11
+ box "Scheme B"
12
+ participant "Handler\nScheme B" as schemeB
13
+ participant "Proxy Cache\nScheme B" as pc_B
14
+ end box
15
+ participant "Payee DFS" as payeeDFSP
16
+
17
+ autonumber 1 "<b>[0]"
18
+
19
+ == POST ==
20
+ payerDFSP ->> schemeA: POST /xxx
21
+ note left
22
+ header
23
+ source: payerDFSP
24
+ destination: payeeDFSP
25
+ body
26
+ {ID: 1234}
27
+ end note
28
+ schemeA -> pc_A: Destination not in scheme:\n payeeDFSP has a proxy mapped\n need to send to 'Proxy AB'
29
+ schemeA ->> xnp: POST /xxx
30
+ xnp->xnp: Add header
31
+ note left
32
+ fxpiop-proxy = "Proxy AB"
33
+ end note
34
+ xnp ->> schemeB: POST /xxx
35
+ note left
36
+ Message if forwarded to schemeB unmodified
37
+ end note
38
+
39
+ schemeB -->> xnp: 202 OK
40
+ xnp -->> schemeA: 202 OK
41
+
42
+ schemeB ->> payeeDFSP: POST /xxx
43
+
44
+ == GET ==
45
+ payerDFSP -> schemeA: GET /xxx/{ID} \nwithout destination
46
+ note left
47
+ source: payerDFSP
48
+ end note
49
+
50
+ schemeA->schemeA: lookup if ID result and triggers put
51
+
52
+ payerDFSP -> schemeA: GET /xxx/{ID} \nwith destination
53
+ note left
54
+ source: payerDFSP
55
+ destination: payeeDFSP
56
+ end note
57
+
58
+ schemeA -> pc_A: Destination not in scheme:\n payeeDFSP has a proxy mapped\n need to send to 'Proxy AB'
59
+ schemeA ->> xnp: GET /xxx
60
+ xnp->xnp: Add header
61
+ note left
62
+ fxpiop-proxy = "Proxy AB"
63
+ end note
64
+ xnp ->> schemeB: GET /xxx
65
+ note left
66
+ Message if forwarded to schemeB unmodified
67
+ end note
68
+ schemeB -->> xnp: 202 OK
69
+ xnp -->> schemeA: 202 OK
70
+
71
+ schemeB ->> payeeDFSP: GET /xxx
72
+
73
+
74
+
75
+ == PUT ==
76
+
77
+
78
+ payeeDFSP -> schemeB: PUT /xxx
79
+ note right
80
+ source: payeeDFSP
81
+ destination: payerDFSP
82
+ end note
83
+ schemeB -> pc_B: Destination not in scheme:\n payerDFSP has a proxy mapped\n need to send to 'Proxy AB'
84
+ schemeB -> xnp: PUT /xxx
85
+ xnp->xnp: Add header
86
+ note left
87
+ fxpiop-proxy = "Proxy AB"
88
+ end note
89
+ xnp -> schemeA: PUT /xxx
90
+ note right
91
+ Message if forwarded to schemeA unmodified
92
+ end note
93
+ schemeA -->> xnp: 200 OK
94
+ xnp -->> schemeB: 200 OK
95
+
96
+ schemeA -> payerDFSP: PUT /xxx
97
+
98
+ @enduml
@@ -0,0 +1,105 @@
1
+ @startuml
2
+
3
+ title Lazy Discovery - No Oracles Registered
4
+
5
+ participant "Payer DFSP" as payerDFSP
6
+ box "Scheme A"
7
+ participant "ALS\nScheme A" as ALS_A
8
+ participant "Proxy Cache\nScheme A" as pc_A
9
+ end box
10
+ participant "XN Proxy" as xnp
11
+ participant "other DFSPs" as dfspsA
12
+ box "Scheme B"
13
+ participant "ALS\nScheme B" as ALS_B
14
+ participant "Proxy Cache\nScheme B" as pc_B
15
+ end box
16
+ participant "Payee DFS" as payeeDFSP
17
+ participant "other DFSPs" as dfspsB
18
+
19
+ autonumber 1 "<b>[0]"
20
+
21
+ == First time Party Identifier is used ==
22
+ payerDFSP ->> ALS_A: GET /parties/{Type}/{ID}
23
+
24
+ note left
25
+ header source = payerDFSP
26
+ end note
27
+ ALS_A ->> ALS_A: Lookup if {Type} and {ID} is mapped to dfsp
28
+ alt if not cached
29
+ loop for all DFSPs in Scheme A and not source
30
+ alt if XN Proxy
31
+ ALS_A ->> xnp: GET /parties/{Type}/{ID}
32
+ xnp ->> ALS_B: GET /parties/{Type}/{ID}
33
+ ALS_B ->> pc_B: Source not in Scheme: \nAdd 'Payer DFSP' to 'XN Proxy' mapping
34
+ pc_B -> pc_B: New mapping
35
+ pc_B -> pc_B: Check JWS signature\n & Add to cache
36
+ note left
37
+ Payer DFSP : XN Proxy
38
+ end note
39
+ ALS_B -> ALS_B: Lookup if {Type} and {ID} is mapped to dfsp
40
+ loop for all DFSPs in Scheme B and not source
41
+ alt if Payee DFSP
42
+ ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID}
43
+ payeeDFSP ->> ALS_B: PUT /parties/{ID}
44
+ note right
45
+ header desitination = payerDFSP
46
+ end note
47
+ ALS_B -> ALS_B: Update cache
48
+ note left
49
+ cache [{Type}][{ID}] = payeeDFSP
50
+ end note
51
+ ALS_B -> pc_B: Lookup payerDFSP proxy
52
+ ALS_B ->> xnp: PUT /parties/{ID}
53
+ xnp ->> ALS_A: PUT /parties/{ID}
54
+ ALS_A -> pc_A: Source not in Scheme: \nAdd 'Payee DFSP' to 'XN Proxy' mapping
55
+ pc_A -> pc_A: New mapping\nCheck JWS signature\n & Add to cache
56
+ note left
57
+ Payee DFSP : XN Proxy
58
+ end note
59
+ ALS_A -> ALS_A: Update cache
60
+ note left
61
+ cache [{Type}][{ID}] = XN Proxy
62
+ end note
63
+ ALS_A ->> payerDFSP: PUT /parties/{ID}
64
+ else if other DFSPs in Scheme B
65
+ ALS_B ->> dfspsB: GET /parties/{Type}/{ID}
66
+ dfspsB ->> ALS_B: PUT /parties/{ID}/error
67
+ note right
68
+ header desitination = payerDFSP
69
+ end note
70
+ ALS_B ->> ALS_B: increment Scheme B Failure Count
71
+ alt if Failure Count == TotalCalls
72
+ ALS_B -> pc_B: Lookup payerDFSP proxy
73
+ ALS_B ->> xnp: PUT /parties/{ID}/error
74
+ xnp ->> ALS_A: PUT /parties/{ID}/error
75
+ end
76
+ end
77
+ end loop
78
+ else if other DFSPs in Scheme A
79
+ ALS_A ->> dfspsA: GET /parties/{Type}/{ID}
80
+ dfspsA ->> ALS_A: PUT /parties/{ID}/error
81
+ ALS_A ->> ALS_A: increment Scheme A Failure Count
82
+ alt if Failure Count == TotalCalls
83
+ ALS_A ->> payerDFSP: PUT /parties/{ID}/error
84
+ end
85
+ end
86
+ end loop
87
+ else
88
+ ALS_A->ALS_A: Yes, it is mapped to XN Proxy
89
+ ALS_A ->> xnp: GET /parties/{Type}/{ID}
90
+ xnp ->> ALS_B: GET /parties/{Type}/{ID}
91
+ ALS_B ->> pc_B: Source not in Scheme: \nAdd 'Payer DFSP' to 'XN Proxy' mapping
92
+ pc_B -> pc_B: Got Mapping
93
+ ALS_B -> ALS_B: Lookup if {Type} and {ID} is mapped to proxy
94
+ ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID}
95
+ payeeDFSP ->> ALS_B: PUT /parties/{ID}
96
+ note right
97
+ header desitination = payerDFSP
98
+ end note
99
+ ALS_B -> ALS_B: Lookup payerDFSP proxy
100
+ ALS_B->ALS_B: Got it; it is mapped to XN Proxy
101
+ ALS_B ->> xnp: PUT /parties/{ID}
102
+ xnp ->> ALS_A: PUT /parties/{ID}
103
+ ALS_A ->> payerDFSP: PUT /parties/{ID}
104
+ end
105
+ @enduml
@@ -0,0 +1,130 @@
1
+ @startuml
2
+
3
+ title On Demand Discovery - Oracles
4
+
5
+ participant "Payer DFSP" as payerDFSP
6
+ box "Scheme A"
7
+ participant "ALS\nScheme A" as ALS_A
8
+ participant "Oracle\nScheme A" as Oracle_A
9
+ participant "Proxy Cache\nScheme A" as pc_A
10
+ end box
11
+ participant "other Proxies" as dfspsA
12
+ participant "Proxy AB" as xnp
13
+ box "Scheme B"
14
+ participant "ALS\nScheme B" as ALS_B
15
+ participant "Oracle\nScheme A" as Oracle_B
16
+ participant "Proxy Cache\nScheme B" as pc_B
17
+ end box
18
+ participant "Payee DFS" as payeeDFSP
19
+
20
+ autonumber 1 "<b>[0]"
21
+
22
+ payerDFSP ->> ALS_A: GET /parties/{Type}/{ID}
23
+ note left
24
+ header source = payerDFSP
25
+ end note
26
+ ALS_A-> Oracle_A: GET /participant/{ID}
27
+ alt if not found in Oracle
28
+
29
+ Oracle_A--> ALS_A: no dfsp found
30
+ ALS_A ->> ALS_A: Are there any proxies in Scheme A?
31
+ ALS_A ->> ALS_A: Cache Proxy that will receive messages
32
+ note left
33
+ SentToProxies[{ID}] = {['Proxy AB', 'Proxy CD', 'Proxy EF']}
34
+ end note
35
+
36
+ loop for all Proxys in Scheme A and not source
37
+ alt if Proxy AB
38
+ ALS_A ->> xnp: GET /parties/{Type}/{ID}
39
+ xnp->xnp: Add header
40
+ note left
41
+ fxpiop-proxy = "Proxy AB"
42
+ end note
43
+
44
+ xnp ->> ALS_B: GET /parties/{Type}/{ID}
45
+ ALS_B -->> xnp: 202 OK
46
+ xnp -->> ALS_A: 202 OK
47
+ ALS_B ->> pc_B: Source not in Scheme: \nfxpiop-proxy = "Proxy AB"\nAdd 'Payer DFSP' to 'Proxy AB' mapping
48
+ alt not MVP
49
+ pc_B -> pc_B: Check JWS signature
50
+ end
51
+ pc_B -> pc_B: Add new mapping to cache
52
+ note left
53
+ Payer DFSP : Proxy AB
54
+ end note
55
+
56
+ ALS_B-> Oracle_B: GET /participant/{ID}
57
+ Oracle_B--> ALS_B: dfps = payeeDFSP
58
+ ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID}
59
+ payeeDFSP ->> ALS_B: PUT /parties/{ID}
60
+ note right
61
+ header desitination = payerDFSP
62
+ source = payeeDFSP
63
+ end note
64
+ ALS_B -> pc_B: Lookup payerDFSP proxy
65
+ ALS_B ->> xnp: PUT /parties/{ID}
66
+ xnp->xnp: Add header
67
+ note left
68
+ fxpiop-proxy = "Proxy AB"
69
+ end note
70
+
71
+ xnp ->> ALS_A: PUT /parties/{ID}
72
+ ALS_A -->> xnp: 200 OK
73
+ xnp -->> ALS_B: 200 OK
74
+ ALS_A -> pc_A: Source not in Scheme: \nfxpiop-proxy = "Proxy AB"\nAdd 'Payee DFSP' to 'Proxy AB' mapping
75
+ pc_A -> pc_A: New mapping\nCheck JWS signature\n & Add to cache
76
+ note left
77
+ Payee DFSP : Proxy AB
78
+ end note
79
+ ALS_A -> Oracle_A: Update Oracle with mapping\nPOST /participants/{Type}/{ID} {{"fspId": "Payee DFSP"}}
80
+ Oracle_A--> ALS_A:
81
+ ALS_A ->> payerDFSP: PUT /parties/{ID}
82
+ else if other Proxy in Scheme A
83
+ ALS_A ->> dfspsA: GET /parties/{Type}/{ID}
84
+ dfspsA ->> ALS_A: PUT /parties/{ID}/error
85
+ ALS_A ->> ALS_A: increment Scheme A Failure Count in cache
86
+ note left
87
+ remove other Proxy from list SentToProxies[{ID}]
88
+ end note
89
+
90
+ alt if SentToProxies[{ID}] is empty
91
+ ALS_A ->> payerDFSP: PUT /parties/{ID}/error
92
+ note right
93
+ SentToProxies[{ID}] is empty
94
+ end note
95
+ end
96
+ end
97
+ end loop
98
+ else if found in Oracle
99
+ Oracle_A--> ALS_A: dfsp = payeeDFSP
100
+
101
+ ALS_A->ALS_A: Payee DFSP is not in scheme A
102
+ ALS_A-> pc_A: Lookup proxy for Payee DFSP
103
+ ALS_A->ALS_A: Add desitation to header
104
+ note left
105
+ destination dfsp: Payee DFSP
106
+ end note
107
+
108
+ ALS_A ->> xnp: GET /parties/{Type}/{ID}
109
+ xnp ->> ALS_B: GET /parties/{Type}/{ID}
110
+ ALS_B -->> xnp: 202 OK
111
+ xnp -->> ALS_A: 202 OK
112
+ ALS_B->ALS_B: Forward to desitination
113
+ ALS_B ->> payeeDFSP: GET /parties/{Type}/{ID}
114
+
115
+ payeeDFSP ->> ALS_B: PUT /parties/{ID}
116
+ note right
117
+ header desitination = payerDFSP
118
+ end note
119
+ ALS_B -> pc_B: Lookup payerDFSP proxy
120
+ ALS_B ->> xnp: PUT /parties/{ID}
121
+ xnp ->> ALS_A: PUT /parties/{ID}
122
+ ALS_A -->> xnp: 200 OK
123
+ xnp -->> ALS_B: 200 OK
124
+ ALS_A -> pc_A: Source not in Scheme: \nAdd 'Payee DFSP' to 'Proxy AB' mapping
125
+ pc_A -> pc_A: Got Mapping
126
+ ALS_A ->> payerDFSP: PUT /parties/{ID}
127
+ end
128
+
129
+
130
+ @enduml
@@ -0,0 +1,72 @@
1
+ @startuml
2
+
3
+ title Lazy Discovery - Party Identifier cache no-longer valid
4
+
5
+ participant "Payer DFSP" as payerDFSP
6
+ box "Scheme A"
7
+ participant "ALS\nScheme A" as ALS_A
8
+ participant "Oracle\nScheme A" as Oracle_A
9
+ participant "Proxy Cache\nScheme A" as pc_A
10
+ end box
11
+ participant "Proxy AB" as xnp
12
+ box "Scheme B"
13
+ participant "ALS\nScheme B" as ALS_B
14
+ participant "Oracle\nScheme A" as Oracle_B
15
+ participant "Proxy Cache\nScheme B" as pc_B
16
+ end box
17
+ participant "Payee DFS" as payeeDFSP
18
+
19
+ autonumber 1 "<b>[0]"
20
+
21
+ payerDFSP ->> ALS_A: **GET** /parties/{Type}/{ID}
22
+ note left
23
+ header source = payerDFSP
24
+ end note
25
+
26
+ ALS_A-> Oracle_A: **GET** /participant/{ID}
27
+ Oracle_A--> ALS_A: found DFSP = payeeDFSP
28
+ ALS_A ->> ALS_A: DFSP not in scheme
29
+ ALS_A -> pc_A: Who is payee DFSP's proxy?
30
+ pc_A --> ALS_A: forward to Proxy AB
31
+ ALS_A ->> xnp: **GET** /parties/{Type}/{ID}
32
+ xnp->xnp: Add header
33
+ note left
34
+ fxpiop-proxy = "Proxy AB"
35
+ end note
36
+
37
+ xnp ->> ALS_B: **GET** /parties/{Type}/{ID}
38
+ ALS_B ->> pc_B: Source not in Scheme: \nfxpiop-proxy = "Proxy AB"\nAdd 'Payer DFSP' to 'Proxy AB' mapping
39
+ alt not MVP
40
+ pc_B -> pc_B: Check JWS signature
41
+ end
42
+ pc_B -> pc_B: Add new mapping to cache
43
+ note left
44
+ Payer DFSP : Proxy AB
45
+ end note
46
+ ALS_B-> Oracle_B: **GET** /participant/{ID}
47
+ Oracle_B--> ALS_B: dfps = payeeDFSP
48
+ ALS_B ->> payeeDFSP: **GET** /parties/{Type}/{ID}
49
+ payeeDFSP ->> ALS_B: **PUT** /parties/{ID}/error
50
+ note right
51
+ header desitination = payerDFSP
52
+ end note
53
+ ALS_B -> pc_B: Lookup payerDFSP proxy
54
+ ALS_B ->> xnp: **PUT** /parties/{ID}/error
55
+ xnp->xnp: Add header
56
+ note left
57
+ fxpiop-proxy = "Proxy AB"
58
+ end note
59
+ xnp ->> ALS_A: **PUT** /parties/{ID}/error
60
+ alt message from proxy & error & desitination in scheme
61
+ note left ALS_A
62
+ fxpiop-proxy = "Proxy AB"
63
+ Error Code = 5107
64
+ Destination = Payer DFSP in Scheme A
65
+ end note
66
+ ALS_A -> Oracle_A: Remove mapping in Oracle\n **DELETE** \participants\{Type}\{ID}
67
+ ALS_A ->> ALS_A: Restart the ALS get parties process
68
+ else
69
+ ALS_A->>payerDFSP: **PUT** /parties/{ID}/error
70
+ end
71
+
72
+ @enduml
@@ -0,0 +1,186 @@
1
+ @startuml
2
+
3
+ title Proxy Patterns - P2P
4
+
5
+ participant "Payer DFSP" as payerDFSP
6
+ box Scheme A
7
+ participant "Mojaloop\nScheme A" as schemeA
8
+ participant "Proxy Cache\nScheme A" as pc_A
9
+ end box
10
+ participant "Proxy AB" as xnp
11
+ box Scheme B
12
+ participant "Mojaloop\nScheme B" as schemeB
13
+ participant "Proxy Cache\nScheme B" as pc_B
14
+ end box
15
+ participant "Payee DFS" as payeeDFSP
16
+
17
+ autonumber 1 "<b>[0]"
18
+
19
+ == Agreement ==
20
+ payerDFSP ->> schemeA: POST /quotes
21
+ note left
22
+ header
23
+ source: payerDFSP
24
+ destination: payeeDFSP
25
+ JWS signed by payerDFSP
26
+ end note
27
+ schemeA -> pc_A: Destination not in Scheme\n Lookup proxy for payeeDFSP = Proxy AB
28
+ schemeA ->> xnp: POST /quotes
29
+ xnp ->> schemeB: POST /quotes\nmessage unmodified
30
+ note left
31
+ header
32
+ source: payerDFSP
33
+ destination: payeeDFSP
34
+ fxpiop-proxy: proxyAB
35
+ JWS signed by payerDFSP
36
+ end note
37
+ schemeB -->> xnp: 202 OK
38
+ xnp -->> schemeA: 202 OK
39
+ schemeB->>payeeDFSP: POST /quotes
40
+ note right
41
+ Checks JWS signed by payerDFSP
42
+ end note
43
+ payeeDFSP->>schemeB: PUT /quotes
44
+ note right
45
+ header
46
+ source: payeeDFSP
47
+ destination: payerDFSP
48
+ JWS signed by payeeDFSP
49
+ end note
50
+ schemeB -> pc_B: Destination not in Scheme\n Lookup proxy for payerDFSP = Proxy AB
51
+ schemeB->>xnp: PUT /quotes
52
+ xnp->>schemeA: PUT /quotes\nmessage unmodified
53
+ note right
54
+ header
55
+ source: payeeDFSP
56
+ destination: payerDFSP
57
+ fxpiop-proxy: proxyAB
58
+ JWS signed by payeeDFSP
59
+ end note
60
+ schemeA-->>xnp: 202 OK
61
+ xnp-->>schemeB: 202 OK
62
+ schemeA->>payerDFSP: PUT /quotes
63
+ note left
64
+ Checks JWS signed by payeeDFSP
65
+ end note
66
+
67
+ == Transfer ==
68
+
69
+ payerDFSP ->> schemeA: POST /transfers
70
+ note left
71
+ header
72
+ source: payerDFSP
73
+ destination: payeeDFSP
74
+ JWS signed by payerDFSP
75
+ body
76
+ transferId: 1234
77
+ end note
78
+ schemeA -> schemeA: Payer DFSP\n - Checks limits\n - Updates position
79
+ schemeA -> pc_A: Destination not in Scheme\nLookup proxy for payeeDFSP = Proxy AB
80
+ schemeA ->> xnp: POST /transfers
81
+ xnp ->> schemeB: POST /transfers
82
+ note left
83
+ header
84
+ source: payerDFSP
85
+ destination: payeeDFSP
86
+ fxpiop-proxy: proxyAB
87
+ JWS signed by payerDFSP
88
+ body
89
+ transferId: 1234
90
+ end note
91
+ schemeB -->> xnp: 202 OK
92
+ xnp -->> schemeA: 202 OK
93
+ schemeA -> schemeA: Disable timeout
94
+
95
+ schemeB -> schemeB: Proxy AB\n **- No limit check**\n - Updates position
96
+ schemeB->>payeeDFSP: POST /transfers
97
+ note right
98
+ Checks JWS signed by payerDFSP
99
+ end note
100
+ payeeDFSP->>schemeB: PUT /transfers \n{fulfilment: "xyz", transferState: "RESERVED"}
101
+ note right
102
+ header
103
+ source: payeeDFSP
104
+ destination: payerDFSP
105
+ JWS signed by payeeDFSP
106
+ end note
107
+ schemeB -> schemeB: Payer DFSP\n - Updates position
108
+ schemeB -> pc_B: Lookup proxy for payerDFSP = Proxy AB
109
+ schemeB->>xnp: PUT /transfers
110
+ xnp->>schemeA: PUT /transfers
111
+ note right
112
+ header
113
+ source: payeeDFSP
114
+ destination: payerDFSP
115
+ fxpiop-proxy: proxyAB
116
+ JWS signed by payeeDFSP
117
+ end note
118
+ schemeA-->>xnp: 200 OK
119
+ xnp-->>schemeB: 200 OK
120
+ schemeB->>payeeDFSP: PATCH /transfers \n{transferState: "COMMITTED"}
121
+ schemeA -> schemeA: NX Proxy\n - Updates position
122
+ schemeA->>payerDFSP: PUT /transfers
123
+ note left
124
+ Checks JWS signed by payeeDFSP
125
+ end note
126
+
127
+ == Get Transfers ==
128
+
129
+ payerDFSP ->> schemeA: GET /transfers/1234
130
+ note left
131
+ header
132
+ source: payerDFSP
133
+ destination: payeeDFSP
134
+ JWS signed by payerDFSP
135
+ end note
136
+ schemeA -> schemeA: Load transfer informtaion\nand check if payeeDFSP is in scheme
137
+ schemeA -> pc_A: Destination not in Scheme\nLookup proxy for payeeDFSP = Proxy AB
138
+ schemeA ->> xnp: GET /transfers/1234
139
+ xnp ->> schemeB: GET /transfers/1234
140
+ note left
141
+ header
142
+ source: payerDFSP
143
+ destination: payeeDFSP
144
+ fxpiop-proxy: proxyAB
145
+ JWS signed by payerDFSP
146
+ end note
147
+ schemeB -->> xnp: 202 OK
148
+ xnp -->> schemeA: 202 OK
149
+ schemeB->schemeB: lookup transfer information
150
+ schemeB->>xnp: PUT /transfers/1234
151
+ note right
152
+ header
153
+ source: schemeB
154
+ destination: payerDFSP
155
+ JWS signed by schemeB
156
+ end note
157
+ xnp->>schemeA: PUT /transfers/1234
158
+ note right
159
+ header
160
+ source: schemeB
161
+ destination: payerDFSP
162
+ fxpiop-proxy: proxyAB
163
+ JWS signed by schemeB
164
+ end note
165
+ schemeA-->>xnp: 200 OK
166
+ xnp-->>schemeB: 200 OK
167
+ schemeA->>payerDFSP: PUT /transfers/1234
168
+
169
+ payeeDFSP->>schemeB: GET /transfers/1234
170
+ note right
171
+ header
172
+ source: payeeDFSP
173
+ JWS signed by payeeDFSP
174
+ end note
175
+ schemeB -> schemeB: Load transfer informtaion\nand check if payeeDFSP is in scheme
176
+ schemeB->>payeeDFSP: Yes; return information\nPUT /transfers/1234
177
+ note left
178
+ header
179
+ source: schemeB
180
+ destination: payeeDFSP
181
+ JWS signed by schemeB
182
+ end note
183
+
184
+
185
+
186
+ @enduml