create_address_info.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use account_data_api::prelude::*;
  2. use solana_program::msg;
  3. use steel::*;
  4. pub fn process_create_address_info(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
  5. msg!("Processing CreateAddressInfo instruction");
  6. let [signer_account, create_address_account, system_program_account] = accounts else {
  7. msg!("Error: Missing required accounts");
  8. return Err(ProgramError::NotEnoughAccountKeys);
  9. };
  10. let (_expected_address, bump) = account_pda();
  11. // Validate accounts
  12. if !signer_account.is_signer {
  13. msg!("Error: Signer account must sign the transaction");
  14. return Err(ProgramError::MissingRequiredSignature);
  15. }
  16. create_address_account
  17. .is_empty()
  18. .map_err(|_| {
  19. msg!("Error: Address account must be empty");
  20. ProgramError::AccountAlreadyInitialized
  21. })?
  22. .is_writable()
  23. .map_err(|_| {
  24. msg!("Error: Address account must be writable");
  25. ProgramError::InvalidAccountData
  26. })?
  27. .has_seeds(&[ADDRESS_INFO_SEED], bump, &account_data_api::ID)
  28. .map_err(|_| {
  29. msg!("Error: Invalid PDA seeds or bump");
  30. ProgramError::InvalidSeeds
  31. })?;
  32. system_program_account.is_program(&system_program::ID)?;
  33. let args = parse_instruction_data(data)?;
  34. msg!(
  35. "Instruction data parsed successfully: {{
  36. name: '{}',
  37. house_number: {},
  38. street: '{}',
  39. city: '{}'
  40. }}",
  41. bytes_to_string(&args.data.name),
  42. u64::from_le_bytes(args.data.house_number),
  43. bytes_to_string(&args.data.street),
  44. bytes_to_string(&args.data.city),
  45. );
  46. create_account::<AddressInfo>(
  47. create_address_account,
  48. &account_data_api::ID,
  49. &[ADDRESS_INFO_SEED, &[bump]],
  50. system_program_account,
  51. signer_account,
  52. )?;
  53. let address_info = create_address_account
  54. .to_account_mut::<AddressInfo>(&account_data_api::ID)
  55. .map_err(|_| {
  56. msg!("Error: Failed to deserialize address info account");
  57. ProgramError::InvalidAccountData
  58. })?;
  59. address_info.data = args.data;
  60. msg!(
  61. "Address info updated successfully: {{
  62. name: '{}',
  63. house_number: {},
  64. street: '{}',
  65. city: '{}'
  66. }}",
  67. bytes_to_string(&address_info.data.name),
  68. u64::from_le_bytes(address_info.data.house_number),
  69. bytes_to_string(&address_info.data.street),
  70. bytes_to_string(&address_info.data.city),
  71. );
  72. msg!("CreateAddressInfo instruction completed successfully");
  73. Ok(())
  74. }
  75. fn parse_instruction_data(data: &[u8]) -> Result<CreateAddressInfo, ProgramError> {
  76. CreateAddressInfo::try_from_bytes(data)
  77. .map(|info| info.to_owned())
  78. .map_err(|_| {
  79. msg!("Error: Failed to parse instruction data");
  80. ProgramError::InvalidInstructionData
  81. })
  82. }
  83. // Helper function to convert byte array to string
  84. fn bytes_to_string(bytes: &[u8]) -> String {
  85. String::from_utf8(
  86. bytes
  87. .iter()
  88. .take_while(|&&b| b != 0)
  89. .copied()
  90. .collect::<Vec<u8>>(),
  91. )
  92. .unwrap_or_default()
  93. }