near_self_update_proc/
lib.rs

1extern crate proc_macro;
2extern crate quote;
3extern crate syn;
4
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{parse_macro_input, DeriveInput};
8
9#[proc_macro_derive(SelfUpdate)]
10pub fn my_derive(input: TokenStream) -> TokenStream {
11    let input = parse_macro_input!(input as DeriveInput);
12    let name = input.ident;
13
14    let expanded = quote! {
15        #[near_bindgen]
16        impl #name {
17            #[payable]
18            pub fn update_contract(&mut self, code: Vec<u8>, callback: Option<String>) -> near_sdk::Promise {
19                self.assert_account_can_update();
20                near_sdk::assert_one_yocto();
21
22                let deploy = near_sdk::Promise::new(near_sdk::env::current_account_id()).deploy_contract(code);
23
24                let Some(callback) = callback else {
25                    return deploy.as_return();
26                };
27
28                deploy
29                    .function_call(callback,
30                                   vec![],
31                                   near_sdk::NearToken::from_yoctonear(0),
32                                   near_sdk::Gas::from_tgas(100),
33                )
34                .   as_return()
35            }
36
37            pub fn contract_version(&self) -> String {
38                const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
39                const VERSION: &str = env!("CARGO_PKG_VERSION");
40                format!("{PACKAGE_NAME}-{VERSION}")
41            }
42        }
43    };
44
45    TokenStream::from(expanded)
46}