2

I have somewhat what seems to be a fairly simple question.

Lets assume we are building a Todo list where everything is public. And lets say a user will be able to create a new Task and that task will have subtasks.

So, For the tasks I can create an account to store all the tasks with the follwing seeds.

pub struct Task {
  pub id: u64;
  pub count: u32; // This is important to keep track of the count of sub tasks on a task
}

This will allow me to create a task account with seed [TASK, task.id, &[bump]] where TASK is const TASK = b"task". And

pub struct SubTask {
  pub task_id: u64;
  pub id: u64;
}

Gives me subtask with seeds [SUBTASK, task.id, sub_task.id, &[bump]]. So this allows me to fetch, all the tasks and the subtasks related to a specific task.

But I was curious, how would I improve this so that I can also fetch all the tasks/sub tasks related to a user irrelevant of market. i.e. give me all the sub tasks an account with pubkey has created.

Thank you.

1 Answer 1

3

You could achieve this by including the user's public key in the PDA.

First include user information in the data structures:

pub struct Task {
    pub creator: Pubkey,
    pub id: u64,
    pub count: u32,
}

pub struct SubTask {
    pub creator: Pubkey,
    pub task_id: u64,
    pub id: u64,
}

Now update the seeds to include the users public key, which ensures that all tasks and subtasks created by a user can be directly associated with them.

In your case, for task the seeds would be:

[b"task", creator.key().as_ref(), &task_id.to_le_bytes(), &[bump]]

& for the subtask it would be:

[b"subtask", creator.key().as_ref(), &task_id.to_le_bytes(), &subtask_id.to_le_bytes(), &[bump]]

Then you can just create an instruction to filter accounts based on the owner. This would look something like:

pub fn get_user_tasks(ctx: Context<GetUserTasks>, user: Pubkey) -> ProgramResult {
    let tasks: Vec<Task> = ctx.accounts
        .task
        .iter()
        .filter(|task| task.creator == user)
        .collect();
    
    // Similarly for SubTasks
    let sub_tasks: Vec<SubTask> = ctx.accounts
        .sub_task
        .iter()
        .filter(|sub_task| sub_task.creator == user)
        .collect();

    // Logic to handle this data or return it
    Ok(())
}
1
  • This is an excellent answer, thank you @brimigs
    – kekti
    Commented Apr 30 at 4:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.