@@ -141,7 +141,7 @@ impl Extension for ConfidentialTransferAccount {
141
141
}
142
142
143
143
impl ConfidentialTransferAccount {
144
- /// Check if a `ConfidentialTransferAccount` has been approved for use
144
+ /// Check if a `ConfidentialTransferAccount` has been approved for use.
145
145
pub fn approved ( & self ) -> ProgramResult {
146
146
if bool:: from ( & self . approved ) {
147
147
Ok ( ( ) )
@@ -150,7 +150,7 @@ impl ConfidentialTransferAccount {
150
150
}
151
151
}
152
152
153
- /// Check if a `ConfidentialTransferAccount` is in a closable state
153
+ /// Check if a `ConfidentialTransferAccount` is in a closable state.
154
154
pub fn closable ( & self ) -> ProgramResult {
155
155
if self . pending_balance_lo == EncryptedBalance :: zeroed ( )
156
156
&& self . pending_balance_hi == EncryptedBalance :: zeroed ( )
@@ -164,12 +164,52 @@ impl ConfidentialTransferAccount {
164
164
}
165
165
166
166
/// Check if a base account of a `ConfidentialTransferAccount` accepts non-confidential
167
- /// transfers
167
+ /// transfers.
168
168
pub fn non_confidential_transfer_allowed ( & self ) -> ProgramResult {
169
169
if bool:: from ( & self . allow_non_confidential_credits ) {
170
170
Ok ( ( ) )
171
171
} else {
172
172
Err ( TokenError :: NonConfidentialTransfersDisabled . into ( ) )
173
173
}
174
174
}
175
+
176
+ /// Checks if a `ConfidentialTransferAccount` is configured to send funds.
177
+ pub fn valid_as_source ( & self ) -> ProgramResult {
178
+ self . approved ( )
179
+ }
180
+
181
+ /// Checks if a confidential extension is configured to receive funds.
182
+ ///
183
+ /// A destination account can receive funds if the following conditions are satisfied:
184
+ /// 1. The account is approved by the confidential transfer mint authority
185
+ /// 2. The account is not disabled by the account owner
186
+ /// 3. The number of credits into the account has reached the maximum credit counter
187
+ pub fn valid_as_destination ( & self ) -> ProgramResult {
188
+ self . approved ( ) ?;
189
+
190
+ if !bool:: from ( self . allow_confidential_credits ) {
191
+ return Err ( TokenError :: ConfidentialTransferDepositsAndTransfersDisabled . into ( ) ) ;
192
+ }
193
+
194
+ let new_destination_pending_balance_credit_counter =
195
+ u64:: from ( self . pending_balance_credit_counter )
196
+ . checked_add ( 1 )
197
+ . ok_or ( TokenError :: Overflow ) ?;
198
+ if new_destination_pending_balance_credit_counter
199
+ > u64:: from ( self . maximum_pending_balance_credit_counter )
200
+ {
201
+ return Err ( TokenError :: MaximumPendingBalanceCreditCounterExceeded . into ( ) ) ;
202
+ }
203
+
204
+ Ok ( ( ) )
205
+ }
206
+
207
+ /// Increments a confidential extension pending balance credit counter.
208
+ pub fn increment_pending_balance_credit_counter ( & mut self ) -> ProgramResult {
209
+ self . pending_balance_credit_counter = ( u64:: from ( self . pending_balance_credit_counter )
210
+ . checked_add ( 1 )
211
+ . ok_or ( TokenError :: Overflow ) ?)
212
+ . into ( ) ;
213
+ Ok ( ( ) )
214
+ }
175
215
}
0 commit comments