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 | import * as anchor from "@coral-xyz/anchor"; |
| #2 | import { Program } from "@coral-xyz/anchor"; |
| #3 | import { Escrow } from "../target/types/escrow"; |
| #4 | import { PublicKey, Keypair, SystemProgram } from "@solana/web3.js"; |
| #5 | import { |
| #6 | TOKEN_PROGRAM_ID, |
| #7 | createMint, |
| #8 | createAccount, |
| #9 | mintTo, |
| #10 | getAccount, |
| #11 | } from "@solana/spl-token"; |
| #12 | import { assert } from "chai"; |
| #13 | |
| #14 | describe("escrow", () => { |
| #15 | // Configure the client to use the local cluster. |
| #16 | const provider = anchor.AnchorProvider.env(); |
| #17 | anchor.setProvider(provider); |
| #18 | |
| #19 | const program = anchor.workspace.Escrow as Program<Escrow>; |
| #20 | |
| #21 | let mintA: PublicKey; |
| #22 | let mintB: PublicKey; |
| #23 | let initializerTokenAccountA: PublicKey; |
| #24 | let initializerTokenAccountB: PublicKey; |
| #25 | let takerTokenAccountA: PublicKey; |
| #26 | let takerTokenAccountB: PublicKey; |
| #27 | |
| #28 | let payer: Keypair; |
| #29 | let initializer: PublicKey; |
| #30 | const taker = Keypair.generate(); |
| #31 | |
| #32 | const initializerAmount = 1000; |
| #33 | const takerAmount = 500; |
| #34 | |
| #35 | before(async () => { |
| #36 | // Create a test keypair and fund it |
| #37 | payer = Keypair.generate(); |
| #38 | const airdropSig = await provider.connection.requestAirdrop( |
| #39 | payer.publicKey, |
| #40 | 10 * anchor.web3.LAMPORTS_PER_SOL |
| #41 | ); |
| #42 | await provider.connection.confirmTransaction(airdropSig); |
| #43 | initializer = payer.publicKey; |
| #44 | |
| #45 | // Airdrop SOL to taker |
| #46 | const signature = await provider.connection.requestAirdrop( |
| #47 | taker.publicKey, |
| #48 | 2 * anchor.web3.LAMPORTS_PER_SOL |
| #49 | ); |
| #50 | await provider.connection.confirmTransaction(signature); |
| #51 | |
| #52 | // Create mints |
| #53 | mintA = await createMint( |
| #54 | provider.connection, |
| #55 | payer, |
| #56 | initializer, |
| #57 | null, |
| #58 | 6 |
| #59 | ); |
| #60 | |
| #61 | mintB = await createMint( |
| #62 | provider.connection, |
| #63 | payer, |
| #64 | initializer, |
| #65 | null, |
| #66 | 6 |
| #67 | ); |
| #68 | |
| #69 | // Create token accounts for initializer |
| #70 | initializerTokenAccountA = await createAccount( |
| #71 | provider.connection, |
| #72 | payer, |
| #73 | mintA, |
| #74 | initializer |
| #75 | ); |
| #76 | |
| #77 | initializerTokenAccountB = await createAccount( |
| #78 | provider.connection, |
| #79 | payer, |
| #80 | mintB, |
| #81 | initializer |
| #82 | ); |
| #83 | |
| #84 | // Create token accounts for taker |
| #85 | takerTokenAccountA = await createAccount( |
| #86 | provider.connection, |
| #87 | payer, |
| #88 | mintA, |
| #89 | taker.publicKey |
| #90 | ); |
| #91 | |
| #92 | takerTokenAccountB = await createAccount( |
| #93 | provider.connection, |
| #94 | payer, |
| #95 | mintB, |
| #96 | taker.publicKey |
| #97 | ); |
| #98 | |
| #99 | // Mint tokens to initializer and taker |
| #100 | await mintTo( |
| #101 | provider.connection, |
| #102 | payer, |
| #103 | mintA, |
| #104 | initializerTokenAccountA, |
| #105 | initializer, |
| #106 | initializerAmount |
| #107 | ); |
| #108 | |
| #109 | await mintTo( |
| #110 | provider.connection, |
| #111 | payer, |
| #112 | mintB, |
| #113 | takerTokenAccountB, |
| #114 | initializer, |
| #115 | takerAmount |
| #116 | ); |
| #117 | }); |
| #118 | |
| #119 | it("Initialize escrow", async () => { |
| #120 | const [escrowPda] = PublicKey.findProgramAddressSync( |
| #121 | [Buffer.from("escrow"), initializer.toBuffer()], |
| #122 | program.programId |
| #123 | ); |
| #124 | |
| #125 | const [escrowTokenAccount] = PublicKey.findProgramAddressSync( |
| #126 | [Buffer.from("escrow_token"), initializer.toBuffer()], |
| #127 | program.programId |
| #128 | ); |
| #129 | |
| #130 | await program.methods |
| #131 | .initialize( |
| #132 | new anchor.BN(initializerAmount), |
| #133 | new anchor.BN(takerAmount) |
| #134 | ) |
| #135 | .accounts({ |
| #136 | initializer: initializer, |
| #137 | escrow: escrowPda, |
| #138 | initializerDepositTokenAccount: initializerTokenAccountA, |
| #139 | mint: mintA, |
| #140 | escrowTokenAccount: escrowTokenAccount, |
| #141 | systemProgram: SystemProgram.programId, |
| #142 | tokenProgram: TOKEN_PROGRAM_ID, |
| #143 | }) |
| #144 | .signers([payer]) |
| #145 | .rpc(); |
| #146 | |
| #147 | // Verify escrow state |
| #148 | const escrowAccount = await program.account.escrowState.fetch(escrowPda); |
| #149 | assert.ok(escrowAccount.initializer.equals(initializer)); |
| #150 | assert.ok( |
| #151 | escrowAccount.initializerTokenAccount.equals(initializerTokenAccountA) |
| #152 | ); |
| #153 | assert.strictEqual( |
| #154 | escrowAccount.initializerAmount.toNumber(), |
| #155 | initializerAmount |
| #156 | ); |
| #157 | assert.strictEqual(escrowAccount.takerAmount.toNumber(), takerAmount); |
| #158 | |
| #159 | // Verify tokens were transferred to escrow |
| #160 | const escrowTokenAccountData = await getAccount( |
| #161 | provider.connection, |
| #162 | escrowTokenAccount |
| #163 | ); |
| #164 | assert.strictEqual( |
| #165 | Number(escrowTokenAccountData.amount), |
| #166 | initializerAmount |
| #167 | ); |
| #168 | |
| #169 | // Verify initializer's token account was debited |
| #170 | const initializerTokenAccountData = await getAccount( |
| #171 | provider.connection, |
| #172 | initializerTokenAccountA |
| #173 | ); |
| #174 | assert.strictEqual(Number(initializerTokenAccountData.amount), 0); |
| #175 | }); |
| #176 | |
| #177 | it("Exchange escrow", async () => { |
| #178 | const [escrowPda] = PublicKey.findProgramAddressSync( |
| #179 | [Buffer.from("escrow"), initializer.toBuffer()], |
| #180 | program.programId |
| #181 | ); |
| #182 | |
| #183 | const [escrowTokenAccount] = PublicKey.findProgramAddressSync( |
| #184 | [Buffer.from("escrow_token"), initializer.toBuffer()], |
| #185 | program.programId |
| #186 | ); |
| #187 | |
| #188 | await program.methods |
| #189 | .exchange() |
| #190 | .accounts({ |
| #191 | taker: taker.publicKey, |
| #192 | escrow: escrowPda, |
| #193 | takerDepositTokenAccount: takerTokenAccountB, |
| #194 | takerReceiveTokenAccount: takerTokenAccountA, |
| #195 | initializerReceiveTokenAccount: initializerTokenAccountB, |
| #196 | escrowTokenAccount: escrowTokenAccount, |
| #197 | initializer: initializer, |
| #198 | tokenProgram: TOKEN_PROGRAM_ID, |
| #199 | }) |
| #200 | .signers([taker]) |
| #201 | .rpc(); |
| #202 | |
| #203 | // Verify taker received initializer's tokens |
| #204 | const takerTokenAccountAData = await getAccount( |
| #205 | provider.connection, |
| #206 | takerTokenAccountA |
| #207 | ); |
| #208 | assert.strictEqual( |
| #209 | Number(takerTokenAccountAData.amount), |
| #210 | initializerAmount |
| #211 | ); |
| #212 | |
| #213 | // Verify initializer received taker's tokens |
| #214 | const initializerTokenAccountBData = await getAccount( |
| #215 | provider.connection, |
| #216 | initializerTokenAccountB |
| #217 | ); |
| #218 | assert.strictEqual(Number(initializerTokenAccountBData.amount), takerAmount); |
| #219 | |
| #220 | // Verify taker's deposit account was debited |
| #221 | const takerTokenAccountBData = await getAccount( |
| #222 | provider.connection, |
| #223 | takerTokenAccountB |
| #224 | ); |
| #225 | assert.strictEqual(Number(takerTokenAccountBData.amount), 0); |
| #226 | |
| #227 | // Verify escrow account was closed |
| #228 | try { |
| #229 | await program.account.escrowState.fetch(escrowPda); |
| #230 | assert.fail("Escrow account should be closed"); |
| #231 | } catch (err) { |
| #232 | assert.ok(err.message.includes("Account does not exist")); |
| #233 | } |
| #234 | }); |
| #235 | |
| #236 | it("Initialize and cancel escrow", async () => { |
| #237 | // Use a different payer for this test to avoid PDA collision |
| #238 | const newPayer = Keypair.generate(); |
| #239 | const airdropSig = await provider.connection.requestAirdrop( |
| #240 | newPayer.publicKey, |
| #241 | 10 * anchor.web3.LAMPORTS_PER_SOL |
| #242 | ); |
| #243 | await provider.connection.confirmTransaction(airdropSig); |
| #244 | |
| #245 | // Create new token account for this payer |
| #246 | const newInitializerTokenAccount = await createAccount( |
| #247 | provider.connection, |
| #248 | newPayer, |
| #249 | mintA, |
| #250 | newPayer.publicKey |
| #251 | ); |
| #252 | |
| #253 | // Mint tokens to new account (using original payer as mint authority) |
| #254 | await mintTo( |
| #255 | provider.connection, |
| #256 | payer, |
| #257 | mintA, |
| #258 | newInitializerTokenAccount, |
| #259 | initializer, |
| #260 | initializerAmount |
| #261 | ); |
| #262 | |
| #263 | const [escrowPda] = PublicKey.findProgramAddressSync( |
| #264 | [Buffer.from("escrow"), newPayer.publicKey.toBuffer()], |
| #265 | program.programId |
| #266 | ); |
| #267 | |
| #268 | const [escrowTokenAccount] = PublicKey.findProgramAddressSync( |
| #269 | [Buffer.from("escrow_token"), newPayer.publicKey.toBuffer()], |
| #270 | program.programId |
| #271 | ); |
| #272 | |
| #273 | // Initialize new escrow |
| #274 | await program.methods |
| #275 | .initialize( |
| #276 | new anchor.BN(initializerAmount), |
| #277 | new anchor.BN(takerAmount) |
| #278 | ) |
| #279 | .accounts({ |
| #280 | initializer: newPayer.publicKey, |
| #281 | escrow: escrowPda, |
| #282 | initializerDepositTokenAccount: newInitializerTokenAccount, |
| #283 | mint: mintA, |
| #284 | escrowTokenAccount: escrowTokenAccount, |
| #285 | systemProgram: SystemProgram.programId, |
| #286 | tokenProgram: TOKEN_PROGRAM_ID, |
| #287 | }) |
| #288 | .signers([newPayer]) |
| #289 | .rpc(); |
| #290 | |
| #291 | // Cancel the escrow |
| #292 | await program.methods |
| #293 | .cancel() |
| #294 | .accounts({ |
| #295 | initializer: newPayer.publicKey, |
| #296 | escrow: escrowPda, |
| #297 | initializerDepositTokenAccount: newInitializerTokenAccount, |
| #298 | escrowTokenAccount: escrowTokenAccount, |
| #299 | tokenProgram: TOKEN_PROGRAM_ID, |
| #300 | }) |
| #301 | .signers([newPayer]) |
| #302 | .rpc(); |
| #303 | |
| #304 | // Verify tokens were returned to initializer |
| #305 | const initializerTokenAccountData = await getAccount( |
| #306 | provider.connection, |
| #307 | newInitializerTokenAccount |
| #308 | ); |
| #309 | assert.strictEqual( |
| #310 | Number(initializerTokenAccountData.amount), |
| #311 | initializerAmount |
| #312 | ); |
| #313 | |
| #314 | // Verify escrow account was closed |
| #315 | try { |
| #316 | await program.account.escrowState.fetch(escrowPda); |
| #317 | assert.fail("Escrow account should be closed"); |
| #318 | } catch (err) { |
| #319 | assert.ok(err.message.includes("Account does not exist")); |
| #320 | } |
| #321 | }); |
| #322 | }); |
| #323 |