bitoku_sdk_agent/
lib.rs

1use anchor_lang::prelude::*;
2pub mod consts;
3pub mod error;
4pub mod helper;
5use consts::*;
6use error::*;
7use helper::*;
8
9type NAME = [u8; MAX_SIZE as usize];
10
11declare_id!("EVRv1mgZt3E21dCMJfXDSh5qXAwwfuJAfVy3YXxfj3xx");
12
13#[program]
14pub mod bitoku_sdk_agent {
15
16    use super::*;
17
18    pub fn init_bitoku(_ctx: Context<InitBitoku>) -> Result<()> {
19        Ok(())
20    }
21
22    pub fn register_client(ctx: Context<RegisterClient>) -> Result<u8> {
23        let mut bookkeeper = ctx.accounts.bookkeeper.load_mut()?;
24        let mut request = ctx.accounts.request.load_init()?;
25        let my_id = bookkeeper.next_id;
26        addel(&mut bookkeeper.status, my_id);
27
28        request.client_id = my_id;
29        if bookkeeper.next_id == 255 {
30            return err!(BitokuAgentError::NoAvailableClients);
31        }
32        bookkeeper.next_id += 1;
33        Ok(my_id)
34    }
35
36    pub fn remove_client(ctx: Context<DeleteClient>, client_id: u8) -> Result<()> {
37        let mut bookkeeper = ctx.accounts.bookkeeper.load_mut()?;
38
39        let bool = isel(bookkeeper.status, client_id);
40        if !bool {
41            return err!(BitokuAgentError::UnregisteredClient);
42        }
43
44        delel(&mut bookkeeper.status, client_id);
45
46        Ok(())
47    }
48
49    pub fn send_request(ctx: Context<SendRequest>, request: Request) -> Result<()> {
50        let s = request.name();
51
52        let name = String::from_utf8(s.to_vec()).unwrap();
53        if validate_name(&name.as_bytes()) == false {
54            return err!(BitokuAgentError::InvalidName);
55        }
56        let req = &mut ctx.accounts.request.load_mut()?;
57        req.requester = ctx.accounts.fee_payer.to_account_info().key();
58        req.request = request;
59        Ok(())
60    }
61}
62
63#[derive(Accounts)]
64pub struct InitBitoku<'info> {
65    #[account(mut)]
66    pub fee_payer: Signer<'info>,
67
68    #[account(init, payer= fee_payer, space=41,seeds= ["book_keeper".as_ref()], bump)]
69    pub bookkeeper: AccountLoader<'info, BookKeeper>,
70
71    pub system_program: Program<'info, System>,
72}
73
74#[derive(Accounts)]
75pub struct RegisterClient<'info> {
76    #[account(mut)]
77    pub fee_payer: Signer<'info>,
78
79    #[account(mut,seeds= ["book_keeper".as_ref()], bump)]
80    pub bookkeeper: AccountLoader<'info, BookKeeper>,
81
82    #[account(
83        init,
84        payer = fee_payer,
85        space = 8+1+32+(1+128+1),
86        seeds= ["request".as_ref(),fee_payer.key().as_ref()],
87        bump
88    )]
89    pub request: AccountLoader<'info, RequestData>,
90
91    pub system_program: Program<'info, System>,
92}
93
94#[derive(Accounts)]
95pub struct DeleteClient<'info> {
96    #[account(mut)]
97    pub fee_payer: Signer<'info>,
98
99    #[account(mut,seeds= ["book_keeper".as_ref()], bump)]
100    pub bookkeeper: AccountLoader<'info, BookKeeper>,
101
102    #[account(
103        mut,
104        close = fee_payer,
105        seeds= ["request".as_ref(),fee_payer.key().as_ref()],
106        bump
107    )]
108    pub request: AccountLoader<'info, RequestData>,
109
110    pub system_program: Program<'info, System>,
111}
112
113#[derive(Accounts)]
114pub struct SendRequest<'info> {
115    #[account(mut)]
116    pub fee_payer: Signer<'info>,
117
118    #[account(mut,seeds= ["book_keeper".as_ref()], bump)]
119    pub bookkeeper: AccountLoader<'info, BookKeeper>,
120
121    #[account(
122        mut,
123        seeds= ["request".as_ref(),fee_payer.key().as_ref()],
124        bump
125    )]
126    pub request: AccountLoader<'info, RequestData>,
127
128    pub system_program: Program<'info, System>,
129}
130
131#[account(zero_copy)]
132pub struct BookKeeper {
133    // status: [u8; ((ClientId::MAX as u64 + 1) >> 3) as usize],
134    status: [u8; 32],
135    next_id: u8,
136}
137
138// Information about particular requests such as id,its client, requester,and request enum
139// for details about the request
140#[account(zero_copy)]
141pub struct RequestData {
142    client_id: u8,
143    requester: Pubkey,
144    request: Request,
145}
146
147#[derive(AnchorSerialize, AnchorDeserialize, Copy, Clone)]
148pub enum Request {
149    CreateBucket { name: [u8; 128] },
150    CreateFile { name: [u8; 128] },
151    WriteFile { name: [u8; 128], file_id: u8 },
152    CloseFile { name: [u8; 128], file_id: u8 },
153    DeleteFile { name: [u8; 128], file_id: u8 },
154    SetPosition { name: [u8; 128], file_id: u8 },
155    OpenFile { name: [u8; 128], file_id: u8 },
156    ReadFile { name: [u8; 128], file_id: u8 },
157}
158
159impl Request {
160    fn name(&self) -> NAME {
161        match self {
162            Request::CreateBucket { name } => *name,
163            Request::CreateFile { name } => *name,
164            Request::WriteFile { name, .. } => *name,
165            Request::DeleteFile { name, .. } => *name,
166            Request::CloseFile { name, .. } => *name,
167            Request::SetPosition { name, .. } => *name,
168            Request::OpenFile { name, .. } => *name,
169            Request::ReadFile { name, .. } => *name,
170        }
171    }
172}