nautilus_model/
currencies.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Common `Currency` constants.
17
18use std::{
19    collections::HashMap,
20    sync::{LazyLock, Mutex, OnceLock},
21};
22
23use ustr::Ustr;
24
25use crate::{enums::CurrencyType, types::Currency};
26
27///////////////////////////////////////////////////////////////////////////////
28// Fiat currencies
29///////////////////////////////////////////////////////////////////////////////
30static AUD_LOCK: OnceLock<Currency> = OnceLock::new();
31static BRL_LOCK: OnceLock<Currency> = OnceLock::new();
32static CAD_LOCK: OnceLock<Currency> = OnceLock::new();
33static CHF_LOCK: OnceLock<Currency> = OnceLock::new();
34static CNY_LOCK: OnceLock<Currency> = OnceLock::new();
35static CNH_LOCK: OnceLock<Currency> = OnceLock::new();
36static CZK_LOCK: OnceLock<Currency> = OnceLock::new();
37static DKK_LOCK: OnceLock<Currency> = OnceLock::new();
38static EUR_LOCK: OnceLock<Currency> = OnceLock::new();
39static GBP_LOCK: OnceLock<Currency> = OnceLock::new();
40static HKD_LOCK: OnceLock<Currency> = OnceLock::new();
41static HUF_LOCK: OnceLock<Currency> = OnceLock::new();
42static ILS_LOCK: OnceLock<Currency> = OnceLock::new();
43static INR_LOCK: OnceLock<Currency> = OnceLock::new();
44static JPY_LOCK: OnceLock<Currency> = OnceLock::new();
45static KRW_LOCK: OnceLock<Currency> = OnceLock::new();
46static MXN_LOCK: OnceLock<Currency> = OnceLock::new();
47static NOK_LOCK: OnceLock<Currency> = OnceLock::new();
48static NZD_LOCK: OnceLock<Currency> = OnceLock::new();
49static PLN_LOCK: OnceLock<Currency> = OnceLock::new();
50static RUB_LOCK: OnceLock<Currency> = OnceLock::new();
51static SAR_LOCK: OnceLock<Currency> = OnceLock::new();
52static SEK_LOCK: OnceLock<Currency> = OnceLock::new();
53static SGD_LOCK: OnceLock<Currency> = OnceLock::new();
54static THB_LOCK: OnceLock<Currency> = OnceLock::new();
55static TRY_LOCK: OnceLock<Currency> = OnceLock::new();
56static TWD_LOCK: OnceLock<Currency> = OnceLock::new();
57static USD_LOCK: OnceLock<Currency> = OnceLock::new();
58static ZAR_LOCK: OnceLock<Currency> = OnceLock::new();
59
60///////////////////////////////////////////////////////////////////////////////
61// Commodity backed currencies
62///////////////////////////////////////////////////////////////////////////////
63static XAG_LOCK: OnceLock<Currency> = OnceLock::new();
64static XAU_LOCK: OnceLock<Currency> = OnceLock::new();
65static XPT_LOCK: OnceLock<Currency> = OnceLock::new();
66
67///////////////////////////////////////////////////////////////////////////////
68// Crypto currencies
69///////////////////////////////////////////////////////////////////////////////
70static ONEINCH_LOCK: OnceLock<Currency> = OnceLock::new();
71static AAVE_LOCK: OnceLock<Currency> = OnceLock::new();
72static ACA_LOCK: OnceLock<Currency> = OnceLock::new();
73static ADA_LOCK: OnceLock<Currency> = OnceLock::new();
74static ARB_LOCK: OnceLock<Currency> = OnceLock::new();
75static AVAX_LOCK: OnceLock<Currency> = OnceLock::new();
76static BCH_LOCK: OnceLock<Currency> = OnceLock::new();
77static BIO_LOCK: OnceLock<Currency> = OnceLock::new();
78static BTC_LOCK: OnceLock<Currency> = OnceLock::new();
79static BTTC_LOCK: OnceLock<Currency> = OnceLock::new();
80static BNB_LOCK: OnceLock<Currency> = OnceLock::new();
81static BRZ_LOCK: OnceLock<Currency> = OnceLock::new();
82static BSV_LOCK: OnceLock<Currency> = OnceLock::new();
83static BUSD_LOCK: OnceLock<Currency> = OnceLock::new();
84static CAKE_LOCK: OnceLock<Currency> = OnceLock::new();
85static CRV_LOCK: OnceLock<Currency> = OnceLock::new();
86static DASH_LOCK: OnceLock<Currency> = OnceLock::new();
87static DOGE_LOCK: OnceLock<Currency> = OnceLock::new();
88static DOT_LOCK: OnceLock<Currency> = OnceLock::new();
89static ENA_LOCK: OnceLock<Currency> = OnceLock::new();
90static EOS_LOCK: OnceLock<Currency> = OnceLock::new();
91static ETH_LOCK: OnceLock<Currency> = OnceLock::new();
92static ETHW_LOCK: OnceLock<Currency> = OnceLock::new();
93static FDUSD_LOCK: OnceLock<Currency> = OnceLock::new();
94static HYPE_LOCK: OnceLock<Currency> = OnceLock::new();
95static JOE_LOCK: OnceLock<Currency> = OnceLock::new();
96static LINK_LOCK: OnceLock<Currency> = OnceLock::new();
97static LTC_LOCK: OnceLock<Currency> = OnceLock::new();
98static LUNA_LOCK: OnceLock<Currency> = OnceLock::new();
99static NBT_LOCK: OnceLock<Currency> = OnceLock::new();
100static PROVE_LOCK: OnceLock<Currency> = OnceLock::new();
101static SOL_LOCK: OnceLock<Currency> = OnceLock::new();
102static SUI_LOCK: OnceLock<Currency> = OnceLock::new();
103static TRX_LOCK: OnceLock<Currency> = OnceLock::new();
104static TRYB_LOCK: OnceLock<Currency> = OnceLock::new();
105static TUSD_LOCK: OnceLock<Currency> = OnceLock::new();
106static SHIB_LOCK: OnceLock<Currency> = OnceLock::new();
107static UNI_LOCK: OnceLock<Currency> = OnceLock::new();
108static VTC_LOCK: OnceLock<Currency> = OnceLock::new();
109static WSB_LOCK: OnceLock<Currency> = OnceLock::new();
110static XBT_LOCK: OnceLock<Currency> = OnceLock::new();
111static XEC_LOCK: OnceLock<Currency> = OnceLock::new();
112static XLM_LOCK: OnceLock<Currency> = OnceLock::new();
113static XMR_LOCK: OnceLock<Currency> = OnceLock::new();
114static XRP_LOCK: OnceLock<Currency> = OnceLock::new();
115static XTZ_LOCK: OnceLock<Currency> = OnceLock::new();
116static USDC_LOCK: OnceLock<Currency> = OnceLock::new();
117static USDC_POS_LOCK: OnceLock<Currency> = OnceLock::new();
118static USDP_LOCK: OnceLock<Currency> = OnceLock::new();
119static USDT_LOCK: OnceLock<Currency> = OnceLock::new();
120static ZEC_LOCK: OnceLock<Currency> = OnceLock::new();
121
122impl Currency {
123    ///////////////////////////////////////////////////////////////////////////
124    // Fiat currencies
125    ///////////////////////////////////////////////////////////////////////////
126    #[allow(non_snake_case)]
127    #[must_use]
128    pub fn AUD() -> Self {
129        *AUD_LOCK.get_or_init(|| Self {
130            code: Ustr::from("AUD"),
131            precision: 2,
132            iso4217: 36,
133            name: Ustr::from("Australian dollar"),
134            currency_type: CurrencyType::Fiat,
135        })
136    }
137    #[allow(non_snake_case)]
138    #[must_use]
139    pub fn BRL() -> Self {
140        *BRL_LOCK.get_or_init(|| Self {
141            code: Ustr::from("BRL"),
142            precision: 2,
143            iso4217: 986,
144            name: Ustr::from("Brazilian real"),
145            currency_type: CurrencyType::Fiat,
146        })
147    }
148
149    #[allow(non_snake_case)]
150    #[must_use]
151    pub fn CAD() -> Self {
152        *CAD_LOCK.get_or_init(|| Self {
153            code: Ustr::from("CAD"),
154            precision: 2,
155            iso4217: 124,
156            name: Ustr::from("Canadian dollar"),
157            currency_type: CurrencyType::Fiat,
158        })
159    }
160
161    #[allow(non_snake_case)]
162    #[must_use]
163    pub fn CHF() -> Self {
164        *CHF_LOCK.get_or_init(|| Self {
165            code: Ustr::from("CHF"),
166            precision: 2,
167            iso4217: 756,
168            name: Ustr::from("Swiss franc"),
169            currency_type: CurrencyType::Fiat,
170        })
171    }
172
173    #[allow(non_snake_case)]
174    #[must_use]
175    pub fn CNY() -> Self {
176        *CNY_LOCK.get_or_init(|| Self {
177            code: Ustr::from("CNY"),
178            precision: 2,
179            iso4217: 156,
180            name: Ustr::from("Chinese yuan"),
181            currency_type: CurrencyType::Fiat,
182        })
183    }
184
185    #[allow(non_snake_case)]
186    #[must_use]
187    pub fn CNH() -> Self {
188        *CNH_LOCK.get_or_init(|| Self {
189            code: Ustr::from("CNH"),
190            precision: 2,
191            iso4217: 0,
192            name: Ustr::from("Chinese yuan (offshore)"),
193            currency_type: CurrencyType::Fiat,
194        })
195    }
196
197    #[allow(non_snake_case)]
198    #[must_use]
199    pub fn CZK() -> Self {
200        *CZK_LOCK.get_or_init(|| Self {
201            code: Ustr::from("CZK"),
202            precision: 2,
203            iso4217: 203,
204            name: Ustr::from("Czech koruna"),
205            currency_type: CurrencyType::Fiat,
206        })
207    }
208
209    #[allow(non_snake_case)]
210    #[must_use]
211    pub fn DKK() -> Self {
212        *DKK_LOCK.get_or_init(|| Self {
213            code: Ustr::from("DKK"),
214            precision: 2,
215            iso4217: 208,
216            name: Ustr::from("Danish krone"),
217            currency_type: CurrencyType::Fiat,
218        })
219    }
220
221    #[allow(non_snake_case)]
222    #[must_use]
223    pub fn EUR() -> Self {
224        *EUR_LOCK.get_or_init(|| Self {
225            code: Ustr::from("EUR"),
226            precision: 2,
227            iso4217: 978,
228            name: Ustr::from("Euro"),
229            currency_type: CurrencyType::Fiat,
230        })
231    }
232
233    #[allow(non_snake_case)]
234    #[must_use]
235    pub fn GBP() -> Self {
236        *GBP_LOCK.get_or_init(|| Self {
237            code: Ustr::from("GBP"),
238            precision: 2,
239            iso4217: 826,
240            name: Ustr::from("British Pound"),
241            currency_type: CurrencyType::Fiat,
242        })
243    }
244
245    #[allow(non_snake_case)]
246    #[must_use]
247    pub fn HKD() -> Self {
248        *HKD_LOCK.get_or_init(|| Self {
249            code: Ustr::from("HKD"),
250            precision: 2,
251            iso4217: 344,
252            name: Ustr::from("Hong Kong dollar"),
253            currency_type: CurrencyType::Fiat,
254        })
255    }
256
257    #[allow(non_snake_case)]
258    #[must_use]
259    pub fn HUF() -> Self {
260        *HUF_LOCK.get_or_init(|| Self {
261            code: Ustr::from("HUF"),
262            precision: 2,
263            iso4217: 348,
264            name: Ustr::from("Hungarian forint"),
265            currency_type: CurrencyType::Fiat,
266        })
267    }
268
269    #[allow(non_snake_case)]
270    #[must_use]
271    pub fn ILS() -> Self {
272        *ILS_LOCK.get_or_init(|| Self {
273            code: Ustr::from("ILS"),
274            precision: 2,
275            iso4217: 376,
276            name: Ustr::from("Israeli new shekel"),
277            currency_type: CurrencyType::Fiat,
278        })
279    }
280
281    #[allow(non_snake_case)]
282    #[must_use]
283    pub fn INR() -> Self {
284        *INR_LOCK.get_or_init(|| Self {
285            code: Ustr::from("INR"),
286            precision: 2,
287            iso4217: 356,
288            name: Ustr::from("Indian rupee"),
289            currency_type: CurrencyType::Fiat,
290        })
291    }
292
293    #[allow(non_snake_case)]
294    #[must_use]
295    pub fn JPY() -> Self {
296        *JPY_LOCK.get_or_init(|| Self {
297            code: Ustr::from("JPY"),
298            precision: 0,
299            iso4217: 392,
300            name: Ustr::from("Japanese yen"),
301            currency_type: CurrencyType::Fiat,
302        })
303    }
304    #[allow(non_snake_case)]
305    #[must_use]
306    pub fn KRW() -> Self {
307        *KRW_LOCK.get_or_init(|| Self {
308            code: Ustr::from("KRW"),
309            precision: 0,
310            iso4217: 410,
311            name: Ustr::from("South Korean won"),
312            currency_type: CurrencyType::Fiat,
313        })
314    }
315
316    #[allow(non_snake_case)]
317    #[must_use]
318    pub fn MXN() -> Self {
319        *MXN_LOCK.get_or_init(|| Self {
320            code: Ustr::from("MXN"),
321            precision: 2,
322            iso4217: 484,
323            name: Ustr::from("Mexican peso"),
324            currency_type: CurrencyType::Fiat,
325        })
326    }
327
328    #[allow(non_snake_case)]
329    #[must_use]
330    pub fn NOK() -> Self {
331        *NOK_LOCK.get_or_init(|| Self {
332            code: Ustr::from("NOK"),
333            precision: 2,
334            iso4217: 578,
335            name: Ustr::from("Norwegian krone"),
336            currency_type: CurrencyType::Fiat,
337        })
338    }
339
340    #[allow(non_snake_case)]
341    #[must_use]
342    pub fn NZD() -> Self {
343        *NZD_LOCK.get_or_init(|| Self {
344            code: Ustr::from("NZD"),
345            precision: 2,
346            iso4217: 554,
347            name: Ustr::from("New Zealand dollar"),
348            currency_type: CurrencyType::Fiat,
349        })
350    }
351
352    #[allow(non_snake_case)]
353    #[must_use]
354    pub fn PLN() -> Self {
355        *PLN_LOCK.get_or_init(|| Self {
356            code: Ustr::from("PLN"),
357            precision: 2,
358            iso4217: 985,
359            name: Ustr::from("Polish złoty"),
360            currency_type: CurrencyType::Fiat,
361        })
362    }
363
364    #[allow(non_snake_case)]
365    #[must_use]
366    pub fn RUB() -> Self {
367        *RUB_LOCK.get_or_init(|| Self {
368            code: Ustr::from("RUB"),
369            precision: 2,
370            iso4217: 643,
371            name: Ustr::from("Russian ruble"),
372            currency_type: CurrencyType::Fiat,
373        })
374    }
375
376    #[allow(non_snake_case)]
377    #[must_use]
378    pub fn SAR() -> Self {
379        *SAR_LOCK.get_or_init(|| Self {
380            code: Ustr::from("SAR"),
381            precision: 2,
382            iso4217: 682,
383            name: Ustr::from("Saudi riyal"),
384            currency_type: CurrencyType::Fiat,
385        })
386    }
387
388    #[allow(non_snake_case)]
389    #[must_use]
390    pub fn SEK() -> Self {
391        *SEK_LOCK.get_or_init(|| Self {
392            code: Ustr::from("SEK"),
393            precision: 2,
394            iso4217: 752,
395            name: Ustr::from("Swedish krona"),
396            currency_type: CurrencyType::Fiat,
397        })
398    }
399
400    #[allow(non_snake_case)]
401    #[must_use]
402    pub fn SGD() -> Self {
403        *SGD_LOCK.get_or_init(|| Self {
404            code: Ustr::from("SGD"),
405            precision: 2,
406            iso4217: 702,
407            name: Ustr::from("Singapore dollar"),
408            currency_type: CurrencyType::Fiat,
409        })
410    }
411
412    #[allow(non_snake_case)]
413    #[must_use]
414    pub fn THB() -> Self {
415        *THB_LOCK.get_or_init(|| Self {
416            code: Ustr::from("THB"),
417            precision: 2,
418            iso4217: 764,
419            name: Ustr::from("Thai baht"),
420            currency_type: CurrencyType::Fiat,
421        })
422    }
423
424    #[allow(non_snake_case)]
425    #[must_use]
426    pub fn TRY() -> Self {
427        *TRY_LOCK.get_or_init(|| Self {
428            code: Ustr::from("TRY"),
429            precision: 2,
430            iso4217: 949,
431            name: Ustr::from("Turkish lira"),
432            currency_type: CurrencyType::Fiat,
433        })
434    }
435
436    #[allow(non_snake_case)]
437    #[must_use]
438    pub fn TWD() -> Self {
439        *TWD_LOCK.get_or_init(|| Self {
440            code: Ustr::from("TWD"),
441            precision: 2,
442            iso4217: 901,
443            name: Ustr::from("New Taiwan dollar"),
444            currency_type: CurrencyType::Fiat,
445        })
446    }
447
448    #[allow(non_snake_case)]
449    #[must_use]
450    pub fn USD() -> Self {
451        *USD_LOCK.get_or_init(|| Self {
452            code: Ustr::from("USD"),
453            precision: 2,
454            iso4217: 840,
455            name: Ustr::from("United States dollar"),
456            currency_type: CurrencyType::Fiat,
457        })
458    }
459    #[allow(non_snake_case)]
460    #[must_use]
461    pub fn ZAR() -> Self {
462        *ZAR_LOCK.get_or_init(|| Self {
463            code: Ustr::from("ZAR"),
464            precision: 2,
465            iso4217: 710,
466            name: Ustr::from("South African rand"),
467            currency_type: CurrencyType::Fiat,
468        })
469    }
470
471    #[allow(non_snake_case)]
472    #[must_use]
473    pub fn XAG() -> Self {
474        *XAG_LOCK.get_or_init(|| Self {
475            code: Ustr::from("XAG"),
476            precision: 2,
477            iso4217: 961,
478            name: Ustr::from("Silver (one troy ounce)"),
479            currency_type: CurrencyType::CommodityBacked,
480        })
481    }
482
483    #[allow(non_snake_case)]
484    #[must_use]
485    pub fn XAU() -> Self {
486        *XAU_LOCK.get_or_init(|| Self {
487            code: Ustr::from("XAU"),
488            precision: 2,
489            iso4217: 959,
490            name: Ustr::from("Gold (one troy ounce)"),
491            currency_type: CurrencyType::CommodityBacked,
492        })
493    }
494
495    #[allow(non_snake_case)]
496    #[must_use]
497    pub fn XPT() -> Self {
498        *XPT_LOCK.get_or_init(|| Self {
499            code: Ustr::from("XPT"),
500            precision: 2,
501            iso4217: 962,
502            name: Ustr::from("Platinum (one troy ounce)"),
503            currency_type: CurrencyType::CommodityBacked,
504        })
505    }
506
507    ///////////////////////////////////////////////////////////////////////////
508    // Crypto currencies
509    ///////////////////////////////////////////////////////////////////////////
510    #[allow(non_snake_case)]
511    #[must_use]
512    pub fn ONEINCH() -> Self {
513        *ONEINCH_LOCK.get_or_init(|| Self {
514            code: Ustr::from("1INCH"),
515            precision: 8,
516            iso4217: 0,
517            name: Ustr::from("1inch Network"),
518            currency_type: CurrencyType::Crypto,
519        })
520    }
521
522    #[allow(non_snake_case)]
523    #[must_use]
524    pub fn AAVE() -> Self {
525        *AAVE_LOCK.get_or_init(|| Self {
526            code: Ustr::from("AAVE"),
527            precision: 8,
528            iso4217: 0,
529            name: Ustr::from("Aave"),
530            currency_type: CurrencyType::Crypto,
531        })
532    }
533
534    #[allow(non_snake_case)]
535    #[must_use]
536    pub fn ACA() -> Self {
537        *ACA_LOCK.get_or_init(|| Self {
538            code: Ustr::from("ACA"),
539            precision: 8,
540            iso4217: 0,
541            name: Ustr::from("Acala Token"),
542            currency_type: CurrencyType::Crypto,
543        })
544    }
545
546    #[allow(non_snake_case)]
547    #[must_use]
548    pub fn ADA() -> Self {
549        *ADA_LOCK.get_or_init(|| Self {
550            code: Ustr::from("ADA"),
551            precision: 6,
552            iso4217: 0,
553            name: Ustr::from("Cardano"),
554            currency_type: CurrencyType::Crypto,
555        })
556    }
557
558    #[allow(non_snake_case)]
559    #[must_use]
560    pub fn ARB() -> Self {
561        *ARB_LOCK.get_or_init(|| Self {
562            code: Ustr::from("ARB"),
563            precision: 8,
564            iso4217: 0,
565            name: Ustr::from("Arbitrum"),
566            currency_type: CurrencyType::Crypto,
567        })
568    }
569
570    #[allow(non_snake_case)]
571    #[must_use]
572    pub fn AVAX() -> Self {
573        *AVAX_LOCK.get_or_init(|| Self {
574            code: Ustr::from("AVAX"),
575            precision: 8,
576            iso4217: 0,
577            name: Ustr::from("Avalanche"),
578            currency_type: CurrencyType::Crypto,
579        })
580    }
581
582    #[allow(non_snake_case)]
583    #[must_use]
584    pub fn BCH() -> Self {
585        *BCH_LOCK.get_or_init(|| Self {
586            code: Ustr::from("BCH"),
587            precision: 8,
588            iso4217: 0,
589            name: Ustr::from("Bitcoin Cash"),
590            currency_type: CurrencyType::Crypto,
591        })
592    }
593
594    #[allow(non_snake_case)]
595    #[must_use]
596    pub fn BIO() -> Self {
597        *BIO_LOCK.get_or_init(|| Self {
598            code: Ustr::from("BIO"),
599            precision: 8,
600            iso4217: 0,
601            name: Ustr::from("BioPassport"),
602            currency_type: CurrencyType::Crypto,
603        })
604    }
605
606    #[allow(non_snake_case)]
607    #[must_use]
608    pub fn BTC() -> Self {
609        *BTC_LOCK.get_or_init(|| Self {
610            code: Ustr::from("BTC"),
611            precision: 8,
612            iso4217: 0,
613            name: Ustr::from("Bitcoin"),
614            currency_type: CurrencyType::Crypto,
615        })
616    }
617
618    #[allow(non_snake_case)]
619    #[must_use]
620    pub fn BTTC() -> Self {
621        *BTTC_LOCK.get_or_init(|| Self {
622            code: Ustr::from("BTTC"),
623            precision: 8,
624            iso4217: 0,
625            name: Ustr::from("BitTorrent"),
626            currency_type: CurrencyType::Crypto,
627        })
628    }
629
630    #[allow(non_snake_case)]
631    #[must_use]
632    pub fn BNB() -> Self {
633        *BNB_LOCK.get_or_init(|| Self {
634            code: Ustr::from("BNB"),
635            precision: 8,
636            iso4217: 0,
637            name: Ustr::from("Binance Coin"),
638            currency_type: CurrencyType::Crypto,
639        })
640    }
641
642    #[allow(non_snake_case)]
643    #[must_use]
644    pub fn BRZ() -> Self {
645        *BRZ_LOCK.get_or_init(|| Self {
646            code: Ustr::from("BRZ"),
647            precision: 6,
648            iso4217: 0,
649            name: Ustr::from("Brazilian Digital Token"),
650            currency_type: CurrencyType::Crypto,
651        })
652    }
653
654    #[allow(non_snake_case)]
655    #[must_use]
656    pub fn BSV() -> Self {
657        *BSV_LOCK.get_or_init(|| Self {
658            code: Ustr::from("BSV"),
659            precision: 8,
660            iso4217: 0,
661            name: Ustr::from("Bitcoin SV"),
662            currency_type: CurrencyType::Crypto,
663        })
664    }
665
666    #[allow(non_snake_case)]
667    #[must_use]
668    pub fn BUSD() -> Self {
669        *BUSD_LOCK.get_or_init(|| Self {
670            code: Ustr::from("BUSD"),
671            precision: 8,
672            iso4217: 0,
673            name: Ustr::from("Binance USD"),
674            currency_type: CurrencyType::Crypto,
675        })
676    }
677
678    #[allow(non_snake_case)]
679    #[must_use]
680    pub fn CAKE() -> Self {
681        *CAKE_LOCK.get_or_init(|| Self {
682            code: Ustr::from("CAKE"),
683            precision: 8,
684            iso4217: 0,
685            name: Ustr::from("PancakeSwap"),
686            currency_type: CurrencyType::Crypto,
687        })
688    }
689
690    #[allow(non_snake_case)]
691    #[must_use]
692    pub fn CRV() -> Self {
693        *CRV_LOCK.get_or_init(|| Self {
694            code: Ustr::from("CRV"),
695            precision: 8,
696            iso4217: 0,
697            name: Ustr::from("Curve DAO Token"),
698            currency_type: CurrencyType::Crypto,
699        })
700    }
701
702    #[allow(non_snake_case)]
703    #[must_use]
704    pub fn DASH() -> Self {
705        *DASH_LOCK.get_or_init(|| Self {
706            code: Ustr::from("DASH"),
707            precision: 8,
708            iso4217: 0,
709            name: Ustr::from("Dash"),
710            currency_type: CurrencyType::Crypto,
711        })
712    }
713
714    #[allow(non_snake_case)]
715    #[must_use]
716    pub fn DOT() -> Self {
717        *DOT_LOCK.get_or_init(|| Self {
718            code: Ustr::from("DOT"),
719            precision: 8,
720            iso4217: 0,
721            name: Ustr::from("Polkadot"),
722            currency_type: CurrencyType::Crypto,
723        })
724    }
725
726    #[allow(non_snake_case)]
727    #[must_use]
728    pub fn DOGE() -> Self {
729        *DOGE_LOCK.get_or_init(|| Self {
730            code: Ustr::from("DOGE"),
731            precision: 8,
732            iso4217: 0,
733            name: Ustr::from("Dogecoin"),
734            currency_type: CurrencyType::Crypto,
735        })
736    }
737
738    #[allow(non_snake_case)]
739    #[must_use]
740    pub fn ENA() -> Self {
741        *ENA_LOCK.get_or_init(|| Self {
742            code: Ustr::from("ENA"),
743            precision: 8,
744            iso4217: 0,
745            name: Ustr::from("Ethena"),
746            currency_type: CurrencyType::Crypto,
747        })
748    }
749
750    #[allow(non_snake_case)]
751    #[must_use]
752    pub fn EOS() -> Self {
753        *EOS_LOCK.get_or_init(|| Self {
754            code: Ustr::from("EOS"),
755            precision: 8,
756            iso4217: 0,
757            name: Ustr::from("EOS"),
758            currency_type: CurrencyType::Crypto,
759        })
760    }
761
762    #[allow(non_snake_case)]
763    #[must_use]
764    pub fn ETH() -> Self {
765        *ETH_LOCK.get_or_init(|| Self {
766            code: Ustr::from("ETH"),
767            precision: 8,
768            iso4217: 0,
769            name: Ustr::from("Ethereum"),
770            currency_type: CurrencyType::Crypto,
771        })
772    }
773
774    #[allow(non_snake_case)]
775    #[must_use]
776    pub fn ETHW() -> Self {
777        *ETHW_LOCK.get_or_init(|| Self {
778            code: Ustr::from("ETHW"),
779            precision: 8,
780            iso4217: 0,
781            name: Ustr::from("EthereumPoW"),
782            currency_type: CurrencyType::Crypto,
783        })
784    }
785
786    #[allow(non_snake_case)]
787    #[must_use]
788    pub fn FDUSD() -> Self {
789        *FDUSD_LOCK.get_or_init(|| Self {
790            code: Ustr::from("FDUSD"),
791            precision: 8,
792            iso4217: 0,
793            name: Ustr::from("First Digital USD"),
794            currency_type: CurrencyType::Crypto,
795        })
796    }
797
798    #[allow(non_snake_case)]
799    #[must_use]
800    pub fn HYPE() -> Self {
801        *HYPE_LOCK.get_or_init(|| Self {
802            code: Ustr::from("HYPE"),
803            precision: 8,
804            iso4217: 0,
805            name: Ustr::from("Hyperliquid"),
806            currency_type: CurrencyType::Crypto,
807        })
808    }
809
810    #[allow(non_snake_case)]
811    #[must_use]
812    pub fn JOE() -> Self {
813        *JOE_LOCK.get_or_init(|| Self {
814            code: Ustr::from("JOE"),
815            precision: 8,
816            iso4217: 0,
817            name: Ustr::from("JOE"),
818            currency_type: CurrencyType::Crypto,
819        })
820    }
821
822    #[allow(non_snake_case)]
823    #[must_use]
824    pub fn LINK() -> Self {
825        *LINK_LOCK.get_or_init(|| Self {
826            code: Ustr::from("LINK"),
827            precision: 8,
828            iso4217: 0,
829            name: Ustr::from("Chainlink"),
830            currency_type: CurrencyType::Crypto,
831        })
832    }
833
834    #[allow(non_snake_case)]
835    #[must_use]
836    pub fn LTC() -> Self {
837        *LTC_LOCK.get_or_init(|| Self {
838            code: Ustr::from("LTC"),
839            precision: 8,
840            iso4217: 0,
841            name: Ustr::from("Litecoin"),
842            currency_type: CurrencyType::Crypto,
843        })
844    }
845
846    #[allow(non_snake_case)]
847    #[must_use]
848    pub fn LUNA() -> Self {
849        *LUNA_LOCK.get_or_init(|| Self {
850            code: Ustr::from("LUNA"),
851            precision: 8,
852            iso4217: 0,
853            name: Ustr::from("Terra"),
854            currency_type: CurrencyType::Crypto,
855        })
856    }
857
858    #[allow(non_snake_case)]
859    #[must_use]
860    pub fn NBT() -> Self {
861        *NBT_LOCK.get_or_init(|| Self {
862            code: Ustr::from("NBT"),
863            precision: 8,
864            iso4217: 0,
865            name: Ustr::from("NanoByte Token"),
866            currency_type: CurrencyType::Crypto,
867        })
868    }
869
870    #[allow(non_snake_case)]
871    #[must_use]
872    pub fn PROVE() -> Self {
873        *PROVE_LOCK.get_or_init(|| Self {
874            code: Ustr::from("PROVE"),
875            precision: 8,
876            iso4217: 0,
877            name: Ustr::from("Prove AI"),
878            currency_type: CurrencyType::Crypto,
879        })
880    }
881
882    #[allow(non_snake_case)]
883    #[must_use]
884    pub fn SOL() -> Self {
885        *SOL_LOCK.get_or_init(|| Self {
886            code: Ustr::from("SOL"),
887            precision: 8,
888            iso4217: 0,
889            name: Ustr::from("Solana"),
890            currency_type: CurrencyType::Crypto,
891        })
892    }
893
894    #[allow(non_snake_case)]
895    #[must_use]
896    pub fn SHIB() -> Self {
897        *SHIB_LOCK.get_or_init(|| Self {
898            code: Ustr::from("SHIB"),
899            precision: 8,
900            iso4217: 0,
901            name: Ustr::from("Shiba Inu"),
902            currency_type: CurrencyType::Crypto,
903        })
904    }
905
906    #[allow(non_snake_case)]
907    #[must_use]
908    pub fn SUI() -> Self {
909        *SUI_LOCK.get_or_init(|| Self {
910            code: Ustr::from("SUI"),
911            precision: 8,
912            iso4217: 0,
913            name: Ustr::from("Sui"),
914            currency_type: CurrencyType::Crypto,
915        })
916    }
917
918    #[allow(non_snake_case)]
919    #[must_use]
920    pub fn TRX() -> Self {
921        *TRX_LOCK.get_or_init(|| Self {
922            code: Ustr::from("TRX"),
923            precision: 8,
924            iso4217: 0,
925            name: Ustr::from("TRON"),
926            currency_type: CurrencyType::Crypto,
927        })
928    }
929
930    #[allow(non_snake_case)]
931    #[must_use]
932    pub fn TRYB() -> Self {
933        *TRYB_LOCK.get_or_init(|| Self {
934            code: Ustr::from("TRYB"),
935            precision: 8,
936            iso4217: 0,
937            name: Ustr::from("BiLibra"),
938            currency_type: CurrencyType::Crypto,
939        })
940    }
941
942    #[allow(non_snake_case)]
943    #[must_use]
944    pub fn TUSD() -> Self {
945        *TUSD_LOCK.get_or_init(|| Self {
946            code: Ustr::from("TUSD"),
947            precision: 8,
948            iso4217: 0,
949            name: Ustr::from("TrueUSD"),
950            currency_type: CurrencyType::Crypto,
951        })
952    }
953
954    #[allow(non_snake_case)]
955    #[must_use]
956    pub fn UNI() -> Self {
957        *UNI_LOCK.get_or_init(|| Self {
958            code: Ustr::from("UNI"),
959            precision: 8,
960            iso4217: 0,
961            name: Ustr::from("Uniswap"),
962            currency_type: CurrencyType::Crypto,
963        })
964    }
965
966    #[allow(non_snake_case)]
967    #[must_use]
968    pub fn VTC() -> Self {
969        *VTC_LOCK.get_or_init(|| Self {
970            code: Ustr::from("VTC"),
971            precision: 8,
972            iso4217: 0,
973            name: Ustr::from("Vertcoin"),
974            currency_type: CurrencyType::Crypto,
975        })
976    }
977
978    #[allow(non_snake_case)]
979    #[must_use]
980    pub fn WSB() -> Self {
981        *WSB_LOCK.get_or_init(|| Self {
982            code: Ustr::from("WSB"),
983            precision: 8,
984            iso4217: 0,
985            name: Ustr::from("WallStreetBets DApp"),
986            currency_type: CurrencyType::Crypto,
987        })
988    }
989
990    #[allow(non_snake_case)]
991    #[must_use]
992    pub fn XBT() -> Self {
993        *XBT_LOCK.get_or_init(|| Self {
994            code: Ustr::from("XBT"),
995            precision: 8,
996            iso4217: 0,
997            name: Ustr::from("Bitcoin"),
998            currency_type: CurrencyType::Crypto,
999        })
1000    }
1001
1002    #[allow(non_snake_case)]
1003    #[must_use]
1004    pub fn XEC() -> Self {
1005        *XEC_LOCK.get_or_init(|| Self {
1006            code: Ustr::from("XEC"),
1007            precision: 8,
1008            iso4217: 0,
1009            name: Ustr::from("eCash"),
1010            currency_type: CurrencyType::Crypto,
1011        })
1012    }
1013
1014    #[allow(non_snake_case)]
1015    #[must_use]
1016    pub fn XLM() -> Self {
1017        *XLM_LOCK.get_or_init(|| Self {
1018            code: Ustr::from("XLM"),
1019            precision: 8,
1020            iso4217: 0,
1021            name: Ustr::from("Stellar Lumen"),
1022            currency_type: CurrencyType::Crypto,
1023        })
1024    }
1025
1026    #[allow(non_snake_case)]
1027    #[must_use]
1028    pub fn XMR() -> Self {
1029        *XMR_LOCK.get_or_init(|| Self {
1030            code: Ustr::from("XMR"),
1031            precision: 8,
1032            iso4217: 0,
1033            name: Ustr::from("Monero"),
1034            currency_type: CurrencyType::Crypto,
1035        })
1036    }
1037
1038    #[allow(non_snake_case)]
1039    #[must_use]
1040    pub fn USDT() -> Self {
1041        *USDT_LOCK.get_or_init(|| Self {
1042            code: Ustr::from("USDT"),
1043            precision: 8,
1044            iso4217: 0,
1045            name: Ustr::from("Tether"),
1046            currency_type: CurrencyType::Crypto,
1047        })
1048    }
1049
1050    #[allow(non_snake_case)]
1051    #[must_use]
1052    pub fn XRP() -> Self {
1053        *XRP_LOCK.get_or_init(|| Self {
1054            code: Ustr::from("XRP"),
1055            precision: 6,
1056            iso4217: 0,
1057            name: Ustr::from("XRP"),
1058            currency_type: CurrencyType::Crypto,
1059        })
1060    }
1061
1062    #[allow(non_snake_case)]
1063    #[must_use]
1064    pub fn XTZ() -> Self {
1065        *XTZ_LOCK.get_or_init(|| Self {
1066            code: Ustr::from("XTZ"),
1067            precision: 6,
1068            iso4217: 0,
1069            name: Ustr::from("Tezos"),
1070            currency_type: CurrencyType::Crypto,
1071        })
1072    }
1073
1074    #[must_use]
1075    #[allow(non_snake_case)]
1076    pub fn USDC() -> Self {
1077        *USDC_LOCK.get_or_init(|| Self {
1078            code: Ustr::from("USDC"),
1079            precision: 8,
1080            iso4217: 0,
1081            name: Ustr::from("USD Coin"),
1082            currency_type: CurrencyType::Crypto,
1083        })
1084    }
1085
1086    #[must_use]
1087    #[allow(non_snake_case)]
1088    pub fn USDC_POS() -> Self {
1089        *USDC_POS_LOCK.get_or_init(|| Self {
1090            code: Ustr::from("USDC.e"),
1091            precision: 6,
1092            iso4217: 0,
1093            name: Ustr::from("USD Coin (PoS)"),
1094            currency_type: CurrencyType::Crypto,
1095        })
1096    }
1097
1098    #[allow(non_snake_case)]
1099    #[must_use]
1100    pub fn USDP() -> Self {
1101        *USDP_LOCK.get_or_init(|| Self {
1102            code: Ustr::from("USDP"),
1103            precision: 4,
1104            iso4217: 0,
1105            name: Ustr::from("Pax Dollar"),
1106            currency_type: CurrencyType::Crypto,
1107        })
1108    }
1109
1110    #[allow(non_snake_case)]
1111    #[must_use]
1112    pub fn ZEC() -> Self {
1113        *ZEC_LOCK.get_or_init(|| Self {
1114            code: Ustr::from("ZEC"),
1115            precision: 8,
1116            iso4217: 0,
1117            name: Ustr::from("Zcash"),
1118            currency_type: CurrencyType::Crypto,
1119        })
1120    }
1121}
1122
1123/// A map of built-in `Currency` constants.
1124pub static CURRENCY_MAP: LazyLock<Mutex<HashMap<String, Currency>>> = LazyLock::new(|| {
1125    let mut map = HashMap::new();
1126    ///////////////////////////////////////////////////////////////////////////
1127    // Fiat currencies
1128    ///////////////////////////////////////////////////////////////////////////
1129    map.insert(Currency::AUD().code.to_string(), Currency::AUD());
1130    map.insert(Currency::BRL().code.to_string(), Currency::BRL());
1131    map.insert(Currency::CAD().code.to_string(), Currency::CAD());
1132    map.insert(Currency::CHF().code.to_string(), Currency::CHF());
1133    map.insert(Currency::CNY().code.to_string(), Currency::CNY());
1134    map.insert(Currency::CNH().code.to_string(), Currency::CNH());
1135    map.insert(Currency::CZK().code.to_string(), Currency::CZK());
1136    map.insert(Currency::DKK().code.to_string(), Currency::DKK());
1137    map.insert(Currency::EUR().code.to_string(), Currency::EUR());
1138    map.insert(Currency::GBP().code.to_string(), Currency::GBP());
1139    map.insert(Currency::HKD().code.to_string(), Currency::HKD());
1140    map.insert(Currency::HUF().code.to_string(), Currency::HUF());
1141    map.insert(Currency::ILS().code.to_string(), Currency::ILS());
1142    map.insert(Currency::INR().code.to_string(), Currency::INR());
1143    map.insert(Currency::JPY().code.to_string(), Currency::JPY());
1144    map.insert(Currency::KRW().code.to_string(), Currency::KRW());
1145    map.insert(Currency::MXN().code.to_string(), Currency::MXN());
1146    map.insert(Currency::NOK().code.to_string(), Currency::NOK());
1147    map.insert(Currency::NZD().code.to_string(), Currency::NZD());
1148    map.insert(Currency::PLN().code.to_string(), Currency::PLN());
1149    map.insert(Currency::RUB().code.to_string(), Currency::RUB());
1150    map.insert(Currency::SAR().code.to_string(), Currency::SAR());
1151    map.insert(Currency::SEK().code.to_string(), Currency::SEK());
1152    map.insert(Currency::SGD().code.to_string(), Currency::SGD());
1153    map.insert(Currency::THB().code.to_string(), Currency::THB());
1154    map.insert(Currency::TRY().code.to_string(), Currency::TRY());
1155    map.insert(Currency::USD().code.to_string(), Currency::USD());
1156    map.insert(Currency::XAG().code.to_string(), Currency::XAG());
1157    map.insert(Currency::XAU().code.to_string(), Currency::XAU());
1158    map.insert(Currency::XPT().code.to_string(), Currency::XPT());
1159    map.insert(Currency::ZAR().code.to_string(), Currency::ZAR());
1160    ///////////////////////////////////////////////////////////////////////////
1161    // Crypto currencies
1162    ///////////////////////////////////////////////////////////////////////////
1163    map.insert(Currency::AAVE().code.to_string(), Currency::AAVE());
1164    map.insert(Currency::ACA().code.to_string(), Currency::ACA());
1165    map.insert(Currency::ADA().code.to_string(), Currency::ADA());
1166    map.insert(Currency::ARB().code.to_string(), Currency::ARB());
1167    map.insert(Currency::AVAX().code.to_string(), Currency::AVAX());
1168    map.insert(Currency::BCH().code.to_string(), Currency::BCH());
1169    map.insert(Currency::BIO().code.to_string(), Currency::BIO());
1170    map.insert(Currency::BTC().code.to_string(), Currency::BTC());
1171    map.insert(Currency::BTTC().code.to_string(), Currency::BTTC());
1172    map.insert(Currency::BNB().code.to_string(), Currency::BNB());
1173    map.insert(Currency::BRZ().code.to_string(), Currency::BRZ());
1174    map.insert(Currency::BSV().code.to_string(), Currency::BSV());
1175    map.insert(Currency::BUSD().code.to_string(), Currency::BUSD());
1176    map.insert(Currency::CRV().code.to_string(), Currency::CRV());
1177    map.insert(Currency::DASH().code.to_string(), Currency::DASH());
1178    map.insert(Currency::DOGE().code.to_string(), Currency::DOGE());
1179    map.insert(Currency::DOT().code.to_string(), Currency::DOT());
1180    map.insert(Currency::ENA().code.to_string(), Currency::ENA());
1181    map.insert(Currency::EOS().code.to_string(), Currency::EOS());
1182    map.insert(Currency::ETH().code.to_string(), Currency::ETH());
1183    map.insert(Currency::ETHW().code.to_string(), Currency::ETHW());
1184    map.insert(Currency::FDUSD().code.to_string(), Currency::FDUSD());
1185    map.insert(Currency::HYPE().code.to_string(), Currency::HYPE());
1186    map.insert(Currency::JOE().code.to_string(), Currency::JOE());
1187    map.insert(Currency::LINK().code.to_string(), Currency::LINK());
1188    map.insert(Currency::LTC().code.to_string(), Currency::LTC());
1189    map.insert(Currency::LUNA().code.to_string(), Currency::LUNA());
1190    map.insert(Currency::NBT().code.to_string(), Currency::NBT());
1191    map.insert(Currency::PROVE().code.to_string(), Currency::PROVE());
1192    map.insert(Currency::SOL().code.to_string(), Currency::SOL());
1193    map.insert(Currency::SUI().code.to_string(), Currency::SUI());
1194    map.insert(Currency::TRX().code.to_string(), Currency::TRX());
1195    map.insert(Currency::TRYB().code.to_string(), Currency::TRYB());
1196    map.insert(Currency::TUSD().code.to_string(), Currency::TUSD());
1197    map.insert(Currency::UNI().code.to_string(), Currency::UNI());
1198    map.insert(Currency::VTC().code.to_string(), Currency::VTC());
1199    map.insert(Currency::WSB().code.to_string(), Currency::WSB());
1200    map.insert(Currency::XBT().code.to_string(), Currency::XBT());
1201    map.insert(Currency::XEC().code.to_string(), Currency::XEC());
1202    map.insert(Currency::XLM().code.to_string(), Currency::XLM());
1203    map.insert(Currency::XMR().code.to_string(), Currency::XMR());
1204    map.insert(Currency::XRP().code.to_string(), Currency::XRP());
1205    map.insert(Currency::XTZ().code.to_string(), Currency::XTZ());
1206    map.insert(Currency::USDC().code.to_string(), Currency::USDC());
1207    map.insert(Currency::USDC_POS().code.to_string(), Currency::USDC_POS());
1208    map.insert(Currency::USDP().code.to_string(), Currency::USDP());
1209    map.insert(Currency::USDT().code.to_string(), Currency::USDT());
1210    map.insert(Currency::ZEC().code.to_string(), Currency::ZEC());
1211    Mutex::new(map)
1212});