1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! [`RegistrySyncPort`] — the contract an EU Central Registry adapter implements.
use async_trait;
use SubmissionAcknowledgement;
use RegistryRecord;
use SubmissionReport;
use RegistrationRequest;
use crateDppError;
/// Port trait for synchronising DPP records with the EU Central Registry.
///
/// No API specification is published. This trait is shaped by what IR (EU)
/// 2026/1778 and the registry's own guide establish about the flow, and by
/// nothing about the wire: that is the adapter's business.
///
/// # A registration happens in two steps, with two different handles
///
/// Submitting does not register anything. The registry accepts a submission for
/// validation and assigns it a **correlation identifier**; it rules on it
/// afterwards (Art. 8(7)), and only a successful ruling generates the passport's
/// **registration identifier** (Art. 8(8)). So:
///
/// - [`register`](Self::register) submits, and answers with the correlation
/// identifier;
/// - [`check_submission`](Self::check_submission) polls the submission by it,
/// and answers with the registration identifier once there is one;
/// - [`check_status`](Self::check_status) and
/// [`notify_transfer`](Self::notify_transfer) act on the registered record by
/// its registration identifier.
///
/// 🚨 **None of them takes this crate's `PassportId`.** The registry never
/// received one: a poll keyed on it asks the registry about a value it has no
/// record of, which is what this trait used to do.
///
/// # Ghost implementation
///
/// Until a deployment is enrolled, platform code can wire
/// [`GhostRegistrySync`](crate::ports::ghosts::GhostRegistrySync), which
/// accepts every submission under a placeholder handle and knows of no records.