1extern crate proc_macro;
39
40use proc_macro::TokenStream;
41use quote::quote;
42
43#[proc_macro]
44pub fn icrc3_state(_input: TokenStream) -> TokenStream {
45 let expanded = quote! {
46 use lazy_static::lazy_static;
47 use std::sync::{Arc, RwLock};
48 use icrc_ledger_types::icrc3::blocks::{GetBlocksResult, GetBlocksRequest, ICRC3DataCertificate, SupportedBlockType};
49 use icrc_ledger_types::icrc3::archive::ICRC3ArchiveInfo;
50 use icrc3::{config::{ICRC3Config, ICRC3Properties}, icrc3::ICRC3, interface::ICRC3Interface, types::Icrc3Error};
51
52 lazy_static! {
53 pub static ref ICRC3_INSTANCE: Arc<RwLock<Option<ICRC3>>> = Arc::new(RwLock::new(None));
54 }
55
56 const __ICRC3_NOT_INITIALIZED: &str = "ICRC3 state has not been initialized";
57
58 pub fn init_icrc3(config: ICRC3Config) {
59 let mut lock = ICRC3_INSTANCE.write().unwrap();
60 *lock = Some(ICRC3::new(config));
61 }
62
63 pub fn is_initialized() -> bool {
64 let lock = ICRC3_INSTANCE.read().unwrap();
65 lock.is_some()
66 }
67
68 pub fn take_icrc3() -> Option<ICRC3> {
69 let mut lock = ICRC3_INSTANCE.write().unwrap();
70 lock.take()
71 }
72
73 pub fn replace_icrc3(icrc3: ICRC3) {
74 let mut lock = ICRC3_INSTANCE.write().unwrap();
75 *lock = Some(icrc3);
76 }
77
78 pub async fn icrc3_add_transaction<T: TransactionType>(
79 transaction: T,
80 ) -> Result<u64, Icrc3Error> {
81 let mut lock = ICRC3_INSTANCE.write().unwrap();
82 let icrc3 = lock.as_mut().expect(__ICRC3_NOT_INITIALIZED);
83 <ICRC3 as ICRC3Interface<T>>::add_transaction(icrc3, transaction).await
84 }
85
86 pub fn icrc3_get_archives<T: TransactionType>() -> Vec<ICRC3ArchiveInfo> {
87 let lock = ICRC3_INSTANCE.read().unwrap();
88 let icrc3 = lock.as_ref().expect(__ICRC3_NOT_INITIALIZED);
89 <ICRC3 as ICRC3Interface<T>>::icrc3_get_archives(&icrc3)
90 }
91
92 pub async fn icrc3_get_blocks<T: TransactionType>(
93 args: Vec<GetBlocksRequest>,
94 ) -> GetBlocksResult {
95 let lock = ICRC3_INSTANCE.read().unwrap();
96 let icrc3 = lock.as_ref().expect(__ICRC3_NOT_INITIALIZED);
97 <ICRC3 as ICRC3Interface<T>>::icrc3_get_blocks(icrc3, args).await
98 }
99
100 pub fn icrc3_get_properties<T: TransactionType>() -> ICRC3Properties {
101 let lock = ICRC3_INSTANCE.read().unwrap();
102 let icrc3 = lock.as_ref().expect(__ICRC3_NOT_INITIALIZED);
103 <ICRC3 as ICRC3Interface<T>>::icrc3_get_properties(&icrc3)
104 }
105
106 pub fn icrc3_get_tip_certificate<T: TransactionType>() -> ICRC3DataCertificate {
107 let lock = ICRC3_INSTANCE.read().unwrap();
108 let icrc3 = lock.as_ref().expect(__ICRC3_NOT_INITIALIZED);
109 <ICRC3 as ICRC3Interface<T>>::icrc3_get_tip_certificate(icrc3)
110 }
111
112 pub fn icrc3_supported_block_types<T: TransactionType>() -> Vec<SupportedBlockType> {
113 let lock = ICRC3_INSTANCE.read().unwrap();
114 let icrc3 = lock.as_ref().expect(__ICRC3_NOT_INITIALIZED);
115 <ICRC3 as ICRC3Interface<T>>::icrc3_supported_block_types(icrc3)
116 }
117 };
118
119 expanded.into()
120}