Skip to content

Commit

Permalink
Add READMEs for SDKs on npmjs and crates (#449)
Browse files Browse the repository at this point in the history
* Add README for TS Whirlpool-Client SDK

* Add orca_whirlpools_client README

* Add orca_whirlpools_core Readme

* Add README for TS Whirlpools Core

* Add note

* Fix typos

* Resolve comments

* Fix title

* Fix comment

* Resolve comment

---------

Co-authored-by: calintje <csimon@orca.so>
  • Loading branch information
calintje and calintje authored Nov 5, 2024
1 parent 8d755d6 commit a418902
Show file tree
Hide file tree
Showing 4 changed files with 341 additions and 4 deletions.
92 changes: 91 additions & 1 deletion rust-sdk/client/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
# Orca Whirlpools Rust Client
# Orca Whirlpools Client SDK

## Overview
This package provides developers with low-level functionalities for interacting with the Whirlpool Program on Solana. It serves as a foundational tool that allows developers to manage and integrate detailed operations into their Rust projects, particularly those related to Orca's Whirlpool Program. This package offers granular control for advanced use cases.

> NOTE: To ensure compatibility, use version 1.18 of the `solana-sdk` crate, which matches the version used to build the Whirlpool program.
## Key Features
- **Codama Client**: The package includes a set of generated client code based on the Whirlpool Program IDL. This ensures all the necessary program information is easily accessible in a structured format. It handles all decoding and encoding of instructions and account data, making it much easier to interact with the program.
- **PDA (Program Derived Addresses) Utilities**: This feature contains utility functions that help derive Program Derived Addresses (PDAs) for accounts within the Whirlpool Program, simplifying address derivation for developers.

## Installation
```bash
cargo add orca_whirlpools_client
```

## Usage
Here are some basic examples of how to use the package:

### Deriving a PDA
To derive a PDA for a Whirlpool account, you can use the `get_whirlpool_address` PDA utility.

```rust
use orca_whirlpools_client::get_whirlpool_address;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

fn main() {
let whirlpool_config_address = Pubkey::from_str("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR").unwrap();
let token_mint_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap(); // wSOL
let token_mint_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // DevUSDC
let tick_spacing = 64;

let (whirlpool_pda, _bump) = get_whirlpool_address(&whirlpool_config_address, &token_mint_a, &token_mint_b, tick_spacing).unwrap();
println!("{:?}", whirlpool_pda);
}
```

### Example: Initialize Pool Instruction

The following example demonstrates how to create an `InitializePool` instruction:

```rust
use orca_whirlpools_client::{
instructions::InitializePoolV2Builder,
get_fee_tier_address,
get_token_badge_address,
get_whirlpool_address,
};
use solana_sdk::{
pubkey::Pubkey,
signer::{keypair::Keypair, Signer},
};
use std::str::FromStr;

fn main() {
let whirlpool_config_address = Pubkey::from_str("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR").unwrap();
let token_mint_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap(); // wSOL
let token_mint_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // DevUSDC
let (token_badge_a, _bump) = get_token_badge_address(&whirlpool_config_address, &token_mint_a).unwrap();
let (token_badge_b, _bump) = get_token_badge_address(&whirlpool_config_address, &token_mint_b).unwrap();
let wallet = Keypair::new(); // CAUTION: this wallet is not persistent
let tick_spacing = 8;
let (whirlpool_pda, _bump) = get_whirlpool_address(&whirlpool_config_address, &token_mint_a, &token_mint_b, tick_spacing).unwrap();
let token_vault_a = Keypair::new();
let token_vault_b = Keypair::new();
let (fee_tier, _bump) = get_fee_tier_address(&whirlpool_config_address, tick_spacing).unwrap();
let token_program_a = Pubkey::from_str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").unwrap();
let token_program_b = Pubkey::from_str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").unwrap();
let initial_sqrt_price = 7459106261056563200u128;

let initialize_pool_v2_instruction = InitializePoolV2Builder::new()
.whirlpools_config(whirlpool_config_address)
.token_mint_a(token_mint_a)
.token_mint_b(token_mint_b)
.token_badge_a(token_badge_a)
.token_badge_b(token_badge_b)
.funder(wallet.pubkey())
.whirlpool(whirlpool_pda)
.token_vault_a(token_vault_a.pubkey())
.token_vault_b(token_vault_b.pubkey())
.fee_tier(fee_tier)
.token_program_a(token_program_a)
.token_program_b(token_program_b)
.tick_spacing(tick_spacing)
.initial_sqrt_price(initial_sqrt_price)
.instruction();

println!("{:?}", initialize_pool_v2_instruction);
}
```
80 changes: 79 additions & 1 deletion rust-sdk/core/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,79 @@
# Orca Whirlpools Rust Core
# Orca Whirlpools Core SDK

This package provides developers with advanced functionalities for interacting with the Whirlpool Program on Solana. The Core SDK offers convenient methods for math calculations, quotes, and other utilities, making it easier to manage complex liquidity and swap operations within Rust projects. It serves as the foundation for the High-Level SDK, providing key building blocks that enable developers to perform sophisticated actions while maintaining control over core details.

## Key Features

- **Math Library**: Contains a variety of functions for math operations related to bundles, positions, prices, ticks, and tokens, including calculations such as determining position status or price conversions.
- **Quote Library**: Provides utility functions for generating quotes, such as increasing liquidity, collecting fees or rewards, and swapping, enabling precise and optimized decision-making in liquidity management.

## Installation
```bash
cargo add orca_whirlpools_core
```

## Usage
Here are some basic examples of how to use the package:

### Math Example
The following example demonstrates how to use the `is_position_in_range` function to determine whether a position is currently in range.

```rust
use orca_whirlpools_core::is_position_in_range;

fn main() {
let current_sqrt_price = 7448043534253661173u128;
let tick_index_1 = -18304;
let tick_index_2 = -17956;

let in_range = is_position_in_range(current_sqrt_price.into(), tick_index_1, tick_index_2);
println!("Position in range? {:?}", in_range);
}
```

Expected output:
```
Position in range? true
```

### Quote Example

The following example demonstrates how to use the increase_liquidity_quote_a function to calculate a quote for increasing liquidity given a token A amount.

```rust
use orca_whirlpools_core::increase_liquidity_quote_a;
use orca_whirlpools_core::TransferFee;

fn main() {
let token_amount_a = 1000000000u64;
let slippage_tolerance_bps = 100u16;
let current_sqrt_price = 7437568627975669726u128;
let tick_index_1 = -18568;
let tick_index_2 = -17668;
let transfer_fee_a = Some(TransferFee::new(200));
let transfer_fee_b = None;

let quote = increase_liquidity_quote_a(
token_amount_a,
slippage_tolerance_bps,
current_sqrt_price.into(),
tick_index_1,
tick_index_2,
transfer_fee_a,
transfer_fee_b,
).unwrap();

println!("{:?}", quote);
}
```

Expected output:
```
IncreaseLiquidityQuote {
liquidity_delta: 16011047470,
token_est_a: 1000000000,
token_est_b: 127889169,
token_max_a: 1010000000,
token_max_b: 129168061,
}
```
102 changes: 101 additions & 1 deletion ts-sdk/client/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,101 @@
# Orca Whirlpools Typescript Client
# Orca Whirlpools Client SDK

## Overview
This package provides developers with low-level functionalities for interacting with the Whirlpool Program on Solana. It serves as a foundational tool that allows developers to manage and integrate detailed operations into their Typescript projects, particularly those related to Orca's Whirlpool Program. While a high-level SDK is available for easier integration, [@orca-so/whirlpools](https://www.npmjs.com/package/@orca-so/whirlpools), this package offers more granular control for advanced use cases.

> **Note:** This SDK uses Solana Web3.js SDK v2, which is currently in Release Candidate (RC) status. It is not compatible with the widely used v1.x.x version.
## Key Features
- **Codama Client**: The package includes a set of generated client code based on the Whirlpool Program IDL. This ensures all the necessary program information is easily accessible in a structured format and handles all decoding and encoding of instructions and account data, making it much easier to interact with the program.
- **GPA (Get Program Accounts) Filters**: This feature contains utilities to add filters to program accounts, allowing developers to fetch program account data more selectively and efficiently.
- **PDA (Program Derived Addresses) Utilities**: This feature contains utility functions that help derive Program Derived Addresses (PDAs) for accounts within the Whirlpool Program, simplifying address generation for developers.

## Installation
You can install the package via npm:

```bash
npm install @orca-so/whirlpools-client
```

## Usage
Here are some basic examples of how to use the package.

### Fetching Whirlpool Accounts with Filters
The following example demonstrates how to fetch Whirlpools accounts based on specific filters, using the GPA utilities:

```tsx
import { createSolanaRpc, address, devnet } from '@solana/web3.js';
import { fetchAllWhirlpoolWithFilter, whirlpoolTokenMintAFilter } from "@orca-so/whirlpools-client";

const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

const tokenMintA = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); //DevUSDC
const filter = whirlpoolTokenMintAFilter(tokenMintA);

const accounts = await fetchAllWhirlpoolWithFilter(rpc, filter);
console.log(accounts);
```

### Deriving a PDA
To derive a PDA for a Whirlpool account, you can use the `getWhirlpoolAddress` PDA utility.

```tsx
import { getWhirlpoolAddress } from "@orca-so/whirlpools-client";
import { address } from '@solana/web3.js';

const whirlpoolConfigAddress = address("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
const tokenMintA = address("So11111111111111111111111111111111111111112"); //wSOL
const tokenMintB = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); //DevUSDC
const tickSpacing = 64;

const whirlpoolPda = await getWhirlpoolAddress(
whirlpoolConfigAddress,
tokenMintA,
tokenMintB,
tickSpacing,
);
console.log(whirlpoolPda);
```

### Example: Initialize Pool Instruction
The following example demonstrates how to create an InitializePool instruction using the Codama-IDL autogenerated code:

```tsx
import { getInitializePoolV2Instruction, getTokenBadgeAddress, getWhirlpoolAddress, getFeeTierAddress } from "@orca-so/whirlpools-client";
import { address, generateKeyPairSigner } from '@solana/web3.js';

const whirlpoolConfigAddress = address("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
const tokenMintA = address("So11111111111111111111111111111111111111112"); // wSOL
const tokenMintB = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); // DevUSDC
const tokenBadgeA = await getTokenBadgeAddress(whirlpoolConfigAddress, tokenMintA)
const tokenBadgeB = await getTokenBadgeAddress(whirlpoolConfigAddress, tokenMintB)
const wallet = await generateKeyPairSigner(); // CAUTION: this wallet is not persistent
const tickSpacing = 8;
const whirlpool = await getWhirlpoolAddress(whirlpoolConfigAddress, tokenMintA, tokenMintB, tickSpacing);
const tokenVaultA = await generateKeyPairSigner();
const tokenVaultB = await generateKeyPairSigner();
const feeTier = await getFeeTierAddress(whirlpoolConfigAddress, tickSpacing);
const tokenProgramA = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const tokenProgramB = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const initialSqrtPrice = BigInt(7459106261056563200n);

const initializePoolInstruction = getInitializePoolV2Instruction({
whirlpoolsConfig: whirlpoolConfigAddress,
tokenMintA,
tokenMintB,
tokenBadgeA,
tokenBadgeB,
funder: wallet,
whirlpool,
tokenVaultA,
tokenVaultB,
feeTier,
whirlpoolBump: 1,
tickSpacing,
tokenProgramA,
tokenProgramB,
initialSqrtPrice
});

console.log(initializePoolInstruction);
```
71 changes: 70 additions & 1 deletion ts-sdk/core/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,70 @@
# Orca Whirlpools Typescript Core
# Orca Whirlpools Core SDK (WebAssembly)
This package provides developers with advanced functionalities for interacting with the Whirlpool Program on Solana. Originally written in Rust, it has been compiled to WebAssembly (Wasm). This compilation makes the SDK accessible in JavaScript/TypeScript environments, offering developers the same core features and calculations for their Typescript projects. The SDK exposes convenient methods for math calculations, quotes, and other utilities, enabling seamless integration within web-based projects.

## Key Features
- **Math Library**: Contains a variety of functions for math operations related to bundles, positions, prices, ticks, and tokens, including calculations such as determining position status or price conversions.
- **Quote Library**: Provides utility functions for generating quotes, such as increasing liquidity, collecting fees or rewards, and swapping, to help developers make informed decisions regarding liquidity management.

## Installation
You can install the package via npm:
```bash
npm install @orca-so/whirlpools-core
```

## Usage
Here are some basic examples of how to use the package:

### Math Example
The following example demonstrates how to use the `isPositionInRange` function to determine whether a position is currently in range.

```tsx
import { isPositionInRange } from "@orca-so/whirlpools-core";

const currentSqrtPrice = 7448043534253661173n;
const tickIndex1 = -18304;
const tickIndex2 = -17956;

const inRange = isPositionInRange(currentSqrtPrice, tickIndex1, tickIndex2);
console.log("Position in range:", inRange);
```

Expected output:
```
Position in range? true
```

### Quote Example
The following example demonstrates how to use the `increaseLiquidityQuoteA` function to calculate a quote for increasing liquidity given a token A amount.

```tsx
import { increaseLiquidityQuoteA } from "@orca-so/whirlpools-core";

const tokenAmountA = 1000000000n;
const slippageToleranceBps = 100;
const currentSqrtPrice = 7437568627975669726n;
const tickIndex1 = -18568;
const tickIndex2 = -17668;
const transferFeeA = { feeBps: 200, maxFee: 1000000000n };

const quote = increaseLiquidityQuoteA(
tokenAmountA,
slippageToleranceBps,
currentSqrtPrice,
tickIndex1,
tickIndex2,
transferFeeA,
);

console.log(quote);
```

Expected output:
```
{
liquidityDelta: 16011047470n,
tokenEstA: 1000000000n,
tokenEstB: 127889169n,
tokenMaxA: 1010000000n,
tokenMaxB: 129168061n
}
```

0 comments on commit a418902

Please sign in to comment.