diff --git a/realtime/src/config/yaml.ts b/realtime/src/config/yaml.ts index 1b9e733..1e854c4 100644 --- a/realtime/src/config/yaml.ts +++ b/realtime/src/config/yaml.ts @@ -5,6 +5,8 @@ import mergeWith from "lodash.mergewith" import * as cron from "node-cron" import Ajv from "ajv" +import countryToCurrency from "@domain/country-to-currency" + import { baseLogger } from "@services/logger" import { ConfigError } from "./error" @@ -55,6 +57,15 @@ export const getFractionDigits = ({ export const supportedCurrencies: FiatCurrency[] = yamlConfig.quotes.map((q) => { const code = q.code.toUpperCase() + + const countryCodes: CountryCode[] = [] + let key: CountryCode + for (key in countryToCurrency) { + if (countryToCurrency[key] === code) { + countryCodes.push(key) + } + } + return { code, symbol: q.symbol, @@ -64,6 +75,7 @@ export const supportedCurrencies: FiatCurrency[] = yamlConfig.quotes.map((q) => currency: code, fractionDigits: q.fractionDigits, }), + countryCodes, } }) export const defaultBaseCurrency: CurrencyCode = yamlConfig.base diff --git a/realtime/src/domain/country-to-currency/index.ts b/realtime/src/domain/country-to-currency/index.ts new file mode 100644 index 0000000..c571c29 --- /dev/null +++ b/realtime/src/domain/country-to-currency/index.ts @@ -0,0 +1,255 @@ +// This is a generated file taken from: +// https://github.com/thiagodp/country-to-currency/blob/v1.1.5/index.ts + +export default { + AD: "EUR", + AE: "AED", + AF: "AFN", + AG: "XCD", + AI: "XCD", + AL: "ALL", + AM: "AMD", + AN: "ANG", + AO: "AOA", + AQ: "USD", + AR: "ARS", + AS: "USD", + AT: "EUR", + AU: "AUD", + AW: "AWG", + AX: "EUR", + AZ: "AZN", + BA: "BAM", + BB: "BBD", + BD: "BDT", + BE: "EUR", + BF: "XOF", + BG: "BGN", + BH: "BHD", + BI: "BIF", + BJ: "XOF", + BL: "EUR", + BM: "BMD", + BN: "BND", + BO: "BOB", + BQ: "USD", + BR: "BRL", + BS: "BSD", + BT: "BTN", + BV: "NOK", + BW: "BWP", + BY: "BYN", + BZ: "BZD", + CA: "CAD", + CC: "AUD", + CD: "CDF", + CF: "XAF", + CG: "XAF", + CH: "CHF", + CI: "XOF", + CK: "NZD", + CL: "CLP", + CM: "XAF", + CN: "CNY", + CO: "COP", + CR: "CRC", + CU: "CUP", + CV: "CVE", + CW: "ANG", + CX: "AUD", + CY: "EUR", + CZ: "CZK", + DE: "EUR", + DJ: "DJF", + DK: "DKK", + DM: "XCD", + DO: "DOP", + DZ: "DZD", + EC: "USD", + EE: "EUR", + EG: "EGP", + EH: "MAD", + ER: "ERN", + ES: "EUR", + ET: "ETB", + FI: "EUR", + FJ: "FJD", + FK: "FKP", + FM: "USD", + FO: "DKK", + FR: "EUR", + GA: "XAF", + GB: "GBP", + GD: "XCD", + GE: "GEL", + GF: "EUR", + GG: "GBP", + GH: "GHS", + GI: "GIP", + GL: "DKK", + GM: "GMD", + GN: "GNF", + GP: "EUR", + GQ: "XAF", + GR: "EUR", + GS: "FKP", + GT: "GTQ", + GU: "USD", + GW: "XOF", + GY: "GYD", + HK: "HKD", + HM: "AUD", + HN: "HNL", + HR: "EUR", + HT: "HTG", + HU: "HUF", + ID: "IDR", + IE: "EUR", + IL: "ILS", + IM: "GBP", + IN: "INR", + IO: "USD", + IQ: "IQD", + IR: "IRR", + IS: "ISK", + IT: "EUR", + JE: "GBP", + JM: "JMD", + JO: "JOD", + JP: "JPY", + KE: "KES", + KG: "KGS", + KH: "KHR", + KI: "AUD", + KM: "KMF", + KN: "XCD", + KP: "KPW", + KR: "KRW", + KW: "KWD", + KY: "KYD", + KZ: "KZT", + LA: "LAK", + LB: "LBP", + LC: "XCD", + LI: "CHF", + LK: "LKR", + LR: "LRD", + LS: "LSL", + LT: "EUR", + LU: "EUR", + LV: "EUR", + LY: "LYD", + MA: "MAD", + MC: "EUR", + MD: "MDL", + ME: "EUR", + MF: "EUR", + MG: "MGA", + MH: "USD", + MK: "MKD", + ML: "XOF", + MM: "MMK", + MN: "MNT", + MO: "MOP", + MP: "USD", + MQ: "EUR", + MR: "MRU", + MS: "XCD", + MT: "EUR", + MU: "MUR", + MV: "MVR", + MW: "MWK", + MX: "MXN", + MY: "MYR", + MZ: "MZN", + NA: "NAD", + NC: "XPF", + NE: "XOF", + NF: "AUD", + NG: "NGN", + NI: "NIO", + NL: "EUR", + NO: "NOK", + NP: "NPR", + NR: "AUD", + NU: "NZD", + NZ: "NZD", + OM: "OMR", + PA: "PAB", + PE: "PEN", + PF: "XPF", + PG: "PGK", + PH: "PHP", + PK: "PKR", + PL: "PLN", + PM: "EUR", + PN: "NZD", + PR: "USD", + PS: "ILS", + PT: "EUR", + PW: "USD", + PY: "PYG", + QA: "QAR", + RE: "EUR", + RO: "RON", + RS: "RSD", + RU: "RUB", + RW: "RWF", + SA: "SAR", + SB: "SBD", + SC: "SCR", + SD: "SDG", + SE: "SEK", + SG: "SGD", + SH: "SHP", + SI: "EUR", + SJ: "NOK", + SK: "EUR", + SL: "SLE", + SM: "EUR", + SN: "XOF", + SO: "SOS", + SR: "SRD", + SS: "SSP", + ST: "STN", + SV: "USD", + SX: "ANG", + SY: "SYP", + SZ: "SZL", + TC: "USD", + TD: "XAF", + TF: "EUR", + TG: "XOF", + TH: "THB", + TJ: "TJS", + TK: "NZD", + TL: "USD", + TM: "TMT", + TN: "TND", + TO: "TOP", + TR: "TRY", + TT: "TTD", + TV: "AUD", + TW: "TWD", + TZ: "TZS", + UA: "UAH", + UG: "UGX", + UM: "USD", + US: "USD", + UY: "UYU", + UZ: "UZS", + VA: "EUR", + VC: "XCD", + VE: "VES", + VG: "USD", + VI: "USD", + VN: "VND", + VU: "VUV", + WF: "XPF", + WS: "WST", + YE: "YER", + YT: "EUR", + ZA: "ZAR", + ZM: "ZMW", + ZW: "ZWL", +} as const diff --git a/realtime/src/domain/country-to-currency/index.types.d.ts b/realtime/src/domain/country-to-currency/index.types.d.ts new file mode 100644 index 0000000..e225180 --- /dev/null +++ b/realtime/src/domain/country-to-currency/index.types.d.ts @@ -0,0 +1 @@ +type CountryCode = keyof typeof import("./index").default diff --git a/realtime/src/domain/primitives/index.types.d.ts b/realtime/src/domain/primitives/index.types.d.ts index 14e53b2..cd96cb1 100644 --- a/realtime/src/domain/primitives/index.types.d.ts +++ b/realtime/src/domain/primitives/index.types.d.ts @@ -9,4 +9,5 @@ type FiatCurrency = { readonly name: string readonly flag: string readonly fractionDigits: number + readonly countryCodes: CountryCode[] } diff --git a/realtime/src/servers/protos/price.proto b/realtime/src/servers/protos/price.proto index aa03f93..c8cb45e 100644 --- a/realtime/src/servers/protos/price.proto +++ b/realtime/src/servers/protos/price.proto @@ -25,4 +25,5 @@ message Currency { string name = 3; string flag = 4; int32 fractionDigits = 5; + repeated string countryCodes = 6; } diff --git a/realtime/test/unit/config/yaml.spec.ts b/realtime/test/unit/config/yaml.spec.ts index 25f17ea..dd1d081 100644 --- a/realtime/test/unit/config/yaml.spec.ts +++ b/realtime/test/unit/config/yaml.spec.ts @@ -1,4 +1,9 @@ -import { coerceToStringArray, ConfigError, getFractionDigits } from "@config" +import { + coerceToStringArray, + ConfigError, + getFractionDigits, + supportedCurrencies, +} from "@config" describe("coerceToStringArray", () => { it("returns an empty array if the input is falsy", () => { @@ -55,3 +60,74 @@ describe("getFractionDigits", () => { expect(() => getFractionDigits({ currency })).toThrowError(expectedErrorMessage) }) }) + +describe("supportedCurrencies", () => { + test("returns correct country codes for a valid currency", () => { + const expectedUsdCountries = [ + "AQ", + "AS", + "BQ", + "EC", + "FM", + "GU", + "IO", + "MH", + "MP", + "PR", + "PW", + "SV", + "TC", + "TL", + "UM", + "US", + "VG", + "VI", + ] + + const expectedEurCountries = [ + "AD", + "AT", + "AX", + "BE", + "BL", + "CY", + "DE", + "EE", + "ES", + "FI", + "FR", + "GF", + "GP", + "GR", + "HR", + "IE", + "IT", + "LT", + "LU", + "LV", + "MC", + "ME", + "MF", + "MQ", + "MT", + "NL", + "PM", + "PT", + "RE", + "SI", + "SK", + "SM", + "TF", + "VA", + "YT", + ] + + const usdCurrency = supportedCurrencies.find((c) => c.code === "USD") + if (usdCurrency === undefined) throw new Error() + expect(usdCurrency.countryCodes).toEqual(expectedUsdCountries) + + const eurCurrency = supportedCurrencies.find((c) => c.code === "EUR") + if (eurCurrency === undefined) throw new Error() + expect(eurCurrency.countryCodes).toEqual(expectedEurCountries) + }) +}) diff --git a/typos.toml b/typos.toml index 6eecf88..53e0a69 100644 --- a/typos.toml +++ b/typos.toml @@ -1,6 +1,7 @@ files.extend-exclude = [ "dev", - "test/postman/*.json" + "test/postman/*.json", + "realtime/src/domain/country-to-currency/index.ts" ] [default.extend-words]