commit fb4c39aa79f4073b45400710fcdd6319f35474ed
parent c7823c6929be3c4b4f61bc07266ee32be0dd027d
Author: Florian Dold <florian@dold.me>
Date: Thu, 5 Jun 2025 11:38:08 +0200
draft DD64
Diffstat:
2 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/design-documents/064-kyc-operation-algo.rst b/design-documents/064-kyc-operation-algo.rst
@@ -0,0 +1,98 @@
+DD 64: Algorithm for transactions with KYC checks
+#################################################
+
+Summary
+=======
+
+This design document specifies the algorithm that wallets and merchants should
+use for processing and (re-)trying transactions where KYC checks may apply.
+
+Motivation
+==========
+
+The exchange requires the customer to pass KYC checks and satisfy AML rules for
+various transactions. However, the corresponding rules are dynamic and may also be
+hidden from the client for regulatory purposes.
+
+Requirements
+============
+
+* Minimize the time time the user has to wait (=> long-poll efficiently)
+* Minimize the number of requests that the exchange has do process (=> do not quickly
+ retry when it's clear the the request is unlikely to succeed now)
+
+Proposed Solution
+=================
+
+Steps for processing operation of type `op` and amount `amt`:
+
+0. Initialize `last_check_success := null`, `last_op_attempt := null`, `last_rule_gen := null`
+
+1. Check if a zero limit for `op` is applicable.
+
+ * If the zero limit blocks `op`, proceed with step 3.
+ * Proceed with step 2.
+
+2. Attempt to make a request for `op` at the exchange. Set `last_op_attempt` to
+ the current time.
+
+ * If the request succeeds, *halt*.
+ * If `last_rule_gen` is not `null` (Note 2), proceed with step 4.
+
+ * Proceed with step 3.
+
+3. Request the `/kyc-check/...` endpoint applicable for `op` (no long-polling!)
+
+ * If the request returns `204 No Content`, proceed with step 2.
+ * If the request returns `200 Ok` or a `202 Accepted`:
+
+ * Set `last_rule_gen := response.rule_gen`
+ * If the exposed limits do not deny `op`, set `last_check_success := now()` and proceed with step 2.
+
+ * Proceed with the next step 4.
+
+4. Request the `/kyc-check/...` endpoint applicable for `op`
+ with long-polling for `min_rule` set to `last_rule_gen`.
+
+ * If the request returns `200 Ok` or a `202 Accepted`:
+
+ * Set `last_rule_gen := response.rule_gen`
+ * If the exposed limits
+ do not deny `op`, set `last_check_success := now()` and proceed with step 2.
+
+ * If if the `last_op_attempt` is `null` or is more than 10 minutes in the past,
+ proceed with step 2. (See Note 1)
+ * Proceed with step 4.
+
+Notes:
+
+ * Note 1: In practice, this might not be necessary, but
+ there could be a non-exposed rule that the client needs
+ to trigger to proceed.
+ * Note 2: We must long-poll for the next rule generation here,
+ since we can assume that the current set of rules contains non-exposed
+ rule that prevents the current operation.
+
+Open questions:
+
+ * What should the `lpt` parameter be in step 4?
+
+Definition of Done
+==================
+
+N/A
+
+Alternatives
+============
+
+N/A
+
+Drawbacks
+=========
+
+N/A
+
+Discussion / Q&A
+================
+
+(This should be filled in with results from discussions on mailing lists / personal communication.)
diff --git a/design-documents/index.rst b/design-documents/index.rst
@@ -75,4 +75,5 @@ Design documents that start with "XX" are considered deprecated.
061-batched-withdraw.rst
062-pq-refresh.rst
063-libeufin-conversion-rate-group
+ 064-kyc-operation-algo
999-template