Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 124 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,111 @@
# RAYDIUM SDK V2 demo
# Raydium SDK V2 Demo

## About the project
## About the Project

This project is for [RAYDIUM SDK V2](https://github.com/raydium-io/raydium-sdk-V2) demonstration
This project demonstrates the usage of the [Raydium SDK V2](https://github.com/raydium-io/raydium-sdk-V2), a powerful toolkit for interacting with the Raydium decentralized exchange (DEX) on the Solana blockchain. It provides examples and utilities for performing various operations such as liquidity management, token swaps, and more.

## Getting Started

### Installation
This documentation is designed to help web2 developers transition into the web3 space by providing clear instructions, explanations, and example codes.

`yarn install`
---

this will install the dependencies for running the demo script
## Getting Started

### Prerequisites

Modify `config.ts.template` to fit your configuration, and rename it to `config.ts`
Before you begin, ensure you have the following:

1. **Node.js and Yarn**: Install [Node.js](https://nodejs.org/) and [Yarn](https://yarnpkg.com/) on your system.
2. **Wallet Secret Key**: A Solana wallet secret key for signing transactions. You can generate one using the [Solana CLI](https://docs.solana.com/cli/install-solana-cli-tools).
3. **RPC URL**: A Solana RPC endpoint for connecting to the blockchain. You can use [QuickNode](https://www.quicknode.com/) or [Alchemy](https://www.alchemy.com/solana) to get an RPC URL.
4. **Raydium API Host (Optional)**: Only required for testing on development environments.

- `<YOUR_WALLET_SECRET_KEY>`: replace to your own one
- `<YOUR_RPC_URL>`: replace to your prefer one
- `<API_HOST>`: by default it's no needed to provide raydium api host, only provide it when test on devent.
### Installation

### Usage
1. Clone the repository:
```bash
git clone https://github.com/raydium-io/raydium-sdk-V2-demo.git
cd raydium-sdk-V2-demo
```

2. Install dependencies:
```bash
yarn install
```

3. Configure the project:
- Copy `config.ts.template` to `config.ts`:
```bash
cp src/config.ts.template src/config.ts
```
- Replace placeholders in `config.ts` with your configuration:
```typescript
export const CONFIG = {
WALLET_SECRET_KEY: '<YOUR_WALLET_SECRET_KEY>', // Your wallet secret key
RPC_URL: '<YOUR_RPC_URL>', // Your preferred RPC URL
API_HOST: '<API_HOST>' // Optional, only needed for development testing
};
```

---

## Usage

### Running Demo Scripts

To run a specific demo script, use the following command:
```bash
yarn dev src/<FOLDER>/<SCRIPT_NAME>
```
Example:
```bash
yarn dev src/cpmm/deposit.ts
```
**Note**: Uncomment the last line in the script if you want to execute transactions.

- `yarn dev src/<FOLDER>/<SCRIPT_NAME>` run the specific demo script, e.g. yarn dev src/cpmm/deposit.ts. **Note: if you want to execute tx, remember to uncomment code in last line**
- `yarn clmm-market 8sLbNZoA1cfnvMJLPfp98ZLAnFSYCFApfJKMbiXNLwxj 10 20` run clmm market maker, arguments 0: poolId, 1: create position deviation, 2: close position deviation, remember to uncomment `close position` and `create new position` code part
### Example: Running a Token Swap

### Sdk Methods
Here is an example of running a token swap using the `swap.ts` script:

#### Transaction methods return data
1. Open the `src/amm/swap.ts` file and ensure the configuration matches your setup.
2. Run the script:
```bash
yarn dev src/amm/swap.ts
```
3. Example output:
```bash
Transaction successful! Swap completed with transaction ID: <TRANSACTION_ID>
```

all transaction related build function (e.g. await raydium.clmm.openPositionFromBase/ await raydium.cpmm.createPool ..etc) will return all transactions and instructions
### Running the CLMM Market Maker

Use the following command to run the CLMM market maker:
```bash
yarn clmm-market <POOL_ID> <CREATE_POSITION_DEVIATION> <CLOSE_POSITION_DEVIATION>
```
const { execute, transaction, builder, extInfo } = await raydium.clmm.openPositionFromBase({ xxx })

Example:
```bash
yarn clmm-market 8sLbNZoA1cfnvMJLPfp98ZLAnFSYCFApfJKMbiXNLwxj 10 20
```
**Note**: Uncomment the `close position` and `create new position` code parts in the script.

---

- `transaction or transactions`: all built transactions
- `builder`: all instructions in transaction. e.g. builder.allInstructions, builder.AllTxData
- `extInfo`: transaction related publicKeys. (e.g: extInfo from raydium.cpmm.createPool includes poolId, programId...etc)
## SDK Methods

#### Fetch pool list by mints (mainnet only)
### Transaction Methods

All transaction-related build functions return the following data:
```javascript
const { execute, transaction, builder, extInfo } = await raydium.clmm.openPositionFromBase({ ...params });
```
import { PoolFetchType } from '@raydium-io/raydium-sdk-v2'
- **`transaction` or `transactions`**: All built transactions.
- **`builder`**: All instructions in the transaction (e.g., `builder.allInstructions`, `builder.AllTxData`).
- **`extInfo`**: Transaction-related public keys (e.g., `poolId`, `programId`).

### Example: Fetch Pool List by Mints (Mainnet Only)

```javascript
import { PoolFetchType } from '@raydium-io/raydium-sdk-v2';

const list = await raydium.api.fetchPoolByMints({
mint1: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', // required
Expand All @@ -52,37 +114,55 @@ const list = await raydium.api.fetchPoolByMints({
sort: 'liquidity', // optional
order: 'desc', // optional
page: 1, // optional
})
});
console.log('Fetched Pool List:', list);
```

### Fetch Mint info from Api or Rpc
### Example: Fetch Mint Info

```
await raydium.token.getTokenInfo('<Mint address>')
```javascript
const mintInfo = await raydium.token.getTokenInfo('<Mint address>');
console.log('Mint Info:', mintInfo);
```

### Fetch token account
### Example: Fetch Token Accounts

```javascript
const tokenAccounts = await raydium.account.fetchWalletTokenAccounts({ forceUpdate: true });
console.log('Token Accounts:', tokenAccounts);
```
await raydium.account.fetchWalletTokenAccounts() // if need to force fetching token account, pass param { forceUpdate: true }
```

### More api methods [check here](https://github.com/raydium-io/raydium-sdk-V2?tab=readme-ov-file#api-methods-httpsgithubcomraydium-ioraydium-sdk-v2blobmastersrcapiapits)
### More API Methods

For more API methods, refer to the [Raydium SDK V2 documentation](https://github.com/raydium-io/raydium-sdk-V2#api-methods).

---

## FAQ

### Common Errors

#### 1. **Error: Block height exceeded / exceeded CUs meter at BPF instruction**
- Transactions expired. Set higher priority fees (`computeBudgetConfig`) to ensure smooth execution.
- For devnet testing, replace the `programId` with the devnet one.

#### 2. **`raydium.api.fetchPoolById` or `raydium.api.fetchFarmInfoById` returns null**
- The API does not support devnet pool/farm data. Test on mainnet.
- Use `raydium.xxxx.getRpcPoolInfos` for devnet `rpc` pool info.
- Newly created pools may take a few minutes to sync data to the API. Use `raydium.xxxx.getRpcPoolInfos` for immediate info.

### FAQ
#### 3. **Create AMM Pool Error**
- **Error Code `0x10001a9`**: Use the provided `createMarket.ts` script to create the market instead of external tools.
- **LP Amount Too Low**: Provide a higher base/quote amount when creating the pool. For SOL/WSOL markets, provide more than 4 SOL (4 * 10^9).

#### Error: block height exceeded / exceeded CUs meter at BPF instruction
---

- transactions were expired, set higher priority fees (computeBudgetConfig) to make it go through smoothly
- if you are testing in devnet, remember to replace programId to devnet one.
## Contributing

#### raydium.api.fetchPoolById/raydium.api.fetchFarmInfoById return null
Contributions are welcome! Feel free to open issues or submit pull requests to improve this project.

- currently api doesn't support devnet pool/farm data, please test on mainnet.
- only raydium.xxxx.getRpcPoolInfos support get devnet `rpc` pool info.
- new created pool needs couple minutes to sync data to api, if you want to get info immediately, use raydium.xxxx.getRpcPoolInfos instead.
---

#### create amm pool error
## License

- `0x10001a9`: you might use https://openbook-tools.dexlab.space/market/create?network=devnet to create devnet market, and they used wrong devent program id, so please use createMarket.ts in demo to create market
- `lp amount is too less`: please provide more base/quote amount when create pool, if there's SOL/WSOL in your market, it's better provide more than 4 sol(4\*10\*\*9) in initial amount.
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
15 changes: 11 additions & 4 deletions src/amm/addLiquidity.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Importing necessary modules and utilities from the Raydium SDK
import {
ApiV3PoolInfoStandardItem,
TokenAmount,
Expand All @@ -13,37 +14,43 @@ import Decimal from 'decimal.js'
import BN from 'bn.js'
import { PublicKey } from '@solana/web3.js'

/**
* Adds liquidity to a specified AMM pool.
*/
export const addLiquidity = async () => {
// Initialize the Raydium SDK
const raydium = await initSdk()

// RAY-USDC pool
// Define the pool ID for the RAY-USDC pool
const poolId = '6UmmUiYoBjSrhakAobJw8BvkmJtDVxaeBtbt7rxWo1mg'
let poolKeys: AmmV4Keys | AmmV5Keys | undefined
let poolInfo: ApiV3PoolInfoStandardItem

if (raydium.cluster === 'mainnet') {
// note: api doesn't support get devnet pool info, so in devnet else we go rpc method
// if you wish to get pool info from rpc, also can modify logic to go rpc method directly
// Fetch pool information from the API (mainnet only)
const data = await raydium.api.fetchPoolById({ ids: poolId })
poolInfo = data[0] as ApiV3PoolInfoStandardItem
} else {
// note: getPoolInfoFromRpc method only return required pool data for computing not all detail pool info
// Fetch pool information from the RPC (for devnet or other clusters)
const data = await raydium.liquidity.getPoolInfoFromRpc({ poolId })
poolInfo = data.poolInfo
poolKeys = data.poolKeys
}

if (!isValidAmm(poolInfo.programId)) throw new Error('target pool is not AMM pool')

// Define the input amount for adding liquidity
const inputAmount = '1'

// Compute the pair amount for the liquidity addition
const r = raydium.liquidity.computePairAmount({
poolInfo,
amount: inputAmount,
baseIn: true,
slippage: new Percent(1, 100), // 1%
})

// Execute the add liquidity transaction
const { execute, transaction } = await raydium.liquidity.addLiquidity({
poolInfo,
poolKeys,
Expand Down
12 changes: 11 additions & 1 deletion src/clmm/createPosition.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
// Importing necessary modules and utilities from the Raydium SDK
import { ApiV3PoolInfoConcentratedItem, TickUtils, PoolUtils, ClmmKeys } from '@raydium-io/raydium-sdk-v2'
import BN from 'bn.js'
import { initSdk, txVersion } from '../config'
import Decimal from 'decimal.js'
import { isValidClmm } from './utils'

/**
* Creates a new position in a CLMM (Concentrated Liquidity Market Maker) pool.
*/
export const createPosition = async () => {
// Initialize the Raydium SDK
const raydium = await initSdk()

let poolInfo: ApiV3PoolInfoConcentratedItem
// RAY-USDC pool
// Define the pool ID for the target CLMM pool
const poolId = '61R1ndXxvsWXXkWSyNkCxnzwd3zUNB8Q2ibmkiLPC8ht'
let poolKeys: ClmmKeys | undefined

if (raydium.cluster === 'mainnet') {
// Fetch pool information from the API (mainnet only)
// note: api doesn't support get devnet pool info, so in devnet else we go rpc method
// if you wish to get pool info from rpc, also can modify logic to go rpc method directly
const data = await raydium.api.fetchPoolById({ ids: poolId })
poolInfo = data[0] as ApiV3PoolInfoConcentratedItem
if (!isValidClmm(poolInfo.programId)) throw new Error('target pool is not CLMM pool')
} else {
// Fetch pool information from the RPC (for devnet or other clusters)
const data = await raydium.clmm.getPoolInfoFromRpc(poolId)
poolInfo = data.poolInfo
poolKeys = data.poolKeys
Expand All @@ -28,9 +35,11 @@ export const createPosition = async () => {
// const rpcData = await raydium.clmm.getRpcClmmPoolInfo({ poolId: poolInfo.id })
// poolInfo.price = rpcData.currentPrice

// Define the input amount and price range for the position
const inputAmount = 0.000001 // RAY amount
const [startPrice, endPrice] = [0.000001, 100000]

// Calculate the tick range based on the price range
const { tick: lowerTick } = TickUtils.getPriceAndTick({
poolInfo,
price: new Decimal(startPrice),
Expand All @@ -56,6 +65,7 @@ export const createPosition = async () => {
epochInfo: epochInfo,
})

// Execute the create position transaction
const { execute, extInfo } = await raydium.clmm.openPositionFromBase({
poolInfo,
poolKeys,
Expand Down
Loading