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}