1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//!
//! # INTERLOCK NETWORK - GENERIC PORT/SOCKET APPLICATION TEMPLATE CONTRACT
//!
//!
//! #### To ensure build with cargo-contract version 2.0.0, run:
//!
//! -     cargo install cargo-contract --force --version 2.0.0
//!
//! #### To build, run:
//!
//! -     cargo +nightly contract build
//!
//! #### To build docs, run:
//!
//! -     cargo +nightly doc --no-deps --document-private-items --open
//!
//! #### To reroute docs in Github, run:
//!
//! -     echo "<meta http-equiv=\"refresh\" content=\"0; url=application\">" >
//! -     target/doc/index.html;
//! -     cp -r target/doc ./docs
//!

#![doc(
    html_logo_url = "https://assets-global.website-files.com/64d9930f57641d176ab09b78/64dde3b1459a01ddf7b4a529_interlock-logo-large.webp",
    html_favicon_url = "https://assets-global.website-files.com/64d9930f57641d176ab09b78/64da50c8875e833f16060147_Favicon.png",
)]

#![cfg_attr(not(feature = "std"), no_std)]

#[ink::contract]
pub mod application {

    use ilockmvp::ILOCKmvpRef;
    use ilockmvp::ilockmvp::OtherError;
    use ink::prelude::vec::Vec;

    // this is the number designating application type's
    // port (the contract hash, owner, cap, tax, paid, collected, etc)
    pub const PORT: u16 = 0;

    #[ink(storage)]
    pub struct Application {

        token_instance: ILOCKmvpRef,
        operator: AccountId,
    }

    impl Application {

        /// - Create new staking application contract linked to token contract.
        #[ink(constructor)]
        pub fn new_application(
            token_address: AccountId,
        ) -> Self {
            
            // create a reference to the deployed token contract
            let token_instance: ILOCKmvpRef = ink::env::call::FromAccountId::from_account_id(token_address);
            let operator: AccountId = Self::env().caller();

            Self { token_instance, operator }
        }

        /// - Register this application contract with the ILOCK PSP22 token contract.
        /// - Only operator may call.
        #[ink(message)]
        pub fn create_socket(
            &mut self
        ) -> Result<(), OtherError> {

            // make sure caller is operator
            if self.env().caller() != self.operator {

                return Err(OtherError::CallerNotOperator);
            }

            self.token_instance.create_socket(self.env().caller(), PORT)
        }

        /// - Make call to registed ILOCK PSP22 token contract socket.
        /// - Only operator may call.
        #[ink(message)]
        pub fn call_socket(
            &mut self,
            address: AccountId,
            amount: Balance,
            data: Vec<u8>,                  // <--! data vector to pass custom information to token
            ) -> Result<(), OtherError> {   //      contract logic

            // make sure caller is operator
            if self.env().caller() != self.operator {

                return Err(OtherError::CallerNotOperator);
            }

            // < do stuff here, then reward user >

            self.token_instance.call_socket(address, amount, data)
        }

        /// - Change application operator.
        /// - Only operator may call.
        #[ink(message)]
        pub fn change_operator(
            &mut self,
            newoperator: AccountId,
        ) -> Result<(), OtherError> {

            // make sure caller is operator
            if self.env().caller() != self.operator {

                return Err(OtherError::CallerNotOperator);
            }

            self.operator = newoperator;

            Ok(())
        }
    }
}