10.63. DD 63: LibEufin Conversion Rate Class#
10.63.1. Summary#
We need an efficient solution to set specific conversion rates for some users. By efficient this means you do not have to set or update them manually for all accounts and a good way to see what are the current rates and which accounts use them.
10.63.2. Proposed Solution#
The current global conversion rate schema is:
interface ConversionRate {
// Minimum fiat amount authorised for cashin before conversion
cashin_min_amount: Amount;
// Exchange rate to buy regional currency from fiat
cashin_ratio: DecimalNumber;
// Regional amount fee to subtract after applying the cashin ratio.
cashin_fee: Amount;
// Smallest possible regional amount, converted amount is rounded to this amount
cashin_tiny_amount: Amount;
// Rounding mode used during cashin conversion
cashin_rounding_mode: "zero" | "up" | "nearest";
// Minimum regional amount authorised for cashout before conversion
cashout_min_amount: Amount;
// Exchange rate to sell regional currency for fiat
cashout_ratio: DecimalNumber;
// Fiat amount fee to subtract after applying the cashout ratio.
cashout_fee: Amount;
// Smallest possible fiat amount, converted amount is rounded to this amount
cashout_tiny_amount: Amount;
// Rounding mode used during cashout conversion
cashout_rounding_mode: "zero" | "up" | "nearest";
}
This would become the default
class, that will be used by all created users. The administrator would be able to create new classes that override some of the default properties:
interface ConversionRateClassRequest {
// The name of this class
name: string;
// A description of the class
description?: string;
// Minimum fiat amount authorised for cashin before conversion
cashin_min_amount?: Amount;
// Exchange rate to buy regional currency from fiat
cashin_ratio?: DecimalNumber;
// Regional amount fee to subtract after applying the cashin ratio.
cashin_fee?: Amount;
// Smallest possible regional amount, converted amount is rounded to this amount
cashin_tiny_amount?: Amount;
// Rounding mode used during cashin conversion
cashin_rounding_mode?: "zero" | "up" | "nearest";
// Minimum regional amount authorised for cashout before conversion
cashout_min_amount?: Amount;
// Exchange rate to sell regional currency for fiat
cashout_ratio?: DecimalNumber;
// Fiat amount fee to subtract after applying the cashout ratio.
cashout_fee?: Amount;
// Smallest possible fiat amount, converted amount is rounded to this amount
cashout_tiny_amount?: Amount;
// Rounding mode used during cashout conversion
cashout_rounding_mode?: "zero" | "up" | "nearest";
}
interface ConversionRateClass {
// The name of this class
name: string;
// A description of the class
description?: string;
// Class unique ID
row_id: Integer;
// Number of users affected to this class
num_users: Integer;
// Applied conversion rate
conversion_rate: ConversionRate;
// Minimum fiat amount authorised for cashin before conversion
cashin_min_amount?: Amount;
// Exchange rate to buy regional currency from fiat
cashin_ratio?: DecimalNumber;
// Regional amount fee to subtract after applying the cashin ratio.
cashin_fee?: Amount;
// Smallest possible regional amount, converted amount is rounded to this amount
cashin_tiny_amount?: Amount;
// Rounding mode used during cashin conversion
cashin_rounding_mode?: "zero" | "up" | "nearest";
// Minimum regional amount authorised for cashout before conversion
cashout_min_amount?: Amount;
// Exchange rate to sell regional currency for fiat
cashout_ratio?: DecimalNumber;
// Fiat amount fee to subtract after applying the cashout ratio.
cashout_fee?: Amount;
// Smallest possible fiat amount, converted amount is rounded to this amount
cashout_tiny_amount?: Amount;
// Rounding mode used during cashout conversion
cashout_rounding_mode?: "zero" | "up" | "nearest";
}
interface ConversionRateClasses {
default: ConversionRate;
classes: ConversionRateClass[];
}
When we run the conversion logic we take values from the user class and fallback to the default values when they are null. If the ratio is zero it disable the conversion.
10.63.2.1. Taler Conversion Info API#
We need to move the current conversion-info API from /conversion-info/*
to /accounts/$USERNAME/conversion-info/*
. We keep the current API to only show the default rate for retro compatibility.
We deprecate POST /conversion-rate
to make the API readonly (the Info in the name was a hint).
TODO: How hard is it to migrate to this in the wallets ?
10.63.2.2. Taler Core Bank API#
We migrate POST /conversion-rate
here to set the default conversion rate class value.
We add new admin only conversion rate class management endpoints:
POST /conversion-rate-class GET /conversion-rate-class GET /conversion-rate-class/$CLASS-ID PATCH /conversion-rate-class/$CLASS-ID DELETE /conversion-rate-class/$CLASS-ID
add /conversion-rate-class/$CLASS-ID/conversion-info/*
We add admin only conversion_rate_class
Integer optional field to POST /accounts and PATCH /accounts/$USERNAME.
We add conversion_rate_class
Integer optional field and query filter to GET /accounts
We add conversion_rate_class
ConversionRateClass field of GET /accounts/$USERNAME