@@ -74,26 +74,31 @@ pub struct Initialize<'info> {
7474
7575#[ inline( always) ]
7676pub fn handle_initialize (
77- accounts : & Initialize , name : & [ u8 ] ,
77+ accounts : & Initialize ,
78+ name : & [ u8 ] ,
7879 symbol : & [ u8 ] ,
7980 uri : & [ u8 ] ,
8081) -> Result < ( ) , ProgramError > {
81- // Calculate the total metadata size.
82- // MetadataPointer (64 bytes) + TLV overhead + actual metadata
83- // Metadata format: 4 (TLV header) + 32 (update_auth) + 32 (mint)
84- // + 4 + name.len + 4 + symbol.len + 4 + uri.len + 4 + 0 (additional metadata)
82+ // Create account with only base + MetadataPointer TLV space initially.
83+ // TokenMetadataInitialize reallocates the account internally when called.
84+ // 165 (base) + 1 (AccountType) + 68 (MetadataPointer TLV: 2+2+64) = 234 bytes
85+ let mint_size_base: usize = 234 ;
86+
87+ // Compute full rent to over-fund the account so the token-2022 realloc
88+ // during TokenMetadataInitialize has sufficient lamports.
89+ // TokenMetadata TLV: 2 (type) + 2 (length) + data
90+ // data: update_auth(32) + mint(32) + name(4+len) + symbol(4+len) + uri(4+len) + additional(4)
8591 let metadata_data_len = 32 + 32 + 4 + name. len ( ) + 4 + symbol. len ( ) + 4 + uri. len ( ) + 4 ;
86- let total_ext_data = 4 + metadata_data_len; // TLV: 2 type + 2 length + data
87- // 165 (base with padding) + 1 (AccountType) + 68 (MetadataPointer TLV) + metadata TLV
88- let mint_size = 165 + 1 + 68 + total_ext_data;
89- let lamports = Rent :: get ( ) ?. try_minimum_balance ( mint_size) ?;
92+ let mint_size_full = mint_size_base + 4 + metadata_data_len;
93+ let lamports = Rent :: get ( ) ?. try_minimum_balance ( mint_size_full) ?;
9094
91- accounts. system_program
95+ accounts
96+ . system_program
9297 . create_account (
9398 accounts. payer ,
9499 accounts. mint_account ,
95100 lamports,
96- mint_size as u64 ,
101+ mint_size_base as u64 ,
97102 accounts. token_program . to_account_view ( ) . address ( ) ,
98103 )
99104 . invoke ( ) ?;
@@ -118,9 +123,9 @@ pub fn handle_initialize(
118123 )
119124 . invoke ( ) ?;
120125
121- // InitializeMint2.
126+ // InitializeMint2: opcode 20
122127 let mut mint_data = [ 0u8 ; 67 ] ;
123- mint_data[ 0 ] = 20 ; // InitializeMint2
128+ mint_data[ 0 ] = 20 ;
124129 mint_data[ 1 ] = 2 ; // decimals
125130 mint_data[ 2 ..34 ] . copy_from_slice ( accounts. payer . to_account_view ( ) . address ( ) . as_ref ( ) ) ;
126131 mint_data[ 34 ] = 0 ; // no freeze authority
@@ -135,36 +140,31 @@ pub fn handle_initialize(
135140 )
136141 . invoke ( ) ?;
137142
138- // TokenMetadataInitialize: TokenInstruction::TokenMetadataExtension = 44
139- // Sub-instruction: Initialize = 0
140- // Layout: [44, 0, update_authority(32 ), mint(32),
141- // name_len(u32 LE ), name, symbol_len(u32 LE), symbol ,
142- // uri_len(u32 LE ), uri ]
143+ // TokenMetadataInitialize: TokenInstruction::TokenMetadataExtension = 44, sub = 0
144+ // Data: [44, 0, update_authority(32), mint(32),
145+ // name_len(u32 LE), name, symbol_len(u32 LE ), symbol, uri_len(u32 LE), uri]
146+ // Accounts: [metadata(=mint, writable ), update_authority(readonly) ,
147+ // mint(readonly ), mint_authority(signer) ]
143148 const MAX_META_IX : usize = 512 ;
144149 let mut buf = [ 0u8 ; MAX_META_IX ] ;
145150 let mut pos = 0usize ;
146151 buf[ pos] = 44 ;
147152 pos += 1 ;
148153 buf[ pos] = 0 ;
149154 pos += 1 ;
150- // update_authority
151155 buf[ pos..pos + 32 ] . copy_from_slice ( accounts. payer . to_account_view ( ) . address ( ) . as_ref ( ) ) ;
152156 pos += 32 ;
153- // mint
154157 buf[ pos..pos + 32 ]
155158 . copy_from_slice ( accounts. mint_account . to_account_view ( ) . address ( ) . as_ref ( ) ) ;
156159 pos += 32 ;
157- // name
158160 buf[ pos..pos + 4 ] . copy_from_slice ( & ( name. len ( ) as u32 ) . to_le_bytes ( ) ) ;
159161 pos += 4 ;
160162 buf[ pos..pos + name. len ( ) ] . copy_from_slice ( name) ;
161163 pos += name. len ( ) ;
162- // symbol
163164 buf[ pos..pos + 4 ] . copy_from_slice ( & ( symbol. len ( ) as u32 ) . to_le_bytes ( ) ) ;
164165 pos += 4 ;
165166 buf[ pos..pos + symbol. len ( ) ] . copy_from_slice ( symbol) ;
166167 pos += symbol. len ( ) ;
167- // uri
168168 buf[ pos..pos + 4 ] . copy_from_slice ( & ( uri. len ( ) as u32 ) . to_le_bytes ( ) ) ;
169169 pos += 4 ;
170170 buf[ pos..pos + uri. len ( ) ] . copy_from_slice ( uri) ;
@@ -173,19 +173,15 @@ pub fn handle_initialize(
173173 quasar_lang:: cpi:: BufCpiCall :: new (
174174 accounts. token_program . to_account_view ( ) . address ( ) ,
175175 [
176- InstructionAccount :: writable (
177- accounts. mint_account . to_account_view ( ) . address ( ) ,
178- ) ,
179- InstructionAccount :: readonly_signer (
180- accounts. payer . to_account_view ( ) . address ( ) ,
181- ) ,
182- InstructionAccount :: readonly_signer (
183- accounts. payer . to_account_view ( ) . address ( ) ,
184- ) ,
176+ InstructionAccount :: writable ( accounts. mint_account . to_account_view ( ) . address ( ) ) ,
177+ InstructionAccount :: readonly ( accounts. payer . to_account_view ( ) . address ( ) ) ,
178+ InstructionAccount :: readonly ( accounts. mint_account . to_account_view ( ) . address ( ) ) ,
179+ InstructionAccount :: readonly_signer ( accounts. payer . to_account_view ( ) . address ( ) ) ,
185180 ] ,
186181 [
187182 accounts. mint_account . to_account_view ( ) ,
188183 accounts. payer . to_account_view ( ) ,
184+ accounts. mint_account . to_account_view ( ) ,
189185 accounts. payer . to_account_view ( ) ,
190186 ] ,
191187 buf,
0 commit comments