/*
This file is part of TALER
Copyright (C) 2022, 2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see
*/
/**
* @file taler_kyclogic_lib.h
* @brief server-side KYC API
* @author Christian Grothoff
*/
#ifndef TALER_KYCLOGIC_LIB_H
#define TALER_KYCLOGIC_LIB_H
#include
#include "taler_exchangedb_plugin.h"
#include "taler_kyclogic_plugin.h"
/**
* Enumeration of possible events that may trigger
* KYC requirements.
*/
enum TALER_KYCLOGIC_KycTriggerEvent
{
/**
* Reserved value for invalid event types.
*/
TALER_KYCLOGIC_KYC_TRIGGER_NONE = 0,
/**
* Customer withdraws coins.
*/
TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW = 1,
/**
* Merchant deposits coins.
*/
TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT = 2,
/**
* Wallet receives P2P payment.
*/
TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 3,
/**
* Wallet balance exceeds threshold. The timeframe is
* irrelevant for this limit.
*/
TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 4,
/**
* Reserve is being closed by force.
*/
TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE = 5,
/**
* Deposits have been aggregated, we are wiring a
* certain amount into a (merchant) bank account.
*/
TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6,
/**
* Limit per transaction. The timeframe is
* irrelevant for this limit.
*/
TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION = 7,
/**
* Limit per refund. The timeframe is
* irrelevant for this limit.
*/
TALER_KYCLOGIC_KYC_TRIGGER_REFUND = 8
};
/**
* Types of KYC checks.
*/
enum TALER_KYCLOGIC_CheckType
{
/**
* Wait for staff or contact staff out-of-band.
*/
TALER_KYCLOGIC_CT_INFO,
/**
* SPA should show an inline form.
*/
TALER_KYCLOGIC_CT_FORM,
/**
* SPA may start external KYC process.
*/
TALER_KYCLOGIC_CT_LINK
};
/**
* KYC measure that can be taken.
*/
struct TALER_KYCLOGIC_Measure
{
/**
* Name of the KYC measure.
*/
char *measure_name;
/**
* Name of the KYC check.
*/
char *check_name;
/**
* Name of the AML program.
*/
char *prog_name;
/**
* Context for the check. Can be NULL.
*/
json_t *context;
/**
* Can this measure be triggered voluntarily?
*/
bool voluntary;
};
/**
* Information about a KYC provider.
*/
struct TALER_KYCLOGIC_KycProvider;
/**
* Abstract representation of a KYC check.
*/
struct TALER_KYCLOGIC_KycCheck
{
/**
* Human-readable name given to the KYC check.
*/
char *check_name;
/**
* Human-readable description of the check in English.
*/
char *description;
/**
* Optional translations of @e description, can be
* NULL.
*/
json_t *description_i18n;
/**
* Array of fields that the context must provide as
* inputs for this check.
*/
char **requires;
/**
* Name of an original measure to take as a fallback
* in case the check fails.
*/
char *fallback;
/**
* Array of outputs provided by the check. Names of the attributes provided
* by the check for the AML program. Either from the configuration or
* obtained via the converter.
*/
char **outputs;
/**
* Length of the @e requires array.
*/
unsigned int num_requires;
/**
* Length of the @e outputs array.
*/
unsigned int num_outputs;
/**
* Type of the KYC check.
*/
enum TALER_KYCLOGIC_CheckType type;
/**
* Details depending on @e type.
*/
union
{
/**
* Fields present only if @e type is #TALER_KYCLOGIC_CT_FORM.
*/
struct
{
/**
* Name of the form to render.
*/
char *name;
} form;
/**
* Fields present only if @e type is TALER_KYCLOGIC_CT_LINK.
*/
struct
{
/**
* Provider used.
*/
const struct TALER_KYCLOGIC_KycProvider *provider;
} link;
} details;
};
/**
* Rule that triggers some measure(s).
*/
struct TALER_KYCLOGIC_KycRule;
/**
* Set of rules that applies to an account.
*/
struct TALER_KYCLOGIC_LegitimizationRuleSet;
/**
* Parse KYC trigger string value from a string
* into enumeration value.
*
* @param trigger_s string to parse
* @param[out] trigger set to the value found
* @return #GNUNET_OK on success, #GNUNET_NO if option
* does not exist, #GNUNET_SYSERR if option is
* malformed
*/
enum GNUNET_GenericReturnValue
TALER_KYCLOGIC_kyc_trigger_from_string (
const char *trigger_s,
enum TALER_KYCLOGIC_KycTriggerEvent *trigger);
/**
* Initialize KYC subsystem. Loads the KYC configuration.
*
* @param cfg configuration to parse
* @param cfg_fn configuration filename for AML helpers
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
TALER_KYCLOGIC_kyc_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *cfg_fn);
/**
* Shut down the KYC subsystem.
*/
void
TALER_KYCLOGIC_kyc_done (void);
/**
* Return JSON array with amounts with thresholds that
* may change KYC requirements for the wallet.
*
* @return JSON array, NULL if no limits apply
*/
json_t *
TALER_KYCLOGIC_get_wallet_thresholds (void);
/**
* Function called to iterate over KYC-relevant
* transaction amounts for a particular time range.
* Called within a database transaction, so must
* not start a new one.
*
* @param cls closure, identifies the event type and
* account to iterate over events for
* @param limit maximum time-range for which events
* should be fetched (timestamp in the past)
* @param cb function to call on each event found,
* events must be returned in reverse chronological
* order
* @param cb_cls closure for @a cb
* @return transaction status
*/
typedef enum GNUNET_DB_QueryStatus
(*TALER_KYCLOGIC_KycAmountIterator)(
void *cls,
struct GNUNET_TIME_Absolute limit,
TALER_EXCHANGEDB_KycAmountCallback cb,
void *cb_cls);
/**
* Function called to iterate over KYC-relevant
* transaction thresholds amounts.
*
* @param cls closure, identifies the event type and
* account to iterate over events for
* @param threshold a relevant threshold amount
*/
typedef void
(*TALER_KYCLOGIC_KycThresholdIterator)(
void *cls,
const struct TALER_Amount *threshold);
/**
* Parse set of legitimization rules that applies to an account.
*
* @param jlrs JSON representation to parse
* @return rule set, NULL if JSON is invalid
*/
struct TALER_KYCLOGIC_LegitimizationRuleSet *
TALER_KYCLOGIC_rules_parse (const json_t *jlrs);
/**
* Free set of legitimization rules.
*
* @param[in] lrs set of rules to free
*/
void
TALER_KYCLOGIC_rules_free (struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs);
/**
* Check if KYC is provided for a particular operation. Returns the set of
* checks that still need to be satisfied.
*
* Called within a database transaction, so must
* not start a new one.
*
* @param event what type of operation is triggering the
* test if KYC is required
* @param lrs legitimization rules to apply;
* NULL to use default rules
* @param ai callback offered to inquire about historic
* amounts involved in this type of operation
* at the given account
* @param ai_cls closure for @a ai
* @param[out] triggered_rule set to NULL if no rule
* is triggered, otherwise the rule with measures
* that must be satisfied (will be the highest
* applicable rule by display priority)
* @param[out] next_threshold set to the next amount
* that may trigger a KYC check (note: only really
* useful for the wallet balance right now, as we
* cannot easily state the applicable timeframe)
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
TALER_KYCLOGIC_kyc_test_required (
enum TALER_KYCLOGIC_KycTriggerEvent event,
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs,
TALER_KYCLOGIC_KycAmountIterator ai,
void *ai_cls,
const struct TALER_KYCLOGIC_KycRule **triggered_rule,
struct TALER_Amount *next_threshold);
/**
* Return JSON array of AccountLimit objects with hard limits of this exchange
* suitable for the "hard_limits" field of the "/keys" response.
*
* @return the JSON array of AccountLimit objects,
* empty array if there are no hard limits
*/
json_t *
TALER_KYCLOGIC_get_hard_limits (void);
/**
* Return JSON array of ZeroLimitedOperation objects with
* operations for which this exchange has a limit
* of zero, that means KYC is always required (or
* the operation is categorically forbidden).
*
* @return the JSON array of ZeroLimitedOperation objects,
* empty array if there are no hard limits
*/
json_t *
TALER_KYCLOGIC_get_zero_limits (void);
/**
* Obtain set of all measures that
* could be triggered at an amount of zero and that
* thus might be requested before a client even
* has performed any operation.
*
* @param lrs rule set to investigate, NULL for default
* @return LegitimizationMeasures, NULL on error
*/
json_t *
TALER_KYCLOGIC_zero_measures (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs);
/**
* Obtain set of all voluntary measures that
* could be triggered by clients at will.
*
* @param lrs rule set to investigate, NULL for default
* @return array of MeasureInformation, never NULL
*/
json_t *
TALER_KYCLOGIC_voluntary_measures (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs);
/**
* Get human-readable name of KYC rule.
*
* @param r rule to convert
* @return name of the rule
*/
const char *
TALER_KYCLOGIC_rule2s (const struct TALER_KYCLOGIC_KycRule *r);
/**
* Convert KYC status to human-readable string.
*
* @param status status to convert
* @return human-readable string
*/
const char *
TALER_KYCLOGIC_status2s (enum TALER_KYCLOGIC_KycStatus status);
/**
* Get priority of KYC rule.
*
* @param r rule to convert
* @return priority of the rule
*/
uint32_t
TALER_KYCLOGIC_rule2priority (const struct TALER_KYCLOGIC_KycRule *r);
/**
* Iterate over all thresholds that are applicable to a particular type of @a
* event under exposed global rules.
*
* @param event thresholds to look up
* @param it function to call on each
* @param it_cls closure for @a it
*/
void
TALER_KYCLOGIC_kyc_iterate_thresholds (
enum TALER_KYCLOGIC_KycTriggerEvent event,
TALER_KYCLOGIC_KycThresholdIterator it,
void *it_cls);
/**
* Check if a given @a rule can be satisfied in principle.
*
* @param rule the rule to check if it is verboten
* @return true if the check can be satisfied,
* false if the check can never be satisfied,
*/
bool
TALER_KYCLOGIC_is_satisfiable (
const struct TALER_KYCLOGIC_KycRule *rule);
/**
* A KYC rule @a r has been triggered. Convert the resulting requirements into
* JSON of type ``LegitimizationMeasures`` for the legitimization measures table.
*
* @param r a rule that was triggered
* @return JSON serialization of the corresponding
* ``LegitimizationMeasures``, NULL on error
*/
json_t *
TALER_KYCLOGIC_rule_to_measures (
const struct TALER_KYCLOGIC_KycRule *r);
/**
* Tuple with information about a KYC check to perform. Note that it will
* have references into the legitimization rule set provided to
* #TALER_KYCLOGIC_requirements_to_check() and thus has a lifetime that
* matches the legitimization rule set.
*
* FIXME(fdold, 2024-11-07): Consider not making this public,
* instead use struct TALER_KYCLOGIC_Measure.
*/
struct TALER_KYCLOGIC_KycCheckContext
{
/**
* KYC check to perform.
*/
const struct TALER_KYCLOGIC_KycCheck *check;
/**
* Context for the check. Can be NULL.
*/
const json_t *context;
/**
* Name of the AML program.
*/
char *prog_name;
};
/**
* A KYC check @a kcc has been triggered. Convert the resulting singular
* requirement (only a single check is possible, not multiple alternatives)
* into JSON of type ``LegitimizationMeasures`` for the legitimization
* measures table.
*
* @param kcc check that was triggered
* @return JSON serialization of the corresponding
* ``LegitimizationMeasures``
*/
json_t *
TALER_KYCLOGIC_check_to_jmeasures (
const struct TALER_KYCLOGIC_KycCheckContext *kcc);
/**
* Convert (internal) @a jrules to (public) @a jlimits.
*
* @param jrules a ``LegitimizationRuleSet`` with KYC rules;
* NULL to use default rules
* @return set to JSON array with public limits
* of type ``AccountLimit``
*/
json_t *
TALER_KYCLOGIC_rules_to_limits (const json_t *jrules);
/**
* Parse the given @a jmeasures and return the measure
* at the @a measure_index.
*
* @param jmeasures a LegitimizationMeasures object
* @param measure_index an index into the measures
* @param[out] check_name set to the name of the check
* @param[out] prog_name set to the name of the program
* @param[out] context set to the measure context
* (or NULL if there is no context)
* @return #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
TALER_KYCLOGIC_select_measure (
const json_t *jmeasures,
size_t measure_index,
const char **check_name,
const char **prog_name,
const json_t **context);
/**
* Check if the form data matches the requirements
* of the selected measure.
*
* @param jmeasures a LegitimizationMeasures object
* @param measure_index an index into the measures
* @param form_data form data submitted for the measure
* @param[out] error_message set to error details
* @return #TALER_EC_NONE if the form data matches the measure
*/
enum TALER_ErrorCode
TALER_KYCLOGIC_check_form (
const json_t *jmeasures,
size_t measure_index,
const json_t *form_data,
const char **error_message);
/**
* Convert MeasureInformation into the
* KycRequirementInformation used by the client.
*
* @param check_name the prescribed check
* @param prog_name the program to run
* @param context context to return, can be NULL
* @param access_token access token for the measure
* @param offset offset of the measure
* @param legitimization_measure_row_id row in the legitimization_measures table
* @return JSON object with matching KycRequirementInformation
*/
json_t *
TALER_KYCLOGIC_measure_to_requirement (
const char *check_name,
const char *prog_name,
const json_t *context,
const struct TALER_AccountAccessTokenP *access_token,
size_t offset,
uint64_t legitimization_measure_row_id);
/**
* Lookup measures from @a measures_spec in @a lrs and create JSON object with
* the corresponding LegitimizationMeasures.
*
* @param lrs set of legitimization rules
* @param measures_spec space-separated set of a measures to trigger from @a lrs; "+"-prefixed if AND-cominbation applies
* @return JSON object of type LegitimizationMeasures
*/
json_t *
TALER_KYCLOGIC_get_jmeasures (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs,
const char *measures_spec);
/**
* Lookup the provider for the given @a check_name.
*
* @param check_name check to lookup provider for
* @return NULL on error (@a check_name unknown or
* not a check that has a provider)
*/
const struct TALER_KYCLOGIC_KycProvider *
TALER_KYCLOGIC_check_to_provider (const char *check_name);
/**
* Extract logic data from a KYC @a provider.
*
* @param provider provider to get logic data from
* @param[out] plugin set to the KYC logic API
* @param[out] pd set to the specific operation context
* @param[out] provider_name set to the name
* of the KYC provider
*/
void
TALER_KYCLOGIC_provider_to_logic (
const struct TALER_KYCLOGIC_KycProvider *provider,
struct TALER_KYCLOGIC_Plugin **plugin,
struct TALER_KYCLOGIC_ProviderDetails **pd,
const char **provider_name);
/**
* Find default measure @a measure_name.
*
* @param measure_name name of measure to find
* @param[out] kcc initialized with KYC check data
* for the default measure
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
TALER_KYCLOGIC_get_original_measure (
const char *measure_name,
struct TALER_KYCLOGIC_KycCheckContext *kcc);
/**
* Obtain the provider logic for a given set of @a lrs
* and a specific @a kyc_rule from @a lrs that was
* triggered and the chosen @a measure_name from the
* list of measures of that @a kyc_rule. Can also be
* used to obtain the "current" check of a @a lrs if
* no trigger has been hit.
*
* @param lrs rule set
* @param kyc_rule rule that was triggered, NULL
* to merely lookup the measure without any trigger
* @param measure_name selected measure,
* NULL to return the "new_check" set by the @a lrs
* @param[out] kcc set to check to run;
* kcc->check will be NULL if the "skip" check is used
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
enum GNUNET_GenericReturnValue
TALER_KYCLOGIC_requirements_to_check (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs,
const struct TALER_KYCLOGIC_KycRule *kyc_rule,
const char *measure_name,
struct TALER_KYCLOGIC_KycCheckContext *kcc);
/**
* Obtain the provider logic for a given @a name.
*
* @param name name of the logic or provider
* @param[out] plugin set to the KYC logic API
* @param[out] pd set to the specific operation context
* @param[out] configuration_section set to the name of the KYC logic configuration section
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
TALER_KYCLOGIC_lookup_logic (
const char *name,
struct TALER_KYCLOGIC_Plugin **plugin,
struct TALER_KYCLOGIC_ProviderDetails **pd,
const char **configuration_section);
/**
* Return expiration time for the given @a lrs
*
* @param lrs legitimization rules to inspect
* @return expiration time
*/
struct GNUNET_TIME_Timestamp
TALER_KYCLOGIC_rules_get_expiration (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs);
/**
* Return successor measure for the given @a lrs
*
* @param lrs legitimization rules to inspect
* @return successor measure;
* NULL to fall back to default rules;
* pointer will be valid as long as @a lrs is valid
*/
const struct TALER_KYCLOGIC_Measure *
TALER_KYCLOGIC_rules_get_successor (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs);
/**
* Function called with the provider details and
* associated plugin closures for matching logics.
*
* @param cls closure
* @param pd provider details of a matching logic
* @param plugin_cls closure of the plugin
* @return #GNUNET_OK to continue to iterate
*/
typedef enum GNUNET_GenericReturnValue
(*TALER_KYCLOGIC_DetailsCallback)(
void *cls,
const struct TALER_KYCLOGIC_ProviderDetails *pd,
void *plugin_cls);
/**
* Call @a cb for all logics with name @a logic_name,
* providing the plugin closure and the @a pd configurations.
* Obtain the provider logic for a given set of @a lrs
* and a specific @a kyc_rule from @a lrs that was
* triggered and the chosen @a measure_name from the
* list of measures of that @a kyc_rule.
*
* @param logic_name name of the logic to match
* @param cb function to call on matching results
* @param cb_cls closure for @a cb
*/
void
TALER_KYCLOGIC_kyc_get_details (
const char *logic_name,
TALER_KYCLOGIC_DetailsCallback cb,
void *cb_cls);
/**
* Return configuration data useful for the
* /aml/$PUB/measures endpoint.
*
* @param[out] proots set to the root measures
* @param[out] pprograms set to available AML programs
* @param[out] pchecks set to available KYC checks
*/
void
TALER_KYCLOGIC_get_measure_configuration (
json_t **proots,
json_t **pprograms,
json_t **pchecks);
/**
* Check if there is a measure triggered by the
* KYC rule @a r that has a check name of "SKIP" and
* thus should be immediately executed. If such a
* measure exists, return it.
*
* @param r rule to check for instant measures
* @return NULL if there is no instant measure
*/
const struct TALER_KYCLOGIC_Measure *
TALER_KYCLOGIC_rule_get_instant_measure (
const struct TALER_KYCLOGIC_KycRule *r);
/**
* Check if there is a measure in @a lrs
* that is included in @a measure_spec
* and a SKIP measure, and thus should be immediately
* executed.
*
* @param lrs legitimization rule set
* @param measures_spec measures spec
* @returns NULL if there is no instant measure
*/
const struct TALER_KYCLOGIC_Measure *
TALER_KYCLOGIC_get_instant_measure (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs,
const char *measures_spec);
/**
* Check if there is a measure in @a lrs that is named @a measure.
*
* @param lrs legitimization rule set
* @param measure_name measures spec
* @returns NULL if not found
*/
const struct TALER_KYCLOGIC_Measure *
TALER_KYCLOGIC_get_measure (
const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs,
const char *measure_name);
/**
* Convert a measure to JSON.
*
* @param m measure to convert to JSON
* @returns JSON representation of the measure
*/
json_t *
TALER_KYCLOGIC_measure_to_jmeasures (
const struct TALER_KYCLOGIC_Measure *m);
/**
* Handle to manage a running AML program.
*/
struct TALER_KYCLOGIC_AmlProgramRunnerHandle;
/**
* Result from running an AML program.
*/
struct TALER_KYCLOGIC_AmlProgramResult
{
/**
* Possible outcomes from running the AML program.
*/
enum
{
/**
* The AML program completed successfully.
*/
TALER_KYCLOGIC_AMLR_SUCCESS,
/**
* The AML program failed.
*/
TALER_KYCLOGIC_AMLR_FAILURE
} status;
/**
* Detailed results depending on @e status.
*/
union
{
/**
* Results if @e status is #TALER_KYCLOGIC_AMLR_SUCCESS.
*/
struct
{
/**
* New account properties to set for the account.
*/
const json_t *account_properties;
/**
* Array of events to trigger.
*/
const char **events;
/**
* New AML/KYC rules to apply to the account.
*/
const json_t *new_rules;
/**
* Length of the @e events array.
*/
unsigned int num_events;
/**
* True if AML staff should investigate the account.
*/
bool to_investigate;
} success;
/**
* Results if @e status is #TALER_KYCLOGIC_AMLR_FAILURE.
*/
struct
{
/**
* Fallback measure to trigger.
*/
const char *fallback_measure;
/**
* Human-readable error message describing the
* failure (for logging).
*/
const char *error_message;
/**
* Error code for the failure.
*/
enum TALER_ErrorCode ec;
} failure;
} details;
};
/**
* Type of function called after AML program was run.
*
* @param cls closure
* @param apr result of the AML program.
*/
typedef void
(*TALER_KYCLOGIC_AmlProgramResultCallback) (
void *cls,
const struct TALER_KYCLOGIC_AmlProgramResult *apr);
/**
* Run AML program based on @a jmeasures using
* the the given inputs.
*
* @param attributes KYC attributes newly obtained
* @param aml_history AML history of the account
* @param kyc_history KYC history of the account
* @param jmeasures current KYC/AML rules to apply;
* they determine also the AML program and
* provide the context
* @param measure_index which KYC measure yielded the
* @a attributes
* @param aprc function to call with the result
* @param aprc_cls closure for @a aprc
* @return NULL if @a jmeasures is invalid for the
* selected @a measure_index or @a attributes
*/
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program (
const json_t *attributes,
const json_t *aml_history,
const json_t *kyc_history,
const json_t *jmeasures,
unsigned int measure_index,
TALER_KYCLOGIC_AmlProgramResultCallback aprc,
void *aprc_cls);
/**
* Run AML program @a prog_name with the given @a context.
*
* @param prog_name name of AML program to run
* @param attributes attributes to run with
* @param aml_history AML history of the account
* @param kyc_history KYC history of the account
* @param context context to run with
* @param aprc function to call with the result
* @param aprc_cls closure for @a aprc
* @return NULL if @a jmeasures is invalid for the
* selected @a measure_index or @a attributes
*/
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program2 (
const char *prog_name,
const json_t *attributes,
const json_t *aml_history,
const json_t *kyc_history,
const json_t *context,
TALER_KYCLOGIC_AmlProgramResultCallback aprc,
void *aprc_cls);
/**
* Run AML program specified by the given
* measure.
*
* @param measure measure with program name and context
* to run
* @param attributes attributes to run with
* @param aml_history AML history of the account
* @param kyc_history KYC history of the account
* @param aprc function to call with the result
* @param aprc_cls closure for @a aprc
* @return NULL if @a jmeasures is invalid for the
* selected @a measure_index or @a attributes
*/
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *
TALER_KYCLOGIC_run_aml_program3 (
const struct TALER_KYCLOGIC_Measure *measure,
const json_t *attributes,
const json_t *aml_history,
const json_t *kyc_history,
TALER_KYCLOGIC_AmlProgramResultCallback aprc,
void *aprc_cls);
/**
* Cancel running AML program.
*
* @param[in] aprh handle of program to cancel
*/
void
TALER_KYCLOGIC_run_aml_program_cancel (
struct TALER_KYCLOGIC_AmlProgramRunnerHandle *aprh);
#endif