Repository navigation
fix: add native flavor for token-swap example #778
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| mod create_amm; | ||
| mod create_pool; | ||
| mod deposit_liquidity; | ||
| mod swap_exact_tokens_for_tokens; | ||
| mod withdraw_liquidity; | ||
|
|
||
| pub use create_amm::*; | ||
| pub use create_pool::*; | ||
| pub use deposit_liquidity::*; | ||
| pub use swap_exact_tokens_for_tokens::*; | ||
| pub use withdraw_liquidity::*; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| use solana_program::{ | ||
| account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey, | ||
| }; | ||
|
|
||
| entrypoint!(process_instruction); | ||
|
|
||
| fn process_instruction( | ||
| program_id: &Pubkey, | ||
| accounts: &[AccountInfo], | ||
| instruction_data: &[u8], | ||
| ) -> ProgramResult { | ||
| msg!("Token Swap Program Entry"); | ||
| // Aqui você adiciona a lógica para processar as instruções | ||
| Ok(()) | ||
|
Comment on lines
+12
to
+14
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| import { | ||
| type Address, | ||
| appendTransactionMessageInstruction, | ||
| createTransactionMessage, | ||
| generateKeyPairSigner, | ||
| getAddressEncoder, | ||
| getProgramDerivedAddress, | ||
| type Instruction, | ||
| type KeyPairSigner, | ||
| lamports, | ||
| pipe, | ||
| setTransactionMessageFeePayerSigner, | ||
| signTransactionMessageWithSigners, | ||
| unwrapOption, | ||
| } from '@solana/kit'; | ||
| import { findAssociatedTokenPda, getMintDecoder, getTokenDecoder, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token'; | ||
| import { assert } from 'chai'; | ||
| import { FailedTransactionMetadata, LiteSVM } from 'litesvm'; | ||
| import { | ||
| createCreateAmmInstruction, | ||
| createCreatePoolInstruction, | ||
| createDepositLiquidityInstruction, | ||
| createSwapExactTokensForTokensInstruction, | ||
| createWithdrawLiquidityInstruction, | ||
| } from '../ts'; | ||
|
Comment on lines
+19
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| const addressEncoder = getAddressEncoder(); | ||
|
|
||
| describe('Token Swap', () => { | ||
| const svm = new LiteSVM(); | ||
| let programId: Address; | ||
| let payer: KeyPairSigner; | ||
| let tokenMintKeypair1: KeyPairSigner; | ||
| let tokenMintKeypair2: KeyPairSigner; | ||
| let ammKeypair: KeyPairSigner; | ||
| let poolKeypair: KeyPairSigner; | ||
|
|
||
| before(async () => { | ||
| programId = (await generateKeyPairSigner()).address; | ||
| svm.addProgramFromFile(programId, 'tests/fixtures/token_swap_program.so'); | ||
|
|
||
| payer = await generateKeyPairSigner(); | ||
| svm.airdrop(payer.address, lamports(10_000_000_000n)); | ||
|
|
||
| tokenMintKeypair1 = await generateKeyPairSigner(); | ||
| tokenMintKeypair2 = await generateKeyPairSigner(); | ||
| ammKeypair = await generateKeyPairSigner(); | ||
| poolKeypair = await generateKeyPairSigner(); | ||
|
Comment on lines
+45
to
+48
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The setup generates mint keypairs but never creates or initializes the mints, creates the payer's token accounts, or gives the payer tokens. The SOL airdrop cannot fund token deposits. Add this setup so the deposit and swap cases can exercise real token transfers once the handlers are implemented. |
||
| }); | ||
|
|
||
| async function sendTransaction(ix: Instruction) { | ||
| const transactionMessage = pipe( | ||
| createTransactionMessage({ version: 0 }), | ||
| m => setTransactionMessageFeePayerSigner(payer, m), | ||
| m => svm.setTransactionMessageLifetimeUsingLatestBlockhash(m), | ||
| m => appendTransactionMessageInstruction(ix, m), | ||
| ); | ||
| const signedTx = await signTransactionMessageWithSigners(transactionMessage); | ||
| const result = svm.sendTransaction(signedTx); | ||
| assert(!(result instanceof FailedTransactionMetadata), `transaction failed: ${result.toString()}`); | ||
| } | ||
|
|
||
| it('Create AMM!', async () => { | ||
| const ix = createCreateAmmInstruction( | ||
| ammKeypair, | ||
| payer.address, | ||
| programId, | ||
| ); | ||
|
|
||
| await sendTransaction(ix); | ||
|
|
||
| const ammInfo = svm.getAccount(ammKeypair.address); | ||
| assert(ammInfo.exists, 'amm account not created'); | ||
| }); | ||
|
|
||
| it('Create Pool!', async () => { | ||
| const ix = createCreatePoolInstruction( | ||
| poolKeypair, | ||
| payer.address, | ||
| ammKeypair.address, | ||
| tokenMintKeypair1.address, | ||
| tokenMintKeypair2.address, | ||
| payer, | ||
| programId, | ||
| ); | ||
|
|
||
| await sendTransaction(ix); | ||
|
|
||
| const poolInfo = svm.getAccount(poolKeypair.address); | ||
| assert(poolInfo.exists, 'pool account not created'); | ||
| }); | ||
|
|
||
| it('Deposit Liquidity!', async () => { | ||
| const ix = createDepositLiquidityInstruction( | ||
| poolKeypair.address, | ||
| payer.address, | ||
| tokenMintKeypair1.address, | ||
| tokenMintKeypair2.address, | ||
| payer, | ||
| programId, | ||
| 100n, | ||
| 100n, | ||
| ); | ||
|
|
||
| await sendTransaction(ix); | ||
|
|
||
| const poolInfo = svm.getAccount(poolKeypair.address); | ||
| assert(poolInfo.exists, 'pool account not updated'); | ||
|
Comment on lines
+107
to
+108
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The deposit, swap, and withdrawal tests only check that the pool still exists. Once the pool is created, these assertions also pass when an operation returns success without doing anything. Check the payer and pool token balances, plus liquidity tokens minted or burned, after each operation. |
||
| }); | ||
|
|
||
| it('Swap Exact Tokens For Tokens!', async () => { | ||
| const ix = createSwapExactTokensForTokensInstruction( | ||
| poolKeypair.address, | ||
| payer.address, | ||
| tokenMintKeypair1.address, | ||
| tokenMintKeypair2.address, | ||
| payer, | ||
| programId, | ||
| 50n, | ||
| ); | ||
|
|
||
| await sendTransaction(ix); | ||
|
|
||
| const poolInfo = svm.getAccount(poolKeypair.address); | ||
| assert(poolInfo.exists, 'pool account not updated'); | ||
| }); | ||
|
|
||
| it('Withdraw Liquidity!', async () => { | ||
| const ix = createWithdrawLiquidityInstruction( | ||
| poolKeypair.address, | ||
| payer.address, | ||
| tokenMintKeypair1.address, | ||
| tokenMintKeypair2.address, | ||
| payer, | ||
| programId, | ||
| 50n, | ||
| ); | ||
|
|
||
| await sendTransaction(ix); | ||
|
|
||
| const poolInfo = svm.getAccount(poolKeypair.address); | ||
| assert(poolInfo.exists, 'pool account not updated'); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new program has no
program/Cargo.tomland is not included in the root Cargo workspace. There is no crate to build these sources or produce the program file loaded by the tests. Add the manifest, dependencies, and build wiring.