hpl_hive_control/
lib.rs

1pub mod assertions;
2pub mod constants;
3pub mod errors;
4mod gateway;
5pub mod instructions;
6pub mod state;
7
8use {
9    anchor_lang::prelude::*,
10    hpl_toolkit::utils::ShortVec,
11    instructions::*,
12    state::{
13        AssociatedProgram, BadgeCriteria, Global, Profile, ProfileDataConfig, Project,
14        SerializableActions, Service, User,
15    },
16};
17
18// For Solita
19pub use spl_account_compression::Node;
20
21declare_id!("HivezrprVqHR6APKKQkkLHmUG8waZorXexEBRZWh5LRm");
22
23#[program]
24pub mod hpl_hive_control {
25
26    use std::str::FromStr;
27
28    use errors::HplHiveControlError;
29    use hpl_toolkit::{
30        prelude::ControlledMerkleTrees,
31        schema::{SchemaContainer, ToSchema},
32    };
33
34    use super::*;
35
36    /// This function initializes the public information for the Honeycomb Protocol.
37    /// It is called when the program is deployed and can be accessed by only the program authority.
38    pub fn init_global(ctx: Context<InitGlobal>, args: InitGlobalArgs) -> Result<()> {
39        instructions::init_global(ctx, args)
40    }
41
42    /// This function sets the public information for the Honeycomb Protocol.
43    /// It is called when the program authority needs to update the public information.
44    pub fn set_global_config(
45        ctx: Context<SetGlobalConfig>,
46        args: SetGlobalConfigArgs,
47    ) -> Result<()> {
48        assertions::assert_program_authority(
49            ctx.accounts.program.to_account_info(),
50            ctx.accounts.program_data.to_account_info(),
51            ctx.accounts.authority.key,
52        )?;
53        instructions::set_global_config(ctx, args)
54    }
55
56    /// This function claims proceedings from Honeycomb Protocol.
57    /// It is called when the program authority needs to withdraw fees proceedings.
58    pub fn withdraw_proceedings(ctx: Context<WithdrawProceedings>, amount: u64) -> Result<()> {
59        assertions::assert_program_authority(
60            ctx.accounts.program.to_account_info(),
61            ctx.accounts.program_data.to_account_info(),
62            ctx.accounts.authority.key,
63        )?;
64        instructions::withdraw_proceedings(ctx, amount)
65    }
66
67    pub fn create_new_user_tree(ctx: Context<CreateNewUserTree>) -> Result<()> {
68        instructions::create_new_user_tree(ctx)
69    }
70
71    pub fn platform_gate(ctx: Context<PlatformGate>, args: PlatformGateArgs) -> Result<()> {
72        instructions::platform_gate(ctx, args)
73    }
74
75    /// This function creates a new project in the Honeycomb Protocol.
76    pub fn create_project(ctx: Context<CreateProject>, args: CreateProjectArgs) -> Result<()> {
77        instructions::platform_gate_fn(
78            SerializableActions::CreateProject,
79            None,
80            &ctx.accounts.project,
81            ctx.accounts.authority.key(),
82            &ctx.accounts.payer,
83            &ctx.accounts.vault,
84            &None,
85            &ctx.accounts.system_program,
86            &ctx.accounts.instructions_sysvar,
87            ID,
88            true,
89        )?;
90
91        instructions::create_project(ctx, args)
92    }
93
94    /// This function changes the driver authority for the specified project in the Honeycomb Protocol.
95    pub fn change_driver(mut ctx: Context<ChangeDriver>) -> Result<()> {
96        instructions::change_driver(&mut ctx)?;
97
98        instructions::platform_gate_fn(
99            SerializableActions::ManageProjectDriver,
100            None,
101            &ctx.accounts.project,
102            ctx.accounts.authority.key(),
103            &ctx.accounts.payer,
104            &ctx.accounts.vault,
105            &ctx.accounts.delegate_authority,
106            &ctx.accounts.system_program,
107            &ctx.accounts.instructions_sysvar,
108            ID,
109            true,
110        )
111    }
112
113    /// This function changes the driver authority for the specified project in the Honeycomb Protocol.
114    pub fn change_authority(mut ctx: Context<ChangeAuthority>) -> Result<()> {
115        instructions::change_authority(&mut ctx)?;
116        instructions::platform_gate_fn(
117            SerializableActions::ManageProjectDriver,
118            None,
119            &ctx.accounts.project,
120            ctx.accounts.authority.key(),
121            &ctx.accounts.payer,
122            &ctx.accounts.vault,
123            &ctx.accounts.delegate_authority,
124            &ctx.accounts.system_program,
125            &ctx.accounts.instructions_sysvar,
126            ID,
127            true,
128        )
129    }
130
131    /// This function changes the driver authority for the specified project in the Honeycomb Protocol.
132    pub fn add_remove_criteria(
133        mut ctx: Context<AddRemoveCriteria>,
134        args: AddRemoveCriteriaArgs,
135    ) -> Result<()> {
136        instructions::add_remove_criteria(&mut ctx, args)?;
137        instructions::platform_gate_fn(
138            SerializableActions::ManageCriterias,
139            None,
140            &ctx.accounts.project,
141            ctx.accounts.authority.key(),
142            &ctx.accounts.payer,
143            &ctx.accounts.vault,
144            &ctx.accounts.delegate_authority,
145            &ctx.accounts.system_program,
146            &ctx.accounts.instructions_sysvar,
147            ID,
148            true,
149        )
150    }
151
152    /// This function clears the profile data configuration for the specified project in the Honeycomb Protocol.
153    pub fn create_new_profiles_tree(
154        mut ctx: Context<CreateNewProfilesTree>,
155        args: CreateNewProfilesTreeArgs,
156    ) -> Result<()> {
157        instructions::create_new_profiles_tree(&mut ctx, args)?;
158        instructions::platform_gate_fn(
159            SerializableActions::PublicLow,
160            None,
161            &ctx.accounts.project,
162            ctx.accounts.authority.key(),
163            &ctx.accounts.payer,
164            &ctx.accounts.vault,
165            &ctx.accounts.delegate_authority,
166            &ctx.accounts.system_program,
167            &ctx.accounts.instructions_sysvar,
168            ID,
169            true,
170        )
171    }
172
173    /// This function adds multiple mint addresses to the specified address container in the Honeycomb Protocol.
174    pub fn create_delegate_authority(
175        mut ctx: Context<CreateDelegateAuthority>,
176        args: CreateDelegateAuthorityArgs,
177    ) -> Result<()> {
178        instructions::create_delegate_authority(&mut ctx, args)?;
179        instructions::platform_gate_fn(
180            SerializableActions::ManageDelegateAuthority,
181            None,
182            &ctx.accounts.project,
183            ctx.accounts.authority.key(),
184            &ctx.accounts.payer,
185            &ctx.accounts.vault,
186            &None,
187            &ctx.accounts.system_program,
188            &ctx.accounts.instructions_sysvar,
189            ID,
190            true,
191        )
192    }
193
194    /// This function adds or removes a delegation for the specified project in the Honeycomb Protocol.
195    pub fn add_remove_delegation(
196        mut ctx: Context<ModifyDelegate>,
197        args: AddRemoveDelegationArgs,
198    ) -> Result<()> {
199        instructions::add_remove_delegation(&mut ctx, args)?;
200        instructions::platform_gate_fn(
201            SerializableActions::ManageDelegateAuthority,
202            None,
203            &ctx.accounts.project,
204            ctx.accounts.authority.key(),
205            &ctx.accounts.payer,
206            &ctx.accounts.vault,
207            &None,
208            &ctx.accounts.system_program,
209            &ctx.accounts.instructions_sysvar,
210            ID,
211            true,
212        )
213    }
214
215    pub fn initialize_badge_criteria<'info>(
216        mut ctx: Context<'_, '_, '_, 'info, InitializeBadgeCriteria<'info>>,
217        args: InitializeBadgeCriteriaArgs,
218    ) -> Result<()> {
219        instructions::initialize_badge_criteria(&mut ctx, args)
220    }
221
222    pub fn claim_badge_criteria<'info>(
223        mut ctx: Context<'_, '_, '_, 'info, ClaimBadgeCriteria<'info>>,
224        args: ClaimBadgeCriteriaArgs,
225    ) -> Result<()> {
226        instructions::claim_badge_criteria(&mut ctx, args)
227    }
228
229    pub fn update_badge_criteria<'info>(
230        mut ctx: Context<'_, '_, '_, 'info, UpdateBadgeCriteria<'info>>,
231        args: UpdateBadgeCriteriaArgs,
232    ) -> Result<()> {
233        instructions::update_badge_criteria(&mut ctx, args)
234    }
235
236    /// This function registers a new user in the Honeycomb Protocol.
237    pub fn new_user(ctx: Context<NewUser>, args: NewUserArgs) -> Result<u64> {
238        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
239        instructions::new_user(ctx, args)
240    }
241
242    /// This function updates user info in the HPL Hive Control program.
243    pub fn update_user<'info>(
244        ctx: Context<'_, '_, '_, 'info, UpdateUser<'info>>,
245        args: UpdateUserArgs,
246    ) -> Result<()> {
247        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
248        instructions::update_user(ctx, args)
249    }
250
251    /// This function registers a new user in the Honeycomb Protocol.
252    pub fn new_profile(mut ctx: Context<NewProfile>, args: NewProfileArgs) -> Result<()> {
253        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
254        instructions::new_profile(&mut ctx, args)?;
255
256        instructions::platform_gate_fn(
257            SerializableActions::PublicLow,
258            None,
259            &ctx.accounts.project,
260            ctx.accounts.authority.key(),
261            &ctx.accounts.payer,
262            &ctx.accounts.vault,
263            &None,
264            &ctx.accounts.system_program,
265            &ctx.accounts.instructions_sysvar,
266            ID,
267            false,
268        )?;
269
270        if ctx.accounts.project.subsidize_fees {
271            instructions::refund(
272                0,
273                &ctx.accounts.project,
274                &ctx.accounts.payer,
275                &ctx.accounts.instructions_sysvar,
276            )?;
277        }
278
279        Ok(())
280    }
281
282    /// This function updates user info in the HPL Hive Control program.
283    pub fn update_profile<'info>(
284        mut ctx: Context<'_, '_, '_, 'info, UpdateProfile<'info>>,
285        args: UpdateProfileArgs,
286    ) -> Result<()> {
287        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
288        instructions::update_profile(&mut ctx, args)?;
289
290        instructions::platform_gate_fn(
291            SerializableActions::PublicHigh,
292            None,
293            &ctx.accounts.project,
294            ctx.accounts.authority.key(),
295            &ctx.accounts.payer,
296            &ctx.accounts.vault,
297            &None,
298            &ctx.accounts.system_program,
299            &ctx.accounts.instructions_sysvar,
300            ID,
301            false,
302        )?;
303
304        if ctx.accounts.project.subsidize_fees {
305            instructions::refund(
306                0,
307                &ctx.accounts.project,
308                &ctx.accounts.payer,
309                &ctx.accounts.instructions_sysvar,
310            )?;
311        }
312
313        Ok(())
314    }
315
316    /// This function updates profile's platform data info in the HPL Hive Control program.
317    pub fn update_platform_data<'info>(
318        mut ctx: Context<'_, '_, '_, 'info, UpdatePlatformData<'info>>,
319        args: UpdatePlatformDataArgs,
320    ) -> Result<()> {
321        instructions::update_platform_data(&mut ctx, args)?;
322
323        instructions::platform_gate_fn(
324            SerializableActions::PublicLow,
325            None,
326            &ctx.accounts.project,
327            ctx.accounts.authority.key(),
328            &ctx.accounts.payer,
329            &ctx.accounts.vault,
330            &ctx.accounts.delegate_authority,
331            &ctx.accounts.system_program,
332            &ctx.accounts.instructions_sysvar,
333            ID,
334            false,
335        )?;
336
337        if ctx.accounts.project.subsidize_fees {
338            instructions::refund(
339                0,
340                &ctx.accounts.project,
341                &ctx.accounts.payer,
342                &ctx.accounts.instructions_sysvar,
343            )?;
344        }
345
346        Ok(())
347    }
348
349    /// This function registers a new user in the Honeycomb Protocol.
350    pub fn new_user_with_profile(
351        mut ctx: Context<NewUserWithProfile>,
352        args: NewUserWithProfileArgs,
353    ) -> Result<()> {
354        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
355        instructions::new_user_with_profile(&mut ctx, args)?;
356
357        instructions::platform_gate_fn(
358            SerializableActions::PublicLow,
359            None,
360            &ctx.accounts.project,
361            ctx.accounts.authority.key(),
362            &ctx.accounts.payer,
363            &ctx.accounts.vault,
364            &None,
365            &ctx.accounts.system_program,
366            &ctx.accounts.instructions_sysvar,
367            ID,
368            false,
369        )?;
370
371        if ctx.accounts.project.subsidize_fees {
372            instructions::refund(
373                0,
374                &ctx.accounts.project,
375                &ctx.accounts.payer,
376                &ctx.accounts.instructions_sysvar,
377            )?;
378        }
379
380        Ok(())
381    }
382
383    pub fn verify_profile<'info>(
384        ctx: Context<'_, '_, '_, 'info, VerifyProfile<'info>>,
385        args: VerifyProfileArgs,
386    ) -> Result<()> {
387        instructions::verify_profile(ctx, args)
388    }
389
390    // Management Ixs
391
392    pub fn populate_user(ctx: Context<NewUser>, user: User) -> Result<u64> {
393        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
394        instructions::populate_user(ctx, user)
395    }
396
397    /// This function updates user info brutally in the HPL Hive Control program.
398    pub fn update_user_brutally<'info>(
399        ctx: Context<'_, '_, '_, 'info, UpdateUser<'info>>,
400        args: UpdateUserBrutallyArgs,
401    ) -> Result<()> {
402        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
403        instructions::update_user_brutally(ctx, args)
404    }
405
406    pub fn populate_profile(ctx: Context<NewProfile>, profile: Profile) -> Result<()> {
407        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
408        instructions::populate_profile(ctx, profile)
409    }
410
411    /// This function updates user info brutally in the HPL Hive Control program.
412    pub fn update_profile_brutally<'info>(
413        ctx: Context<'_, '_, '_, 'info, UpdateProfile<'info>>,
414        args: UpdateProfileBrutallyArgs,
415    ) -> Result<()> {
416        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
417        instructions::update_profile_brutally(ctx, args)
418    }
419
420    /// This function registers a new user in the Honeycomb Protocol.
421    pub fn populate_user_with_profile(
422        ctx: Context<NewUserWithProfile>,
423        args: PopulateUserWithProfileArgs,
424    ) -> Result<()> {
425        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
426        instructions::populate_user_with_profile(ctx, args)
427    }
428
429    pub fn delete_leaf<'info>(
430        ctx: Context<'_, '_, '_, 'info, DeleteLeaf<'info>>,
431        args: DeleteLeafArgs,
432    ) -> Result<()> {
433        // assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
434        instructions::delete_leaf(ctx, args)
435    }
436
437    pub fn close_user_tree<'info>(ctx: Context<CloseUserTree>) -> Result<()> {
438        // assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
439        instructions::close_user_tree(ctx)
440    }
441
442    pub fn close_profiles_tree<'info>(ctx: Context<CloseProfilesTree>) -> Result<()> {
443        // assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
444        instructions::close_profiles_tree(ctx)
445    }
446
447    pub fn migrate_project<'info>(
448        ctx: Context<MigrateProject>,
449        args: MigrateProjectArgs,
450    ) -> Result<()> {
451        assertions::assert_global_driver(&ctx.accounts.global, &ctx.accounts.authority)?;
452        let mut data = ctx.accounts.project.try_borrow_mut_data()?;
453
454        let project = Project {
455            bump: args.bump,
456            authority: args.authority,
457            key: args.key,
458            driver: args.driver,
459            name: args.name,
460            services: args.services.as_vec(),
461            associated_programs: args.associated_programs.as_vec(),
462            profile_data_config: args.profile_data_config,
463            profile_trees: ControlledMerkleTrees {
464                active: args.profile_trees_active,
465                merkle_trees: args.profile_trees_trees.as_vec(),
466                schema: SchemaContainer::new(Profile::schema()),
467            },
468            badge_criteria: args.badge_criteria.map(|x| x.as_vec()),
469            subsidize_fees: args.subsidize_fees,
470        };
471        project.serialize(&mut *data)?;
472        Ok(())
473    }
474
475    /// This function sets the public information for the Honeycomb Protocol.
476    /// It is called when the program authority needs to update the public information.
477    pub fn change_project_authority(ctx: Context<ChangeProjectAuthority>) -> Result<()> {
478        if !Pubkey::from_str("EgukF3ucRRiTzTLQm2Wv9NXJGAXghMaDU7H2dfTfBHom")
479            .unwrap()
480            .eq(ctx.accounts.authority.key)
481        {
482            return Err(HplHiveControlError::ConstAuthorityMismatch.into());
483        }
484        ctx.accounts.project.authority = *ctx.accounts.new_authority.key;
485        Ok(())
486    }
487
488    /// This function sets the public information for the Honeycomb Protocol.
489    /// It is called when the program authority needs to update the public information.
490    pub fn close_account(ctx: Context<CloseAccount>) -> Result<()> {
491        if !Pubkey::from_str("EgukF3ucRRiTzTLQm2Wv9NXJGAXghMaDU7H2dfTfBHom")
492            .unwrap()
493            .eq(ctx.accounts.authority.key)
494        {
495            return Err(HplHiveControlError::ConstAuthorityMismatch.into());
496        }
497
498        let lamports = ctx.accounts.account.lamports();
499        **ctx.accounts.account.lamports.borrow_mut() = 0;
500        **ctx.accounts.authority.lamports.borrow_mut() += lamports;
501
502        Ok(())
503    }
504}
505
506#[derive(Accounts)]
507pub struct MigrateProject<'info> {
508    pub global: Box<Account<'info, Global>>,
509
510    /// CHECK: safe
511    #[account(mut)]
512    pub project: AccountInfo<'info>,
513
514    pub authority: Signer<'info>,
515}
516
517#[derive(AnchorSerialize, AnchorDeserialize)]
518pub struct MigrateProjectArgs {
519    pub bump: u8,
520    pub authority: Pubkey,
521    pub key: Pubkey,
522    pub driver: Pubkey,
523    pub name: String,
524    pub services: ShortVec<Service>,
525    pub associated_programs: ShortVec<AssociatedProgram>,
526    pub profile_data_config: ProfileDataConfig,
527    pub profile_trees_active: u8,
528    pub profile_trees_trees: ShortVec<Pubkey>,
529    pub badge_criteria: Option<ShortVec<BadgeCriteria>>,
530    pub subsidize_fees: bool,
531}
532
533#[derive(Accounts)]
534pub struct ChangeProjectAuthority<'info> {
535    /// CHECK: safe
536    #[account(mut)]
537    pub project: Account<'info, Project>,
538
539    /// CHECK: safe
540    pub new_authority: AccountInfo<'info>,
541
542    pub authority: Signer<'info>,
543}
544
545#[derive(Accounts)]
546pub struct CloseAccount<'info> {
547    /// CHECK: safe
548    #[account(mut, owner = crate::id())]
549    pub account: AccountInfo<'info>,
550
551    pub authority: Signer<'info>,
552}