psp22_full/
lib.rs

1//! Main module for the PSP22 token implementation.
2//!
3//! This module defines the main `Token` struct and re-exports key components from other modules.
4#![cfg_attr(not(feature = "std"), no_std, no_main)]
5
6
7
8pub mod data;
9pub mod errors;
10pub mod traits;
11
12pub use data::{PSP22Data, PSP22Event};
13pub use errors::PSP22Error;
14pub use traits::PSP22;
15
16/// PSP22 token implementation.
17///
18/// This struct represents a PSP22 compliant fungible token.
19#[cfg(feature = "contract")]
20#[ink::contract]
21pub mod token {
22    use ink::prelude::vec::Vec;
23
24    use crate::{PSP22, PSP22Data, PSP22Error, PSP22Event};
25
26    #[ink(storage)]
27    pub struct Token {
28        pub data: PSP22Data,
29    }
30
31    impl Token {
32        /// Creates a new PSP22 token with a specified initial supply.
33        ///
34        /// # Arguments
35        ///
36        /// * `supply` - The total number of tokens to be issued initially.
37        ///
38        /// # Returns
39        ///
40        /// A new instance of `Token`.
41        #[ink(constructor)]
42        pub fn new(
43            supply: u128,
44        ) -> Self {
45            Self {
46                data: PSP22Data::new(supply, Self::env().caller()),
47            }
48        }
49
50        /// Emits specified PSP22 events.
51        ///
52        /// # Arguments
53        ///
54        /// * `events` - A vector of `PSP22Event` to be emitted.
55        fn emit_events(&self, events: Vec<PSP22Event>) {
56            for event in events {
57                match event {
58                    PSP22Event::Transfer { from, to, value } => {
59                        self.env().emit_event(Transfer { from, to, value })
60                    }
61                    PSP22Event::Approval {
62                        owner,
63                        spender,
64                        amount,
65                    } => self.env().emit_event(Approval {
66                        owner,
67                        spender,
68                        amount,
69                    }),
70                }
71            }
72        }
73    }
74
75    #[ink(event)]
76    pub struct Approval {
77        #[ink(topic)]
78        owner: AccountId,
79        #[ink(topic)]
80        spender: AccountId,
81        amount: u128,
82    }
83
84    #[ink(event)]
85    pub struct Transfer {
86        #[ink(topic)]
87        from: Option<AccountId>,
88        #[ink(topic)]
89        to: Option<AccountId>,
90        value: u128,
91    }
92
93    impl PSP22 for Token {
94        /// Returns the total supply of tokens.
95        ///
96        /// # Returns
97        ///
98        /// The total number of tokens in existence.
99        #[ink(message)]
100        fn total_supply(&self) -> u128 {
101            self.data.total_supply()
102        }
103
104        /// Gets the balance of the specified address.
105        ///
106        /// # Arguments
107        ///
108        /// * `owner` - The address to query the balance of.
109        ///
110        /// # Returns
111        ///
112        /// Number of tokens owned by the given address.
113        #[ink(message)]
114        fn balance_of(&self, owner: AccountId) -> u128 {
115            self.data.balance_of(owner)
116        }
117
118        /// Gets the amount of tokens that an owner allowed to a spender.
119        ///
120        /// # Arguments
121        ///
122        /// * `owner` - The address which owns the funds.
123        /// * `spender` - The address which will spend the funds.
124        ///
125        /// # Returns
126        ///
127        /// The number of tokens still available for the spender.
128        #[ink(message)]
129        fn allowance(&self, owner: AccountId, spender: AccountId) -> u128 {
130            self.data.allowance(owner, spender)
131        }
132
133        /// Transfers tokens to a specified address.
134        ///
135        /// This method moves the `value` amount of tokens from the caller's account
136        /// to the `to` account.
137        ///
138        /// # Arguments
139        ///
140        /// * `to` - The address of the recipient.
141        /// * `value` - The amount of tokens to be transferred.
142        /// * `_data` - Additional data passed with the transfer.
143        ///
144        /// # Returns
145        ///
146        /// An `Ok(())` if the transfer is successful, otherwise a `PSP22Error`.
147        ///
148        /// # Events
149        ///
150        /// Emits a `Transfer` event on successful transfer.
151        #[ink(message)]
152        fn transfer(
153            &mut self,
154            to: AccountId,
155            value: u128,
156            _data: Vec<u8>,
157        ) -> Result<(), PSP22Error> {
158            let events = self.data.transfer(self.env().caller(), to, value)?;
159            self.emit_events(events);
160            Ok(())
161        }
162
163        /// Transfers tokens from one address to another.
164        ///
165        /// This method moves the `value` amount of tokens from the `from` account
166        /// to the `to` account using the allowance mechanism. The caller must
167        /// have an allowance from `from` for at least `value` tokens.
168        ///
169        /// # Arguments
170        ///
171        /// * `from` - The address of the sender.
172        /// * `to` - The address of the recipient.
173        /// * `value` - The amount of tokens to be transferred.
174        /// * `_data` - Additional data passed with the transfer.
175        ///
176        /// # Returns
177        ///
178        /// An `Ok(())` if the transfer is successful, otherwise a `PSP22Error`.
179        ///
180        /// # Events
181        ///
182        /// Emits a `Transfer` event and potentially an `Approval` event on successful transfer.
183        #[ink(message)]
184        fn transfer_from(
185            &mut self,
186            from: AccountId,
187            to: AccountId,
188            value: u128,
189            _data: Vec<u8>,
190        ) -> Result<(), PSP22Error> {
191            let events = self
192                .data
193                .transfer_from(self.env().caller(), from, to, value)?;
194            self.emit_events(events);
195            Ok(())
196        }
197
198        /// Approves the passed address to spend the specified amount of tokens on behalf of the caller.
199        ///
200        /// # Arguments
201        ///
202        /// * `spender` - The address which will spend the funds.
203        /// * `value` - The amount of tokens to be spent.
204        ///
205        /// # Returns
206        ///
207        /// An `Ok(())` if the approval is successful, otherwise a `PSP22Error`.
208        ///
209        /// # Events
210        ///
211        /// Emits an `Approval` event on successful approval.
212        #[ink(message)]
213        fn approve(&mut self, spender: AccountId, value: u128) -> Result<(), PSP22Error> {
214            let events = self.data.approve(self.env().caller(), spender, value)?;
215            self.emit_events(events);
216            Ok(())
217        }
218
219        /// Increases the allowance granted to a spender.
220        ///
221        /// This method adds the `delta_value` to the allowance the caller has granted
222        /// to the `spender`.
223        ///
224        /// # Arguments
225        ///
226        /// * `spender` - The address which will spend the funds.
227        /// * `delta_value` - The amount by which the allowance is to be increased.
228        ///
229        /// # Returns
230        ///
231        /// An `Ok(())` if the increase is successful, otherwise a `PSP22Error`.
232        ///
233        /// # Events
234        ///
235        /// Emits an `Approval` event with the new allowance amount.
236        #[ink(message)]
237        fn increase_allowance(
238            &mut self,
239            spender: AccountId,
240            delta_value: u128,
241        ) -> Result<(), PSP22Error> {
242            let events = self
243                .data
244                .increase_allowance(self.env().caller(), spender, delta_value)?;
245            self.emit_events(events);
246            Ok(())
247        }
248
249        /// Decreases the allowance granted to a spender.
250        ///
251        /// This method subtracts the `delta_value` from the allowance the caller has
252        /// granted to the `spender`.
253        ///
254        /// # Arguments
255        ///
256        /// * `spender` - The address which will spend the funds.
257        /// * `delta_value` - The amount by which the allowance is to be decreased.
258        ///
259        /// # Returns
260        ///
261        /// An `Ok(())` if the decrease is successful, otherwise a `PSP22Error`.
262        ///
263        /// # Events
264        ///
265        /// Emits an `Approval` event with the new allowance amount.
266        ///
267        /// # Errors
268        ///
269        /// Reverts with `InsufficientAllowance` if the `delta_value` exceeds the current allowance.
270        #[ink(message)]
271        fn decrease_allowance(
272            &mut self,
273            spender: AccountId,
274            delta_value: u128,
275        ) -> Result<(), PSP22Error> {
276            let events = self
277                .data
278                .decrease_allowance(self.env().caller(), spender, delta_value)?;
279            self.emit_events(events);
280            Ok(())
281        }
282    }
283}