streamflow_sdk/
lib.rs

1pub mod state;
2
3use anchor_lang::prelude::*;
4
5use anchor_spl::{
6    associated_token::AssociatedToken,
7    token::{Mint, Token, TokenAccount},
8};
9
10#[cfg(feature = "devnet")]
11declare_id!("HqDGZjaVRXJ9MGRQEw7qDc2rAr6iH1n1kAQdCZaCMfMZ");
12#[cfg(not(feature = "devnet"))]
13declare_id!("strmRqUCoQUgGUan5YhzUZa6KqdzwX5L6FpUxfmKg5m");
14
15/// Streamflow sdk module defining anchor account structs expected from the Streamflow protocol
16/// as well as anchor cpi module used for invoking Streamflow protocol
17///
18/// ## Usage
19///
20/// Declaring a dependency in program's Cargo.toml
21///
22/// ```toml
23/// streamflow_sdk = {version = "0.7", features = ["cpi"]}
24/// ```
25///
26/// To use protocol on devnet add sdk with `devnet` feature
27///
28/// ```toml
29/// streamflow_sdk = {version = "0.7", features = ["cpi", "devnet"]}
30/// ```
31///
32/// Example anchor program invoking streamflow create instruction
33///
34///
35/// ```rust
36/// use anchor_lang::prelude::*;
37/// use anchor_spl::{
38///     associated_token::AssociatedToken,
39///     token::{Mint, Token, TokenAccount},
40/// };
41///
42/// use streamflow_sdk;
43/// use streamflow_sdk::cpi::accounts::{
44///     Create as CpiCreate,
45///     CreateUnchecked as CpiCreateUnchecked,
46///     Update as CpiUpdate,
47///     Withdraw as CpiWithdraw,
48///     Topup as CpiTopup,
49///     Transfer as CpiTransfer,
50///     Cancel as CpiCancel,
51/// };
52///
53/// declare_id!("FGjLaVo5zLGdzCxMo9gu9tXr1kzTToKd8C8K7YS5hNM1");
54///
55/// #[program]
56/// pub mod example_program {
57///     use super::*;
58///
59///     //anchor rpc handlers
60///     pub fn create(
61///         ctx: Context<Create>,
62///         start_time: u64,
63///         net_amount_deposited: u64,
64///         period: u64,
65///         amount_per_period: u64,
66///         cliff: u64,
67///         cliff_amount: u64,
68///         cancelable_by_sender: bool,
69///         cancelable_by_recipient: bool,
70///         automatic_withdrawal: bool,
71///         transferable_by_sender: bool,
72///         transferable_by_recipient: bool,
73///         can_topup: bool,
74///         stream_name: [u8; 64],
75///         withdraw_frequency: u64,
76///         pausable: Option<bool>,
77///         can_update_rate: Option<bool>,
78///     ) -> Result<()> {
79///         msg!("Got create");
80///         // initializing accounts struct for cross-program invoke
81///         let accs = CpiCreate {
82///             sender: ctx.accounts.sender.to_account_info(),
83///             sender_tokens: ctx.accounts.sender_tokens.to_account_info(),
84///             recipient: ctx.accounts.recipient.to_account_info(),
85///             recipient_tokens: ctx.accounts.recipient_tokens.to_account_info(),
86///             metadata: ctx.accounts.metadata.to_account_info(),
87///             escrow_tokens: ctx.accounts.escrow_tokens.to_account_info(),
88///             streamflow_treasury: ctx.accounts.streamflow_treasury.to_account_info(),
89///             streamflow_treasury_tokens: ctx.accounts.streamflow_treasury_tokens.to_account_info(),
90///             withdrawor: ctx.accounts.withdrawor.to_account_info(),
91///             partner: ctx.accounts.partner.to_account_info(),
92///             partner_tokens: ctx.accounts.partner_tokens.to_account_info(),
93///             mint: ctx.accounts.mint.to_account_info(),
94///             fee_oracle: ctx.accounts.fee_oracle.to_account_info(),
95///             rent: ctx.accounts.rent.to_account_info(),
96///             timelock_program: ctx.accounts.streamflow_program.to_account_info(),
97///             token_program: ctx.accounts.token_program.to_account_info(),
98///             associated_token_program: ctx.accounts.associated_token_program.to_account_info(),
99///             system_program: ctx.accounts.system_program.to_account_info(),
100///         };
101///
102///         // initializing anchor CpiContext, can be used in native solana programs as well
103///         // additional reference: https://project-serum.github.io/anchor/tutorials/tutorial-3.html
104///         let cpi_ctx = CpiContext::new(ctx.accounts.streamflow_program.to_account_info(), accs);
105///
106///         // calling cpi method which calls solana_program invoke with serialized instruction data
107///         // fit for streamflow program
108///         streamflow_sdk::cpi::create(
109///             cpi_ctx,
110///             start_time,
111///             net_amount_deposited,
112///             period,
113///             amount_per_period,
114///             cliff,
115///             cliff_amount,
116///             cancelable_by_sender,
117///             cancelable_by_recipient,
118///             automatic_withdrawal,
119///             transferable_by_sender,
120///             transferable_by_recipient,
121///             can_topup,
122///             stream_name,
123///             withdraw_frequency,
124///             pausable,
125///             can_update_rate
126///         )
127///     }
128/// }
129///
130/// #[derive(Accounts)]
131/// pub struct Create<'info> {
132///     #[account(mut)]
133///     pub sender: Signer<'info>,
134///     #[account(
135///         associated_token::mint = mint,
136///         associated_token::authority = sender,
137///     )]
138///     pub sender_tokens: Box<Account<'info, TokenAccount>>,
139///     #[account(mut)]
140///     /// CHECK: Wallet address of the recipient.
141///     pub recipient: UncheckedAccount<'info>,
142///     #[account(
143///         init_if_needed,
144///         payer = sender,
145///         associated_token::mint = mint,
146///         associated_token::authority = recipient,
147///     )]
148///     pub recipient_tokens: Box<Account<'info, TokenAccount>>,
149///     #[account(mut)]
150///     pub metadata: Signer<'info>,
151///     #[account(
152///         mut,
153///         seeds = [b"strm", metadata.key().to_bytes().as_ref()],
154///         bump,
155///         seeds::program = streamflow_program
156///     )]
157///     /// CHECK: The escrow account holding the funds, expects empty (non-initialized) account.
158///     pub escrow_tokens: AccountInfo<'info>,
159///     #[account(mut)]
160///     /// CHECK: Streamflow treasury account.
161///     pub streamflow_treasury: UncheckedAccount<'info>,
162///     #[account(
163///         init_if_needed,
164///         payer = sender,
165///         associated_token::mint = mint,
166///         associated_token::authority = streamflow_treasury,
167///     )]
168///     /// CHECK: Associated token account address of `streamflow_treasury`.
169///     pub streamflow_treasury_tokens: Box<Account<'info, TokenAccount>>,
170///     #[account(mut)]
171///     /// CHECK: Delegate account for automatically withdrawing contracts.
172///     pub withdrawor: UncheckedAccount<'info>,
173///     #[account(mut)]
174///     /// CHECK: Partner treasury account.
175///     pub partner: UncheckedAccount<'info>,
176///     #[account(
177///         init_if_needed,
178///         payer = sender,
179///         associated_token::mint = mint,
180///         associated_token::authority = partner,
181///     )]
182///     pub partner_tokens: Box<Account<'info, TokenAccount>>,
183///     pub mint: Box<Account<'info, Mint>>,
184///     /// CHECK: Internal program that handles fees for specified partners.
185///     pub fee_oracle: UncheckedAccount<'info>,
186///     pub rent: Sysvar<'info, Rent>,
187///     /// CHECK: Streamflow protocol (alias timelock) program account.
188///     pub streamflow_program: UncheckedAccount<'info>,
189///     pub token_program: Program<'info, Token>,
190///     pub associated_token_program: Program<'info, AssociatedToken>,
191///     pub system_program: Program<'info, System>,
192/// }
193/// ```
194
195
196#[program]
197pub mod streamflow_sdk {
198    use super::*;
199
200    /// Create a Stream
201    ///
202    /// # Arguments
203    ///
204    /// * `ctx` - Accounts that will be used on Stream creation
205    /// * `start_time` - Unix Timestamp for Stream start, can be 0 to use current time
206    /// * `net_amount_deposited` - Amount of Tokens to deposit to the Stream
207    /// * `period` - Unlock Period in Seconds, tokens will be unlocked every `period` seconds
208    /// * `amount_per_period` - Unlock Amount, every `period` we unlock `amount_per_period` tokens
209    /// * `cliff` - Unix Timestamp of Cliff (first unlock), can be 0 to use current time or not use at all
210    /// * `cliff_amount` - Cliff Amount of tokens, can 0 to not use Cliff at all
211    /// * `cancelable_by_sender` - Whether Stream can by cancelled by Sender
212    /// * `cancelable_by_recipient` - Whether Stream can be cancelled by Recipient
213    /// * `automatic_withdrawal` - Whether automatic withdrawals are enabled
214    /// * `transferable_by_sender` - Whether Stream can be transferred by Sender
215    /// * `transferable_by_recipient` - Whether Stream can be transferred by Recipient
216    /// * `can_topup` - Whether Stream can be topped up (deposit additional tokens) by Sender
217    /// * `stream_name` - Name of the Stream
218    /// * `withdraw_frequency` - if `automatic_withdrawal` is on, every `withdraw_frequency` seconds **all unlocked** tokens will be sent to the recipient
219    /// * `pausable` - Whether Stream can be paused by Sender
220    /// * `can_update_rate` - Whether Sender can update `amount_per_period` value of the Stream via `update` method
221    #[allow(unused_variables)]
222    pub fn create(
223        ctx: Context<Create>,
224        start_time: u64,
225        net_amount_deposited: u64,
226        period: u64,
227        amount_per_period: u64,
228        cliff: u64,
229        cliff_amount: u64,
230        cancelable_by_sender: bool,
231        cancelable_by_recipient: bool,
232        automatic_withdrawal: bool,
233        transferable_by_sender: bool,
234        transferable_by_recipient: bool,
235        can_topup: bool,
236        stream_name: [u8; 64],
237        withdraw_frequency: u64,
238        pausable: Option<bool>,
239        can_update_rate: Option<bool>,
240    ) -> Result<()> {
241        Ok(())
242    }
243
244    /// Create a Stream and skip some optional checks
245    ///
246    /// This method creates a stream and omit some of address checks on creation.
247    /// It is not recommended to use this method unless you need create a Stream inside a contract and you don't have space for extra accounts.
248    ///
249    /// # Arguments
250    ///
251    /// * `ctx` - Accounts that will be used on Stream creation, `metadata` account shuold be initialized!
252    /// * `start_time` - Unix Timestamp for Stream start, can be 0 to use current time
253    /// * `net_amount_deposited` - Amount of Tokens to deposit to the Stream
254    /// * `period` - Unlock Period in Seconds, tokens will be unlocked every `period` seconds
255    /// * `amount_per_period` - Unlock Amount, every `period` we unlock `amount_per_period` tokens
256    /// * `cliff` - Unix Timestamp of Cliff (first unlock), can be 0 to use current time or not use at all
257    /// * `cliff_amount` - Cliff Amount of tokens, can 0 to not use Cliff at all
258    /// * `cancelable_by_sender` - Whether Stream can by cancelled by Sender
259    /// * `cancelable_by_recipient` - Whether Stream can be cancelled by Recipient
260    /// * `automatic_withdrawal` - Whether automatic withdrawals are enabled
261    /// * `transferable_by_sender` - Whether Stream can be transferred by Sender
262    /// * `transferable_by_recipient` - Whether Stream can be transferred by Recipient
263    /// * `can_topup` - Whether Stream can be topped up (deposit additional tokens) by Sender
264    /// * `stream_name` - Name of the Stream
265    /// * `withdraw_frequency` - if `automatic_withdrawal` is on, every `withdraw_frequency` seconds **all unlocked** tokens will be sent to the recipient
266    /// * `pausable` - Whether Stream can be paused by Sender
267    /// * `can_update_rate` - Whether Sender can update `amount_per_period` value of the Stream via `update` method
268
269    #[allow(unused_variables)]
270    pub fn create_unchecked(
271        ctx: Context<CreateUnchecked>,
272        start_time: u64,
273        net_amount_deposited: u64,
274        period: u64,
275        amount_per_period: u64,
276        cliff: u64,
277        cliff_amount: u64,
278        cancelable_by_sender: bool,
279        cancelable_by_recipient: bool,
280        automatic_withdrawal: bool,
281        transferable_by_sender: bool,
282        transferable_by_recipient: bool,
283        can_topup: bool,
284        stream_name: [u8; 64],
285        withdraw_frequency: u64,
286        recipient: Pubkey,
287        partner: Pubkey,
288        pausable: bool,
289        can_update_rate: bool,
290    ) -> Result<()> { Ok(()) }
291
292    /// Create a Stream and skip some optional checks
293    ///
294    /// This method creates a stream and omit some of address checks on creation.
295    /// Also on creation `payer` account will be used to initiliaze accounts and pay withdrawal fees.
296    /// It is not recommended to use this method unless you need create a Stream inside a contract and you don't have space for extra accounts
297    /// and `sender` can't pay for fees (for example, if `sender` is your contract).
298    ///
299    /// # Arguments
300    ///
301    /// * `ctx` - Accounts that will be used on Stream creation, `metadata` account shuold be initialized!
302    /// * `start_time` - Unix Timestamp for Stream start, can be 0 to use current time
303    /// * `net_amount_deposited` - Amount of Tokens to deposit to the Stream
304    /// * `period` - Unlock Period in Seconds, tokens will be unlocked every `period` seconds
305    /// * `amount_per_period` - Unlock Amount, every `period` we unlock `amount_per_period` tokens
306    /// * `cliff` - Unix Timestamp of Cliff (first unlock), can be 0 to use current time or not use at all
307    /// * `cliff_amount` - Cliff Amount of tokens, can 0 to not use Cliff at all
308    /// * `cancelable_by_sender` - Whether Stream can by cancelled by Sender
309    /// * `cancelable_by_recipient` - Whether Stream can be cancelled by Recipient
310    /// * `automatic_withdrawal` - Whether automatic withdrawals are enabled
311    /// * `transferable_by_sender` - Whether Stream can be transferred by Sender
312    /// * `transferable_by_recipient` - Whether Stream can be transferred by Recipient
313    /// * `can_topup` - Whether Stream can be topped up (deposit additional tokens) by Sender
314    /// * `stream_name` - Name of the Stream
315    /// * `withdraw_frequency` - if `automatic_withdrawal` is on, every `withdraw_frequency` seconds **all unlocked** tokens will be sent to the recipient
316    /// * `pausable` - Whether Stream can be paused by Sender
317    /// * `can_update_rate` - Whether Sender can update `amount_per_period` value of the Stream via `update` method
318    #[allow(unused_variables)]
319    pub fn create_unchecked_with_payer(
320        ctx: Context<CreateUncheckedWithPayer>,
321        start_time: u64,
322        net_amount_deposited: u64,
323        period: u64,
324        amount_per_period: u64,
325        cliff: u64,
326        cliff_amount: u64,
327        cancelable_by_sender: bool,
328        cancelable_by_recipient: bool,
329        automatic_withdrawal: bool,
330        transferable_by_sender: bool,
331        transferable_by_recipient: bool,
332        can_topup: bool,
333        stream_name: [u8; 64],
334        withdraw_frequency: u64,
335        recipient: Pubkey,
336        partner: Pubkey,
337        pausable: bool,
338        can_update_rate: bool,
339    ) -> Result<()> { Ok(()) }
340
341    /// Update a Stream
342    ///
343    /// This method enables automatic withdrawals and/or updates `amount_per_period` in a Stream
344    ///
345    /// # Arguments
346    /// * `ctx` - Accounts that will be used on Stream update
347    /// * `enable_automatic_withdrawal` - Whether to enable automatic withdrawals (can't be disabled)
348    /// * `withdraw_frequency` - Set withdrawal frequency, use it only if `enable_automatic_withdrawal` is set to Some(true)
349    /// * `amount_per_period` - Whether to update Unlock Amount of the Stream, `can_update_rate` should be enabled
350    #[allow(unused_variables)]
351    pub fn update(
352        ctx: Context<Update>,
353        enable_automatic_withdrawal: Option<bool>,
354        withdraw_frequency: Option<u64>,
355        amount_per_period: Option<u64>
356    ) -> Result<()> {
357        Ok(())
358    }
359
360    /// Withdraw tokens from a Stream
361    ///
362    /// This methods withdraws tokens from a Stream, requested amount of tokens will be sent to the Recipient
363    /// If `enable_automatic_withdrawal` is set to false only Recipient can request a Withdrawal
364    ///
365    /// # Arguments
366    /// * `ctx` - Accounts that will be used on Stream withdrawal
367    /// * `amount` - amount to withdraw, should <= unlocked amount. Use `u64::MAX` if you want to withdraw all unlocked amount
368    #[allow(unused_variables)]
369    pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
370        Ok(())
371    }
372
373    /// Cancel a Stream
374    ///
375    /// Cancels a stream, withdraws all unlocked amount to Recipient and returns all leftover tokens back to Sender
376    ///
377    /// # Arguments
378    /// * `ctx` - Accounts that will be used on Stream cancellation
379    #[allow(unused_variables)]
380    pub fn cancel(ctx: Context<Cancel>) -> Result<()> {
381        Ok(())
382    }
383
384    /// Pause a Stream
385    ///
386    /// This method pauses a Stream, meaning that no unlocks will be processed, only already unlocked amount can be withdrawn
387    ///
388    /// # Arguments
389    /// * `ctx` - Accounts that will be used on Stream pause
390    #[allow(unused_variables)]
391    pub fn pause(ctx: Context<Pause>) -> Result<()> {
392        Ok(())
393    }
394
395    /// Unpause a Stream
396    ///
397    /// This method unpauses a paused Stream
398    ///
399    /// # Arguments
400    /// * `ctx` - Accounts that will be used on Stream unpause
401    #[allow(unused_variables)]
402    pub fn unpause(ctx: Context<UnPause>) -> Result<()> {
403        Ok(())
404    }
405
406    /// Transfer a Stream
407    ///
408    /// This method transfer Stream to another Recipient, already unlocked amount **won't** be sent to the old Recipient
409    /// Because of that this method can be effectively used when if you chose wrong Recipient on Stream creation
410    ///
411    /// # Arguments
412    /// * `ctx` - Accounts that will be used on Stream transfer
413    #[allow(unused_variables)]
414    pub fn transfer_recipient(ctx: Context<Transfer>) -> Result<()> {
415        Ok(())
416    }
417
418    /// Topup a Stream
419    ///
420    /// This method tops up a Stream **if it's not closed**
421    ///
422    /// # Arguments
423    /// * `ctx` - Accounts that will be used on Stream unpause
424    /// * `amount` - Amount to Topup a Stream with
425    #[allow(unused_variables)]
426    pub fn topup(ctx: Context<Topup>, amount: u64) -> Result<()> {
427        Ok(())
428    }
429}
430
431/// Accounts expected in create instruction
432#[derive(Accounts)]
433pub struct Create<'info> {
434    /// Wallet of the contract creator.
435    #[account(mut)]
436    pub sender: Signer<'info>,
437    /// Associated token account address of `sender`.
438    #[account(mut)]
439    pub sender_tokens: AccountInfo<'info>,
440    /// Wallet address of the recipient.
441    #[account(mut)]
442    pub recipient: AccountInfo<'info>,
443    /// The account holding the contract parameters.
444    /// Expects empty (non-initialized) account that should also be a signer.
445    #[account(mut, signer)]
446    pub metadata: AccountInfo<'info>,
447    /// The escrow account holding the funds.
448    /// Should be a PDA, use `streamflow_sdk::state::find_escrow_account` to derive
449    /// Expects empty (non-initialized) account.
450    #[account(mut)]
451    pub escrow_tokens: AccountInfo<'info>,
452    /// Associated token account address of `recipient`.
453    #[account(mut)]
454    pub recipient_tokens: AccountInfo<'info>,
455    /// Streamflow treasury account.
456    /// Use constant `streamflow_sdk::state::STRM_TREASURY`
457    #[account(mut)]
458    pub streamflow_treasury: AccountInfo<'info>,
459    /// Associated token account address of `streamflow_treasury`.
460    #[account(mut)]
461    pub streamflow_treasury_tokens: AccountInfo<'info>,
462    /// Delegate account for automatically withdrawing contracts.
463    /// Use constant `streamflow_sdk::state::WITHDRAWOR_ADDRESS`
464    #[account(mut)]
465    pub withdrawor: AccountInfo<'info>,
466    /// Partner treasury account. If no partner fees are expected on behalf of the program
467    /// integrating with streamflow, `streamflow_treasury` can be passed in here.
468    #[account(mut)]
469    pub partner: AccountInfo<'info>,
470    /// Associated token account address of `partner`. If no partner fees are expected on behalf of the
471    /// program integrating with streamflow, `streamflow_treasury_tokens` can be passed in here.
472    #[account(mut)]
473    pub partner_tokens: AccountInfo<'info>,
474    /// The SPL token mint account.
475    pub mint: Account<'info, Mint>,
476    /// Internal program that handles fees for specified partners. If no partner fees are expected
477    /// on behalf of the program integrating with streamflow, `streamflow_treasury` can be passed
478    /// in here.
479    /// Use constant `streamflow_sdk::state::FEE_ORACLE_ADDRESS`
480    pub fee_oracle: AccountInfo<'info>,
481    /// The Rent Sysvar account.
482    pub rent: Sysvar<'info, Rent>,
483    /// Streamflow protocol (alias timelock) program account.
484    /// Use `streamflow_sdk:id()`
485    pub timelock_program: AccountInfo<'info>,
486    /// The SPL program needed in case an associated account
487    /// for the new recipient is being created.
488    pub token_program: Program<'info, Token>,
489    /// The Associated Token program needed in case associated
490    /// account for the new recipient is being created.
491    pub associated_token_program: Program<'info, AssociatedToken>,
492    /// The Solana system program needed for account creation.
493    pub system_program: Program<'info, System>,
494}
495
496/// Accounts expected in create_unchecked instruction
497#[derive(Accounts)]
498pub struct CreateUnchecked<'info> {
499    /// Wallet of the contract creator.
500    #[account(mut)]
501    pub sender: Signer<'info>,
502    /// Associated token account address of `sender` for `mint`.
503    #[account(mut)]
504    pub sender_tokens: AccountInfo<'info>,
505    /// The account holding the contract parameters.
506    /// Expects account initialized with `streamflow_sdk::state::METADATA_LEN` bytes length and assigned program ID.
507    #[account(mut)]
508    pub metadata: AccountInfo<'info>,
509    /// The escrow account holding the funds.
510    /// Should be a PDA, use `streamflow_sdk::state::find_escrow_account` to derive
511    /// Expects empty (non-initialized) account.
512    #[account(mut)]
513    pub escrow_tokens: AccountInfo<'info>,
514    /// Delegate account for automatically withdrawing contracts.
515    /// Use constant `streamflow_sdk::state::WITHDRAWOR_ADDRESS`
516    #[account(mut)]
517    pub withdrawor: AccountInfo<'info>,
518    /// The SPL token mint account.
519    pub mint: Account<'info, Mint>,
520    /// Internal program that handles fees for specified partners. If no partner fees are expected
521    /// on behalf of the program integrating with streamflow, `streamflow_treasury` can be passed
522    /// in here.
523    /// Use constant `streamflow_sdk::state::FEE_ORACLE_ADDRESS`
524    pub fee_oracle: AccountInfo<'info>,
525    /// The Rent Sysvar account.
526    pub rent: Sysvar<'info, Rent>,
527    /// Streamflow protocol (alias timelock) program account.
528    /// Use `streamflow_sdk:id()`
529    pub timelock_program: AccountInfo<'info>,
530    /// The SPL program account.
531    pub token_program: Program<'info, Token>,
532    /// The Solana system program needed for account creation.
533    pub system_program: Program<'info, System>,
534}
535
536/// Accounts expected in create_unchecked instruction
537#[derive(Accounts)]
538pub struct CreateUncheckedWithPayer<'info> {
539    /// Wallet of the payer account to pay for accounts creation
540    #[account(mut)]
541    pub payer: Signer<'info>,
542    /// Wallet of the contract creator.
543    #[account(mut)]
544    pub sender: Signer<'info>,
545    /// Associated token account address of `sender`.
546    #[account(mut)]
547    pub sender_tokens: AccountInfo<'info>,
548    /// The account holding the contract parameters.
549    /// Expects account initialized with 1104 bytes.
550    #[account(mut)]
551    pub metadata: AccountInfo<'info>,
552    /// The escrow account holding the funds.
553    /// Should be a PDA, use `streamflow_sdk::state::find_escrow_account` to derive
554    /// Expects empty (non-initialized) account.
555    #[account(mut)]
556    pub escrow_tokens: AccountInfo<'info>,
557    /// Delegate account for automatically withdrawing contracts.
558    /// Use constant `streamflow_sdk::state::WITHDRAWOR_ADDRESS`
559    #[account(mut)]
560    pub withdrawor: AccountInfo<'info>,
561    /// The SPL token mint account.
562    pub mint: Account<'info, Mint>,
563    /// Internal program that handles fees for specified partners. If no partner fees are expected
564    /// on behalf of the program integrating with streamflow, `streamflow_treasury` can be passed
565    /// in here.
566    /// Use constant `streamflow_sdk::state::FEE_ORACLE_ADDRESS`
567    pub fee_oracle: AccountInfo<'info>,
568    /// The Rent Sysvar account.
569    pub rent: Sysvar<'info, Rent>,
570    /// Streamflow protocol (alias timelock) program account.
571    /// Use `streamflow_sdk:id()`
572    pub timelock_program: AccountInfo<'info>,
573    /// The SPL program account.
574    pub token_program: Program<'info, Token>,
575    /// The Solana system program needed for account creation.
576    pub system_program: Program<'info, System>,
577}
578
579/// Accounts expected in update instruction
580#[derive(Accounts)]
581pub struct Update<'info> {
582    /// Wallet that initiates contract update.
583    #[account(mut)]
584    pub sender: Signer<'info>,
585    /// The account holding the contract parameters.
586    /// Expects initialized account.
587    #[account(mut)]
588    pub metadata: AccountInfo<'info>,
589    /// Delegate account for automatically withdrawing contracts.
590    /// Use constant `streamflow_sdk::state::WITHDRAWOR_ADDRESS`
591    #[account(mut)]
592    pub withdrawor: AccountInfo<'info>,
593    pub system_program: Program<'info, System>,
594}
595
596/// Accounts expected in pause instruction
597#[derive(Accounts)]
598pub struct Pause<'info> {
599    #[account()]
600    pub sender: Signer<'info>,
601    #[account(mut)]
602    pub metadata: AccountInfo<'info>,
603}
604
605/// Accounts expected in unpause instruction
606#[derive(Accounts)]
607pub struct UnPause<'info> {
608    #[account()]
609    pub sender: Signer<'info>,
610    #[account(mut)]
611    pub metadata: AccountInfo<'info>,
612}
613
614/// Accounts expected in withdraw instruction
615#[derive(Accounts)]
616pub struct Withdraw<'info> {
617    /// Wallet of the contract withdrawor.
618    #[account()]
619    pub authority: Signer<'info>,
620    #[account(mut)]
621    /// Wallet address of the recipient.
622    pub recipient: AccountInfo<'info>,
623    /// Associated token account address of `recipient`.
624    #[account(mut)]
625    pub recipient_tokens: Account<'info, TokenAccount>,
626    /// The account holding the contract parameters.
627    /// Expects initialized account.
628    #[account(mut)]
629    pub metadata: AccountInfo<'info>,
630    /// The escrow account holding the funds.
631    /// Should be a PDA, use `streamflow_sdk::state::find_escrow_account` to derive
632    /// Expects initialized account.
633    #[account(mut)]
634    pub escrow_tokens: Account<'info, TokenAccount>,
635    /// Streamflow treasury account.
636    /// Use constant `streamflow_sdk::state::STRM_TREASURY`
637    #[account(mut)]
638    pub streamflow_treasury: AccountInfo<'info>,
639    /// Associated token account address of `streamflow_treasury`.
640    #[account(mut)]
641    pub streamflow_treasury_tokens: AccountInfo<'info>,
642    /// Partner treasury account. If no partner fees are expected on behalf of the program
643    /// integrating with streamflow, `streamflow_treasury` can be passed in here.
644    /// Must match partner account in contract metadata.
645    #[account(mut)]
646    pub partner: AccountInfo<'info>,
647    /// Associated token account address of `partner`. If no partner fees are expected on behalf of the
648    /// program integrating with streamflow, `streamflow_treasury_tokens` can be passed in here.
649    /// Must match partner token account in contract metadata.
650    #[account(mut)]
651    pub partner_tokens: AccountInfo<'info>,
652    /// The SPL token mint account.
653    #[account(mut)]
654    pub mint: Account<'info, Mint>,
655    /// The SPL program needed in case an associated account
656    /// for the new recipient is being created.
657    pub token_program: Program<'info, Token>,
658}
659
660/// Accounts expected in cancel instruction
661#[derive(Accounts)]
662pub struct Cancel<'info> {
663    /// Wallet that initiates contract cancel.
664    #[account()]
665    pub authority: Signer<'info>,
666    /// Wallet of the contract creator.
667    #[account(mut)]
668    pub sender: AccountInfo<'info>,
669    /// Associated token account address of `sender`.
670    #[account(mut)]
671    pub sender_tokens: Account<'info, TokenAccount>,
672    /// Wallet address of the recipient.
673    #[account(mut)]
674    pub recipient: AccountInfo<'info>,
675    /// Associated token account address of `recipient`.
676    #[account(mut)]
677    pub recipient_tokens: Account<'info, TokenAccount>,
678    /// The account holding the contract parameters.
679    /// Expects initialized account.
680    #[account(mut)]
681    pub metadata: AccountInfo<'info>,
682    /// The escrow account holding the funds.
683    /// Should be a PDA, use `streamflow_sdk::state::find_escrow_account` to derive
684    /// Expects initialized account.
685    #[account(mut)]
686    pub escrow_tokens: Account<'info, TokenAccount>,
687    /// Streamflow treasury account.
688    /// Use constant `streamflow_sdk::state::STRM_TREASURY`
689    #[account(mut)]
690    pub streamflow_treasury: AccountInfo<'info>,
691    /// Associated token account address of `streamflow_treasury`.
692    #[account(mut)]
693    pub streamflow_treasury_tokens: AccountInfo<'info>,
694    /// Partner treasury account. If no partner fees are expected on behalf of the program
695    /// integrating with streamflow, `streamflow_treasury` can be passed in here. Must match partner
696    /// account in contract metadata.
697    #[account(mut)]
698    pub partner: AccountInfo<'info>,
699    /// Associated token account address of `partner`. If no partner fees are expected on behalf of the
700    /// program integrating with streamflow, `streamflow_treasury_tokens` can be passed in here.
701    /// Must match partner token account in contract metadata.
702    #[account(mut)]
703    pub partner_tokens: AccountInfo<'info>,
704    /// The SPL token mint account.
705    #[account(mut)]
706    pub mint: Account<'info, Mint>,
707    /// The SPL program needed in case an associated account
708    /// for the new recipient is being created.
709    pub token_program: Program<'info, Token>,
710}
711
712/// Accounts expected in transfer instruction
713#[derive(Accounts)]
714pub struct Transfer<'info> {
715    /// Wallet that initiates contract transfer.
716    #[account(mut)]
717    pub authority: Signer<'info>,
718    /// Wallet address of the new contract recipient
719    #[account(mut)]
720    pub new_recipient: AccountInfo<'info>,
721    /// Wallet address of the new contract recipient's token account
722    #[account(mut)]
723    pub new_recipient_tokens: AccountInfo<'info>,
724    /// The account holding the contract parameters.
725    /// Expects initialized account.
726    #[account(mut)]
727    pub metadata: AccountInfo<'info>,
728    /// The SPL token mint account.
729    pub mint: Account<'info, Mint>,
730    /// The Rent Sysvar account.
731    pub rent: Sysvar<'info, Rent>,
732    /// The SPL program needed in case an associated account
733    /// for the new recipient is being created.
734    pub token_program: Program<'info, Token>,
735    /// The Associated Token program needed in case associated
736    /// account for the new recipient is being created.
737    pub associated_token_program: Program<'info, AssociatedToken>,
738    /// The Solana system program needed for account creation.
739    pub system_program: Program<'info, System>,
740}
741
742/// Accounts expected in topup instruction
743#[derive(Accounts)]
744pub struct Topup<'info> {
745    /// Wallet of the contract creator.
746    #[account(mut)]
747    pub sender: Signer<'info>,
748    /// Associated token account address of `sender`.
749    #[account(mut)]
750    pub sender_tokens: AccountInfo<'info>,
751    /// The account holding the contract parameters.
752    /// Expects initialized account.
753    #[account(mut)]
754    pub metadata: AccountInfo<'info>,
755    /// The escrow account holding the funds.
756    /// Should be a PDA, use `streamflow_sdk::state::find_escrow_account` to derive
757    /// Expects initialized account.
758    #[account(mut)]
759    pub escrow_tokens: Account<'info, TokenAccount>,
760    /// Streamflow treasury account.
761    /// Use constant `streamflow_sdk::state::STRM_TREASURY`
762    #[account(mut)]
763    pub streamflow_treasury: AccountInfo<'info>,
764    /// Associated token account address of `streamflow_treasury`.
765    #[account(mut)]
766    pub streamflow_treasury_tokens: AccountInfo<'info>,
767    /// Delegate account for automatically withdrawing contracts.
768    /// Use constant `streamflow_sdk::state::WITHDRAWOR_ADDRESS`
769    #[account(mut)]
770    pub withdrawor: AccountInfo<'info>,
771    /// Partner treasury account. If no partner fees are expected on behalf of the program
772    /// integrating with streamflow, `streamflow_treasury` can be passed in here. Must match partner
773    /// account in contract metadata.
774    #[account(mut)]
775    pub partner: AccountInfo<'info>,
776    /// Associated token account address of `partner`. If no partner fees are expected on behalf of the
777    /// program integrating with streamflow, `streamflow_treasury_tokens` can be passed in here.
778    /// Must match partner token account in contract metadata.
779    #[account(mut)]
780    pub partner_tokens: AccountInfo<'info>,
781    /// The SPL token mint account.
782    pub mint: Account<'info, Mint>,
783    /// The SPL program needed in case an associated account
784    /// for the new recipient is being created.
785    pub token_program: Program<'info, Token>,
786    /// The Solana system program needed for account creation.
787    pub system_program: Program<'info, System>,
788}