1use crate::errors::ProfileMetadataError;
2use crate::events::{ProfileMetadataDeleted, ProfileMetadataNew, ProfileMetadataUpdated};
3use crate::state::{Profile, ProfileMetadata, User, MAX_LEN_URI};
4
5use anchor_lang::prelude::*;
6use std::convert::AsRef;
7
8use crate::constants::*;
9
10#[derive(Accounts)]
12#[instruction(metadata_uri: String)]
13pub struct CreateProfileMetadata<'info> {
14 #[account(
16 init,
17 seeds = [
18 PROFILE_METADATA_PREFIX_SEED.as_bytes(),
19 profile.to_account_info().key.as_ref(),
20 ],
21 bump,
22 payer = authority,
23 space = ProfileMetadata::LEN
24 )]
25 pub profile_metadata: Account<'info, ProfileMetadata>,
26 #[account(
27 seeds = [
28 PROFILE_PREFIX_SEED.as_bytes(),
29 profile.namespace.as_ref().as_bytes(),
30 user.to_account_info().key.as_ref(),
31 ],
32 bump,
33 has_one = user,
34 )]
35 pub profile: Account<'info, Profile>,
36 #[account(
37 seeds = [
38 USER_PREFIX_SEED.as_bytes(),
39 user.random_hash.as_ref(),
40 ],
41 bump,
42 has_one = authority,
43 )]
44 pub user: Account<'info, User>,
45 #[account(mut)]
46 pub authority: Signer<'info>,
47 pub system_program: Program<'info, System>,
49}
50
51pub fn create_profile_metadata_handler(
53 ctx: Context<CreateProfileMetadata>,
54 metadata_uri: String,
55) -> Result<()> {
56 require!(
58 metadata_uri.len() <= MAX_LEN_URI,
59 ProfileMetadataError::URITooLong
60 );
61
62 let profile_metadata = &mut ctx.accounts.profile_metadata;
63 profile_metadata.metadata_uri = metadata_uri;
64 profile_metadata.profile = *ctx.accounts.profile.to_account_info().key;
65 emit!(ProfileMetadataNew {
67 profile_metadata: *profile_metadata.to_account_info().key,
68 profile: *ctx.accounts.profile.to_account_info().key,
69 user: *ctx.accounts.user.to_account_info().key,
70 metadata_uri: profile_metadata.metadata_uri.clone(),
71 timestamp: Clock::get()?.unix_timestamp,
72 });
73 Ok(())
74}
75
76#[derive(Accounts)]
78#[instruction(metadata_uri: String)]
79pub struct UpdateProfileMetadata<'info> {
80 #[account(
82 mut,
83 seeds = [
84 PROFILE_METADATA_PREFIX_SEED.as_bytes(),
85 profile.to_account_info().key.as_ref(),
86 ],
87 bump,
88 has_one = profile,
89 )]
90 pub profile_metadata: Account<'info, ProfileMetadata>,
91 #[account(
92 seeds = [
93 PROFILE_PREFIX_SEED.as_bytes(),
94 profile.namespace.as_ref().as_bytes(),
95 user.to_account_info().key.as_ref(),
96 ],
97 bump,
98 has_one = user,
99 )]
100 pub profile: Account<'info, Profile>,
101 #[account(
102 seeds = [
103 USER_PREFIX_SEED.as_bytes(),
104 user.random_hash.as_ref(),
105 ],
106 bump,
107 has_one = authority,
108 )]
109 pub user: Account<'info, User>,
110 #[account(mut)]
111 pub authority: Signer<'info>,
112 pub system_program: Program<'info, System>,
113}
114
115pub fn update_profile_metadata_handler(
117 ctx: Context<UpdateProfileMetadata>,
118 metadata_uri: String,
119) -> Result<()> {
120 require!(
122 metadata_uri.len() <= MAX_LEN_URI,
123 ProfileMetadataError::URITooLong
124 );
125 let profile_metadata = &mut ctx.accounts.profile_metadata;
126 profile_metadata.metadata_uri = metadata_uri;
127 emit!(ProfileMetadataUpdated {
129 profile_metadata: *profile_metadata.to_account_info().key,
130 profile: *ctx.accounts.profile.to_account_info().key,
131 user: *ctx.accounts.user.to_account_info().key,
132 metadata_uri: profile_metadata.metadata_uri.clone(),
133 timestamp: Clock::get()?.unix_timestamp,
134 });
135 Ok(())
136}
137
138#[derive(Accounts)]
140pub struct DeleteProfileMetadata<'info> {
141 #[account(
143 mut,
144 seeds = [
145 PROFILE_METADATA_PREFIX_SEED.as_bytes(),
146 profile.to_account_info().key.as_ref(),
147 ],
148 bump,
149 has_one = profile,
150 close = authority,
151 )]
152 pub profile_metadata: Account<'info, ProfileMetadata>,
153 #[account(
154 seeds = [
155 PROFILE_PREFIX_SEED.as_bytes(),
156 profile.namespace.as_ref().as_bytes(),
157 user.to_account_info().key.as_ref(),
158 ],
159 bump,
160 has_one = user,
161 )]
162 pub profile: Account<'info, Profile>,
163 #[account(
164 seeds = [
165 USER_PREFIX_SEED.as_bytes(),
166 user.random_hash.as_ref(),
167 ],
168 bump,
169 has_one = authority,
170 )]
171 pub user: Account<'info, User>,
172 #[account(mut)]
173 pub authority: Signer<'info>,
174 pub system_program: Program<'info, System>,
175}
176
177pub fn delete_profile_metadata_handler(ctx: Context<DeleteProfileMetadata>) -> Result<()> {
179 emit!(ProfileMetadataDeleted {
181 profile_metadata: *ctx.accounts.profile_metadata.to_account_info().key,
182 profile: *ctx.accounts.profile.to_account_info().key,
183 user: *ctx.accounts.user.to_account_info().key,
184 timestamp: Clock::get()?.unix_timestamp,
185 });
186 Ok(())
187}