repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | use anchor_lang::prelude::*; |
| #2 | use anchor_spl::token::{self, Mint, Token, TokenAccount, Transfer}; |
| #3 | |
| #4 | declare_id!("FyeRokiKoSz9VxRdgDEuKVKwWuGsZLEbMkywgJQDXeFK"); |
| #5 | |
| #6 | #[program] |
| #7 | pub mod escrow { |
| #8 | use super::*; |
| #9 | |
| #10 | /// Initialize an escrow account |
| #11 | /// |
| #12 | /// This creates an escrow state that defines the terms of the exchange: |
| #13 | /// - The initializer deposits token A |
| #14 | /// - The taker must provide token B to complete the exchange |
| #15 | pub fn initialize( |
| #16 | ctx: Context<Initialize>, |
| #17 | amount: u64, |
| #18 | taker_amount: u64, |
| #19 | ) -> Result<()> { |
| #20 | let escrow = &mut ctx.accounts.escrow; |
| #21 | |
| #22 | escrow.initializer = ctx.accounts.initializer.key(); |
| #23 | escrow.initializer_token_account = ctx.accounts.initializer_deposit_token_account.key(); |
| #24 | escrow.initializer_amount = amount; |
| #25 | escrow.taker_amount = taker_amount; |
| #26 | escrow.escrow_token_account = ctx.accounts.escrow_token_account.key(); |
| #27 | escrow.bump = ctx.bumps.escrow; |
| #28 | |
| #29 | // Transfer tokens from initializer to escrow |
| #30 | let cpi_accounts = Transfer { |
| #31 | from: ctx.accounts.initializer_deposit_token_account.to_account_info(), |
| #32 | to: ctx.accounts.escrow_token_account.to_account_info(), |
| #33 | authority: ctx.accounts.initializer.to_account_info(), |
| #34 | }; |
| #35 | let cpi_program = ctx.accounts.token_program.to_account_info(); |
| #36 | let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); |
| #37 | token::transfer(cpi_ctx, amount)?; |
| #38 | |
| #39 | msg!("Escrow initialized: {} tokens deposited", amount); |
| #40 | Ok(()) |
| #41 | } |
| #42 | |
| #43 | /// Execute the escrow exchange |
| #44 | /// |
| #45 | /// The taker deposits their tokens and receives the initializer's tokens. |
| #46 | /// The initializer receives the taker's tokens. |
| #47 | pub fn exchange(ctx: Context<Exchange>) -> Result<()> { |
| #48 | let escrow = &ctx.accounts.escrow; |
| #49 | |
| #50 | // Transfer taker's tokens to initializer |
| #51 | let cpi_accounts = Transfer { |
| #52 | from: ctx.accounts.taker_deposit_token_account.to_account_info(), |
| #53 | to: ctx.accounts.initializer_receive_token_account.to_account_info(), |
| #54 | authority: ctx.accounts.taker.to_account_info(), |
| #55 | }; |
| #56 | let cpi_program = ctx.accounts.token_program.to_account_info(); |
| #57 | let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); |
| #58 | token::transfer(cpi_ctx, escrow.taker_amount)?; |
| #59 | |
| #60 | // Transfer initializer's tokens from escrow to taker |
| #61 | let seeds = &[ |
| #62 | b"escrow".as_ref(), |
| #63 | escrow.initializer.as_ref(), |
| #64 | &[escrow.bump], |
| #65 | ]; |
| #66 | let signer = &[&seeds[..]]; |
| #67 | |
| #68 | let cpi_accounts = Transfer { |
| #69 | from: ctx.accounts.escrow_token_account.to_account_info(), |
| #70 | to: ctx.accounts.taker_receive_token_account.to_account_info(), |
| #71 | authority: ctx.accounts.escrow.to_account_info(), |
| #72 | }; |
| #73 | let cpi_program = ctx.accounts.token_program.to_account_info(); |
| #74 | let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer); |
| #75 | token::transfer(cpi_ctx, escrow.initializer_amount)?; |
| #76 | |
| #77 | msg!("Escrow exchange completed successfully"); |
| #78 | Ok(()) |
| #79 | } |
| #80 | |
| #81 | /// Cancel the escrow and return tokens to initializer |
| #82 | pub fn cancel(ctx: Context<Cancel>) -> Result<()> { |
| #83 | let escrow = &ctx.accounts.escrow; |
| #84 | |
| #85 | // Transfer tokens back from escrow to initializer |
| #86 | let seeds = &[ |
| #87 | b"escrow".as_ref(), |
| #88 | escrow.initializer.as_ref(), |
| #89 | &[escrow.bump], |
| #90 | ]; |
| #91 | let signer = &[&seeds[..]]; |
| #92 | |
| #93 | let cpi_accounts = Transfer { |
| #94 | from: ctx.accounts.escrow_token_account.to_account_info(), |
| #95 | to: ctx.accounts.initializer_deposit_token_account.to_account_info(), |
| #96 | authority: ctx.accounts.escrow.to_account_info(), |
| #97 | }; |
| #98 | let cpi_program = ctx.accounts.token_program.to_account_info(); |
| #99 | let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer); |
| #100 | token::transfer(cpi_ctx, escrow.initializer_amount)?; |
| #101 | |
| #102 | msg!("Escrow cancelled, tokens returned to initializer"); |
| #103 | Ok(()) |
| #104 | } |
| #105 | } |
| #106 | |
| #107 | #[derive(Accounts)] |
| #108 | pub struct Initialize<'info> { |
| #109 | #[account(mut)] |
| #110 | pub initializer: Signer<'info>, |
| #111 | |
| #112 | #[account( |
| #113 | init, |
| #114 | payer = initializer, |
| #115 | space = 8 + EscrowState::INIT_SPACE, |
| #116 | seeds = [b"escrow", initializer.key().as_ref()], |
| #117 | bump |
| #118 | )] |
| #119 | pub escrow: Account<'info, EscrowState>, |
| #120 | |
| #121 | #[account(mut)] |
| #122 | pub initializer_deposit_token_account: Account<'info, TokenAccount>, |
| #123 | |
| #124 | pub mint: Account<'info, Mint>, |
| #125 | |
| #126 | #[account( |
| #127 | init, |
| #128 | payer = initializer, |
| #129 | token::mint = mint, |
| #130 | token::authority = escrow, |
| #131 | seeds = [b"escrow_token", initializer.key().as_ref()], |
| #132 | bump |
| #133 | )] |
| #134 | pub escrow_token_account: Account<'info, TokenAccount>, |
| #135 | |
| #136 | pub system_program: Program<'info, System>, |
| #137 | pub token_program: Program<'info, Token>, |
| #138 | } |
| #139 | |
| #140 | #[derive(Accounts)] |
| #141 | pub struct Exchange<'info> { |
| #142 | #[account(mut)] |
| #143 | pub taker: Signer<'info>, |
| #144 | |
| #145 | #[account( |
| #146 | mut, |
| #147 | seeds = [b"escrow", escrow.initializer.as_ref()], |
| #148 | bump = escrow.bump, |
| #149 | close = initializer |
| #150 | )] |
| #151 | pub escrow: Account<'info, EscrowState>, |
| #152 | |
| #153 | #[account(mut)] |
| #154 | pub taker_deposit_token_account: Account<'info, TokenAccount>, |
| #155 | |
| #156 | #[account(mut)] |
| #157 | pub taker_receive_token_account: Account<'info, TokenAccount>, |
| #158 | |
| #159 | #[account(mut)] |
| #160 | pub initializer_receive_token_account: Account<'info, TokenAccount>, |
| #161 | |
| #162 | #[account( |
| #163 | mut, |
| #164 | seeds = [b"escrow_token", escrow.initializer.as_ref()], |
| #165 | bump |
| #166 | )] |
| #167 | pub escrow_token_account: Account<'info, TokenAccount>, |
| #168 | |
| #169 | /// CHECK: This is the initializer account that will receive rent |
| #170 | #[account(mut)] |
| #171 | pub initializer: AccountInfo<'info>, |
| #172 | |
| #173 | pub token_program: Program<'info, Token>, |
| #174 | } |
| #175 | |
| #176 | #[derive(Accounts)] |
| #177 | pub struct Cancel<'info> { |
| #178 | #[account(mut)] |
| #179 | pub initializer: Signer<'info>, |
| #180 | |
| #181 | #[account( |
| #182 | mut, |
| #183 | seeds = [b"escrow", initializer.key().as_ref()], |
| #184 | bump = escrow.bump, |
| #185 | has_one = initializer, |
| #186 | close = initializer |
| #187 | )] |
| #188 | pub escrow: Account<'info, EscrowState>, |
| #189 | |
| #190 | #[account(mut)] |
| #191 | pub initializer_deposit_token_account: Account<'info, TokenAccount>, |
| #192 | |
| #193 | #[account( |
| #194 | mut, |
| #195 | seeds = [b"escrow_token", initializer.key().as_ref()], |
| #196 | bump |
| #197 | )] |
| #198 | pub escrow_token_account: Account<'info, TokenAccount>, |
| #199 | |
| #200 | pub token_program: Program<'info, Token>, |
| #201 | } |
| #202 | |
| #203 | #[account] |
| #204 | #[derive(InitSpace)] |
| #205 | pub struct EscrowState { |
| #206 | pub initializer: Pubkey, |
| #207 | pub initializer_token_account: Pubkey, |
| #208 | pub initializer_amount: u64, |
| #209 | pub taker_amount: u64, |
| #210 | pub escrow_token_account: Pubkey, |
| #211 | pub bump: u8, |
| #212 | } |
| #213 | |
| #214 | #[error_code] |
| #215 | pub enum EscrowError { |
| #216 | #[msg("The provided amount must be greater than zero")] |
| #217 | InvalidAmount, |
| #218 | } |
| #219 |